lkml.org 
[lkml]   [1999]   [Mar]   [18]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
Patch in this message
/
Date
From
SubjectRe: [patch] /proc race fixes [Re: sleeping while holding a rwspinlock?]
Hi Stephen,

In the light of your response to Andrea, perhaps it is worth then to
consider my patch which is very simple (see below).

Sorry, Andrea - your stuff is probably more clever and I am not being
nasty - it's just perhaps simple things should be solved in a simple
manner?

The "race fixes" which I hope my patch fixes is the issue of dropping
tasklist_lock too soon, while still using the task_struct in question.

Regards,
Tigran.

diff -urN linux/fs/proc/array.c linux-2.2.3-proc_tasklock/fs/proc/array.c
--- linux/fs/proc/array.c Sat Mar 13 11:57:16 1999
+++ linux-2.2.3-proc_tasklock/fs/proc/array.c Sat Mar 13 23:14:27 1999
@@ -454,26 +454,31 @@
static int get_env(int pid, char * buffer)
{
struct task_struct *p;
+ int len = 0;

read_lock(&tasklist_lock);
p = find_task_by_pid(pid);
- read_unlock(&tasklist_lock); /* FIXME!! This should be done after the last use */
-
if (!p || !p->mm)
- return 0;
- return get_array(p, p->mm->env_start, p->mm->env_end, buffer);
+ goto out;
+ len = get_array(p, p->mm->env_start, p->mm->env_end, buffer);
+out:
+ read_unlock(&tasklist_lock);
+ return len;
}

static int get_arg(int pid, char * buffer)
{
struct task_struct *p;
+ int len = 0;

read_lock(&tasklist_lock);
p = find_task_by_pid(pid);
- read_unlock(&tasklist_lock); /* FIXME!! This should be done after the last use */
if (!p || !p->mm)
- return 0;
- return get_array(p, p->mm->arg_start, p->mm->arg_end, buffer);
+ goto out;
+ len = get_array(p, p->mm->arg_start, p->mm->arg_end, buffer);
+out:
+ read_unlock(&tasklist_lock);
+ return len;
}

/*
@@ -825,14 +830,15 @@

read_lock(&tasklist_lock);
tsk = find_task_by_pid(pid);
- read_unlock(&tasklist_lock); /* FIXME!! This should be done after the last use */
if (!tsk)
- return 0;
+ goto out;
buffer = task_name(tsk, buffer);
buffer = task_state(tsk, buffer);
buffer = task_mem(tsk, buffer);
buffer = task_sig(tsk, buffer);
buffer = task_cap(tsk, buffer);
+out:
+ read_unlock(&tasklist_lock);
return buffer - orig;
}

@@ -841,15 +847,14 @@
struct task_struct *tsk;
unsigned long vsize, eip, esp, wchan;
long priority, nice;
- int tty_pgrp;
+ int tty_pgrp, len = 0;
sigset_t sigign, sigcatch;
char state;

read_lock(&tasklist_lock);
tsk = find_task_by_pid(pid);
- read_unlock(&tasklist_lock); /* FIXME!! This should be done after the last use */
if (!tsk)
- return 0;
+ goto out;
state = *get_task_state(tsk);
vsize = eip = esp = 0;
if (tsk->mm && tsk->mm != &init_mm) {
@@ -878,7 +883,7 @@
nice = tsk->priority;
nice = 20 - (nice * 20 + DEF_PRIORITY / 2) / DEF_PRIORITY;

- return sprintf(buffer,"%d (%s) %c %d %d %d %d %d %lu %lu \
+ len = sprintf(buffer,"%d (%s) %c %d %d %d %d %d %lu %lu \
%lu %lu %lu %lu %lu %ld %ld %ld %ld %ld %ld %lu %lu %ld %lu %lu %lu %lu %lu \
%lu %lu %lu %lu %lu %lu %lu %lu %d\n",
pid,
@@ -923,6 +928,9 @@
tsk->nswap,
tsk->cnswap,
tsk->exit_signal);
+out:
+ read_unlock(&tasklist_lock);
+ return len;
}

static inline void statm_pte_range(pmd_t * pmd, unsigned long address, unsigned long size,
@@ -1001,13 +1009,12 @@
static int get_statm(int pid, char * buffer)
{
struct task_struct *tsk;
- int size=0, resident=0, share=0, trs=0, lrs=0, drs=0, dt=0;
+ int len=0, size=0, resident=0, share=0, trs=0, lrs=0, drs=0, dt=0;

read_lock(&tasklist_lock);
tsk = find_task_by_pid(pid);
- read_unlock(&tasklist_lock); /* FIXME!! This should be done after the last use */
if (!tsk)
- return 0;
+ goto out;
if (tsk->mm && tsk->mm != &init_mm) {
struct vm_area_struct * vma = tsk->mm->mmap;

@@ -1031,8 +1038,11 @@
vma = vma->vm_next;
}
}
- return sprintf(buffer,"%d %d %d %d %d %d %d\n",
+ len = sprintf(buffer,"%d %d %d %d %d %d %d\n",
size, resident, share, trs, lrs, drs, dt);
+out:
+ read_unlock(&tasklist_lock);
+ return len;
}

/*
@@ -1200,15 +1210,13 @@
static int get_pidcpu(int pid, char * buffer)
{
struct task_struct * tsk = current ;
- int i, len;
+ int i, len = 0;

read_lock(&tasklist_lock);
if (pid != tsk->pid)
tsk = find_task_by_pid(pid);
- read_unlock(&tasklist_lock); /* FIXME!! This should be done after the last use */
-
if (tsk == NULL)
- return 0;
+ goto out;

len = sprintf(buffer,
"cpu %lu %lu\n",
@@ -1220,7 +1228,8 @@
i,
tsk->per_cpu_utime[cpu_logical_map(i)],
tsk->per_cpu_stime[cpu_logical_map(i)]);
-
+out:
+ read_unlock(&tasklist_lock);
return len;
}
#endif
[unhandled content-type:application/x-gunzip]
\
 
 \ /
  Last update: 2005-03-22 13:50    [W:0.023 / U:0.844 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site