lkml.org 
[lkml]   [1999]   [Jul]   [28]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
Patch in this message
/
From
Date
Subject[PATCH] Uniquely identifying memory usage
Hi,

Here is a really short patch that uses the proc filesystem to tell user
space what processes are share virtual memory. I may have missed
something, but I don't think that there's currently any way to find out if
two processes are sharing memory or just happen to be using exactly the
same amount of memory. The patch adds a /proc/*/mm_id that provides a
unique ID for memory usage.

The patch has one known issue that really ought to be solved if it
becomes actually a part of the kernel: It uses the process ID of the first
process to use a mm_struct as the ID for that struct. This means that
under the following scenario, the scheme fails:

1. Process A is forked
2. A clones B with CLONE_MM
3. A exits
4. Process C is forked, and reuses A's pid.

Now B and C will share an mm_id despite the fact that they are not even
related to each other. I didn't fix this because first of all, doing so
would require some way to keep track of free mm_ids, which might require
some extra kernel memory. (Actually, if we use a bit mask it requires 64
bytes for the default NR_TASKS == 512, but I just thought of this a few
seconds ago).

Second, this situation won't ever actually happen under the only situation
most people use CLONE_MM, which is for LinuxThreads. That doesn't excuse
the BUG, but it does mean that the patch is usable by most people until
the bug gets fixed.

Comments are welcome. Since this is actually my first kernel patch ever,
is it considered good enough to just post a small patch like this to the
list, or should I put it on my web page somewhere? I assume the list
archives are good enough?

Chris Smith <cd_smith@ou.edu>

diff -Nru linux-old/fs/proc/array.c linux/fs/proc/array.c
--- linux-old/fs/proc/array.c Sat Jul 3 14:04:12 1999
+++ linux/fs/proc/array.c Wed Jul 28 19:17:25 1999
@@ -1052,6 +1052,23 @@
size, resident, share, trs, lrs, drs, dt);
}

+static int get_mm_id(int pid, char * buffer)
+{
+ struct task_struct *tsk;
+ int mm_id = 0;
+
+ read_lock(&tasklist_lock);
+ tsk = find_task_by_pid(pid);
+ read_unlock(&tasklist_lock);
+
+ if (!tsk)
+ return 0;
+ if (tsk->mm && tsk->mm != &init_mm)
+ mm_id = tsk->mm->mm_id;
+
+ return sprintf(buffer,"%d\n", mm_id);
+}
+
/*
* The way we support synthetic files > 4K
* - without storing their contents in some buffer and
@@ -1416,6 +1433,8 @@
return get_stat(pid, page);
case PROC_PID_STATM:
return get_statm(pid, page);
+ case PROC_PID_MM_ID:
+ return get_mm_id(pid, page);
#ifdef __SMP__
case PROC_PID_CPU:
return get_pidcpu(pid, page);
diff -Nru linux-old/fs/proc/base.c linux/fs/proc/base.c
--- linux-old/fs/proc/base.c Sat Jun 26 14:04:39 1999
+++ linux/fs/proc/base.c Wed Jul 28 19:18:34 1999
@@ -159,6 +159,12 @@
0, &proc_arraylong_inode_operations,
NULL, proc_pid_fill_inode,
};
+static struct proc_dir_entry proc_pid_mm_id = {
+ PROC_PID_MM_ID, 5, "mm_id",
+ S_IFREG | S_IRUGO, 1, 0, 0,
+ 0, &proc_array_inode_operations,
+ NULL, proc_pid_fill_inode,
+};

#if CONFIG_AP1000
static struct proc_dir_entry proc_pid_ringbuf = {
@@ -194,6 +200,7 @@
proc_register(&proc_pid, &proc_pid_stat);
proc_register(&proc_pid, &proc_pid_statm);
proc_register(&proc_pid, &proc_pid_maps);
+ proc_register(&proc_pid, &proc_pid_mm_id);
#ifdef __SMP__
proc_register(&proc_pid, &proc_pid_cpu);
#endif
diff -Nru linux-old/include/linux/proc_fs.h linux/include/linux/proc_fs.h
--- linux-old/include/linux/proc_fs.h Wed Jul 7 11:21:05 1999
+++ linux/include/linux/proc_fs.h Wed Jul 28 19:33:44 1999
@@ -70,6 +70,7 @@
PROC_PID_STAT,
PROC_PID_STATM,
PROC_PID_MAPS,
+ PROC_PID_MM_ID,
#if CONFIG_AP1000
PROC_PID_RINGBUF,
#endif
diff -Nru linux-old/include/linux/sched.h linux/include/linux/sched.h
--- linux-old/include/linux/sched.h Wed Jul 7 11:20:45 1999
+++ linux/include/linux/sched.h Wed Jul 28 19:22:20 1999
@@ -187,6 +187,7 @@
* part of Linux does not know about any segments.
*/
void * segments;
+ pid_t mm_id;
};

#define INIT_MM(name) { \
@@ -200,7 +201,8 @@
0, 0, 0, \
0, 0, 0, 0, \
0, 0, 0, \
- 0, 0, 0, 0, NULL }
+ 0, 0, 0, 0, NULL, \
+ 0 }

struct signal_struct {
atomic_t count;
diff -Nru linux-old/kernel/fork.c linux/kernel/fork.c
--- linux-old/kernel/fork.c Mon Jul 5 22:34:31 1999
+++ linux/kernel/fork.c Wed Jul 28 18:50:07 1999
@@ -382,6 +382,7 @@
if (!mm)
goto fail_nomem;

+ mm->mm_id = tsk->pid;
tsk->mm = mm;
copy_segments(nr, tsk, mm);
retval = new_page_tables(tsk);

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.rutgers.edu
Please read the FAQ at http://www.tux.org/lkml/

\
 
 \ /
  Last update: 2005-03-22 13:53    [W:0.025 / U:0.076 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site