Re: Processes freezing in D state

Stephen C. Tweedie (sct@redhat.com)
Mon, 25 Jan 1999 16:50:26 GMT


Hi,

On Fri, 22 Jan 1999 11:04:04 -0500, Andrew Lewycky
<amplewycky@undergrad.math.uwaterloo.ca> said:

> Once under 2.2.0-pre8 and once under 2.2.0-final, I've had many of the
> processes on my system simultaneously enter the D state.

"ps -axl" is the best way to start diagnosing this. You'll need the
patch below to fix wchan on pre9.

--Stephen

----------------------------------------------------------------
--- fs/proc/array.c~ Tue Jan 19 11:40:58 1999
+++ fs/proc/array.c Wed Jan 20 18:55:48 1999
@@ -512,8 +512,11 @@
#define first_sched ((unsigned long) scheduling_functions_start_here)
#define last_sched ((unsigned long) scheduling_functions_end_here)

-static unsigned long get_wchan(struct task_struct *p)
+/* p is the pointer to the usable snapshot of the task_struct.
+ * a is the real address of the struct in core. */
+static unsigned long get_wchan(struct task_struct *p, struct task_struct *a)
{
+ printk(KERN_DEBUG "get_wchan(%p)\n", p);
if (!p || p == current || p->state == TASK_RUNNING)
return 0;
#if defined(__i386__)
@@ -522,16 +525,19 @@
unsigned long stack_page;
int count = 0;

- stack_page = (unsigned long)p;
+ stack_page = (unsigned long)a;
esp = p->tss.esp;
+ printk(KERN_DEBUG "stack/esp = %08lx %08lx\n", stack_page,esp);
if (!stack_page || esp < stack_page || esp >= 8188+stack_page)
return 0;
/* include/asm-i386/system.h:switch_to() pushes ebp last. */
ebp = *(unsigned long *) esp;
do {
+ printk(KERN_DEBUG " ebp = %08lx\n", ebp);
if (ebp < stack_page || ebp >= 8188+stack_page)
return 0;
eip = *(unsigned long *) (ebp+4);
+ printk(KERN_DEBUG " eip = %08lx\n", eip);
if (eip < first_sched || eip >= last_sched)
return eip;
ebp = *(unsigned long *) ebp;
@@ -849,13 +855,17 @@
cap_t(p->cap_effective));
}

-static struct task_struct *grab_task(int pid, struct task_struct *dst)
+static struct task_struct *grab_task(int pid,
+ struct task_struct *dst,
+ struct task_struct **real_dst)
{
struct task_struct *tsk = current;
if (pid != tsk->pid) {
read_lock(&tasklist_lock);
tsk = find_task_by_pid(pid);
if (tsk) {
+ if (real_dst)
+ *real_dst = tsk;
memcpy(dst, tsk, sizeof(struct task_struct));
tsk = dst;
if (tsk->mm && tsk->mm != &init_mm)
@@ -877,7 +887,7 @@
char * orig = buffer;
struct task_struct *tsk, mytask;

- tsk = grab_task(pid, &mytask);
+ tsk = grab_task(pid, &mytask, 0);
if (!tsk)
return 0;
buffer = task_name(tsk, buffer);
@@ -891,7 +901,7 @@

static int get_stat(int pid, char * buffer)
{
- struct task_struct *tsk, mytask;
+ struct task_struct *tsk, *real_tsk, mytask;
unsigned long vsize, eip, esp, wchan;
long priority, nice;
int tty_pgrp;
@@ -899,7 +909,7 @@
char state;
int res;

- tsk = grab_task(pid, &mytask);
+ tsk = grab_task(pid, &mytask, &real_tsk);
if (!tsk)
return 0;
state = *get_task_state(tsk);
@@ -917,7 +927,7 @@
esp = KSTK_ESP(tsk);
}

- wchan = get_wchan(tsk);
+ wchan = get_wchan(tsk, real_tsk);

collect_sigign_sigcatch(tsk, &sigign, &sigcatch);

@@ -1258,7 +1268,7 @@
struct task_struct * tsk, mytask;
int i, len;

- tsk = grab_task(pid, &mytask);
+ tsk = grab_task(pid, &mytask, 0);
if (!tsk)
return 0;

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.rutgers.edu
Please read the FAQ at http://www.tux.org/lkml/