[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
querying mm's from a module
I have a module that wants to know mm->total_vm for a task. I'm
developing this module for 2.4.18+ kernels. I tried to implement this
using fine-grained locking ala fs/proc/array.c. In the following code,
mem is a struct that contains the pid of the task I want to query, and
a vmsize field where total_vm is stored (in kbytes, which explains the
shifting):
/* version 1 */
struct task_struct * task;
struct mm_struct * mm;
read_lock (&tasklist_lock);
task = find_task_by_pid (mem->pid);
if (task)
get_task_struct (task);
read_unlock (&tasklist_lock);
if (!task)
return -EINVAL;
task_lock (task);
mm = task->mm;
if (mm)
atomic_inc (&mm->mm_users);
task_unlock (task);
free_task_struct (task);
if (!mm)
return -EINVAL;
down_read (&mm->mmap_sem);
mem->vmsize = mm->total_vm << (PAGE_SHIFT-10);
up_read (&mm->mmap_sem);
mmput (mm);
Unfortunately, it looks like mmput isn't exported to module space.
If I change the code to use just the tasklist_lock, like this:
/* version 2 */
int ret;
struct task_struct * task;
struct mm_struct * mm;
ret = -EINVAL;
read_lock (&tasklist_lock);
task = find_task_by_pid (mem->pid);
if (!task)
goto out;
mm = task->mm;
if (!mm)
goto out;
mem->vmsize = mm->total_vm << (PAGE_SHIFT-10);
ret = 0;
out:
read_unlock (&tasklist_lock);
return ret;
will this work? I don't know enough about the kernel yet to be sure
that mm can't go away while I'm holding tasklist_lock. Version 2
of my code is based on mm/oom_kill.c does, so I'd expect it to be safe,
but glancing at do_exit and __exit_mm, I can't see what prevents the
following execution on an SMP machine, where p1 is running my module (or
oom_kill) and p2 is running do_exit():
p1: mm = task->mm;
p2: __exit_mm (tsk); <-- assume tsk is the same task that p1 is
examining.
<-- after __exit_mm's mmput, mm may have been
deallocated
p1: mem->vmsize = mm->total_vm << (PAGE_SHIFT-10);
<-- boom, if mm was deallocated by
__exit_mm on p2
Looks to me like anyone who's trying to do something with mm should be
doing a task_lock + atomic_inc(mm->mm_users) + task_unlock + mmput(mm)
sequence, but that doesn't appear to be the case in mm/oom_kill.c.
What am I missing?
thanks!
-dwh-
--
Kernelnewbies: Help each other learn about the Linux kernel.
Archive: http://mail.nl.linux.org/kernelnewbies/
FAQ: http://kernelnewbies.org/faq/