Commit 2f61876e authored by Robert Love's avatar Robert Love Committed by Linus Torvalds

[PATCH] decoded wchan in /proc

This implements a pre-decoded wchan in /proc using kallsyms.  I.e.:

        [21:23:17]rml@phantasy:~$ cat /proc/1228/wchan
        wait4

Which, aside from being cool, means procps will not have to parse
Sysyem.map for each process.  In fact, procps will no longer require
System.map.

If CONFIG_KALLSYMS is not enabled, /proc/#/wchan does not exist to
conserve memory.  Regardless of CONFIG_KALLSYMS's value, the old wchan
field in /proc/#/stat still exists.

I have a procps patch I will merge once this is in your tree.
parent 3ccd5369
...@@ -130,6 +130,7 @@ Table 1-1: Process specific entries in /proc ...@@ -130,6 +130,7 @@ Table 1-1: Process specific entries in /proc
stat Process status stat Process status
statm Process memory status information statm Process memory status information
status Process status in human readable form status Process status in human readable form
wchan If CONFIG_KALLSYMS is set, a pre-decoded wchan
.............................................................................. ..............................................................................
For example, to get the status information of a process, all you have to do is For example, to get the status information of a process, all you have to do is
......
...@@ -28,6 +28,7 @@ ...@@ -28,6 +28,7 @@
#include <linux/namespace.h> #include <linux/namespace.h>
#include <linux/mm.h> #include <linux/mm.h>
#include <linux/smp_lock.h> #include <linux/smp_lock.h>
#include <linux/kallsyms.h>
/* /*
* For hysterical raisins we keep the same inumbers as in the old procfs. * For hysterical raisins we keep the same inumbers as in the old procfs.
...@@ -54,6 +55,7 @@ enum pid_directory_inos { ...@@ -54,6 +55,7 @@ enum pid_directory_inos {
PROC_PID_MAPS, PROC_PID_MAPS,
PROC_PID_CPU, PROC_PID_CPU,
PROC_PID_MOUNTS, PROC_PID_MOUNTS,
PROC_PID_WCHAN,
PROC_PID_FD_DIR = 0x8000, /* 0x8000-0xffff */ PROC_PID_FD_DIR = 0x8000, /* 0x8000-0xffff */
}; };
...@@ -81,6 +83,9 @@ static struct pid_entry base_stuff[] = { ...@@ -81,6 +83,9 @@ static struct pid_entry base_stuff[] = {
E(PROC_PID_ROOT, "root", S_IFLNK|S_IRWXUGO), E(PROC_PID_ROOT, "root", S_IFLNK|S_IRWXUGO),
E(PROC_PID_EXE, "exe", S_IFLNK|S_IRWXUGO), E(PROC_PID_EXE, "exe", S_IFLNK|S_IRWXUGO),
E(PROC_PID_MOUNTS, "mounts", S_IFREG|S_IRUGO), E(PROC_PID_MOUNTS, "mounts", S_IFREG|S_IRUGO),
#ifdef CONFIG_KALLSYMS
E(PROC_PID_WCHAN, "wchan", S_IFREG|S_IRUGO),
#endif
{0,0,NULL,0} {0,0,NULL,0}
}; };
#undef E #undef E
...@@ -245,6 +250,28 @@ static int proc_pid_cmdline(struct task_struct *task, char * buffer) ...@@ -245,6 +250,28 @@ static int proc_pid_cmdline(struct task_struct *task, char * buffer)
return res; return res;
} }
#ifdef CONFIG_KALLSYMS
/*
* Provides a wchan file via kallsyms in a proper one-value-per-file format.
* Returns the resolved symbol. If that fails, simply return the address.
*/
static int proc_pid_wchan(struct task_struct *task, char *buffer)
{
const char *sym_name, *ignore;
unsigned long wchan, dummy;
wchan = get_wchan(task);
if (!kallsyms_address_to_symbol(wchan, &ignore, &dummy, &dummy,
&ignore, &dummy, &dummy, &sym_name,
&dummy, &dummy)) {
return sprintf(buffer, "%lu", wchan);
}
return sprintf(buffer, "%s", sym_name);
}
#endif
/************************************************************************/ /************************************************************************/
/* Here the fs part begins */ /* Here the fs part begins */
/************************************************************************/ /************************************************************************/
...@@ -1016,6 +1043,12 @@ static struct dentry *proc_base_lookup(struct inode *dir, struct dentry *dentry) ...@@ -1016,6 +1043,12 @@ static struct dentry *proc_base_lookup(struct inode *dir, struct dentry *dentry)
case PROC_PID_MOUNTS: case PROC_PID_MOUNTS:
inode->i_fop = &proc_mounts_operations; inode->i_fop = &proc_mounts_operations;
break; break;
#ifdef CONFIG_KALLSYMS
case PROC_PID_WCHAN:
inode->i_fop = &proc_info_file_operations;
ei->op.proc_read = proc_pid_wchan;
break;
#endif
default: default:
printk("procfs: impossible type (%d)",p->type); printk("procfs: impossible type (%d)",p->type);
iput(inode); iput(inode);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment