Skip to contentSkip to conversation

fix BUG in do_task_stat()

PATCH New Makhlis, Lev 1 participant 1 message Sep 10, 2004 Proc filesystem

lore
Share & tools
lore
#0 lore raw

PATCH 1/1 fix BUG in do_task_stat()

Quoted 6 lines

kernel BUG in next_thread at kernel/exit.c:852! cpu 0x2: Vector: 700 (Program Check) at [c00000027bcf3770]

    pc: c000000000058454: .next_thread+0x14/0x48
    lr: c0000000000f1a84: .do_task_stat+0x238/0x53c

I've been able to reproduce this. This patch makes sure next_thread() is only called while holding ->sighand->siglock. Ran it overnight with a load, and no problems so far.

fs/proc/array.c +14 -14
diff -pruN linux-2.6.9-rc1-mm4/fs/proc/array.c linux/fs/proc/array.c
@@ -336,6 +336,16 @@ static int do_task_stat(struct task_stru
 		spin_lock_irq(&task->sighand->siglock);
 		num_threads = atomic_read(&task->signal->count);
 		collect_sigign_sigcatch(task, &sigign, &sigcatch);
+		if (whole) {
+			t = task;
+			do {
+				min_flt += t->min_flt;
+				maj_flt += t->maj_flt;
+				utime += t->utime;
+				stime += t->stime;
+				t = next_thread(t);
+			} while (t != task);
+		}
 		spin_unlock_irq(&task->sighand->siglock);
 	}
 	if (task->signal) {
@@ -350,22 +360,12 @@ static int do_task_stat(struct task_stru
 		cutime = task->signal->cutime;
 		cstime = task->signal->cstime;
 		if (whole) {
-			min_flt = task->signal->min_flt;
-			maj_flt = task->signal->maj_flt;
-			utime = task->signal->utime;
-			stime = task->signal->stime;
+			min_flt += task->signal->min_flt;
+			maj_flt += task->signal->maj_flt;
+			utime += task->signal->utime;
+			stime += task->signal->stime;
 		}
 	}
-	if (whole) {
-		t = task;
-		do {
-			min_flt += t->min_flt;
-			maj_flt += t->maj_flt;
-			utime += t->utime;
-			stime += t->stime;
-			t = next_thread(t);
-		} while (t != task);
-	}
 	ppid = task->pid ? task->real_parent->pid : 0;
 	read_unlock(&tasklist_lock);