querying mm's from a module

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 




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/


[Index of Archives]     [Newbies FAQ]     [Linux Kernel Mentors]     [Linux Kernel Development]     [IETF Annouce]     [Git]     [Networking]     [Security]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux RAID]     [Linux SCSI]     [Linux ACPI]
  Powered by Linux