aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2009-01-07 15:01:06 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2009-01-07 15:01:06 -0500
commita0c9f240a992c4c2b6ac40324ece27475cf3b71a (patch)
treee42e5231d0e551b1b1f726c06c2ca27c510efb7a
parent5bb47b9ff3d16d40f8d45380b373497a545fa280 (diff)
parent230e40fbda242544389a5428a2efac568178ddfe (diff)
Merge branch 'proc-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/adobriyan/proc
* 'proc-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/adobriyan/proc: proc: remove write-only variable in proc_pident_lookup() proc: fix sparse warning proc: add /proc/*/stack proc: remove '##' usage proc: remove useless WARN_ONs proc: stop using BKL
-rw-r--r--Documentation/filesystems/proc.txt1
-rw-r--r--arch/mips/kernel/stacktrace.c24
-rw-r--r--fs/proc/base.c231
-rw-r--r--fs/proc/generic.c8
-rw-r--r--fs/proc/inode.c3
-rw-r--r--fs/proc/proc_net.c2
-rw-r--r--fs/proc/root.c8
7 files changed, 153 insertions, 124 deletions
diff --git a/Documentation/filesystems/proc.txt b/Documentation/filesystems/proc.txt
index 32e94635484f..d105eb45282a 100644
--- a/Documentation/filesystems/proc.txt
+++ b/Documentation/filesystems/proc.txt
@@ -140,6 +140,7 @@ Table 1-1: Process specific entries in /proc
140 statm Process memory status information 140 statm Process memory status information
141 status Process status in human readable form 141 status Process status in human readable form
142 wchan If CONFIG_KALLSYMS is set, a pre-decoded wchan 142 wchan If CONFIG_KALLSYMS is set, a pre-decoded wchan
143 stack Report full stack trace, enable via CONFIG_STACKTRACE
143 smaps Extension based on maps, the rss size for each mapped file 144 smaps Extension based on maps, the rss size for each mapped file
144.............................................................................. 145..............................................................................
145 146
diff --git a/arch/mips/kernel/stacktrace.c b/arch/mips/kernel/stacktrace.c
index 0632e2a849c0..58f5cd76c8c3 100644
--- a/arch/mips/kernel/stacktrace.c
+++ b/arch/mips/kernel/stacktrace.c
@@ -32,7 +32,8 @@ static void save_raw_context_stack(struct stack_trace *trace,
32 } 32 }
33} 33}
34 34
35static void save_context_stack(struct stack_trace *trace, struct pt_regs *regs) 35static void save_context_stack(struct stack_trace *trace,
36 struct task_struct *tsk, struct pt_regs *regs)
36{ 37{
37 unsigned long sp = regs->regs[29]; 38 unsigned long sp = regs->regs[29];
38#ifdef CONFIG_KALLSYMS 39#ifdef CONFIG_KALLSYMS
@@ -41,7 +42,7 @@ static void save_context_stack(struct stack_trace *trace, struct pt_regs *regs)
41 42
42 if (raw_show_trace || !__kernel_text_address(pc)) { 43 if (raw_show_trace || !__kernel_text_address(pc)) {
43 unsigned long stack_page = 44 unsigned long stack_page =
44 (unsigned long)task_stack_page(current); 45 (unsigned long)task_stack_page(tsk);
45 if (stack_page && sp >= stack_page && 46 if (stack_page && sp >= stack_page &&
46 sp <= stack_page + THREAD_SIZE - 32) 47 sp <= stack_page + THREAD_SIZE - 32)
47 save_raw_context_stack(trace, sp); 48 save_raw_context_stack(trace, sp);
@@ -54,7 +55,7 @@ static void save_context_stack(struct stack_trace *trace, struct pt_regs *regs)
54 trace->entries[trace->nr_entries++] = pc; 55 trace->entries[trace->nr_entries++] = pc;
55 if (trace->nr_entries >= trace->max_entries) 56 if (trace->nr_entries >= trace->max_entries)
56 break; 57 break;
57 pc = unwind_stack(current, &sp, pc, &ra); 58 pc = unwind_stack(tsk, &sp, pc, &ra);
58 } while (pc); 59 } while (pc);
59#else 60#else
60 save_raw_context_stack(trace, sp); 61 save_raw_context_stack(trace, sp);
@@ -66,12 +67,23 @@ static void save_context_stack(struct stack_trace *trace, struct pt_regs *regs)
66 */ 67 */
67void save_stack_trace(struct stack_trace *trace) 68void save_stack_trace(struct stack_trace *trace)
68{ 69{
70 save_stack_trace_tsk(current, trace);
71}
72EXPORT_SYMBOL_GPL(save_stack_trace);
73
74void save_stack_trace_tsk(struct task_struct *tsk, struct stack_trace *trace)
75{
69 struct pt_regs dummyregs; 76 struct pt_regs dummyregs;
70 struct pt_regs *regs = &dummyregs; 77 struct pt_regs *regs = &dummyregs;
71 78
72 WARN_ON(trace->nr_entries || !trace->max_entries); 79 WARN_ON(trace->nr_entries || !trace->max_entries);
73 80
74 prepare_frametrace(regs); 81 if (tsk != current) {
75 save_context_stack(trace, regs); 82 regs->regs[29] = tsk->thread.reg29;
83 regs->regs[31] = 0;
84 regs->cp0_epc = tsk->thread.reg31;
85 } else
86 prepare_frametrace(regs);
87 save_context_stack(trace, tsk, regs);
76} 88}
77EXPORT_SYMBOL_GPL(save_stack_trace); 89EXPORT_SYMBOL_GPL(save_stack_trace_tsk);
diff --git a/fs/proc/base.c b/fs/proc/base.c
index 10fd5223d600..0c9de19a1633 100644
--- a/fs/proc/base.c
+++ b/fs/proc/base.c
@@ -65,6 +65,7 @@
65#include <linux/mm.h> 65#include <linux/mm.h>
66#include <linux/rcupdate.h> 66#include <linux/rcupdate.h>
67#include <linux/kallsyms.h> 67#include <linux/kallsyms.h>
68#include <linux/stacktrace.h>
68#include <linux/resource.h> 69#include <linux/resource.h>
69#include <linux/module.h> 70#include <linux/module.h>
70#include <linux/mount.h> 71#include <linux/mount.h>
@@ -109,25 +110,22 @@ struct pid_entry {
109 .op = OP, \ 110 .op = OP, \
110} 111}
111 112
112#define DIR(NAME, MODE, OTYPE) \ 113#define DIR(NAME, MODE, iops, fops) \
113 NOD(NAME, (S_IFDIR|(MODE)), \ 114 NOD(NAME, (S_IFDIR|(MODE)), &iops, &fops, {} )
114 &proc_##OTYPE##_inode_operations, &proc_##OTYPE##_operations, \ 115#define LNK(NAME, get_link) \
115 {} )
116#define LNK(NAME, OTYPE) \
117 NOD(NAME, (S_IFLNK|S_IRWXUGO), \ 116 NOD(NAME, (S_IFLNK|S_IRWXUGO), \
118 &proc_pid_link_inode_operations, NULL, \ 117 &proc_pid_link_inode_operations, NULL, \
119 { .proc_get_link = &proc_##OTYPE##_link } ) 118 { .proc_get_link = get_link } )
120#define REG(NAME, MODE, OTYPE) \ 119#define REG(NAME, MODE, fops) \
121 NOD(NAME, (S_IFREG|(MODE)), NULL, \ 120 NOD(NAME, (S_IFREG|(MODE)), NULL, &fops, {})
122 &proc_##OTYPE##_operations, {}) 121#define INF(NAME, MODE, read) \
123#define INF(NAME, MODE, OTYPE) \
124 NOD(NAME, (S_IFREG|(MODE)), \ 122 NOD(NAME, (S_IFREG|(MODE)), \
125 NULL, &proc_info_file_operations, \ 123 NULL, &proc_info_file_operations, \
126 { .proc_read = &proc_##OTYPE } ) 124 { .proc_read = read } )
127#define ONE(NAME, MODE, OTYPE) \ 125#define ONE(NAME, MODE, show) \
128 NOD(NAME, (S_IFREG|(MODE)), \ 126 NOD(NAME, (S_IFREG|(MODE)), \
129 NULL, &proc_single_file_operations, \ 127 NULL, &proc_single_file_operations, \
130 { .proc_show = &proc_##OTYPE } ) 128 { .proc_show = show } )
131 129
132/* 130/*
133 * Count the number of hardlinks for the pid_entry table, excluding the . 131 * Count the number of hardlinks for the pid_entry table, excluding the .
@@ -308,9 +306,9 @@ static int proc_pid_auxv(struct task_struct *task, char *buffer)
308 struct mm_struct *mm = get_task_mm(task); 306 struct mm_struct *mm = get_task_mm(task);
309 if (mm) { 307 if (mm) {
310 unsigned int nwords = 0; 308 unsigned int nwords = 0;
311 do 309 do {
312 nwords += 2; 310 nwords += 2;
313 while (mm->saved_auxv[nwords - 2] != 0); /* AT_NULL */ 311 } while (mm->saved_auxv[nwords - 2] != 0); /* AT_NULL */
314 res = nwords * sizeof(mm->saved_auxv[0]); 312 res = nwords * sizeof(mm->saved_auxv[0]);
315 if (res > PAGE_SIZE) 313 if (res > PAGE_SIZE)
316 res = PAGE_SIZE; 314 res = PAGE_SIZE;
@@ -340,6 +338,37 @@ static int proc_pid_wchan(struct task_struct *task, char *buffer)
340} 338}
341#endif /* CONFIG_KALLSYMS */ 339#endif /* CONFIG_KALLSYMS */
342 340
341#ifdef CONFIG_STACKTRACE
342
343#define MAX_STACK_TRACE_DEPTH 64
344
345static int proc_pid_stack(struct seq_file *m, struct pid_namespace *ns,
346 struct pid *pid, struct task_struct *task)
347{
348 struct stack_trace trace;
349 unsigned long *entries;
350 int i;
351
352 entries = kmalloc(MAX_STACK_TRACE_DEPTH * sizeof(*entries), GFP_KERNEL);
353 if (!entries)
354 return -ENOMEM;
355
356 trace.nr_entries = 0;
357 trace.max_entries = MAX_STACK_TRACE_DEPTH;
358 trace.entries = entries;
359 trace.skip = 0;
360 save_stack_trace_tsk(task, &trace);
361
362 for (i = 0; i < trace.nr_entries; i++) {
363 seq_printf(m, "[<%p>] %pS\n",
364 (void *)entries[i], (void *)entries[i]);
365 }
366 kfree(entries);
367
368 return 0;
369}
370#endif
371
343#ifdef CONFIG_SCHEDSTATS 372#ifdef CONFIG_SCHEDSTATS
344/* 373/*
345 * Provides /proc/PID/schedstat 374 * Provides /proc/PID/schedstat
@@ -1186,8 +1215,6 @@ static int sched_show(struct seq_file *m, void *v)
1186 struct inode *inode = m->private; 1215 struct inode *inode = m->private;
1187 struct task_struct *p; 1216 struct task_struct *p;
1188 1217
1189 WARN_ON(!inode);
1190
1191 p = get_proc_task(inode); 1218 p = get_proc_task(inode);
1192 if (!p) 1219 if (!p)
1193 return -ESRCH; 1220 return -ESRCH;
@@ -1205,8 +1232,6 @@ sched_write(struct file *file, const char __user *buf,
1205 struct inode *inode = file->f_path.dentry->d_inode; 1232 struct inode *inode = file->f_path.dentry->d_inode;
1206 struct task_struct *p; 1233 struct task_struct *p;
1207 1234
1208 WARN_ON(!inode);
1209
1210 p = get_proc_task(inode); 1235 p = get_proc_task(inode);
1211 if (!p) 1236 if (!p)
1212 return -ESRCH; 1237 return -ESRCH;
@@ -1974,13 +1999,11 @@ static struct dentry *proc_pident_lookup(struct inode *dir,
1974 const struct pid_entry *ents, 1999 const struct pid_entry *ents,
1975 unsigned int nents) 2000 unsigned int nents)
1976{ 2001{
1977 struct inode *inode;
1978 struct dentry *error; 2002 struct dentry *error;
1979 struct task_struct *task = get_proc_task(dir); 2003 struct task_struct *task = get_proc_task(dir);
1980 const struct pid_entry *p, *last; 2004 const struct pid_entry *p, *last;
1981 2005
1982 error = ERR_PTR(-ENOENT); 2006 error = ERR_PTR(-ENOENT);
1983 inode = NULL;
1984 2007
1985 if (!task) 2008 if (!task)
1986 goto out_no_task; 2009 goto out_no_task;
@@ -2136,12 +2159,12 @@ static const struct file_operations proc_pid_attr_operations = {
2136}; 2159};
2137 2160
2138static const struct pid_entry attr_dir_stuff[] = { 2161static const struct pid_entry attr_dir_stuff[] = {
2139 REG("current", S_IRUGO|S_IWUGO, pid_attr), 2162 REG("current", S_IRUGO|S_IWUGO, proc_pid_attr_operations),
2140 REG("prev", S_IRUGO, pid_attr), 2163 REG("prev", S_IRUGO, proc_pid_attr_operations),
2141 REG("exec", S_IRUGO|S_IWUGO, pid_attr), 2164 REG("exec", S_IRUGO|S_IWUGO, proc_pid_attr_operations),
2142 REG("fscreate", S_IRUGO|S_IWUGO, pid_attr), 2165 REG("fscreate", S_IRUGO|S_IWUGO, proc_pid_attr_operations),
2143 REG("keycreate", S_IRUGO|S_IWUGO, pid_attr), 2166 REG("keycreate", S_IRUGO|S_IWUGO, proc_pid_attr_operations),
2144 REG("sockcreate", S_IRUGO|S_IWUGO, pid_attr), 2167 REG("sockcreate", S_IRUGO|S_IWUGO, proc_pid_attr_operations),
2145}; 2168};
2146 2169
2147static int proc_attr_dir_readdir(struct file * filp, 2170static int proc_attr_dir_readdir(struct file * filp,
@@ -2461,74 +2484,77 @@ static const struct file_operations proc_task_operations;
2461static const struct inode_operations proc_task_inode_operations; 2484static const struct inode_operations proc_task_inode_operations;
2462 2485
2463static const struct pid_entry tgid_base_stuff[] = { 2486static const struct pid_entry tgid_base_stuff[] = {
2464 DIR("task", S_IRUGO|S_IXUGO, task), 2487 DIR("task", S_IRUGO|S_IXUGO, proc_task_inode_operations, proc_task_operations),
2465 DIR("fd", S_IRUSR|S_IXUSR, fd), 2488 DIR("fd", S_IRUSR|S_IXUSR, proc_fd_inode_operations, proc_fd_operations),
2466 DIR("fdinfo", S_IRUSR|S_IXUSR, fdinfo), 2489 DIR("fdinfo", S_IRUSR|S_IXUSR, proc_fdinfo_inode_operations, proc_fdinfo_operations),
2467#ifdef CONFIG_NET 2490#ifdef CONFIG_NET
2468 DIR("net", S_IRUGO|S_IXUGO, net), 2491 DIR("net", S_IRUGO|S_IXUGO, proc_net_inode_operations, proc_net_operations),
2469#endif 2492#endif
2470 REG("environ", S_IRUSR, environ), 2493 REG("environ", S_IRUSR, proc_environ_operations),
2471 INF("auxv", S_IRUSR, pid_auxv), 2494 INF("auxv", S_IRUSR, proc_pid_auxv),
2472 ONE("status", S_IRUGO, pid_status), 2495 ONE("status", S_IRUGO, proc_pid_status),
2473 ONE("personality", S_IRUSR, pid_personality), 2496 ONE("personality", S_IRUSR, proc_pid_personality),
2474 INF("limits", S_IRUSR, pid_limits), 2497 INF("limits", S_IRUSR, proc_pid_limits),
2475#ifdef CONFIG_SCHED_DEBUG 2498#ifdef CONFIG_SCHED_DEBUG
2476 REG("sched", S_IRUGO|S_IWUSR, pid_sched), 2499 REG("sched", S_IRUGO|S_IWUSR, proc_pid_sched_operations),
2477#endif 2500#endif
2478#ifdef CONFIG_HAVE_ARCH_TRACEHOOK 2501#ifdef CONFIG_HAVE_ARCH_TRACEHOOK
2479 INF("syscall", S_IRUSR, pid_syscall), 2502 INF("syscall", S_IRUSR, proc_pid_syscall),
2480#endif 2503#endif
2481 INF("cmdline", S_IRUGO, pid_cmdline), 2504 INF("cmdline", S_IRUGO, proc_pid_cmdline),
2482 ONE("stat", S_IRUGO, tgid_stat), 2505 ONE("stat", S_IRUGO, proc_tgid_stat),
2483 ONE("statm", S_IRUGO, pid_statm), 2506 ONE("statm", S_IRUGO, proc_pid_statm),
2484 REG("maps", S_IRUGO, maps), 2507 REG("maps", S_IRUGO, proc_maps_operations),
2485#ifdef CONFIG_NUMA 2508#ifdef CONFIG_NUMA
2486 REG("numa_maps", S_IRUGO, numa_maps), 2509 REG("numa_maps", S_IRUGO, proc_numa_maps_operations),
2487#endif 2510#endif
2488 REG("mem", S_IRUSR|S_IWUSR, mem), 2511 REG("mem", S_IRUSR|S_IWUSR, proc_mem_operations),
2489 LNK("cwd", cwd), 2512 LNK("cwd", proc_cwd_link),
2490 LNK("root", root), 2513 LNK("root", proc_root_link),
2491 LNK("exe", exe), 2514 LNK("exe", proc_exe_link),
2492 REG("mounts", S_IRUGO, mounts), 2515 REG("mounts", S_IRUGO, proc_mounts_operations),
2493 REG("mountinfo", S_IRUGO, mountinfo), 2516 REG("mountinfo", S_IRUGO, proc_mountinfo_operations),
2494 REG("mountstats", S_IRUSR, mountstats), 2517 REG("mountstats", S_IRUSR, proc_mountstats_operations),
2495#ifdef CONFIG_PROC_PAGE_MONITOR 2518#ifdef CONFIG_PROC_PAGE_MONITOR
2496 REG("clear_refs", S_IWUSR, clear_refs), 2519 REG("clear_refs", S_IWUSR, proc_clear_refs_operations),
2497 REG("smaps", S_IRUGO, smaps), 2520 REG("smaps", S_IRUGO, proc_smaps_operations),
2498 REG("pagemap", S_IRUSR, pagemap), 2521 REG("pagemap", S_IRUSR, proc_pagemap_operations),
2499#endif 2522#endif
2500#ifdef CONFIG_SECURITY 2523#ifdef CONFIG_SECURITY
2501 DIR("attr", S_IRUGO|S_IXUGO, attr_dir), 2524 DIR("attr", S_IRUGO|S_IXUGO, proc_attr_dir_inode_operations, proc_attr_dir_operations),
2502#endif 2525#endif
2503#ifdef CONFIG_KALLSYMS 2526#ifdef CONFIG_KALLSYMS
2504 INF("wchan", S_IRUGO, pid_wchan), 2527 INF("wchan", S_IRUGO, proc_pid_wchan),
2528#endif
2529#ifdef CONFIG_STACKTRACE
2530 ONE("stack", S_IRUSR, proc_pid_stack),
2505#endif 2531#endif
2506#ifdef CONFIG_SCHEDSTATS 2532#ifdef CONFIG_SCHEDSTATS
2507 INF("schedstat", S_IRUGO, pid_schedstat), 2533 INF("schedstat", S_IRUGO, proc_pid_schedstat),
2508#endif 2534#endif
2509#ifdef CONFIG_LATENCYTOP 2535#ifdef CONFIG_LATENCYTOP
2510 REG("latency", S_IRUGO, lstats), 2536 REG("latency", S_IRUGO, proc_lstats_operations),
2511#endif 2537#endif
2512#ifdef CONFIG_PROC_PID_CPUSET 2538#ifdef CONFIG_PROC_PID_CPUSET
2513 REG("cpuset", S_IRUGO, cpuset), 2539 REG("cpuset", S_IRUGO, proc_cpuset_operations),
2514#endif 2540#endif
2515#ifdef CONFIG_CGROUPS 2541#ifdef CONFIG_CGROUPS
2516 REG("cgroup", S_IRUGO, cgroup), 2542 REG("cgroup", S_IRUGO, proc_cgroup_operations),
2517#endif 2543#endif
2518 INF("oom_score", S_IRUGO, oom_score), 2544 INF("oom_score", S_IRUGO, proc_oom_score),
2519 REG("oom_adj", S_IRUGO|S_IWUSR, oom_adjust), 2545 REG("oom_adj", S_IRUGO|S_IWUSR, proc_oom_adjust_operations),
2520#ifdef CONFIG_AUDITSYSCALL 2546#ifdef CONFIG_AUDITSYSCALL
2521 REG("loginuid", S_IWUSR|S_IRUGO, loginuid), 2547 REG("loginuid", S_IWUSR|S_IRUGO, proc_loginuid_operations),
2522 REG("sessionid", S_IRUGO, sessionid), 2548 REG("sessionid", S_IRUGO, proc_sessionid_operations),
2523#endif 2549#endif
2524#ifdef CONFIG_FAULT_INJECTION 2550#ifdef CONFIG_FAULT_INJECTION
2525 REG("make-it-fail", S_IRUGO|S_IWUSR, fault_inject), 2551 REG("make-it-fail", S_IRUGO|S_IWUSR, proc_fault_inject_operations),
2526#endif 2552#endif
2527#if defined(USE_ELF_CORE_DUMP) && defined(CONFIG_ELF_CORE) 2553#if defined(USE_ELF_CORE_DUMP) && defined(CONFIG_ELF_CORE)
2528 REG("coredump_filter", S_IRUGO|S_IWUSR, coredump_filter), 2554 REG("coredump_filter", S_IRUGO|S_IWUSR, proc_coredump_filter_operations),
2529#endif 2555#endif
2530#ifdef CONFIG_TASK_IO_ACCOUNTING 2556#ifdef CONFIG_TASK_IO_ACCOUNTING
2531 INF("io", S_IRUGO, tgid_io_accounting), 2557 INF("io", S_IRUGO, proc_tgid_io_accounting),
2532#endif 2558#endif
2533}; 2559};
2534 2560
@@ -2801,66 +2827,69 @@ out_no_task:
2801 * Tasks 2827 * Tasks
2802 */ 2828 */
2803static const struct pid_entry tid_base_stuff[] = { 2829static const struct pid_entry tid_base_stuff[] = {
2804 DIR("fd", S_IRUSR|S_IXUSR, fd), 2830 DIR("fd", S_IRUSR|S_IXUSR, proc_fd_inode_operations, proc_fd_operations),
2805 DIR("fdinfo", S_IRUSR|S_IXUSR, fdinfo), 2831 DIR("fdinfo", S_IRUSR|S_IXUSR, proc_fdinfo_inode_operations, proc_fd_operations),
2806 REG("environ", S_IRUSR, environ), 2832 REG("environ", S_IRUSR, proc_environ_operations),
2807 INF("auxv", S_IRUSR, pid_auxv), 2833 INF("auxv", S_IRUSR, proc_pid_auxv),
2808 ONE("status", S_IRUGO, pid_status), 2834 ONE("status", S_IRUGO, proc_pid_status),
2809 ONE("personality", S_IRUSR, pid_personality), 2835 ONE("personality", S_IRUSR, proc_pid_personality),
2810 INF("limits", S_IRUSR, pid_limits), 2836 INF("limits", S_IRUSR, proc_pid_limits),
2811#ifdef CONFIG_SCHED_DEBUG 2837#ifdef CONFIG_SCHED_DEBUG
2812 REG("sched", S_IRUGO|S_IWUSR, pid_sched), 2838 REG("sched", S_IRUGO|S_IWUSR, proc_pid_sched_operations),
2813#endif 2839#endif
2814#ifdef CONFIG_HAVE_ARCH_TRACEHOOK 2840#ifdef CONFIG_HAVE_ARCH_TRACEHOOK
2815 INF("syscall", S_IRUSR, pid_syscall), 2841 INF("syscall", S_IRUSR, proc_pid_syscall),
2816#endif 2842#endif
2817 INF("cmdline", S_IRUGO, pid_cmdline), 2843 INF("cmdline", S_IRUGO, proc_pid_cmdline),
2818 ONE("stat", S_IRUGO, tid_stat), 2844 ONE("stat", S_IRUGO, proc_tid_stat),
2819 ONE("statm", S_IRUGO, pid_statm), 2845 ONE("statm", S_IRUGO, proc_pid_statm),
2820 REG("maps", S_IRUGO, maps), 2846 REG("maps", S_IRUGO, proc_maps_operations),
2821#ifdef CONFIG_NUMA 2847#ifdef CONFIG_NUMA
2822 REG("numa_maps", S_IRUGO, numa_maps), 2848 REG("numa_maps", S_IRUGO, proc_numa_maps_operations),
2823#endif 2849#endif
2824 REG("mem", S_IRUSR|S_IWUSR, mem), 2850 REG("mem", S_IRUSR|S_IWUSR, proc_mem_operations),
2825 LNK("cwd", cwd), 2851 LNK("cwd", proc_cwd_link),
2826 LNK("root", root), 2852 LNK("root", proc_root_link),
2827 LNK("exe", exe), 2853 LNK("exe", proc_exe_link),
2828 REG("mounts", S_IRUGO, mounts), 2854 REG("mounts", S_IRUGO, proc_mounts_operations),
2829 REG("mountinfo", S_IRUGO, mountinfo), 2855 REG("mountinfo", S_IRUGO, proc_mountinfo_operations),
2830#ifdef CONFIG_PROC_PAGE_MONITOR 2856#ifdef CONFIG_PROC_PAGE_MONITOR
2831 REG("clear_refs", S_IWUSR, clear_refs), 2857 REG("clear_refs", S_IWUSR, proc_clear_refs_operations),
2832 REG("smaps", S_IRUGO, smaps), 2858 REG("smaps", S_IRUGO, proc_smaps_operations),
2833 REG("pagemap", S_IRUSR, pagemap), 2859 REG("pagemap", S_IRUSR, proc_pagemap_operations),
2834#endif 2860#endif
2835#ifdef CONFIG_SECURITY 2861#ifdef CONFIG_SECURITY
2836 DIR("attr", S_IRUGO|S_IXUGO, attr_dir), 2862 DIR("attr", S_IRUGO|S_IXUGO, proc_attr_dir_inode_operations, proc_attr_dir_operations),
2837#endif 2863#endif
2838#ifdef CONFIG_KALLSYMS 2864#ifdef CONFIG_KALLSYMS
2839 INF("wchan", S_IRUGO, pid_wchan), 2865 INF("wchan", S_IRUGO, proc_pid_wchan),
2866#endif
2867#ifdef CONFIG_STACKTRACE
2868 ONE("stack", S_IRUSR, proc_pid_stack),
2840#endif 2869#endif
2841#ifdef CONFIG_SCHEDSTATS 2870#ifdef CONFIG_SCHEDSTATS
2842 INF("schedstat", S_IRUGO, pid_schedstat), 2871 INF("schedstat", S_IRUGO, proc_pid_schedstat),
2843#endif 2872#endif
2844#ifdef CONFIG_LATENCYTOP 2873#ifdef CONFIG_LATENCYTOP
2845 REG("latency", S_IRUGO, lstats), 2874 REG("latency", S_IRUGO, proc_lstats_operations),
2846#endif 2875#endif
2847#ifdef CONFIG_PROC_PID_CPUSET 2876#ifdef CONFIG_PROC_PID_CPUSET
2848 REG("cpuset", S_IRUGO, cpuset), 2877 REG("cpuset", S_IRUGO, proc_cpuset_operations),
2849#endif 2878#endif
2850#ifdef CONFIG_CGROUPS 2879#ifdef CONFIG_CGROUPS
2851 REG("cgroup", S_IRUGO, cgroup), 2880 REG("cgroup", S_IRUGO, proc_cgroup_operations),
2852#endif 2881#endif
2853 INF("oom_score", S_IRUGO, oom_score), 2882 INF("oom_score", S_IRUGO, proc_oom_score),
2854 REG("oom_adj", S_IRUGO|S_IWUSR, oom_adjust), 2883 REG("oom_adj", S_IRUGO|S_IWUSR, proc_oom_adjust_operations),
2855#ifdef CONFIG_AUDITSYSCALL 2884#ifdef CONFIG_AUDITSYSCALL
2856 REG("loginuid", S_IWUSR|S_IRUGO, loginuid), 2885 REG("loginuid", S_IWUSR|S_IRUGO, proc_loginuid_operations),
2857 REG("sessionid", S_IRUSR, sessionid), 2886 REG("sessionid", S_IRUSR, proc_sessionid_operations),
2858#endif 2887#endif
2859#ifdef CONFIG_FAULT_INJECTION 2888#ifdef CONFIG_FAULT_INJECTION
2860 REG("make-it-fail", S_IRUGO|S_IWUSR, fault_inject), 2889 REG("make-it-fail", S_IRUGO|S_IWUSR, proc_fault_inject_operations),
2861#endif 2890#endif
2862#ifdef CONFIG_TASK_IO_ACCOUNTING 2891#ifdef CONFIG_TASK_IO_ACCOUNTING
2863 INF("io", S_IRUGO, tid_io_accounting), 2892 INF("io", S_IRUGO, proc_tid_io_accounting),
2864#endif 2893#endif
2865}; 2894};
2866 2895
diff --git a/fs/proc/generic.c b/fs/proc/generic.c
index 60a359b35582..db7fa5cab988 100644
--- a/fs/proc/generic.c
+++ b/fs/proc/generic.c
@@ -14,7 +14,6 @@
14#include <linux/stat.h> 14#include <linux/stat.h>
15#include <linux/module.h> 15#include <linux/module.h>
16#include <linux/mount.h> 16#include <linux/mount.h>
17#include <linux/smp_lock.h>
18#include <linux/init.h> 17#include <linux/init.h>
19#include <linux/idr.h> 18#include <linux/idr.h>
20#include <linux/namei.h> 19#include <linux/namei.h>
@@ -379,7 +378,6 @@ struct dentry *proc_lookup_de(struct proc_dir_entry *de, struct inode *dir,
379 struct inode *inode = NULL; 378 struct inode *inode = NULL;
380 int error = -ENOENT; 379 int error = -ENOENT;
381 380
382 lock_kernel();
383 spin_lock(&proc_subdir_lock); 381 spin_lock(&proc_subdir_lock);
384 for (de = de->subdir; de ; de = de->next) { 382 for (de = de->subdir; de ; de = de->next) {
385 if (de->namelen != dentry->d_name.len) 383 if (de->namelen != dentry->d_name.len)
@@ -397,7 +395,6 @@ struct dentry *proc_lookup_de(struct proc_dir_entry *de, struct inode *dir,
397 } 395 }
398 spin_unlock(&proc_subdir_lock); 396 spin_unlock(&proc_subdir_lock);
399out_unlock: 397out_unlock:
400 unlock_kernel();
401 398
402 if (inode) { 399 if (inode) {
403 dentry->d_op = &proc_dentry_operations; 400 dentry->d_op = &proc_dentry_operations;
@@ -432,8 +429,6 @@ int proc_readdir_de(struct proc_dir_entry *de, struct file *filp, void *dirent,
432 struct inode *inode = filp->f_path.dentry->d_inode; 429 struct inode *inode = filp->f_path.dentry->d_inode;
433 int ret = 0; 430 int ret = 0;
434 431
435 lock_kernel();
436
437 ino = inode->i_ino; 432 ino = inode->i_ino;
438 i = filp->f_pos; 433 i = filp->f_pos;
439 switch (i) { 434 switch (i) {
@@ -487,7 +482,7 @@ int proc_readdir_de(struct proc_dir_entry *de, struct file *filp, void *dirent,
487 spin_unlock(&proc_subdir_lock); 482 spin_unlock(&proc_subdir_lock);
488 } 483 }
489 ret = 1; 484 ret = 1;
490out: unlock_kernel(); 485out:
491 return ret; 486 return ret;
492} 487}
493 488
@@ -504,6 +499,7 @@ int proc_readdir(struct file *filp, void *dirent, filldir_t filldir)
504 * the /proc directory. 499 * the /proc directory.
505 */ 500 */
506static const struct file_operations proc_dir_operations = { 501static const struct file_operations proc_dir_operations = {
502 .llseek = generic_file_llseek,
507 .read = generic_read_dir, 503 .read = generic_read_dir,
508 .readdir = proc_readdir, 504 .readdir = proc_readdir,
509}; 505};
diff --git a/fs/proc/inode.c b/fs/proc/inode.c
index 2543fd00c658..3e76bb9b3ad6 100644
--- a/fs/proc/inode.c
+++ b/fs/proc/inode.c
@@ -35,16 +35,13 @@ struct proc_dir_entry *de_get(struct proc_dir_entry *de)
35 */ 35 */
36void de_put(struct proc_dir_entry *de) 36void de_put(struct proc_dir_entry *de)
37{ 37{
38 lock_kernel();
39 if (!atomic_read(&de->count)) { 38 if (!atomic_read(&de->count)) {
40 printk("de_put: entry %s already free!\n", de->name); 39 printk("de_put: entry %s already free!\n", de->name);
41 unlock_kernel();
42 return; 40 return;
43 } 41 }
44 42
45 if (atomic_dec_and_test(&de->count)) 43 if (atomic_dec_and_test(&de->count))
46 free_proc_entry(de); 44 free_proc_entry(de);
47 unlock_kernel();
48} 45}
49 46
50/* 47/*
diff --git a/fs/proc/proc_net.c b/fs/proc/proc_net.c
index 7bc296f424ae..04d1270f1c38 100644
--- a/fs/proc/proc_net.c
+++ b/fs/proc/proc_net.c
@@ -18,7 +18,6 @@
18#include <linux/sched.h> 18#include <linux/sched.h>
19#include <linux/module.h> 19#include <linux/module.h>
20#include <linux/bitops.h> 20#include <linux/bitops.h>
21#include <linux/smp_lock.h>
22#include <linux/mount.h> 21#include <linux/mount.h>
23#include <linux/nsproxy.h> 22#include <linux/nsproxy.h>
24#include <net/net_namespace.h> 23#include <net/net_namespace.h>
@@ -172,6 +171,7 @@ static int proc_tgid_net_readdir(struct file *filp, void *dirent,
172} 171}
173 172
174const struct file_operations proc_net_operations = { 173const struct file_operations proc_net_operations = {
174 .llseek = generic_file_llseek,
175 .read = generic_read_dir, 175 .read = generic_read_dir,
176 .readdir = proc_tgid_net_readdir, 176 .readdir = proc_tgid_net_readdir,
177}; 177};
diff --git a/fs/proc/root.c b/fs/proc/root.c
index 7761602af9de..f6299a25594e 100644
--- a/fs/proc/root.c
+++ b/fs/proc/root.c
@@ -16,7 +16,6 @@
16#include <linux/sched.h> 16#include <linux/sched.h>
17#include <linux/module.h> 17#include <linux/module.h>
18#include <linux/bitops.h> 18#include <linux/bitops.h>
19#include <linux/smp_lock.h>
20#include <linux/mount.h> 19#include <linux/mount.h>
21#include <linux/pid_namespace.h> 20#include <linux/pid_namespace.h>
22 21
@@ -162,17 +161,12 @@ static int proc_root_readdir(struct file * filp,
162 unsigned int nr = filp->f_pos; 161 unsigned int nr = filp->f_pos;
163 int ret; 162 int ret;
164 163
165 lock_kernel();
166
167 if (nr < FIRST_PROCESS_ENTRY) { 164 if (nr < FIRST_PROCESS_ENTRY) {
168 int error = proc_readdir(filp, dirent, filldir); 165 int error = proc_readdir(filp, dirent, filldir);
169 if (error <= 0) { 166 if (error <= 0)
170 unlock_kernel();
171 return error; 167 return error;
172 }
173 filp->f_pos = FIRST_PROCESS_ENTRY; 168 filp->f_pos = FIRST_PROCESS_ENTRY;
174 } 169 }
175 unlock_kernel();
176 170
177 ret = proc_pid_readdir(filp, dirent, filldir); 171 ret = proc_pid_readdir(filp, dirent, filldir);
178 return ret; 172 return ret;