lkml.org 
[lkml]   [2003]   [Oct]   [18]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
Patch in this message
/
Date
From
SubjectRe: reproduceable oops in -test8
On Sat, Oct 18, 2003 at 11:48:48PM +0200, Diego Calleja Garc?a wrote:
> Hi, I got some oops with test8; the first time I got it it was under
> test8-wli1; but it seems the same is happening under plain -test8.
> This is the original bug report:
> The system was working well. Then I decided to run totem - a neat
> video player. It hanged. Trying to kill it I did "ps xa"; suprisingly
> after pid 560 ps (and the terminal) stopped and hanged. The rest of
were still alive. Then I fired another terminal, did /proc/562 (the
> following pid after 560); I run ls; and ls hanged. I fired another
> terminal, and I did 'find /proc'; and I got the oops. Some seconds
> after that the system locked up completely. Box is a dual p3; 256 MB
> ram, ide disks, running debian sid, no NPTL. Config pasted below.

Two stupid bugs in my case. With a bit of noise surrounding things
(e.g. EXPORT_SYMBOL() crud, init_task paranoia garbage, ->f_pos in
unsigned long removal), un-reversing the arguments to find_pid()
and not blowing away the last-seen tid while formatting it and later
trying to use it as ->f_pos are the needed fixes.


-- wli


diff -prauN wli-2.6.0-test8-38/fs/proc/base.c wli-2.6.0-test8-39/fs/proc/base.c
--- wli-2.6.0-test8-38/fs/proc/base.c 2003-10-17 19:16:54.000000000 -0700
+++ wli-2.6.0-test8-39/fs/proc/base.c 2003-10-18 18:01:43.000000000 -0700
@@ -1673,44 +1673,43 @@ static int proc_task_readdir(struct file
struct inode *inode = dentry->d_inode;
int retval = -ENOENT;
ino_t ino;
- unsigned long pos = filp->f_pos; /* avoiding "long long" filp->f_pos */

if (!pid_alive(proc_task(inode)))
goto out;
retval = 0;

- switch (pos) {
+ switch (filp->f_pos) {
case 0:
ino = inode->i_ino;
- if (filldir(dirent, ".", 1, pos, ino, DT_DIR) < 0)
+ if (filldir(dirent, ".", 1, filp->f_pos, ino, DT_DIR) < 0)
goto out;
- pos++;
+ filp->f_pos++;
/* fall through */
case 1:
ino = parent_ino(dentry);
- if (filldir(dirent, "..", 2, pos, ino, DT_DIR) < 0)
+ if (filldir(dirent, "..", 2, filp->f_pos, ino, DT_DIR) < 0)
goto out;
- pos++;
+ filp->f_pos++;
/* fall through */
}

- nr_tids = find_tids_after(proc_task(inode)->tgid, pos - 2, tid_array);
+ nr_tids = find_tids_after(proc_task(inode)->tgid, filp->f_pos - 2, tid_array);

for (i = 0; i < nr_tids; i++) {
- unsigned long j = PROC_NUMBUF;
+ unsigned long k, j = PROC_NUMBUF;
int tid = tid_array[i];

ino = fake_ino(tid, PROC_TID_INO);

+ k = tid;
do
- buf[--j] = '0' + (tid % 10);
- while (tid /= 10);
+ buf[--j] = '0' + (k % 10);
+ while (k /= 10);

- if (filldir(dirent, buf+j, PROC_NUMBUF-j, pos, ino, DT_DIR) < 0)
+ if (filldir(dirent, buf+j, PROC_NUMBUF-j, filp->f_pos, ino, DT_DIR) < 0)
break;
- pos = tid + 2;
+ filp->f_pos = tid + 2;
}
out:
- filp->f_pos = pos;
return retval;
}
diff -prauN wli-2.6.0-test8-38/include/linux/init_task.h wli-2.6.0-test8-39/include/linux/init_task.h
--- wli-2.6.0-test8-38/include/linux/init_task.h 2003-10-17 19:14:11.000000000 -0700
+++ wli-2.6.0-test8-39/include/linux/init_task.h 2003-10-18 17:23:20.000000000 -0700
@@ -56,6 +56,29 @@
.siglock = SPIN_LOCK_UNLOCKED, \
}

+#define INIT_PID(tsk, type) \
+{ \
+ .nr = 0, \
+ .count = ATOMIC_INIT(1), \
+ .task = &(tsk), \
+ .task_list = { \
+ .rb_node = NULL, \
+ }, \
+ .hash_chain = LIST_HEAD_INIT((tsk).pids[type].pid.hash_chain), \
+}
+
+#define INIT_PID_LINK(task, type) \
+ { \
+ .pid_chain = { \
+ .rb_parent = NULL, \
+ .rb_left = NULL, \
+ .rb_right = NULL, \
+ .rb_color = RB_BLACK, \
+ }, \
+ .pidptr = NULL, \
+ .pid = INIT_PID(task, type), \
+ }
+
/*
* INIT_TASK is used to set up the first task table, touch at
* your own risk!. Base=0, limit=0x1fffff (=2MB)
@@ -113,6 +136,12 @@
.proc_lock = SPIN_LOCK_UNLOCKED, \
.switch_lock = SPIN_LOCK_UNLOCKED, \
.journal_info = NULL, \
+ .pids = { \
+ INIT_PID_LINK(tsk, 0), \
+ INIT_PID_LINK(tsk, 1), \
+ INIT_PID_LINK(tsk, 2), \
+ INIT_PID_LINK(tsk, 3), \
+ }, \
}


diff -prauN wli-2.6.0-test8-38/kernel/pid.c wli-2.6.0-test8-39/kernel/pid.c
--- wli-2.6.0-test8-38/kernel/pid.c 2003-10-17 19:16:54.000000000 -0700
+++ wli-2.6.0-test8-39/kernel/pid.c 2003-10-18 18:02:45.000000000 -0700
@@ -167,6 +167,7 @@ task_t *first_task(void)
BUG_ON(!node);
return rb_entry(node, task_t, tasks);
}
+EXPORT_SYMBOL(first_task);

void insert_task_list(task_t *task)
{
@@ -339,6 +340,7 @@ int find_tgids_after(int tgid, int tgids
read_unlock(&tasklist_lock);
return k;
}
+EXPORT_SYMBOL(find_tgids_after);

int find_tids_after(int tgid, int tid, int tids[PROC_MAXPIDS])
{
@@ -348,7 +350,7 @@ int find_tids_after(int tgid, int tid, i
int k = 0;

read_lock(&tasklist_lock);
- pid = find_pid(tgid, PIDTYPE_TGID);
+ pid = find_pid(PIDTYPE_TGID, tgid);
if (!pid)
goto out;
node = pid->task_list.rb_node;
@@ -373,6 +375,7 @@ out:
read_unlock(&tasklist_lock);
return k;
}
+EXPORT_SYMBOL(find_tids_after);

task_t *find_task_by_pid(int nr)
{
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
\
 
 \ /
  Last update: 2005-03-22 13:58    [W:0.621 / U:0.084 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site