Commit baf48f6577e581a9adb8fe849dc80e24b21d171d
Committed by
Ingo Molnar
1 parent
e4fa4c9701
Exists in
master
and in
4 other branches
softlock: fix false panic which can occur if softlockup_thresh is reduced
At run-time, if softlockup_thresh is changed to a much lower value, touch_timestamp is likely to be much older than the new softlock_thresh. This will cause a false softlockup to be detected. If softlockup_panic is enabled, the system will panic. The fix is to touch all watchdogs before changing softlockup_thresh. Signed-off-by: Mandeep Singh Baines <msb@google.com> Signed-off-by: Ingo Molnar <mingo@elte.hu>
Showing 3 changed files with 13 additions and 1 deletions Inline Diff
include/linux/sched.h
1 | #ifndef _LINUX_SCHED_H | 1 | #ifndef _LINUX_SCHED_H |
2 | #define _LINUX_SCHED_H | 2 | #define _LINUX_SCHED_H |
3 | 3 | ||
4 | /* | 4 | /* |
5 | * cloning flags: | 5 | * cloning flags: |
6 | */ | 6 | */ |
7 | #define CSIGNAL 0x000000ff /* signal mask to be sent at exit */ | 7 | #define CSIGNAL 0x000000ff /* signal mask to be sent at exit */ |
8 | #define CLONE_VM 0x00000100 /* set if VM shared between processes */ | 8 | #define CLONE_VM 0x00000100 /* set if VM shared between processes */ |
9 | #define CLONE_FS 0x00000200 /* set if fs info shared between processes */ | 9 | #define CLONE_FS 0x00000200 /* set if fs info shared between processes */ |
10 | #define CLONE_FILES 0x00000400 /* set if open files shared between processes */ | 10 | #define CLONE_FILES 0x00000400 /* set if open files shared between processes */ |
11 | #define CLONE_SIGHAND 0x00000800 /* set if signal handlers and blocked signals shared */ | 11 | #define CLONE_SIGHAND 0x00000800 /* set if signal handlers and blocked signals shared */ |
12 | #define CLONE_PTRACE 0x00002000 /* set if we want to let tracing continue on the child too */ | 12 | #define CLONE_PTRACE 0x00002000 /* set if we want to let tracing continue on the child too */ |
13 | #define CLONE_VFORK 0x00004000 /* set if the parent wants the child to wake it up on mm_release */ | 13 | #define CLONE_VFORK 0x00004000 /* set if the parent wants the child to wake it up on mm_release */ |
14 | #define CLONE_PARENT 0x00008000 /* set if we want to have the same parent as the cloner */ | 14 | #define CLONE_PARENT 0x00008000 /* set if we want to have the same parent as the cloner */ |
15 | #define CLONE_THREAD 0x00010000 /* Same thread group? */ | 15 | #define CLONE_THREAD 0x00010000 /* Same thread group? */ |
16 | #define CLONE_NEWNS 0x00020000 /* New namespace group? */ | 16 | #define CLONE_NEWNS 0x00020000 /* New namespace group? */ |
17 | #define CLONE_SYSVSEM 0x00040000 /* share system V SEM_UNDO semantics */ | 17 | #define CLONE_SYSVSEM 0x00040000 /* share system V SEM_UNDO semantics */ |
18 | #define CLONE_SETTLS 0x00080000 /* create a new TLS for the child */ | 18 | #define CLONE_SETTLS 0x00080000 /* create a new TLS for the child */ |
19 | #define CLONE_PARENT_SETTID 0x00100000 /* set the TID in the parent */ | 19 | #define CLONE_PARENT_SETTID 0x00100000 /* set the TID in the parent */ |
20 | #define CLONE_CHILD_CLEARTID 0x00200000 /* clear the TID in the child */ | 20 | #define CLONE_CHILD_CLEARTID 0x00200000 /* clear the TID in the child */ |
21 | #define CLONE_DETACHED 0x00400000 /* Unused, ignored */ | 21 | #define CLONE_DETACHED 0x00400000 /* Unused, ignored */ |
22 | #define CLONE_UNTRACED 0x00800000 /* set if the tracing process can't force CLONE_PTRACE on this clone */ | 22 | #define CLONE_UNTRACED 0x00800000 /* set if the tracing process can't force CLONE_PTRACE on this clone */ |
23 | #define CLONE_CHILD_SETTID 0x01000000 /* set the TID in the child */ | 23 | #define CLONE_CHILD_SETTID 0x01000000 /* set the TID in the child */ |
24 | #define CLONE_STOPPED 0x02000000 /* Start in stopped state */ | 24 | #define CLONE_STOPPED 0x02000000 /* Start in stopped state */ |
25 | #define CLONE_NEWUTS 0x04000000 /* New utsname group? */ | 25 | #define CLONE_NEWUTS 0x04000000 /* New utsname group? */ |
26 | #define CLONE_NEWIPC 0x08000000 /* New ipcs */ | 26 | #define CLONE_NEWIPC 0x08000000 /* New ipcs */ |
27 | #define CLONE_NEWUSER 0x10000000 /* New user namespace */ | 27 | #define CLONE_NEWUSER 0x10000000 /* New user namespace */ |
28 | #define CLONE_NEWPID 0x20000000 /* New pid namespace */ | 28 | #define CLONE_NEWPID 0x20000000 /* New pid namespace */ |
29 | #define CLONE_NEWNET 0x40000000 /* New network namespace */ | 29 | #define CLONE_NEWNET 0x40000000 /* New network namespace */ |
30 | #define CLONE_IO 0x80000000 /* Clone io context */ | 30 | #define CLONE_IO 0x80000000 /* Clone io context */ |
31 | 31 | ||
32 | /* | 32 | /* |
33 | * Scheduling policies | 33 | * Scheduling policies |
34 | */ | 34 | */ |
35 | #define SCHED_NORMAL 0 | 35 | #define SCHED_NORMAL 0 |
36 | #define SCHED_FIFO 1 | 36 | #define SCHED_FIFO 1 |
37 | #define SCHED_RR 2 | 37 | #define SCHED_RR 2 |
38 | #define SCHED_BATCH 3 | 38 | #define SCHED_BATCH 3 |
39 | /* SCHED_ISO: reserved but not implemented yet */ | 39 | /* SCHED_ISO: reserved but not implemented yet */ |
40 | #define SCHED_IDLE 5 | 40 | #define SCHED_IDLE 5 |
41 | 41 | ||
42 | #ifdef __KERNEL__ | 42 | #ifdef __KERNEL__ |
43 | 43 | ||
44 | struct sched_param { | 44 | struct sched_param { |
45 | int sched_priority; | 45 | int sched_priority; |
46 | }; | 46 | }; |
47 | 47 | ||
48 | #include <asm/param.h> /* for HZ */ | 48 | #include <asm/param.h> /* for HZ */ |
49 | 49 | ||
50 | #include <linux/capability.h> | 50 | #include <linux/capability.h> |
51 | #include <linux/threads.h> | 51 | #include <linux/threads.h> |
52 | #include <linux/kernel.h> | 52 | #include <linux/kernel.h> |
53 | #include <linux/types.h> | 53 | #include <linux/types.h> |
54 | #include <linux/timex.h> | 54 | #include <linux/timex.h> |
55 | #include <linux/jiffies.h> | 55 | #include <linux/jiffies.h> |
56 | #include <linux/rbtree.h> | 56 | #include <linux/rbtree.h> |
57 | #include <linux/thread_info.h> | 57 | #include <linux/thread_info.h> |
58 | #include <linux/cpumask.h> | 58 | #include <linux/cpumask.h> |
59 | #include <linux/errno.h> | 59 | #include <linux/errno.h> |
60 | #include <linux/nodemask.h> | 60 | #include <linux/nodemask.h> |
61 | #include <linux/mm_types.h> | 61 | #include <linux/mm_types.h> |
62 | 62 | ||
63 | #include <asm/system.h> | 63 | #include <asm/system.h> |
64 | #include <asm/page.h> | 64 | #include <asm/page.h> |
65 | #include <asm/ptrace.h> | 65 | #include <asm/ptrace.h> |
66 | #include <asm/cputime.h> | 66 | #include <asm/cputime.h> |
67 | 67 | ||
68 | #include <linux/smp.h> | 68 | #include <linux/smp.h> |
69 | #include <linux/sem.h> | 69 | #include <linux/sem.h> |
70 | #include <linux/signal.h> | 70 | #include <linux/signal.h> |
71 | #include <linux/fs_struct.h> | 71 | #include <linux/fs_struct.h> |
72 | #include <linux/compiler.h> | 72 | #include <linux/compiler.h> |
73 | #include <linux/completion.h> | 73 | #include <linux/completion.h> |
74 | #include <linux/pid.h> | 74 | #include <linux/pid.h> |
75 | #include <linux/percpu.h> | 75 | #include <linux/percpu.h> |
76 | #include <linux/topology.h> | 76 | #include <linux/topology.h> |
77 | #include <linux/proportions.h> | 77 | #include <linux/proportions.h> |
78 | #include <linux/seccomp.h> | 78 | #include <linux/seccomp.h> |
79 | #include <linux/rcupdate.h> | 79 | #include <linux/rcupdate.h> |
80 | #include <linux/rtmutex.h> | 80 | #include <linux/rtmutex.h> |
81 | 81 | ||
82 | #include <linux/time.h> | 82 | #include <linux/time.h> |
83 | #include <linux/param.h> | 83 | #include <linux/param.h> |
84 | #include <linux/resource.h> | 84 | #include <linux/resource.h> |
85 | #include <linux/timer.h> | 85 | #include <linux/timer.h> |
86 | #include <linux/hrtimer.h> | 86 | #include <linux/hrtimer.h> |
87 | #include <linux/task_io_accounting.h> | 87 | #include <linux/task_io_accounting.h> |
88 | #include <linux/kobject.h> | 88 | #include <linux/kobject.h> |
89 | #include <linux/latencytop.h> | 89 | #include <linux/latencytop.h> |
90 | #include <linux/cred.h> | 90 | #include <linux/cred.h> |
91 | 91 | ||
92 | #include <asm/processor.h> | 92 | #include <asm/processor.h> |
93 | 93 | ||
94 | struct mem_cgroup; | 94 | struct mem_cgroup; |
95 | struct exec_domain; | 95 | struct exec_domain; |
96 | struct futex_pi_state; | 96 | struct futex_pi_state; |
97 | struct robust_list_head; | 97 | struct robust_list_head; |
98 | struct bio; | 98 | struct bio; |
99 | struct bts_tracer; | 99 | struct bts_tracer; |
100 | 100 | ||
101 | /* | 101 | /* |
102 | * List of flags we want to share for kernel threads, | 102 | * List of flags we want to share for kernel threads, |
103 | * if only because they are not used by them anyway. | 103 | * if only because they are not used by them anyway. |
104 | */ | 104 | */ |
105 | #define CLONE_KERNEL (CLONE_FS | CLONE_FILES | CLONE_SIGHAND) | 105 | #define CLONE_KERNEL (CLONE_FS | CLONE_FILES | CLONE_SIGHAND) |
106 | 106 | ||
107 | /* | 107 | /* |
108 | * These are the constant used to fake the fixed-point load-average | 108 | * These are the constant used to fake the fixed-point load-average |
109 | * counting. Some notes: | 109 | * counting. Some notes: |
110 | * - 11 bit fractions expand to 22 bits by the multiplies: this gives | 110 | * - 11 bit fractions expand to 22 bits by the multiplies: this gives |
111 | * a load-average precision of 10 bits integer + 11 bits fractional | 111 | * a load-average precision of 10 bits integer + 11 bits fractional |
112 | * - if you want to count load-averages more often, you need more | 112 | * - if you want to count load-averages more often, you need more |
113 | * precision, or rounding will get you. With 2-second counting freq, | 113 | * precision, or rounding will get you. With 2-second counting freq, |
114 | * the EXP_n values would be 1981, 2034 and 2043 if still using only | 114 | * the EXP_n values would be 1981, 2034 and 2043 if still using only |
115 | * 11 bit fractions. | 115 | * 11 bit fractions. |
116 | */ | 116 | */ |
117 | extern unsigned long avenrun[]; /* Load averages */ | 117 | extern unsigned long avenrun[]; /* Load averages */ |
118 | 118 | ||
119 | #define FSHIFT 11 /* nr of bits of precision */ | 119 | #define FSHIFT 11 /* nr of bits of precision */ |
120 | #define FIXED_1 (1<<FSHIFT) /* 1.0 as fixed-point */ | 120 | #define FIXED_1 (1<<FSHIFT) /* 1.0 as fixed-point */ |
121 | #define LOAD_FREQ (5*HZ+1) /* 5 sec intervals */ | 121 | #define LOAD_FREQ (5*HZ+1) /* 5 sec intervals */ |
122 | #define EXP_1 1884 /* 1/exp(5sec/1min) as fixed-point */ | 122 | #define EXP_1 1884 /* 1/exp(5sec/1min) as fixed-point */ |
123 | #define EXP_5 2014 /* 1/exp(5sec/5min) */ | 123 | #define EXP_5 2014 /* 1/exp(5sec/5min) */ |
124 | #define EXP_15 2037 /* 1/exp(5sec/15min) */ | 124 | #define EXP_15 2037 /* 1/exp(5sec/15min) */ |
125 | 125 | ||
126 | #define CALC_LOAD(load,exp,n) \ | 126 | #define CALC_LOAD(load,exp,n) \ |
127 | load *= exp; \ | 127 | load *= exp; \ |
128 | load += n*(FIXED_1-exp); \ | 128 | load += n*(FIXED_1-exp); \ |
129 | load >>= FSHIFT; | 129 | load >>= FSHIFT; |
130 | 130 | ||
131 | extern unsigned long total_forks; | 131 | extern unsigned long total_forks; |
132 | extern int nr_threads; | 132 | extern int nr_threads; |
133 | DECLARE_PER_CPU(unsigned long, process_counts); | 133 | DECLARE_PER_CPU(unsigned long, process_counts); |
134 | extern int nr_processes(void); | 134 | extern int nr_processes(void); |
135 | extern unsigned long nr_running(void); | 135 | extern unsigned long nr_running(void); |
136 | extern unsigned long nr_uninterruptible(void); | 136 | extern unsigned long nr_uninterruptible(void); |
137 | extern unsigned long nr_active(void); | 137 | extern unsigned long nr_active(void); |
138 | extern unsigned long nr_iowait(void); | 138 | extern unsigned long nr_iowait(void); |
139 | 139 | ||
140 | struct seq_file; | 140 | struct seq_file; |
141 | struct cfs_rq; | 141 | struct cfs_rq; |
142 | struct task_group; | 142 | struct task_group; |
143 | #ifdef CONFIG_SCHED_DEBUG | 143 | #ifdef CONFIG_SCHED_DEBUG |
144 | extern void proc_sched_show_task(struct task_struct *p, struct seq_file *m); | 144 | extern void proc_sched_show_task(struct task_struct *p, struct seq_file *m); |
145 | extern void proc_sched_set_task(struct task_struct *p); | 145 | extern void proc_sched_set_task(struct task_struct *p); |
146 | extern void | 146 | extern void |
147 | print_cfs_rq(struct seq_file *m, int cpu, struct cfs_rq *cfs_rq); | 147 | print_cfs_rq(struct seq_file *m, int cpu, struct cfs_rq *cfs_rq); |
148 | #else | 148 | #else |
149 | static inline void | 149 | static inline void |
150 | proc_sched_show_task(struct task_struct *p, struct seq_file *m) | 150 | proc_sched_show_task(struct task_struct *p, struct seq_file *m) |
151 | { | 151 | { |
152 | } | 152 | } |
153 | static inline void proc_sched_set_task(struct task_struct *p) | 153 | static inline void proc_sched_set_task(struct task_struct *p) |
154 | { | 154 | { |
155 | } | 155 | } |
156 | static inline void | 156 | static inline void |
157 | print_cfs_rq(struct seq_file *m, int cpu, struct cfs_rq *cfs_rq) | 157 | print_cfs_rq(struct seq_file *m, int cpu, struct cfs_rq *cfs_rq) |
158 | { | 158 | { |
159 | } | 159 | } |
160 | #endif | 160 | #endif |
161 | 161 | ||
162 | extern unsigned long long time_sync_thresh; | 162 | extern unsigned long long time_sync_thresh; |
163 | 163 | ||
164 | /* | 164 | /* |
165 | * Task state bitmask. NOTE! These bits are also | 165 | * Task state bitmask. NOTE! These bits are also |
166 | * encoded in fs/proc/array.c: get_task_state(). | 166 | * encoded in fs/proc/array.c: get_task_state(). |
167 | * | 167 | * |
168 | * We have two separate sets of flags: task->state | 168 | * We have two separate sets of flags: task->state |
169 | * is about runnability, while task->exit_state are | 169 | * is about runnability, while task->exit_state are |
170 | * about the task exiting. Confusing, but this way | 170 | * about the task exiting. Confusing, but this way |
171 | * modifying one set can't modify the other one by | 171 | * modifying one set can't modify the other one by |
172 | * mistake. | 172 | * mistake. |
173 | */ | 173 | */ |
174 | #define TASK_RUNNING 0 | 174 | #define TASK_RUNNING 0 |
175 | #define TASK_INTERRUPTIBLE 1 | 175 | #define TASK_INTERRUPTIBLE 1 |
176 | #define TASK_UNINTERRUPTIBLE 2 | 176 | #define TASK_UNINTERRUPTIBLE 2 |
177 | #define __TASK_STOPPED 4 | 177 | #define __TASK_STOPPED 4 |
178 | #define __TASK_TRACED 8 | 178 | #define __TASK_TRACED 8 |
179 | /* in tsk->exit_state */ | 179 | /* in tsk->exit_state */ |
180 | #define EXIT_ZOMBIE 16 | 180 | #define EXIT_ZOMBIE 16 |
181 | #define EXIT_DEAD 32 | 181 | #define EXIT_DEAD 32 |
182 | /* in tsk->state again */ | 182 | /* in tsk->state again */ |
183 | #define TASK_DEAD 64 | 183 | #define TASK_DEAD 64 |
184 | #define TASK_WAKEKILL 128 | 184 | #define TASK_WAKEKILL 128 |
185 | 185 | ||
186 | /* Convenience macros for the sake of set_task_state */ | 186 | /* Convenience macros for the sake of set_task_state */ |
187 | #define TASK_KILLABLE (TASK_WAKEKILL | TASK_UNINTERRUPTIBLE) | 187 | #define TASK_KILLABLE (TASK_WAKEKILL | TASK_UNINTERRUPTIBLE) |
188 | #define TASK_STOPPED (TASK_WAKEKILL | __TASK_STOPPED) | 188 | #define TASK_STOPPED (TASK_WAKEKILL | __TASK_STOPPED) |
189 | #define TASK_TRACED (TASK_WAKEKILL | __TASK_TRACED) | 189 | #define TASK_TRACED (TASK_WAKEKILL | __TASK_TRACED) |
190 | 190 | ||
191 | /* Convenience macros for the sake of wake_up */ | 191 | /* Convenience macros for the sake of wake_up */ |
192 | #define TASK_NORMAL (TASK_INTERRUPTIBLE | TASK_UNINTERRUPTIBLE) | 192 | #define TASK_NORMAL (TASK_INTERRUPTIBLE | TASK_UNINTERRUPTIBLE) |
193 | #define TASK_ALL (TASK_NORMAL | __TASK_STOPPED | __TASK_TRACED) | 193 | #define TASK_ALL (TASK_NORMAL | __TASK_STOPPED | __TASK_TRACED) |
194 | 194 | ||
195 | /* get_task_state() */ | 195 | /* get_task_state() */ |
196 | #define TASK_REPORT (TASK_RUNNING | TASK_INTERRUPTIBLE | \ | 196 | #define TASK_REPORT (TASK_RUNNING | TASK_INTERRUPTIBLE | \ |
197 | TASK_UNINTERRUPTIBLE | __TASK_STOPPED | \ | 197 | TASK_UNINTERRUPTIBLE | __TASK_STOPPED | \ |
198 | __TASK_TRACED) | 198 | __TASK_TRACED) |
199 | 199 | ||
200 | #define task_is_traced(task) ((task->state & __TASK_TRACED) != 0) | 200 | #define task_is_traced(task) ((task->state & __TASK_TRACED) != 0) |
201 | #define task_is_stopped(task) ((task->state & __TASK_STOPPED) != 0) | 201 | #define task_is_stopped(task) ((task->state & __TASK_STOPPED) != 0) |
202 | #define task_is_stopped_or_traced(task) \ | 202 | #define task_is_stopped_or_traced(task) \ |
203 | ((task->state & (__TASK_STOPPED | __TASK_TRACED)) != 0) | 203 | ((task->state & (__TASK_STOPPED | __TASK_TRACED)) != 0) |
204 | #define task_contributes_to_load(task) \ | 204 | #define task_contributes_to_load(task) \ |
205 | ((task->state & TASK_UNINTERRUPTIBLE) != 0) | 205 | ((task->state & TASK_UNINTERRUPTIBLE) != 0) |
206 | 206 | ||
207 | #define __set_task_state(tsk, state_value) \ | 207 | #define __set_task_state(tsk, state_value) \ |
208 | do { (tsk)->state = (state_value); } while (0) | 208 | do { (tsk)->state = (state_value); } while (0) |
209 | #define set_task_state(tsk, state_value) \ | 209 | #define set_task_state(tsk, state_value) \ |
210 | set_mb((tsk)->state, (state_value)) | 210 | set_mb((tsk)->state, (state_value)) |
211 | 211 | ||
212 | /* | 212 | /* |
213 | * set_current_state() includes a barrier so that the write of current->state | 213 | * set_current_state() includes a barrier so that the write of current->state |
214 | * is correctly serialised wrt the caller's subsequent test of whether to | 214 | * is correctly serialised wrt the caller's subsequent test of whether to |
215 | * actually sleep: | 215 | * actually sleep: |
216 | * | 216 | * |
217 | * set_current_state(TASK_UNINTERRUPTIBLE); | 217 | * set_current_state(TASK_UNINTERRUPTIBLE); |
218 | * if (do_i_need_to_sleep()) | 218 | * if (do_i_need_to_sleep()) |
219 | * schedule(); | 219 | * schedule(); |
220 | * | 220 | * |
221 | * If the caller does not need such serialisation then use __set_current_state() | 221 | * If the caller does not need such serialisation then use __set_current_state() |
222 | */ | 222 | */ |
223 | #define __set_current_state(state_value) \ | 223 | #define __set_current_state(state_value) \ |
224 | do { current->state = (state_value); } while (0) | 224 | do { current->state = (state_value); } while (0) |
225 | #define set_current_state(state_value) \ | 225 | #define set_current_state(state_value) \ |
226 | set_mb(current->state, (state_value)) | 226 | set_mb(current->state, (state_value)) |
227 | 227 | ||
228 | /* Task command name length */ | 228 | /* Task command name length */ |
229 | #define TASK_COMM_LEN 16 | 229 | #define TASK_COMM_LEN 16 |
230 | 230 | ||
231 | #include <linux/spinlock.h> | 231 | #include <linux/spinlock.h> |
232 | 232 | ||
233 | /* | 233 | /* |
234 | * This serializes "schedule()" and also protects | 234 | * This serializes "schedule()" and also protects |
235 | * the run-queue from deletions/modifications (but | 235 | * the run-queue from deletions/modifications (but |
236 | * _adding_ to the beginning of the run-queue has | 236 | * _adding_ to the beginning of the run-queue has |
237 | * a separate lock). | 237 | * a separate lock). |
238 | */ | 238 | */ |
239 | extern rwlock_t tasklist_lock; | 239 | extern rwlock_t tasklist_lock; |
240 | extern spinlock_t mmlist_lock; | 240 | extern spinlock_t mmlist_lock; |
241 | 241 | ||
242 | struct task_struct; | 242 | struct task_struct; |
243 | 243 | ||
244 | extern void sched_init(void); | 244 | extern void sched_init(void); |
245 | extern void sched_init_smp(void); | 245 | extern void sched_init_smp(void); |
246 | extern asmlinkage void schedule_tail(struct task_struct *prev); | 246 | extern asmlinkage void schedule_tail(struct task_struct *prev); |
247 | extern void init_idle(struct task_struct *idle, int cpu); | 247 | extern void init_idle(struct task_struct *idle, int cpu); |
248 | extern void init_idle_bootup_task(struct task_struct *idle); | 248 | extern void init_idle_bootup_task(struct task_struct *idle); |
249 | 249 | ||
250 | extern int runqueue_is_locked(void); | 250 | extern int runqueue_is_locked(void); |
251 | extern void task_rq_unlock_wait(struct task_struct *p); | 251 | extern void task_rq_unlock_wait(struct task_struct *p); |
252 | 252 | ||
253 | extern cpumask_var_t nohz_cpu_mask; | 253 | extern cpumask_var_t nohz_cpu_mask; |
254 | #if defined(CONFIG_SMP) && defined(CONFIG_NO_HZ) | 254 | #if defined(CONFIG_SMP) && defined(CONFIG_NO_HZ) |
255 | extern int select_nohz_load_balancer(int cpu); | 255 | extern int select_nohz_load_balancer(int cpu); |
256 | #else | 256 | #else |
257 | static inline int select_nohz_load_balancer(int cpu) | 257 | static inline int select_nohz_load_balancer(int cpu) |
258 | { | 258 | { |
259 | return 0; | 259 | return 0; |
260 | } | 260 | } |
261 | #endif | 261 | #endif |
262 | 262 | ||
263 | /* | 263 | /* |
264 | * Only dump TASK_* tasks. (0 for all tasks) | 264 | * Only dump TASK_* tasks. (0 for all tasks) |
265 | */ | 265 | */ |
266 | extern void show_state_filter(unsigned long state_filter); | 266 | extern void show_state_filter(unsigned long state_filter); |
267 | 267 | ||
268 | static inline void show_state(void) | 268 | static inline void show_state(void) |
269 | { | 269 | { |
270 | show_state_filter(0); | 270 | show_state_filter(0); |
271 | } | 271 | } |
272 | 272 | ||
273 | extern void show_regs(struct pt_regs *); | 273 | extern void show_regs(struct pt_regs *); |
274 | 274 | ||
275 | /* | 275 | /* |
276 | * TASK is a pointer to the task whose backtrace we want to see (or NULL for current | 276 | * TASK is a pointer to the task whose backtrace we want to see (or NULL for current |
277 | * task), SP is the stack pointer of the first frame that should be shown in the back | 277 | * task), SP is the stack pointer of the first frame that should be shown in the back |
278 | * trace (or NULL if the entire call-chain of the task should be shown). | 278 | * trace (or NULL if the entire call-chain of the task should be shown). |
279 | */ | 279 | */ |
280 | extern void show_stack(struct task_struct *task, unsigned long *sp); | 280 | extern void show_stack(struct task_struct *task, unsigned long *sp); |
281 | 281 | ||
282 | void io_schedule(void); | 282 | void io_schedule(void); |
283 | long io_schedule_timeout(long timeout); | 283 | long io_schedule_timeout(long timeout); |
284 | 284 | ||
285 | extern void cpu_init (void); | 285 | extern void cpu_init (void); |
286 | extern void trap_init(void); | 286 | extern void trap_init(void); |
287 | extern void update_process_times(int user); | 287 | extern void update_process_times(int user); |
288 | extern void scheduler_tick(void); | 288 | extern void scheduler_tick(void); |
289 | 289 | ||
290 | extern void sched_show_task(struct task_struct *p); | 290 | extern void sched_show_task(struct task_struct *p); |
291 | 291 | ||
292 | #ifdef CONFIG_DETECT_SOFTLOCKUP | 292 | #ifdef CONFIG_DETECT_SOFTLOCKUP |
293 | extern void softlockup_tick(void); | 293 | extern void softlockup_tick(void); |
294 | extern void touch_softlockup_watchdog(void); | 294 | extern void touch_softlockup_watchdog(void); |
295 | extern void touch_all_softlockup_watchdogs(void); | 295 | extern void touch_all_softlockup_watchdogs(void); |
296 | extern int proc_dosoftlockup_thresh(struct ctl_table *table, int write, | ||
297 | struct file *filp, void __user *buffer, | ||
298 | size_t *lenp, loff_t *ppos); | ||
296 | extern unsigned int softlockup_panic; | 299 | extern unsigned int softlockup_panic; |
297 | extern unsigned long sysctl_hung_task_check_count; | 300 | extern unsigned long sysctl_hung_task_check_count; |
298 | extern unsigned long sysctl_hung_task_timeout_secs; | 301 | extern unsigned long sysctl_hung_task_timeout_secs; |
299 | extern unsigned long sysctl_hung_task_warnings; | 302 | extern unsigned long sysctl_hung_task_warnings; |
300 | extern int softlockup_thresh; | 303 | extern int softlockup_thresh; |
301 | #else | 304 | #else |
302 | static inline void softlockup_tick(void) | 305 | static inline void softlockup_tick(void) |
303 | { | 306 | { |
304 | } | 307 | } |
305 | static inline void spawn_softlockup_task(void) | 308 | static inline void spawn_softlockup_task(void) |
306 | { | 309 | { |
307 | } | 310 | } |
308 | static inline void touch_softlockup_watchdog(void) | 311 | static inline void touch_softlockup_watchdog(void) |
309 | { | 312 | { |
310 | } | 313 | } |
311 | static inline void touch_all_softlockup_watchdogs(void) | 314 | static inline void touch_all_softlockup_watchdogs(void) |
312 | { | 315 | { |
313 | } | 316 | } |
314 | #endif | 317 | #endif |
315 | 318 | ||
316 | 319 | ||
317 | /* Attach to any functions which should be ignored in wchan output. */ | 320 | /* Attach to any functions which should be ignored in wchan output. */ |
318 | #define __sched __attribute__((__section__(".sched.text"))) | 321 | #define __sched __attribute__((__section__(".sched.text"))) |
319 | 322 | ||
320 | /* Linker adds these: start and end of __sched functions */ | 323 | /* Linker adds these: start and end of __sched functions */ |
321 | extern char __sched_text_start[], __sched_text_end[]; | 324 | extern char __sched_text_start[], __sched_text_end[]; |
322 | 325 | ||
323 | /* Is this address in the __sched functions? */ | 326 | /* Is this address in the __sched functions? */ |
324 | extern int in_sched_functions(unsigned long addr); | 327 | extern int in_sched_functions(unsigned long addr); |
325 | 328 | ||
326 | #define MAX_SCHEDULE_TIMEOUT LONG_MAX | 329 | #define MAX_SCHEDULE_TIMEOUT LONG_MAX |
327 | extern signed long schedule_timeout(signed long timeout); | 330 | extern signed long schedule_timeout(signed long timeout); |
328 | extern signed long schedule_timeout_interruptible(signed long timeout); | 331 | extern signed long schedule_timeout_interruptible(signed long timeout); |
329 | extern signed long schedule_timeout_killable(signed long timeout); | 332 | extern signed long schedule_timeout_killable(signed long timeout); |
330 | extern signed long schedule_timeout_uninterruptible(signed long timeout); | 333 | extern signed long schedule_timeout_uninterruptible(signed long timeout); |
331 | asmlinkage void schedule(void); | 334 | asmlinkage void schedule(void); |
332 | 335 | ||
333 | struct nsproxy; | 336 | struct nsproxy; |
334 | struct user_namespace; | 337 | struct user_namespace; |
335 | 338 | ||
336 | /* Maximum number of active map areas.. This is a random (large) number */ | 339 | /* Maximum number of active map areas.. This is a random (large) number */ |
337 | #define DEFAULT_MAX_MAP_COUNT 65536 | 340 | #define DEFAULT_MAX_MAP_COUNT 65536 |
338 | 341 | ||
339 | extern int sysctl_max_map_count; | 342 | extern int sysctl_max_map_count; |
340 | 343 | ||
341 | #include <linux/aio.h> | 344 | #include <linux/aio.h> |
342 | 345 | ||
343 | extern unsigned long | 346 | extern unsigned long |
344 | arch_get_unmapped_area(struct file *, unsigned long, unsigned long, | 347 | arch_get_unmapped_area(struct file *, unsigned long, unsigned long, |
345 | unsigned long, unsigned long); | 348 | unsigned long, unsigned long); |
346 | extern unsigned long | 349 | extern unsigned long |
347 | arch_get_unmapped_area_topdown(struct file *filp, unsigned long addr, | 350 | arch_get_unmapped_area_topdown(struct file *filp, unsigned long addr, |
348 | unsigned long len, unsigned long pgoff, | 351 | unsigned long len, unsigned long pgoff, |
349 | unsigned long flags); | 352 | unsigned long flags); |
350 | extern void arch_unmap_area(struct mm_struct *, unsigned long); | 353 | extern void arch_unmap_area(struct mm_struct *, unsigned long); |
351 | extern void arch_unmap_area_topdown(struct mm_struct *, unsigned long); | 354 | extern void arch_unmap_area_topdown(struct mm_struct *, unsigned long); |
352 | 355 | ||
353 | #if USE_SPLIT_PTLOCKS | 356 | #if USE_SPLIT_PTLOCKS |
354 | /* | 357 | /* |
355 | * The mm counters are not protected by its page_table_lock, | 358 | * The mm counters are not protected by its page_table_lock, |
356 | * so must be incremented atomically. | 359 | * so must be incremented atomically. |
357 | */ | 360 | */ |
358 | #define set_mm_counter(mm, member, value) atomic_long_set(&(mm)->_##member, value) | 361 | #define set_mm_counter(mm, member, value) atomic_long_set(&(mm)->_##member, value) |
359 | #define get_mm_counter(mm, member) ((unsigned long)atomic_long_read(&(mm)->_##member)) | 362 | #define get_mm_counter(mm, member) ((unsigned long)atomic_long_read(&(mm)->_##member)) |
360 | #define add_mm_counter(mm, member, value) atomic_long_add(value, &(mm)->_##member) | 363 | #define add_mm_counter(mm, member, value) atomic_long_add(value, &(mm)->_##member) |
361 | #define inc_mm_counter(mm, member) atomic_long_inc(&(mm)->_##member) | 364 | #define inc_mm_counter(mm, member) atomic_long_inc(&(mm)->_##member) |
362 | #define dec_mm_counter(mm, member) atomic_long_dec(&(mm)->_##member) | 365 | #define dec_mm_counter(mm, member) atomic_long_dec(&(mm)->_##member) |
363 | 366 | ||
364 | #else /* !USE_SPLIT_PTLOCKS */ | 367 | #else /* !USE_SPLIT_PTLOCKS */ |
365 | /* | 368 | /* |
366 | * The mm counters are protected by its page_table_lock, | 369 | * The mm counters are protected by its page_table_lock, |
367 | * so can be incremented directly. | 370 | * so can be incremented directly. |
368 | */ | 371 | */ |
369 | #define set_mm_counter(mm, member, value) (mm)->_##member = (value) | 372 | #define set_mm_counter(mm, member, value) (mm)->_##member = (value) |
370 | #define get_mm_counter(mm, member) ((mm)->_##member) | 373 | #define get_mm_counter(mm, member) ((mm)->_##member) |
371 | #define add_mm_counter(mm, member, value) (mm)->_##member += (value) | 374 | #define add_mm_counter(mm, member, value) (mm)->_##member += (value) |
372 | #define inc_mm_counter(mm, member) (mm)->_##member++ | 375 | #define inc_mm_counter(mm, member) (mm)->_##member++ |
373 | #define dec_mm_counter(mm, member) (mm)->_##member-- | 376 | #define dec_mm_counter(mm, member) (mm)->_##member-- |
374 | 377 | ||
375 | #endif /* !USE_SPLIT_PTLOCKS */ | 378 | #endif /* !USE_SPLIT_PTLOCKS */ |
376 | 379 | ||
377 | #define get_mm_rss(mm) \ | 380 | #define get_mm_rss(mm) \ |
378 | (get_mm_counter(mm, file_rss) + get_mm_counter(mm, anon_rss)) | 381 | (get_mm_counter(mm, file_rss) + get_mm_counter(mm, anon_rss)) |
379 | #define update_hiwater_rss(mm) do { \ | 382 | #define update_hiwater_rss(mm) do { \ |
380 | unsigned long _rss = get_mm_rss(mm); \ | 383 | unsigned long _rss = get_mm_rss(mm); \ |
381 | if ((mm)->hiwater_rss < _rss) \ | 384 | if ((mm)->hiwater_rss < _rss) \ |
382 | (mm)->hiwater_rss = _rss; \ | 385 | (mm)->hiwater_rss = _rss; \ |
383 | } while (0) | 386 | } while (0) |
384 | #define update_hiwater_vm(mm) do { \ | 387 | #define update_hiwater_vm(mm) do { \ |
385 | if ((mm)->hiwater_vm < (mm)->total_vm) \ | 388 | if ((mm)->hiwater_vm < (mm)->total_vm) \ |
386 | (mm)->hiwater_vm = (mm)->total_vm; \ | 389 | (mm)->hiwater_vm = (mm)->total_vm; \ |
387 | } while (0) | 390 | } while (0) |
388 | 391 | ||
389 | #define get_mm_hiwater_rss(mm) max((mm)->hiwater_rss, get_mm_rss(mm)) | 392 | #define get_mm_hiwater_rss(mm) max((mm)->hiwater_rss, get_mm_rss(mm)) |
390 | #define get_mm_hiwater_vm(mm) max((mm)->hiwater_vm, (mm)->total_vm) | 393 | #define get_mm_hiwater_vm(mm) max((mm)->hiwater_vm, (mm)->total_vm) |
391 | 394 | ||
392 | extern void set_dumpable(struct mm_struct *mm, int value); | 395 | extern void set_dumpable(struct mm_struct *mm, int value); |
393 | extern int get_dumpable(struct mm_struct *mm); | 396 | extern int get_dumpable(struct mm_struct *mm); |
394 | 397 | ||
395 | /* mm flags */ | 398 | /* mm flags */ |
396 | /* dumpable bits */ | 399 | /* dumpable bits */ |
397 | #define MMF_DUMPABLE 0 /* core dump is permitted */ | 400 | #define MMF_DUMPABLE 0 /* core dump is permitted */ |
398 | #define MMF_DUMP_SECURELY 1 /* core file is readable only by root */ | 401 | #define MMF_DUMP_SECURELY 1 /* core file is readable only by root */ |
399 | #define MMF_DUMPABLE_BITS 2 | 402 | #define MMF_DUMPABLE_BITS 2 |
400 | 403 | ||
401 | /* coredump filter bits */ | 404 | /* coredump filter bits */ |
402 | #define MMF_DUMP_ANON_PRIVATE 2 | 405 | #define MMF_DUMP_ANON_PRIVATE 2 |
403 | #define MMF_DUMP_ANON_SHARED 3 | 406 | #define MMF_DUMP_ANON_SHARED 3 |
404 | #define MMF_DUMP_MAPPED_PRIVATE 4 | 407 | #define MMF_DUMP_MAPPED_PRIVATE 4 |
405 | #define MMF_DUMP_MAPPED_SHARED 5 | 408 | #define MMF_DUMP_MAPPED_SHARED 5 |
406 | #define MMF_DUMP_ELF_HEADERS 6 | 409 | #define MMF_DUMP_ELF_HEADERS 6 |
407 | #define MMF_DUMP_HUGETLB_PRIVATE 7 | 410 | #define MMF_DUMP_HUGETLB_PRIVATE 7 |
408 | #define MMF_DUMP_HUGETLB_SHARED 8 | 411 | #define MMF_DUMP_HUGETLB_SHARED 8 |
409 | #define MMF_DUMP_FILTER_SHIFT MMF_DUMPABLE_BITS | 412 | #define MMF_DUMP_FILTER_SHIFT MMF_DUMPABLE_BITS |
410 | #define MMF_DUMP_FILTER_BITS 7 | 413 | #define MMF_DUMP_FILTER_BITS 7 |
411 | #define MMF_DUMP_FILTER_MASK \ | 414 | #define MMF_DUMP_FILTER_MASK \ |
412 | (((1 << MMF_DUMP_FILTER_BITS) - 1) << MMF_DUMP_FILTER_SHIFT) | 415 | (((1 << MMF_DUMP_FILTER_BITS) - 1) << MMF_DUMP_FILTER_SHIFT) |
413 | #define MMF_DUMP_FILTER_DEFAULT \ | 416 | #define MMF_DUMP_FILTER_DEFAULT \ |
414 | ((1 << MMF_DUMP_ANON_PRIVATE) | (1 << MMF_DUMP_ANON_SHARED) |\ | 417 | ((1 << MMF_DUMP_ANON_PRIVATE) | (1 << MMF_DUMP_ANON_SHARED) |\ |
415 | (1 << MMF_DUMP_HUGETLB_PRIVATE) | MMF_DUMP_MASK_DEFAULT_ELF) | 418 | (1 << MMF_DUMP_HUGETLB_PRIVATE) | MMF_DUMP_MASK_DEFAULT_ELF) |
416 | 419 | ||
417 | #ifdef CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS | 420 | #ifdef CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS |
418 | # define MMF_DUMP_MASK_DEFAULT_ELF (1 << MMF_DUMP_ELF_HEADERS) | 421 | # define MMF_DUMP_MASK_DEFAULT_ELF (1 << MMF_DUMP_ELF_HEADERS) |
419 | #else | 422 | #else |
420 | # define MMF_DUMP_MASK_DEFAULT_ELF 0 | 423 | # define MMF_DUMP_MASK_DEFAULT_ELF 0 |
421 | #endif | 424 | #endif |
422 | 425 | ||
423 | struct sighand_struct { | 426 | struct sighand_struct { |
424 | atomic_t count; | 427 | atomic_t count; |
425 | struct k_sigaction action[_NSIG]; | 428 | struct k_sigaction action[_NSIG]; |
426 | spinlock_t siglock; | 429 | spinlock_t siglock; |
427 | wait_queue_head_t signalfd_wqh; | 430 | wait_queue_head_t signalfd_wqh; |
428 | }; | 431 | }; |
429 | 432 | ||
430 | struct pacct_struct { | 433 | struct pacct_struct { |
431 | int ac_flag; | 434 | int ac_flag; |
432 | long ac_exitcode; | 435 | long ac_exitcode; |
433 | unsigned long ac_mem; | 436 | unsigned long ac_mem; |
434 | cputime_t ac_utime, ac_stime; | 437 | cputime_t ac_utime, ac_stime; |
435 | unsigned long ac_minflt, ac_majflt; | 438 | unsigned long ac_minflt, ac_majflt; |
436 | }; | 439 | }; |
437 | 440 | ||
438 | /** | 441 | /** |
439 | * struct task_cputime - collected CPU time counts | 442 | * struct task_cputime - collected CPU time counts |
440 | * @utime: time spent in user mode, in &cputime_t units | 443 | * @utime: time spent in user mode, in &cputime_t units |
441 | * @stime: time spent in kernel mode, in &cputime_t units | 444 | * @stime: time spent in kernel mode, in &cputime_t units |
442 | * @sum_exec_runtime: total time spent on the CPU, in nanoseconds | 445 | * @sum_exec_runtime: total time spent on the CPU, in nanoseconds |
443 | * | 446 | * |
444 | * This structure groups together three kinds of CPU time that are | 447 | * This structure groups together three kinds of CPU time that are |
445 | * tracked for threads and thread groups. Most things considering | 448 | * tracked for threads and thread groups. Most things considering |
446 | * CPU time want to group these counts together and treat all three | 449 | * CPU time want to group these counts together and treat all three |
447 | * of them in parallel. | 450 | * of them in parallel. |
448 | */ | 451 | */ |
449 | struct task_cputime { | 452 | struct task_cputime { |
450 | cputime_t utime; | 453 | cputime_t utime; |
451 | cputime_t stime; | 454 | cputime_t stime; |
452 | unsigned long long sum_exec_runtime; | 455 | unsigned long long sum_exec_runtime; |
453 | }; | 456 | }; |
454 | /* Alternate field names when used to cache expirations. */ | 457 | /* Alternate field names when used to cache expirations. */ |
455 | #define prof_exp stime | 458 | #define prof_exp stime |
456 | #define virt_exp utime | 459 | #define virt_exp utime |
457 | #define sched_exp sum_exec_runtime | 460 | #define sched_exp sum_exec_runtime |
458 | 461 | ||
459 | /** | 462 | /** |
460 | * struct thread_group_cputime - thread group interval timer counts | 463 | * struct thread_group_cputime - thread group interval timer counts |
461 | * @totals: thread group interval timers; substructure for | 464 | * @totals: thread group interval timers; substructure for |
462 | * uniprocessor kernel, per-cpu for SMP kernel. | 465 | * uniprocessor kernel, per-cpu for SMP kernel. |
463 | * | 466 | * |
464 | * This structure contains the version of task_cputime, above, that is | 467 | * This structure contains the version of task_cputime, above, that is |
465 | * used for thread group CPU clock calculations. | 468 | * used for thread group CPU clock calculations. |
466 | */ | 469 | */ |
467 | struct thread_group_cputime { | 470 | struct thread_group_cputime { |
468 | struct task_cputime *totals; | 471 | struct task_cputime *totals; |
469 | }; | 472 | }; |
470 | 473 | ||
471 | /* | 474 | /* |
472 | * NOTE! "signal_struct" does not have it's own | 475 | * NOTE! "signal_struct" does not have it's own |
473 | * locking, because a shared signal_struct always | 476 | * locking, because a shared signal_struct always |
474 | * implies a shared sighand_struct, so locking | 477 | * implies a shared sighand_struct, so locking |
475 | * sighand_struct is always a proper superset of | 478 | * sighand_struct is always a proper superset of |
476 | * the locking of signal_struct. | 479 | * the locking of signal_struct. |
477 | */ | 480 | */ |
478 | struct signal_struct { | 481 | struct signal_struct { |
479 | atomic_t count; | 482 | atomic_t count; |
480 | atomic_t live; | 483 | atomic_t live; |
481 | 484 | ||
482 | wait_queue_head_t wait_chldexit; /* for wait4() */ | 485 | wait_queue_head_t wait_chldexit; /* for wait4() */ |
483 | 486 | ||
484 | /* current thread group signal load-balancing target: */ | 487 | /* current thread group signal load-balancing target: */ |
485 | struct task_struct *curr_target; | 488 | struct task_struct *curr_target; |
486 | 489 | ||
487 | /* shared signal handling: */ | 490 | /* shared signal handling: */ |
488 | struct sigpending shared_pending; | 491 | struct sigpending shared_pending; |
489 | 492 | ||
490 | /* thread group exit support */ | 493 | /* thread group exit support */ |
491 | int group_exit_code; | 494 | int group_exit_code; |
492 | /* overloaded: | 495 | /* overloaded: |
493 | * - notify group_exit_task when ->count is equal to notify_count | 496 | * - notify group_exit_task when ->count is equal to notify_count |
494 | * - everyone except group_exit_task is stopped during signal delivery | 497 | * - everyone except group_exit_task is stopped during signal delivery |
495 | * of fatal signals, group_exit_task processes the signal. | 498 | * of fatal signals, group_exit_task processes the signal. |
496 | */ | 499 | */ |
497 | int notify_count; | 500 | int notify_count; |
498 | struct task_struct *group_exit_task; | 501 | struct task_struct *group_exit_task; |
499 | 502 | ||
500 | /* thread group stop support, overloads group_exit_code too */ | 503 | /* thread group stop support, overloads group_exit_code too */ |
501 | int group_stop_count; | 504 | int group_stop_count; |
502 | unsigned int flags; /* see SIGNAL_* flags below */ | 505 | unsigned int flags; /* see SIGNAL_* flags below */ |
503 | 506 | ||
504 | /* POSIX.1b Interval Timers */ | 507 | /* POSIX.1b Interval Timers */ |
505 | struct list_head posix_timers; | 508 | struct list_head posix_timers; |
506 | 509 | ||
507 | /* ITIMER_REAL timer for the process */ | 510 | /* ITIMER_REAL timer for the process */ |
508 | struct hrtimer real_timer; | 511 | struct hrtimer real_timer; |
509 | struct pid *leader_pid; | 512 | struct pid *leader_pid; |
510 | ktime_t it_real_incr; | 513 | ktime_t it_real_incr; |
511 | 514 | ||
512 | /* ITIMER_PROF and ITIMER_VIRTUAL timers for the process */ | 515 | /* ITIMER_PROF and ITIMER_VIRTUAL timers for the process */ |
513 | cputime_t it_prof_expires, it_virt_expires; | 516 | cputime_t it_prof_expires, it_virt_expires; |
514 | cputime_t it_prof_incr, it_virt_incr; | 517 | cputime_t it_prof_incr, it_virt_incr; |
515 | 518 | ||
516 | /* | 519 | /* |
517 | * Thread group totals for process CPU clocks. | 520 | * Thread group totals for process CPU clocks. |
518 | * See thread_group_cputime(), et al, for details. | 521 | * See thread_group_cputime(), et al, for details. |
519 | */ | 522 | */ |
520 | struct thread_group_cputime cputime; | 523 | struct thread_group_cputime cputime; |
521 | 524 | ||
522 | /* Earliest-expiration cache. */ | 525 | /* Earliest-expiration cache. */ |
523 | struct task_cputime cputime_expires; | 526 | struct task_cputime cputime_expires; |
524 | 527 | ||
525 | struct list_head cpu_timers[3]; | 528 | struct list_head cpu_timers[3]; |
526 | 529 | ||
527 | /* job control IDs */ | 530 | /* job control IDs */ |
528 | 531 | ||
529 | /* | 532 | /* |
530 | * pgrp and session fields are deprecated. | 533 | * pgrp and session fields are deprecated. |
531 | * use the task_session_Xnr and task_pgrp_Xnr routines below | 534 | * use the task_session_Xnr and task_pgrp_Xnr routines below |
532 | */ | 535 | */ |
533 | 536 | ||
534 | union { | 537 | union { |
535 | pid_t pgrp __deprecated; | 538 | pid_t pgrp __deprecated; |
536 | pid_t __pgrp; | 539 | pid_t __pgrp; |
537 | }; | 540 | }; |
538 | 541 | ||
539 | struct pid *tty_old_pgrp; | 542 | struct pid *tty_old_pgrp; |
540 | 543 | ||
541 | union { | 544 | union { |
542 | pid_t session __deprecated; | 545 | pid_t session __deprecated; |
543 | pid_t __session; | 546 | pid_t __session; |
544 | }; | 547 | }; |
545 | 548 | ||
546 | /* boolean value for session group leader */ | 549 | /* boolean value for session group leader */ |
547 | int leader; | 550 | int leader; |
548 | 551 | ||
549 | struct tty_struct *tty; /* NULL if no tty */ | 552 | struct tty_struct *tty; /* NULL if no tty */ |
550 | 553 | ||
551 | /* | 554 | /* |
552 | * Cumulative resource counters for dead threads in the group, | 555 | * Cumulative resource counters for dead threads in the group, |
553 | * and for reaped dead child processes forked by this group. | 556 | * and for reaped dead child processes forked by this group. |
554 | * Live threads maintain their own counters and add to these | 557 | * Live threads maintain their own counters and add to these |
555 | * in __exit_signal, except for the group leader. | 558 | * in __exit_signal, except for the group leader. |
556 | */ | 559 | */ |
557 | cputime_t cutime, cstime; | 560 | cputime_t cutime, cstime; |
558 | cputime_t gtime; | 561 | cputime_t gtime; |
559 | cputime_t cgtime; | 562 | cputime_t cgtime; |
560 | unsigned long nvcsw, nivcsw, cnvcsw, cnivcsw; | 563 | unsigned long nvcsw, nivcsw, cnvcsw, cnivcsw; |
561 | unsigned long min_flt, maj_flt, cmin_flt, cmaj_flt; | 564 | unsigned long min_flt, maj_flt, cmin_flt, cmaj_flt; |
562 | unsigned long inblock, oublock, cinblock, coublock; | 565 | unsigned long inblock, oublock, cinblock, coublock; |
563 | struct task_io_accounting ioac; | 566 | struct task_io_accounting ioac; |
564 | 567 | ||
565 | /* | 568 | /* |
566 | * We don't bother to synchronize most readers of this at all, | 569 | * We don't bother to synchronize most readers of this at all, |
567 | * because there is no reader checking a limit that actually needs | 570 | * because there is no reader checking a limit that actually needs |
568 | * to get both rlim_cur and rlim_max atomically, and either one | 571 | * to get both rlim_cur and rlim_max atomically, and either one |
569 | * alone is a single word that can safely be read normally. | 572 | * alone is a single word that can safely be read normally. |
570 | * getrlimit/setrlimit use task_lock(current->group_leader) to | 573 | * getrlimit/setrlimit use task_lock(current->group_leader) to |
571 | * protect this instead of the siglock, because they really | 574 | * protect this instead of the siglock, because they really |
572 | * have no need to disable irqs. | 575 | * have no need to disable irqs. |
573 | */ | 576 | */ |
574 | struct rlimit rlim[RLIM_NLIMITS]; | 577 | struct rlimit rlim[RLIM_NLIMITS]; |
575 | 578 | ||
576 | #ifdef CONFIG_BSD_PROCESS_ACCT | 579 | #ifdef CONFIG_BSD_PROCESS_ACCT |
577 | struct pacct_struct pacct; /* per-process accounting information */ | 580 | struct pacct_struct pacct; /* per-process accounting information */ |
578 | #endif | 581 | #endif |
579 | #ifdef CONFIG_TASKSTATS | 582 | #ifdef CONFIG_TASKSTATS |
580 | struct taskstats *stats; | 583 | struct taskstats *stats; |
581 | #endif | 584 | #endif |
582 | #ifdef CONFIG_AUDIT | 585 | #ifdef CONFIG_AUDIT |
583 | unsigned audit_tty; | 586 | unsigned audit_tty; |
584 | struct tty_audit_buf *tty_audit_buf; | 587 | struct tty_audit_buf *tty_audit_buf; |
585 | #endif | 588 | #endif |
586 | }; | 589 | }; |
587 | 590 | ||
588 | /* Context switch must be unlocked if interrupts are to be enabled */ | 591 | /* Context switch must be unlocked if interrupts are to be enabled */ |
589 | #ifdef __ARCH_WANT_INTERRUPTS_ON_CTXSW | 592 | #ifdef __ARCH_WANT_INTERRUPTS_ON_CTXSW |
590 | # define __ARCH_WANT_UNLOCKED_CTXSW | 593 | # define __ARCH_WANT_UNLOCKED_CTXSW |
591 | #endif | 594 | #endif |
592 | 595 | ||
593 | /* | 596 | /* |
594 | * Bits in flags field of signal_struct. | 597 | * Bits in flags field of signal_struct. |
595 | */ | 598 | */ |
596 | #define SIGNAL_STOP_STOPPED 0x00000001 /* job control stop in effect */ | 599 | #define SIGNAL_STOP_STOPPED 0x00000001 /* job control stop in effect */ |
597 | #define SIGNAL_STOP_DEQUEUED 0x00000002 /* stop signal dequeued */ | 600 | #define SIGNAL_STOP_DEQUEUED 0x00000002 /* stop signal dequeued */ |
598 | #define SIGNAL_STOP_CONTINUED 0x00000004 /* SIGCONT since WCONTINUED reap */ | 601 | #define SIGNAL_STOP_CONTINUED 0x00000004 /* SIGCONT since WCONTINUED reap */ |
599 | #define SIGNAL_GROUP_EXIT 0x00000008 /* group exit in progress */ | 602 | #define SIGNAL_GROUP_EXIT 0x00000008 /* group exit in progress */ |
600 | /* | 603 | /* |
601 | * Pending notifications to parent. | 604 | * Pending notifications to parent. |
602 | */ | 605 | */ |
603 | #define SIGNAL_CLD_STOPPED 0x00000010 | 606 | #define SIGNAL_CLD_STOPPED 0x00000010 |
604 | #define SIGNAL_CLD_CONTINUED 0x00000020 | 607 | #define SIGNAL_CLD_CONTINUED 0x00000020 |
605 | #define SIGNAL_CLD_MASK (SIGNAL_CLD_STOPPED|SIGNAL_CLD_CONTINUED) | 608 | #define SIGNAL_CLD_MASK (SIGNAL_CLD_STOPPED|SIGNAL_CLD_CONTINUED) |
606 | 609 | ||
607 | #define SIGNAL_UNKILLABLE 0x00000040 /* for init: ignore fatal signals */ | 610 | #define SIGNAL_UNKILLABLE 0x00000040 /* for init: ignore fatal signals */ |
608 | 611 | ||
609 | /* If true, all threads except ->group_exit_task have pending SIGKILL */ | 612 | /* If true, all threads except ->group_exit_task have pending SIGKILL */ |
610 | static inline int signal_group_exit(const struct signal_struct *sig) | 613 | static inline int signal_group_exit(const struct signal_struct *sig) |
611 | { | 614 | { |
612 | return (sig->flags & SIGNAL_GROUP_EXIT) || | 615 | return (sig->flags & SIGNAL_GROUP_EXIT) || |
613 | (sig->group_exit_task != NULL); | 616 | (sig->group_exit_task != NULL); |
614 | } | 617 | } |
615 | 618 | ||
616 | /* | 619 | /* |
617 | * Some day this will be a full-fledged user tracking system.. | 620 | * Some day this will be a full-fledged user tracking system.. |
618 | */ | 621 | */ |
619 | struct user_struct { | 622 | struct user_struct { |
620 | atomic_t __count; /* reference count */ | 623 | atomic_t __count; /* reference count */ |
621 | atomic_t processes; /* How many processes does this user have? */ | 624 | atomic_t processes; /* How many processes does this user have? */ |
622 | atomic_t files; /* How many open files does this user have? */ | 625 | atomic_t files; /* How many open files does this user have? */ |
623 | atomic_t sigpending; /* How many pending signals does this user have? */ | 626 | atomic_t sigpending; /* How many pending signals does this user have? */ |
624 | #ifdef CONFIG_INOTIFY_USER | 627 | #ifdef CONFIG_INOTIFY_USER |
625 | atomic_t inotify_watches; /* How many inotify watches does this user have? */ | 628 | atomic_t inotify_watches; /* How many inotify watches does this user have? */ |
626 | atomic_t inotify_devs; /* How many inotify devs does this user have opened? */ | 629 | atomic_t inotify_devs; /* How many inotify devs does this user have opened? */ |
627 | #endif | 630 | #endif |
628 | #ifdef CONFIG_EPOLL | 631 | #ifdef CONFIG_EPOLL |
629 | atomic_t epoll_devs; /* The number of epoll descriptors currently open */ | 632 | atomic_t epoll_devs; /* The number of epoll descriptors currently open */ |
630 | atomic_t epoll_watches; /* The number of file descriptors currently watched */ | 633 | atomic_t epoll_watches; /* The number of file descriptors currently watched */ |
631 | #endif | 634 | #endif |
632 | #ifdef CONFIG_POSIX_MQUEUE | 635 | #ifdef CONFIG_POSIX_MQUEUE |
633 | /* protected by mq_lock */ | 636 | /* protected by mq_lock */ |
634 | unsigned long mq_bytes; /* How many bytes can be allocated to mqueue? */ | 637 | unsigned long mq_bytes; /* How many bytes can be allocated to mqueue? */ |
635 | #endif | 638 | #endif |
636 | unsigned long locked_shm; /* How many pages of mlocked shm ? */ | 639 | unsigned long locked_shm; /* How many pages of mlocked shm ? */ |
637 | 640 | ||
638 | #ifdef CONFIG_KEYS | 641 | #ifdef CONFIG_KEYS |
639 | struct key *uid_keyring; /* UID specific keyring */ | 642 | struct key *uid_keyring; /* UID specific keyring */ |
640 | struct key *session_keyring; /* UID's default session keyring */ | 643 | struct key *session_keyring; /* UID's default session keyring */ |
641 | #endif | 644 | #endif |
642 | 645 | ||
643 | /* Hash table maintenance information */ | 646 | /* Hash table maintenance information */ |
644 | struct hlist_node uidhash_node; | 647 | struct hlist_node uidhash_node; |
645 | uid_t uid; | 648 | uid_t uid; |
646 | struct user_namespace *user_ns; | 649 | struct user_namespace *user_ns; |
647 | 650 | ||
648 | #ifdef CONFIG_USER_SCHED | 651 | #ifdef CONFIG_USER_SCHED |
649 | struct task_group *tg; | 652 | struct task_group *tg; |
650 | #ifdef CONFIG_SYSFS | 653 | #ifdef CONFIG_SYSFS |
651 | struct kobject kobj; | 654 | struct kobject kobj; |
652 | struct work_struct work; | 655 | struct work_struct work; |
653 | #endif | 656 | #endif |
654 | #endif | 657 | #endif |
655 | }; | 658 | }; |
656 | 659 | ||
657 | extern int uids_sysfs_init(void); | 660 | extern int uids_sysfs_init(void); |
658 | 661 | ||
659 | extern struct user_struct *find_user(uid_t); | 662 | extern struct user_struct *find_user(uid_t); |
660 | 663 | ||
661 | extern struct user_struct root_user; | 664 | extern struct user_struct root_user; |
662 | #define INIT_USER (&root_user) | 665 | #define INIT_USER (&root_user) |
663 | 666 | ||
664 | 667 | ||
665 | struct backing_dev_info; | 668 | struct backing_dev_info; |
666 | struct reclaim_state; | 669 | struct reclaim_state; |
667 | 670 | ||
668 | #if defined(CONFIG_SCHEDSTATS) || defined(CONFIG_TASK_DELAY_ACCT) | 671 | #if defined(CONFIG_SCHEDSTATS) || defined(CONFIG_TASK_DELAY_ACCT) |
669 | struct sched_info { | 672 | struct sched_info { |
670 | /* cumulative counters */ | 673 | /* cumulative counters */ |
671 | unsigned long pcount; /* # of times run on this cpu */ | 674 | unsigned long pcount; /* # of times run on this cpu */ |
672 | unsigned long long run_delay; /* time spent waiting on a runqueue */ | 675 | unsigned long long run_delay; /* time spent waiting on a runqueue */ |
673 | 676 | ||
674 | /* timestamps */ | 677 | /* timestamps */ |
675 | unsigned long long last_arrival,/* when we last ran on a cpu */ | 678 | unsigned long long last_arrival,/* when we last ran on a cpu */ |
676 | last_queued; /* when we were last queued to run */ | 679 | last_queued; /* when we were last queued to run */ |
677 | #ifdef CONFIG_SCHEDSTATS | 680 | #ifdef CONFIG_SCHEDSTATS |
678 | /* BKL stats */ | 681 | /* BKL stats */ |
679 | unsigned int bkl_count; | 682 | unsigned int bkl_count; |
680 | #endif | 683 | #endif |
681 | }; | 684 | }; |
682 | #endif /* defined(CONFIG_SCHEDSTATS) || defined(CONFIG_TASK_DELAY_ACCT) */ | 685 | #endif /* defined(CONFIG_SCHEDSTATS) || defined(CONFIG_TASK_DELAY_ACCT) */ |
683 | 686 | ||
684 | #ifdef CONFIG_TASK_DELAY_ACCT | 687 | #ifdef CONFIG_TASK_DELAY_ACCT |
685 | struct task_delay_info { | 688 | struct task_delay_info { |
686 | spinlock_t lock; | 689 | spinlock_t lock; |
687 | unsigned int flags; /* Private per-task flags */ | 690 | unsigned int flags; /* Private per-task flags */ |
688 | 691 | ||
689 | /* For each stat XXX, add following, aligned appropriately | 692 | /* For each stat XXX, add following, aligned appropriately |
690 | * | 693 | * |
691 | * struct timespec XXX_start, XXX_end; | 694 | * struct timespec XXX_start, XXX_end; |
692 | * u64 XXX_delay; | 695 | * u64 XXX_delay; |
693 | * u32 XXX_count; | 696 | * u32 XXX_count; |
694 | * | 697 | * |
695 | * Atomicity of updates to XXX_delay, XXX_count protected by | 698 | * Atomicity of updates to XXX_delay, XXX_count protected by |
696 | * single lock above (split into XXX_lock if contention is an issue). | 699 | * single lock above (split into XXX_lock if contention is an issue). |
697 | */ | 700 | */ |
698 | 701 | ||
699 | /* | 702 | /* |
700 | * XXX_count is incremented on every XXX operation, the delay | 703 | * XXX_count is incremented on every XXX operation, the delay |
701 | * associated with the operation is added to XXX_delay. | 704 | * associated with the operation is added to XXX_delay. |
702 | * XXX_delay contains the accumulated delay time in nanoseconds. | 705 | * XXX_delay contains the accumulated delay time in nanoseconds. |
703 | */ | 706 | */ |
704 | struct timespec blkio_start, blkio_end; /* Shared by blkio, swapin */ | 707 | struct timespec blkio_start, blkio_end; /* Shared by blkio, swapin */ |
705 | u64 blkio_delay; /* wait for sync block io completion */ | 708 | u64 blkio_delay; /* wait for sync block io completion */ |
706 | u64 swapin_delay; /* wait for swapin block io completion */ | 709 | u64 swapin_delay; /* wait for swapin block io completion */ |
707 | u32 blkio_count; /* total count of the number of sync block */ | 710 | u32 blkio_count; /* total count of the number of sync block */ |
708 | /* io operations performed */ | 711 | /* io operations performed */ |
709 | u32 swapin_count; /* total count of the number of swapin block */ | 712 | u32 swapin_count; /* total count of the number of swapin block */ |
710 | /* io operations performed */ | 713 | /* io operations performed */ |
711 | 714 | ||
712 | struct timespec freepages_start, freepages_end; | 715 | struct timespec freepages_start, freepages_end; |
713 | u64 freepages_delay; /* wait for memory reclaim */ | 716 | u64 freepages_delay; /* wait for memory reclaim */ |
714 | u32 freepages_count; /* total count of memory reclaim */ | 717 | u32 freepages_count; /* total count of memory reclaim */ |
715 | }; | 718 | }; |
716 | #endif /* CONFIG_TASK_DELAY_ACCT */ | 719 | #endif /* CONFIG_TASK_DELAY_ACCT */ |
717 | 720 | ||
718 | static inline int sched_info_on(void) | 721 | static inline int sched_info_on(void) |
719 | { | 722 | { |
720 | #ifdef CONFIG_SCHEDSTATS | 723 | #ifdef CONFIG_SCHEDSTATS |
721 | return 1; | 724 | return 1; |
722 | #elif defined(CONFIG_TASK_DELAY_ACCT) | 725 | #elif defined(CONFIG_TASK_DELAY_ACCT) |
723 | extern int delayacct_on; | 726 | extern int delayacct_on; |
724 | return delayacct_on; | 727 | return delayacct_on; |
725 | #else | 728 | #else |
726 | return 0; | 729 | return 0; |
727 | #endif | 730 | #endif |
728 | } | 731 | } |
729 | 732 | ||
730 | enum cpu_idle_type { | 733 | enum cpu_idle_type { |
731 | CPU_IDLE, | 734 | CPU_IDLE, |
732 | CPU_NOT_IDLE, | 735 | CPU_NOT_IDLE, |
733 | CPU_NEWLY_IDLE, | 736 | CPU_NEWLY_IDLE, |
734 | CPU_MAX_IDLE_TYPES | 737 | CPU_MAX_IDLE_TYPES |
735 | }; | 738 | }; |
736 | 739 | ||
737 | /* | 740 | /* |
738 | * sched-domains (multiprocessor balancing) declarations: | 741 | * sched-domains (multiprocessor balancing) declarations: |
739 | */ | 742 | */ |
740 | 743 | ||
741 | /* | 744 | /* |
742 | * Increase resolution of nice-level calculations: | 745 | * Increase resolution of nice-level calculations: |
743 | */ | 746 | */ |
744 | #define SCHED_LOAD_SHIFT 10 | 747 | #define SCHED_LOAD_SHIFT 10 |
745 | #define SCHED_LOAD_SCALE (1L << SCHED_LOAD_SHIFT) | 748 | #define SCHED_LOAD_SCALE (1L << SCHED_LOAD_SHIFT) |
746 | 749 | ||
747 | #define SCHED_LOAD_SCALE_FUZZ SCHED_LOAD_SCALE | 750 | #define SCHED_LOAD_SCALE_FUZZ SCHED_LOAD_SCALE |
748 | 751 | ||
749 | #ifdef CONFIG_SMP | 752 | #ifdef CONFIG_SMP |
750 | #define SD_LOAD_BALANCE 1 /* Do load balancing on this domain. */ | 753 | #define SD_LOAD_BALANCE 1 /* Do load balancing on this domain. */ |
751 | #define SD_BALANCE_NEWIDLE 2 /* Balance when about to become idle */ | 754 | #define SD_BALANCE_NEWIDLE 2 /* Balance when about to become idle */ |
752 | #define SD_BALANCE_EXEC 4 /* Balance on exec */ | 755 | #define SD_BALANCE_EXEC 4 /* Balance on exec */ |
753 | #define SD_BALANCE_FORK 8 /* Balance on fork, clone */ | 756 | #define SD_BALANCE_FORK 8 /* Balance on fork, clone */ |
754 | #define SD_WAKE_IDLE 16 /* Wake to idle CPU on task wakeup */ | 757 | #define SD_WAKE_IDLE 16 /* Wake to idle CPU on task wakeup */ |
755 | #define SD_WAKE_AFFINE 32 /* Wake task to waking CPU */ | 758 | #define SD_WAKE_AFFINE 32 /* Wake task to waking CPU */ |
756 | #define SD_WAKE_BALANCE 64 /* Perform balancing at task wakeup */ | 759 | #define SD_WAKE_BALANCE 64 /* Perform balancing at task wakeup */ |
757 | #define SD_SHARE_CPUPOWER 128 /* Domain members share cpu power */ | 760 | #define SD_SHARE_CPUPOWER 128 /* Domain members share cpu power */ |
758 | #define SD_POWERSAVINGS_BALANCE 256 /* Balance for power savings */ | 761 | #define SD_POWERSAVINGS_BALANCE 256 /* Balance for power savings */ |
759 | #define SD_SHARE_PKG_RESOURCES 512 /* Domain members share cpu pkg resources */ | 762 | #define SD_SHARE_PKG_RESOURCES 512 /* Domain members share cpu pkg resources */ |
760 | #define SD_SERIALIZE 1024 /* Only a single load balancing instance */ | 763 | #define SD_SERIALIZE 1024 /* Only a single load balancing instance */ |
761 | #define SD_WAKE_IDLE_FAR 2048 /* Gain latency sacrificing cache hit */ | 764 | #define SD_WAKE_IDLE_FAR 2048 /* Gain latency sacrificing cache hit */ |
762 | 765 | ||
763 | enum powersavings_balance_level { | 766 | enum powersavings_balance_level { |
764 | POWERSAVINGS_BALANCE_NONE = 0, /* No power saving load balance */ | 767 | POWERSAVINGS_BALANCE_NONE = 0, /* No power saving load balance */ |
765 | POWERSAVINGS_BALANCE_BASIC, /* Fill one thread/core/package | 768 | POWERSAVINGS_BALANCE_BASIC, /* Fill one thread/core/package |
766 | * first for long running threads | 769 | * first for long running threads |
767 | */ | 770 | */ |
768 | POWERSAVINGS_BALANCE_WAKEUP, /* Also bias task wakeups to semi-idle | 771 | POWERSAVINGS_BALANCE_WAKEUP, /* Also bias task wakeups to semi-idle |
769 | * cpu package for power savings | 772 | * cpu package for power savings |
770 | */ | 773 | */ |
771 | MAX_POWERSAVINGS_BALANCE_LEVELS | 774 | MAX_POWERSAVINGS_BALANCE_LEVELS |
772 | }; | 775 | }; |
773 | 776 | ||
774 | extern int sched_mc_power_savings, sched_smt_power_savings; | 777 | extern int sched_mc_power_savings, sched_smt_power_savings; |
775 | 778 | ||
776 | static inline int sd_balance_for_mc_power(void) | 779 | static inline int sd_balance_for_mc_power(void) |
777 | { | 780 | { |
778 | if (sched_smt_power_savings) | 781 | if (sched_smt_power_savings) |
779 | return SD_POWERSAVINGS_BALANCE; | 782 | return SD_POWERSAVINGS_BALANCE; |
780 | 783 | ||
781 | return 0; | 784 | return 0; |
782 | } | 785 | } |
783 | 786 | ||
784 | static inline int sd_balance_for_package_power(void) | 787 | static inline int sd_balance_for_package_power(void) |
785 | { | 788 | { |
786 | if (sched_mc_power_savings | sched_smt_power_savings) | 789 | if (sched_mc_power_savings | sched_smt_power_savings) |
787 | return SD_POWERSAVINGS_BALANCE; | 790 | return SD_POWERSAVINGS_BALANCE; |
788 | 791 | ||
789 | return 0; | 792 | return 0; |
790 | } | 793 | } |
791 | 794 | ||
792 | /* | 795 | /* |
793 | * Optimise SD flags for power savings: | 796 | * Optimise SD flags for power savings: |
794 | * SD_BALANCE_NEWIDLE helps agressive task consolidation and power savings. | 797 | * SD_BALANCE_NEWIDLE helps agressive task consolidation and power savings. |
795 | * Keep default SD flags if sched_{smt,mc}_power_saving=0 | 798 | * Keep default SD flags if sched_{smt,mc}_power_saving=0 |
796 | */ | 799 | */ |
797 | 800 | ||
798 | static inline int sd_power_saving_flags(void) | 801 | static inline int sd_power_saving_flags(void) |
799 | { | 802 | { |
800 | if (sched_mc_power_savings | sched_smt_power_savings) | 803 | if (sched_mc_power_savings | sched_smt_power_savings) |
801 | return SD_BALANCE_NEWIDLE; | 804 | return SD_BALANCE_NEWIDLE; |
802 | 805 | ||
803 | return 0; | 806 | return 0; |
804 | } | 807 | } |
805 | 808 | ||
806 | struct sched_group { | 809 | struct sched_group { |
807 | struct sched_group *next; /* Must be a circular list */ | 810 | struct sched_group *next; /* Must be a circular list */ |
808 | 811 | ||
809 | /* | 812 | /* |
810 | * CPU power of this group, SCHED_LOAD_SCALE being max power for a | 813 | * CPU power of this group, SCHED_LOAD_SCALE being max power for a |
811 | * single CPU. This is read only (except for setup, hotplug CPU). | 814 | * single CPU. This is read only (except for setup, hotplug CPU). |
812 | * Note : Never change cpu_power without recompute its reciprocal | 815 | * Note : Never change cpu_power without recompute its reciprocal |
813 | */ | 816 | */ |
814 | unsigned int __cpu_power; | 817 | unsigned int __cpu_power; |
815 | /* | 818 | /* |
816 | * reciprocal value of cpu_power to avoid expensive divides | 819 | * reciprocal value of cpu_power to avoid expensive divides |
817 | * (see include/linux/reciprocal_div.h) | 820 | * (see include/linux/reciprocal_div.h) |
818 | */ | 821 | */ |
819 | u32 reciprocal_cpu_power; | 822 | u32 reciprocal_cpu_power; |
820 | 823 | ||
821 | unsigned long cpumask[]; | 824 | unsigned long cpumask[]; |
822 | }; | 825 | }; |
823 | 826 | ||
824 | static inline struct cpumask *sched_group_cpus(struct sched_group *sg) | 827 | static inline struct cpumask *sched_group_cpus(struct sched_group *sg) |
825 | { | 828 | { |
826 | return to_cpumask(sg->cpumask); | 829 | return to_cpumask(sg->cpumask); |
827 | } | 830 | } |
828 | 831 | ||
829 | enum sched_domain_level { | 832 | enum sched_domain_level { |
830 | SD_LV_NONE = 0, | 833 | SD_LV_NONE = 0, |
831 | SD_LV_SIBLING, | 834 | SD_LV_SIBLING, |
832 | SD_LV_MC, | 835 | SD_LV_MC, |
833 | SD_LV_CPU, | 836 | SD_LV_CPU, |
834 | SD_LV_NODE, | 837 | SD_LV_NODE, |
835 | SD_LV_ALLNODES, | 838 | SD_LV_ALLNODES, |
836 | SD_LV_MAX | 839 | SD_LV_MAX |
837 | }; | 840 | }; |
838 | 841 | ||
839 | struct sched_domain_attr { | 842 | struct sched_domain_attr { |
840 | int relax_domain_level; | 843 | int relax_domain_level; |
841 | }; | 844 | }; |
842 | 845 | ||
843 | #define SD_ATTR_INIT (struct sched_domain_attr) { \ | 846 | #define SD_ATTR_INIT (struct sched_domain_attr) { \ |
844 | .relax_domain_level = -1, \ | 847 | .relax_domain_level = -1, \ |
845 | } | 848 | } |
846 | 849 | ||
847 | struct sched_domain { | 850 | struct sched_domain { |
848 | /* These fields must be setup */ | 851 | /* These fields must be setup */ |
849 | struct sched_domain *parent; /* top domain must be null terminated */ | 852 | struct sched_domain *parent; /* top domain must be null terminated */ |
850 | struct sched_domain *child; /* bottom domain must be null terminated */ | 853 | struct sched_domain *child; /* bottom domain must be null terminated */ |
851 | struct sched_group *groups; /* the balancing groups of the domain */ | 854 | struct sched_group *groups; /* the balancing groups of the domain */ |
852 | unsigned long min_interval; /* Minimum balance interval ms */ | 855 | unsigned long min_interval; /* Minimum balance interval ms */ |
853 | unsigned long max_interval; /* Maximum balance interval ms */ | 856 | unsigned long max_interval; /* Maximum balance interval ms */ |
854 | unsigned int busy_factor; /* less balancing by factor if busy */ | 857 | unsigned int busy_factor; /* less balancing by factor if busy */ |
855 | unsigned int imbalance_pct; /* No balance until over watermark */ | 858 | unsigned int imbalance_pct; /* No balance until over watermark */ |
856 | unsigned int cache_nice_tries; /* Leave cache hot tasks for # tries */ | 859 | unsigned int cache_nice_tries; /* Leave cache hot tasks for # tries */ |
857 | unsigned int busy_idx; | 860 | unsigned int busy_idx; |
858 | unsigned int idle_idx; | 861 | unsigned int idle_idx; |
859 | unsigned int newidle_idx; | 862 | unsigned int newidle_idx; |
860 | unsigned int wake_idx; | 863 | unsigned int wake_idx; |
861 | unsigned int forkexec_idx; | 864 | unsigned int forkexec_idx; |
862 | int flags; /* See SD_* */ | 865 | int flags; /* See SD_* */ |
863 | enum sched_domain_level level; | 866 | enum sched_domain_level level; |
864 | 867 | ||
865 | /* Runtime fields. */ | 868 | /* Runtime fields. */ |
866 | unsigned long last_balance; /* init to jiffies. units in jiffies */ | 869 | unsigned long last_balance; /* init to jiffies. units in jiffies */ |
867 | unsigned int balance_interval; /* initialise to 1. units in ms. */ | 870 | unsigned int balance_interval; /* initialise to 1. units in ms. */ |
868 | unsigned int nr_balance_failed; /* initialise to 0 */ | 871 | unsigned int nr_balance_failed; /* initialise to 0 */ |
869 | 872 | ||
870 | u64 last_update; | 873 | u64 last_update; |
871 | 874 | ||
872 | #ifdef CONFIG_SCHEDSTATS | 875 | #ifdef CONFIG_SCHEDSTATS |
873 | /* load_balance() stats */ | 876 | /* load_balance() stats */ |
874 | unsigned int lb_count[CPU_MAX_IDLE_TYPES]; | 877 | unsigned int lb_count[CPU_MAX_IDLE_TYPES]; |
875 | unsigned int lb_failed[CPU_MAX_IDLE_TYPES]; | 878 | unsigned int lb_failed[CPU_MAX_IDLE_TYPES]; |
876 | unsigned int lb_balanced[CPU_MAX_IDLE_TYPES]; | 879 | unsigned int lb_balanced[CPU_MAX_IDLE_TYPES]; |
877 | unsigned int lb_imbalance[CPU_MAX_IDLE_TYPES]; | 880 | unsigned int lb_imbalance[CPU_MAX_IDLE_TYPES]; |
878 | unsigned int lb_gained[CPU_MAX_IDLE_TYPES]; | 881 | unsigned int lb_gained[CPU_MAX_IDLE_TYPES]; |
879 | unsigned int lb_hot_gained[CPU_MAX_IDLE_TYPES]; | 882 | unsigned int lb_hot_gained[CPU_MAX_IDLE_TYPES]; |
880 | unsigned int lb_nobusyg[CPU_MAX_IDLE_TYPES]; | 883 | unsigned int lb_nobusyg[CPU_MAX_IDLE_TYPES]; |
881 | unsigned int lb_nobusyq[CPU_MAX_IDLE_TYPES]; | 884 | unsigned int lb_nobusyq[CPU_MAX_IDLE_TYPES]; |
882 | 885 | ||
883 | /* Active load balancing */ | 886 | /* Active load balancing */ |
884 | unsigned int alb_count; | 887 | unsigned int alb_count; |
885 | unsigned int alb_failed; | 888 | unsigned int alb_failed; |
886 | unsigned int alb_pushed; | 889 | unsigned int alb_pushed; |
887 | 890 | ||
888 | /* SD_BALANCE_EXEC stats */ | 891 | /* SD_BALANCE_EXEC stats */ |
889 | unsigned int sbe_count; | 892 | unsigned int sbe_count; |
890 | unsigned int sbe_balanced; | 893 | unsigned int sbe_balanced; |
891 | unsigned int sbe_pushed; | 894 | unsigned int sbe_pushed; |
892 | 895 | ||
893 | /* SD_BALANCE_FORK stats */ | 896 | /* SD_BALANCE_FORK stats */ |
894 | unsigned int sbf_count; | 897 | unsigned int sbf_count; |
895 | unsigned int sbf_balanced; | 898 | unsigned int sbf_balanced; |
896 | unsigned int sbf_pushed; | 899 | unsigned int sbf_pushed; |
897 | 900 | ||
898 | /* try_to_wake_up() stats */ | 901 | /* try_to_wake_up() stats */ |
899 | unsigned int ttwu_wake_remote; | 902 | unsigned int ttwu_wake_remote; |
900 | unsigned int ttwu_move_affine; | 903 | unsigned int ttwu_move_affine; |
901 | unsigned int ttwu_move_balance; | 904 | unsigned int ttwu_move_balance; |
902 | #endif | 905 | #endif |
903 | #ifdef CONFIG_SCHED_DEBUG | 906 | #ifdef CONFIG_SCHED_DEBUG |
904 | char *name; | 907 | char *name; |
905 | #endif | 908 | #endif |
906 | 909 | ||
907 | /* span of all CPUs in this domain */ | 910 | /* span of all CPUs in this domain */ |
908 | unsigned long span[]; | 911 | unsigned long span[]; |
909 | }; | 912 | }; |
910 | 913 | ||
911 | static inline struct cpumask *sched_domain_span(struct sched_domain *sd) | 914 | static inline struct cpumask *sched_domain_span(struct sched_domain *sd) |
912 | { | 915 | { |
913 | return to_cpumask(sd->span); | 916 | return to_cpumask(sd->span); |
914 | } | 917 | } |
915 | 918 | ||
916 | extern void partition_sched_domains(int ndoms_new, struct cpumask *doms_new, | 919 | extern void partition_sched_domains(int ndoms_new, struct cpumask *doms_new, |
917 | struct sched_domain_attr *dattr_new); | 920 | struct sched_domain_attr *dattr_new); |
918 | 921 | ||
919 | /* Test a flag in parent sched domain */ | 922 | /* Test a flag in parent sched domain */ |
920 | static inline int test_sd_parent(struct sched_domain *sd, int flag) | 923 | static inline int test_sd_parent(struct sched_domain *sd, int flag) |
921 | { | 924 | { |
922 | if (sd->parent && (sd->parent->flags & flag)) | 925 | if (sd->parent && (sd->parent->flags & flag)) |
923 | return 1; | 926 | return 1; |
924 | 927 | ||
925 | return 0; | 928 | return 0; |
926 | } | 929 | } |
927 | 930 | ||
928 | #else /* CONFIG_SMP */ | 931 | #else /* CONFIG_SMP */ |
929 | 932 | ||
930 | struct sched_domain_attr; | 933 | struct sched_domain_attr; |
931 | 934 | ||
932 | static inline void | 935 | static inline void |
933 | partition_sched_domains(int ndoms_new, struct cpumask *doms_new, | 936 | partition_sched_domains(int ndoms_new, struct cpumask *doms_new, |
934 | struct sched_domain_attr *dattr_new) | 937 | struct sched_domain_attr *dattr_new) |
935 | { | 938 | { |
936 | } | 939 | } |
937 | #endif /* !CONFIG_SMP */ | 940 | #endif /* !CONFIG_SMP */ |
938 | 941 | ||
939 | struct io_context; /* See blkdev.h */ | 942 | struct io_context; /* See blkdev.h */ |
940 | 943 | ||
941 | 944 | ||
942 | #ifdef ARCH_HAS_PREFETCH_SWITCH_STACK | 945 | #ifdef ARCH_HAS_PREFETCH_SWITCH_STACK |
943 | extern void prefetch_stack(struct task_struct *t); | 946 | extern void prefetch_stack(struct task_struct *t); |
944 | #else | 947 | #else |
945 | static inline void prefetch_stack(struct task_struct *t) { } | 948 | static inline void prefetch_stack(struct task_struct *t) { } |
946 | #endif | 949 | #endif |
947 | 950 | ||
948 | struct audit_context; /* See audit.c */ | 951 | struct audit_context; /* See audit.c */ |
949 | struct mempolicy; | 952 | struct mempolicy; |
950 | struct pipe_inode_info; | 953 | struct pipe_inode_info; |
951 | struct uts_namespace; | 954 | struct uts_namespace; |
952 | 955 | ||
953 | struct rq; | 956 | struct rq; |
954 | struct sched_domain; | 957 | struct sched_domain; |
955 | 958 | ||
956 | struct sched_class { | 959 | struct sched_class { |
957 | const struct sched_class *next; | 960 | const struct sched_class *next; |
958 | 961 | ||
959 | void (*enqueue_task) (struct rq *rq, struct task_struct *p, int wakeup); | 962 | void (*enqueue_task) (struct rq *rq, struct task_struct *p, int wakeup); |
960 | void (*dequeue_task) (struct rq *rq, struct task_struct *p, int sleep); | 963 | void (*dequeue_task) (struct rq *rq, struct task_struct *p, int sleep); |
961 | void (*yield_task) (struct rq *rq); | 964 | void (*yield_task) (struct rq *rq); |
962 | 965 | ||
963 | void (*check_preempt_curr) (struct rq *rq, struct task_struct *p, int sync); | 966 | void (*check_preempt_curr) (struct rq *rq, struct task_struct *p, int sync); |
964 | 967 | ||
965 | struct task_struct * (*pick_next_task) (struct rq *rq); | 968 | struct task_struct * (*pick_next_task) (struct rq *rq); |
966 | void (*put_prev_task) (struct rq *rq, struct task_struct *p); | 969 | void (*put_prev_task) (struct rq *rq, struct task_struct *p); |
967 | 970 | ||
968 | #ifdef CONFIG_SMP | 971 | #ifdef CONFIG_SMP |
969 | int (*select_task_rq)(struct task_struct *p, int sync); | 972 | int (*select_task_rq)(struct task_struct *p, int sync); |
970 | 973 | ||
971 | unsigned long (*load_balance) (struct rq *this_rq, int this_cpu, | 974 | unsigned long (*load_balance) (struct rq *this_rq, int this_cpu, |
972 | struct rq *busiest, unsigned long max_load_move, | 975 | struct rq *busiest, unsigned long max_load_move, |
973 | struct sched_domain *sd, enum cpu_idle_type idle, | 976 | struct sched_domain *sd, enum cpu_idle_type idle, |
974 | int *all_pinned, int *this_best_prio); | 977 | int *all_pinned, int *this_best_prio); |
975 | 978 | ||
976 | int (*move_one_task) (struct rq *this_rq, int this_cpu, | 979 | int (*move_one_task) (struct rq *this_rq, int this_cpu, |
977 | struct rq *busiest, struct sched_domain *sd, | 980 | struct rq *busiest, struct sched_domain *sd, |
978 | enum cpu_idle_type idle); | 981 | enum cpu_idle_type idle); |
979 | void (*pre_schedule) (struct rq *this_rq, struct task_struct *task); | 982 | void (*pre_schedule) (struct rq *this_rq, struct task_struct *task); |
980 | void (*post_schedule) (struct rq *this_rq); | 983 | void (*post_schedule) (struct rq *this_rq); |
981 | void (*task_wake_up) (struct rq *this_rq, struct task_struct *task); | 984 | void (*task_wake_up) (struct rq *this_rq, struct task_struct *task); |
982 | 985 | ||
983 | void (*set_cpus_allowed)(struct task_struct *p, | 986 | void (*set_cpus_allowed)(struct task_struct *p, |
984 | const struct cpumask *newmask); | 987 | const struct cpumask *newmask); |
985 | 988 | ||
986 | void (*rq_online)(struct rq *rq); | 989 | void (*rq_online)(struct rq *rq); |
987 | void (*rq_offline)(struct rq *rq); | 990 | void (*rq_offline)(struct rq *rq); |
988 | #endif | 991 | #endif |
989 | 992 | ||
990 | void (*set_curr_task) (struct rq *rq); | 993 | void (*set_curr_task) (struct rq *rq); |
991 | void (*task_tick) (struct rq *rq, struct task_struct *p, int queued); | 994 | void (*task_tick) (struct rq *rq, struct task_struct *p, int queued); |
992 | void (*task_new) (struct rq *rq, struct task_struct *p); | 995 | void (*task_new) (struct rq *rq, struct task_struct *p); |
993 | 996 | ||
994 | void (*switched_from) (struct rq *this_rq, struct task_struct *task, | 997 | void (*switched_from) (struct rq *this_rq, struct task_struct *task, |
995 | int running); | 998 | int running); |
996 | void (*switched_to) (struct rq *this_rq, struct task_struct *task, | 999 | void (*switched_to) (struct rq *this_rq, struct task_struct *task, |
997 | int running); | 1000 | int running); |
998 | void (*prio_changed) (struct rq *this_rq, struct task_struct *task, | 1001 | void (*prio_changed) (struct rq *this_rq, struct task_struct *task, |
999 | int oldprio, int running); | 1002 | int oldprio, int running); |
1000 | 1003 | ||
1001 | #ifdef CONFIG_FAIR_GROUP_SCHED | 1004 | #ifdef CONFIG_FAIR_GROUP_SCHED |
1002 | void (*moved_group) (struct task_struct *p); | 1005 | void (*moved_group) (struct task_struct *p); |
1003 | #endif | 1006 | #endif |
1004 | }; | 1007 | }; |
1005 | 1008 | ||
1006 | struct load_weight { | 1009 | struct load_weight { |
1007 | unsigned long weight, inv_weight; | 1010 | unsigned long weight, inv_weight; |
1008 | }; | 1011 | }; |
1009 | 1012 | ||
1010 | /* | 1013 | /* |
1011 | * CFS stats for a schedulable entity (task, task-group etc) | 1014 | * CFS stats for a schedulable entity (task, task-group etc) |
1012 | * | 1015 | * |
1013 | * Current field usage histogram: | 1016 | * Current field usage histogram: |
1014 | * | 1017 | * |
1015 | * 4 se->block_start | 1018 | * 4 se->block_start |
1016 | * 4 se->run_node | 1019 | * 4 se->run_node |
1017 | * 4 se->sleep_start | 1020 | * 4 se->sleep_start |
1018 | * 6 se->load.weight | 1021 | * 6 se->load.weight |
1019 | */ | 1022 | */ |
1020 | struct sched_entity { | 1023 | struct sched_entity { |
1021 | struct load_weight load; /* for load-balancing */ | 1024 | struct load_weight load; /* for load-balancing */ |
1022 | struct rb_node run_node; | 1025 | struct rb_node run_node; |
1023 | struct list_head group_node; | 1026 | struct list_head group_node; |
1024 | unsigned int on_rq; | 1027 | unsigned int on_rq; |
1025 | 1028 | ||
1026 | u64 exec_start; | 1029 | u64 exec_start; |
1027 | u64 sum_exec_runtime; | 1030 | u64 sum_exec_runtime; |
1028 | u64 vruntime; | 1031 | u64 vruntime; |
1029 | u64 prev_sum_exec_runtime; | 1032 | u64 prev_sum_exec_runtime; |
1030 | 1033 | ||
1031 | u64 last_wakeup; | 1034 | u64 last_wakeup; |
1032 | u64 avg_overlap; | 1035 | u64 avg_overlap; |
1033 | 1036 | ||
1034 | #ifdef CONFIG_SCHEDSTATS | 1037 | #ifdef CONFIG_SCHEDSTATS |
1035 | u64 wait_start; | 1038 | u64 wait_start; |
1036 | u64 wait_max; | 1039 | u64 wait_max; |
1037 | u64 wait_count; | 1040 | u64 wait_count; |
1038 | u64 wait_sum; | 1041 | u64 wait_sum; |
1039 | 1042 | ||
1040 | u64 sleep_start; | 1043 | u64 sleep_start; |
1041 | u64 sleep_max; | 1044 | u64 sleep_max; |
1042 | s64 sum_sleep_runtime; | 1045 | s64 sum_sleep_runtime; |
1043 | 1046 | ||
1044 | u64 block_start; | 1047 | u64 block_start; |
1045 | u64 block_max; | 1048 | u64 block_max; |
1046 | u64 exec_max; | 1049 | u64 exec_max; |
1047 | u64 slice_max; | 1050 | u64 slice_max; |
1048 | 1051 | ||
1049 | u64 nr_migrations; | 1052 | u64 nr_migrations; |
1050 | u64 nr_migrations_cold; | 1053 | u64 nr_migrations_cold; |
1051 | u64 nr_failed_migrations_affine; | 1054 | u64 nr_failed_migrations_affine; |
1052 | u64 nr_failed_migrations_running; | 1055 | u64 nr_failed_migrations_running; |
1053 | u64 nr_failed_migrations_hot; | 1056 | u64 nr_failed_migrations_hot; |
1054 | u64 nr_forced_migrations; | 1057 | u64 nr_forced_migrations; |
1055 | u64 nr_forced2_migrations; | 1058 | u64 nr_forced2_migrations; |
1056 | 1059 | ||
1057 | u64 nr_wakeups; | 1060 | u64 nr_wakeups; |
1058 | u64 nr_wakeups_sync; | 1061 | u64 nr_wakeups_sync; |
1059 | u64 nr_wakeups_migrate; | 1062 | u64 nr_wakeups_migrate; |
1060 | u64 nr_wakeups_local; | 1063 | u64 nr_wakeups_local; |
1061 | u64 nr_wakeups_remote; | 1064 | u64 nr_wakeups_remote; |
1062 | u64 nr_wakeups_affine; | 1065 | u64 nr_wakeups_affine; |
1063 | u64 nr_wakeups_affine_attempts; | 1066 | u64 nr_wakeups_affine_attempts; |
1064 | u64 nr_wakeups_passive; | 1067 | u64 nr_wakeups_passive; |
1065 | u64 nr_wakeups_idle; | 1068 | u64 nr_wakeups_idle; |
1066 | #endif | 1069 | #endif |
1067 | 1070 | ||
1068 | #ifdef CONFIG_FAIR_GROUP_SCHED | 1071 | #ifdef CONFIG_FAIR_GROUP_SCHED |
1069 | struct sched_entity *parent; | 1072 | struct sched_entity *parent; |
1070 | /* rq on which this entity is (to be) queued: */ | 1073 | /* rq on which this entity is (to be) queued: */ |
1071 | struct cfs_rq *cfs_rq; | 1074 | struct cfs_rq *cfs_rq; |
1072 | /* rq "owned" by this entity/group: */ | 1075 | /* rq "owned" by this entity/group: */ |
1073 | struct cfs_rq *my_q; | 1076 | struct cfs_rq *my_q; |
1074 | #endif | 1077 | #endif |
1075 | }; | 1078 | }; |
1076 | 1079 | ||
1077 | struct sched_rt_entity { | 1080 | struct sched_rt_entity { |
1078 | struct list_head run_list; | 1081 | struct list_head run_list; |
1079 | unsigned long timeout; | 1082 | unsigned long timeout; |
1080 | unsigned int time_slice; | 1083 | unsigned int time_slice; |
1081 | int nr_cpus_allowed; | 1084 | int nr_cpus_allowed; |
1082 | 1085 | ||
1083 | struct sched_rt_entity *back; | 1086 | struct sched_rt_entity *back; |
1084 | #ifdef CONFIG_RT_GROUP_SCHED | 1087 | #ifdef CONFIG_RT_GROUP_SCHED |
1085 | struct sched_rt_entity *parent; | 1088 | struct sched_rt_entity *parent; |
1086 | /* rq on which this entity is (to be) queued: */ | 1089 | /* rq on which this entity is (to be) queued: */ |
1087 | struct rt_rq *rt_rq; | 1090 | struct rt_rq *rt_rq; |
1088 | /* rq "owned" by this entity/group: */ | 1091 | /* rq "owned" by this entity/group: */ |
1089 | struct rt_rq *my_q; | 1092 | struct rt_rq *my_q; |
1090 | #endif | 1093 | #endif |
1091 | }; | 1094 | }; |
1092 | 1095 | ||
1093 | struct task_struct { | 1096 | struct task_struct { |
1094 | volatile long state; /* -1 unrunnable, 0 runnable, >0 stopped */ | 1097 | volatile long state; /* -1 unrunnable, 0 runnable, >0 stopped */ |
1095 | void *stack; | 1098 | void *stack; |
1096 | atomic_t usage; | 1099 | atomic_t usage; |
1097 | unsigned int flags; /* per process flags, defined below */ | 1100 | unsigned int flags; /* per process flags, defined below */ |
1098 | unsigned int ptrace; | 1101 | unsigned int ptrace; |
1099 | 1102 | ||
1100 | int lock_depth; /* BKL lock depth */ | 1103 | int lock_depth; /* BKL lock depth */ |
1101 | 1104 | ||
1102 | #ifdef CONFIG_SMP | 1105 | #ifdef CONFIG_SMP |
1103 | #ifdef __ARCH_WANT_UNLOCKED_CTXSW | 1106 | #ifdef __ARCH_WANT_UNLOCKED_CTXSW |
1104 | int oncpu; | 1107 | int oncpu; |
1105 | #endif | 1108 | #endif |
1106 | #endif | 1109 | #endif |
1107 | 1110 | ||
1108 | int prio, static_prio, normal_prio; | 1111 | int prio, static_prio, normal_prio; |
1109 | unsigned int rt_priority; | 1112 | unsigned int rt_priority; |
1110 | const struct sched_class *sched_class; | 1113 | const struct sched_class *sched_class; |
1111 | struct sched_entity se; | 1114 | struct sched_entity se; |
1112 | struct sched_rt_entity rt; | 1115 | struct sched_rt_entity rt; |
1113 | 1116 | ||
1114 | #ifdef CONFIG_PREEMPT_NOTIFIERS | 1117 | #ifdef CONFIG_PREEMPT_NOTIFIERS |
1115 | /* list of struct preempt_notifier: */ | 1118 | /* list of struct preempt_notifier: */ |
1116 | struct hlist_head preempt_notifiers; | 1119 | struct hlist_head preempt_notifiers; |
1117 | #endif | 1120 | #endif |
1118 | 1121 | ||
1119 | /* | 1122 | /* |
1120 | * fpu_counter contains the number of consecutive context switches | 1123 | * fpu_counter contains the number of consecutive context switches |
1121 | * that the FPU is used. If this is over a threshold, the lazy fpu | 1124 | * that the FPU is used. If this is over a threshold, the lazy fpu |
1122 | * saving becomes unlazy to save the trap. This is an unsigned char | 1125 | * saving becomes unlazy to save the trap. This is an unsigned char |
1123 | * so that after 256 times the counter wraps and the behavior turns | 1126 | * so that after 256 times the counter wraps and the behavior turns |
1124 | * lazy again; this to deal with bursty apps that only use FPU for | 1127 | * lazy again; this to deal with bursty apps that only use FPU for |
1125 | * a short time | 1128 | * a short time |
1126 | */ | 1129 | */ |
1127 | unsigned char fpu_counter; | 1130 | unsigned char fpu_counter; |
1128 | s8 oomkilladj; /* OOM kill score adjustment (bit shift). */ | 1131 | s8 oomkilladj; /* OOM kill score adjustment (bit shift). */ |
1129 | #ifdef CONFIG_BLK_DEV_IO_TRACE | 1132 | #ifdef CONFIG_BLK_DEV_IO_TRACE |
1130 | unsigned int btrace_seq; | 1133 | unsigned int btrace_seq; |
1131 | #endif | 1134 | #endif |
1132 | 1135 | ||
1133 | unsigned int policy; | 1136 | unsigned int policy; |
1134 | cpumask_t cpus_allowed; | 1137 | cpumask_t cpus_allowed; |
1135 | 1138 | ||
1136 | #ifdef CONFIG_PREEMPT_RCU | 1139 | #ifdef CONFIG_PREEMPT_RCU |
1137 | int rcu_read_lock_nesting; | 1140 | int rcu_read_lock_nesting; |
1138 | int rcu_flipctr_idx; | 1141 | int rcu_flipctr_idx; |
1139 | #endif /* #ifdef CONFIG_PREEMPT_RCU */ | 1142 | #endif /* #ifdef CONFIG_PREEMPT_RCU */ |
1140 | 1143 | ||
1141 | #if defined(CONFIG_SCHEDSTATS) || defined(CONFIG_TASK_DELAY_ACCT) | 1144 | #if defined(CONFIG_SCHEDSTATS) || defined(CONFIG_TASK_DELAY_ACCT) |
1142 | struct sched_info sched_info; | 1145 | struct sched_info sched_info; |
1143 | #endif | 1146 | #endif |
1144 | 1147 | ||
1145 | struct list_head tasks; | 1148 | struct list_head tasks; |
1146 | 1149 | ||
1147 | struct mm_struct *mm, *active_mm; | 1150 | struct mm_struct *mm, *active_mm; |
1148 | 1151 | ||
1149 | /* task state */ | 1152 | /* task state */ |
1150 | struct linux_binfmt *binfmt; | 1153 | struct linux_binfmt *binfmt; |
1151 | int exit_state; | 1154 | int exit_state; |
1152 | int exit_code, exit_signal; | 1155 | int exit_code, exit_signal; |
1153 | int pdeath_signal; /* The signal sent when the parent dies */ | 1156 | int pdeath_signal; /* The signal sent when the parent dies */ |
1154 | /* ??? */ | 1157 | /* ??? */ |
1155 | unsigned int personality; | 1158 | unsigned int personality; |
1156 | unsigned did_exec:1; | 1159 | unsigned did_exec:1; |
1157 | pid_t pid; | 1160 | pid_t pid; |
1158 | pid_t tgid; | 1161 | pid_t tgid; |
1159 | 1162 | ||
1160 | #ifdef CONFIG_CC_STACKPROTECTOR | 1163 | #ifdef CONFIG_CC_STACKPROTECTOR |
1161 | /* Canary value for the -fstack-protector gcc feature */ | 1164 | /* Canary value for the -fstack-protector gcc feature */ |
1162 | unsigned long stack_canary; | 1165 | unsigned long stack_canary; |
1163 | #endif | 1166 | #endif |
1164 | /* | 1167 | /* |
1165 | * pointers to (original) parent process, youngest child, younger sibling, | 1168 | * pointers to (original) parent process, youngest child, younger sibling, |
1166 | * older sibling, respectively. (p->father can be replaced with | 1169 | * older sibling, respectively. (p->father can be replaced with |
1167 | * p->real_parent->pid) | 1170 | * p->real_parent->pid) |
1168 | */ | 1171 | */ |
1169 | struct task_struct *real_parent; /* real parent process */ | 1172 | struct task_struct *real_parent; /* real parent process */ |
1170 | struct task_struct *parent; /* recipient of SIGCHLD, wait4() reports */ | 1173 | struct task_struct *parent; /* recipient of SIGCHLD, wait4() reports */ |
1171 | /* | 1174 | /* |
1172 | * children/sibling forms the list of my natural children | 1175 | * children/sibling forms the list of my natural children |
1173 | */ | 1176 | */ |
1174 | struct list_head children; /* list of my children */ | 1177 | struct list_head children; /* list of my children */ |
1175 | struct list_head sibling; /* linkage in my parent's children list */ | 1178 | struct list_head sibling; /* linkage in my parent's children list */ |
1176 | struct task_struct *group_leader; /* threadgroup leader */ | 1179 | struct task_struct *group_leader; /* threadgroup leader */ |
1177 | 1180 | ||
1178 | /* | 1181 | /* |
1179 | * ptraced is the list of tasks this task is using ptrace on. | 1182 | * ptraced is the list of tasks this task is using ptrace on. |
1180 | * This includes both natural children and PTRACE_ATTACH targets. | 1183 | * This includes both natural children and PTRACE_ATTACH targets. |
1181 | * p->ptrace_entry is p's link on the p->parent->ptraced list. | 1184 | * p->ptrace_entry is p's link on the p->parent->ptraced list. |
1182 | */ | 1185 | */ |
1183 | struct list_head ptraced; | 1186 | struct list_head ptraced; |
1184 | struct list_head ptrace_entry; | 1187 | struct list_head ptrace_entry; |
1185 | 1188 | ||
1186 | #ifdef CONFIG_X86_PTRACE_BTS | 1189 | #ifdef CONFIG_X86_PTRACE_BTS |
1187 | /* | 1190 | /* |
1188 | * This is the tracer handle for the ptrace BTS extension. | 1191 | * This is the tracer handle for the ptrace BTS extension. |
1189 | * This field actually belongs to the ptracer task. | 1192 | * This field actually belongs to the ptracer task. |
1190 | */ | 1193 | */ |
1191 | struct bts_tracer *bts; | 1194 | struct bts_tracer *bts; |
1192 | /* | 1195 | /* |
1193 | * The buffer to hold the BTS data. | 1196 | * The buffer to hold the BTS data. |
1194 | */ | 1197 | */ |
1195 | void *bts_buffer; | 1198 | void *bts_buffer; |
1196 | size_t bts_size; | 1199 | size_t bts_size; |
1197 | #endif /* CONFIG_X86_PTRACE_BTS */ | 1200 | #endif /* CONFIG_X86_PTRACE_BTS */ |
1198 | 1201 | ||
1199 | /* PID/PID hash table linkage. */ | 1202 | /* PID/PID hash table linkage. */ |
1200 | struct pid_link pids[PIDTYPE_MAX]; | 1203 | struct pid_link pids[PIDTYPE_MAX]; |
1201 | struct list_head thread_group; | 1204 | struct list_head thread_group; |
1202 | 1205 | ||
1203 | struct completion *vfork_done; /* for vfork() */ | 1206 | struct completion *vfork_done; /* for vfork() */ |
1204 | int __user *set_child_tid; /* CLONE_CHILD_SETTID */ | 1207 | int __user *set_child_tid; /* CLONE_CHILD_SETTID */ |
1205 | int __user *clear_child_tid; /* CLONE_CHILD_CLEARTID */ | 1208 | int __user *clear_child_tid; /* CLONE_CHILD_CLEARTID */ |
1206 | 1209 | ||
1207 | cputime_t utime, stime, utimescaled, stimescaled; | 1210 | cputime_t utime, stime, utimescaled, stimescaled; |
1208 | cputime_t gtime; | 1211 | cputime_t gtime; |
1209 | cputime_t prev_utime, prev_stime; | 1212 | cputime_t prev_utime, prev_stime; |
1210 | unsigned long nvcsw, nivcsw; /* context switch counts */ | 1213 | unsigned long nvcsw, nivcsw; /* context switch counts */ |
1211 | struct timespec start_time; /* monotonic time */ | 1214 | struct timespec start_time; /* monotonic time */ |
1212 | struct timespec real_start_time; /* boot based time */ | 1215 | struct timespec real_start_time; /* boot based time */ |
1213 | /* mm fault and swap info: this can arguably be seen as either mm-specific or thread-specific */ | 1216 | /* mm fault and swap info: this can arguably be seen as either mm-specific or thread-specific */ |
1214 | unsigned long min_flt, maj_flt; | 1217 | unsigned long min_flt, maj_flt; |
1215 | 1218 | ||
1216 | struct task_cputime cputime_expires; | 1219 | struct task_cputime cputime_expires; |
1217 | struct list_head cpu_timers[3]; | 1220 | struct list_head cpu_timers[3]; |
1218 | 1221 | ||
1219 | /* process credentials */ | 1222 | /* process credentials */ |
1220 | const struct cred *real_cred; /* objective and real subjective task | 1223 | const struct cred *real_cred; /* objective and real subjective task |
1221 | * credentials (COW) */ | 1224 | * credentials (COW) */ |
1222 | const struct cred *cred; /* effective (overridable) subjective task | 1225 | const struct cred *cred; /* effective (overridable) subjective task |
1223 | * credentials (COW) */ | 1226 | * credentials (COW) */ |
1224 | struct mutex cred_exec_mutex; /* execve vs ptrace cred calculation mutex */ | 1227 | struct mutex cred_exec_mutex; /* execve vs ptrace cred calculation mutex */ |
1225 | 1228 | ||
1226 | char comm[TASK_COMM_LEN]; /* executable name excluding path | 1229 | char comm[TASK_COMM_LEN]; /* executable name excluding path |
1227 | - access with [gs]et_task_comm (which lock | 1230 | - access with [gs]et_task_comm (which lock |
1228 | it with task_lock()) | 1231 | it with task_lock()) |
1229 | - initialized normally by flush_old_exec */ | 1232 | - initialized normally by flush_old_exec */ |
1230 | /* file system info */ | 1233 | /* file system info */ |
1231 | int link_count, total_link_count; | 1234 | int link_count, total_link_count; |
1232 | #ifdef CONFIG_SYSVIPC | 1235 | #ifdef CONFIG_SYSVIPC |
1233 | /* ipc stuff */ | 1236 | /* ipc stuff */ |
1234 | struct sysv_sem sysvsem; | 1237 | struct sysv_sem sysvsem; |
1235 | #endif | 1238 | #endif |
1236 | #ifdef CONFIG_DETECT_SOFTLOCKUP | 1239 | #ifdef CONFIG_DETECT_SOFTLOCKUP |
1237 | /* hung task detection */ | 1240 | /* hung task detection */ |
1238 | unsigned long last_switch_timestamp; | 1241 | unsigned long last_switch_timestamp; |
1239 | unsigned long last_switch_count; | 1242 | unsigned long last_switch_count; |
1240 | #endif | 1243 | #endif |
1241 | /* CPU-specific state of this task */ | 1244 | /* CPU-specific state of this task */ |
1242 | struct thread_struct thread; | 1245 | struct thread_struct thread; |
1243 | /* filesystem information */ | 1246 | /* filesystem information */ |
1244 | struct fs_struct *fs; | 1247 | struct fs_struct *fs; |
1245 | /* open file information */ | 1248 | /* open file information */ |
1246 | struct files_struct *files; | 1249 | struct files_struct *files; |
1247 | /* namespaces */ | 1250 | /* namespaces */ |
1248 | struct nsproxy *nsproxy; | 1251 | struct nsproxy *nsproxy; |
1249 | /* signal handlers */ | 1252 | /* signal handlers */ |
1250 | struct signal_struct *signal; | 1253 | struct signal_struct *signal; |
1251 | struct sighand_struct *sighand; | 1254 | struct sighand_struct *sighand; |
1252 | 1255 | ||
1253 | sigset_t blocked, real_blocked; | 1256 | sigset_t blocked, real_blocked; |
1254 | sigset_t saved_sigmask; /* restored if set_restore_sigmask() was used */ | 1257 | sigset_t saved_sigmask; /* restored if set_restore_sigmask() was used */ |
1255 | struct sigpending pending; | 1258 | struct sigpending pending; |
1256 | 1259 | ||
1257 | unsigned long sas_ss_sp; | 1260 | unsigned long sas_ss_sp; |
1258 | size_t sas_ss_size; | 1261 | size_t sas_ss_size; |
1259 | int (*notifier)(void *priv); | 1262 | int (*notifier)(void *priv); |
1260 | void *notifier_data; | 1263 | void *notifier_data; |
1261 | sigset_t *notifier_mask; | 1264 | sigset_t *notifier_mask; |
1262 | struct audit_context *audit_context; | 1265 | struct audit_context *audit_context; |
1263 | #ifdef CONFIG_AUDITSYSCALL | 1266 | #ifdef CONFIG_AUDITSYSCALL |
1264 | uid_t loginuid; | 1267 | uid_t loginuid; |
1265 | unsigned int sessionid; | 1268 | unsigned int sessionid; |
1266 | #endif | 1269 | #endif |
1267 | seccomp_t seccomp; | 1270 | seccomp_t seccomp; |
1268 | 1271 | ||
1269 | /* Thread group tracking */ | 1272 | /* Thread group tracking */ |
1270 | u32 parent_exec_id; | 1273 | u32 parent_exec_id; |
1271 | u32 self_exec_id; | 1274 | u32 self_exec_id; |
1272 | /* Protection of (de-)allocation: mm, files, fs, tty, keyrings */ | 1275 | /* Protection of (de-)allocation: mm, files, fs, tty, keyrings */ |
1273 | spinlock_t alloc_lock; | 1276 | spinlock_t alloc_lock; |
1274 | 1277 | ||
1275 | /* Protection of the PI data structures: */ | 1278 | /* Protection of the PI data structures: */ |
1276 | spinlock_t pi_lock; | 1279 | spinlock_t pi_lock; |
1277 | 1280 | ||
1278 | #ifdef CONFIG_RT_MUTEXES | 1281 | #ifdef CONFIG_RT_MUTEXES |
1279 | /* PI waiters blocked on a rt_mutex held by this task */ | 1282 | /* PI waiters blocked on a rt_mutex held by this task */ |
1280 | struct plist_head pi_waiters; | 1283 | struct plist_head pi_waiters; |
1281 | /* Deadlock detection and priority inheritance handling */ | 1284 | /* Deadlock detection and priority inheritance handling */ |
1282 | struct rt_mutex_waiter *pi_blocked_on; | 1285 | struct rt_mutex_waiter *pi_blocked_on; |
1283 | #endif | 1286 | #endif |
1284 | 1287 | ||
1285 | #ifdef CONFIG_DEBUG_MUTEXES | 1288 | #ifdef CONFIG_DEBUG_MUTEXES |
1286 | /* mutex deadlock detection */ | 1289 | /* mutex deadlock detection */ |
1287 | struct mutex_waiter *blocked_on; | 1290 | struct mutex_waiter *blocked_on; |
1288 | #endif | 1291 | #endif |
1289 | #ifdef CONFIG_TRACE_IRQFLAGS | 1292 | #ifdef CONFIG_TRACE_IRQFLAGS |
1290 | unsigned int irq_events; | 1293 | unsigned int irq_events; |
1291 | int hardirqs_enabled; | 1294 | int hardirqs_enabled; |
1292 | unsigned long hardirq_enable_ip; | 1295 | unsigned long hardirq_enable_ip; |
1293 | unsigned int hardirq_enable_event; | 1296 | unsigned int hardirq_enable_event; |
1294 | unsigned long hardirq_disable_ip; | 1297 | unsigned long hardirq_disable_ip; |
1295 | unsigned int hardirq_disable_event; | 1298 | unsigned int hardirq_disable_event; |
1296 | int softirqs_enabled; | 1299 | int softirqs_enabled; |
1297 | unsigned long softirq_disable_ip; | 1300 | unsigned long softirq_disable_ip; |
1298 | unsigned int softirq_disable_event; | 1301 | unsigned int softirq_disable_event; |
1299 | unsigned long softirq_enable_ip; | 1302 | unsigned long softirq_enable_ip; |
1300 | unsigned int softirq_enable_event; | 1303 | unsigned int softirq_enable_event; |
1301 | int hardirq_context; | 1304 | int hardirq_context; |
1302 | int softirq_context; | 1305 | int softirq_context; |
1303 | #endif | 1306 | #endif |
1304 | #ifdef CONFIG_LOCKDEP | 1307 | #ifdef CONFIG_LOCKDEP |
1305 | # define MAX_LOCK_DEPTH 48UL | 1308 | # define MAX_LOCK_DEPTH 48UL |
1306 | u64 curr_chain_key; | 1309 | u64 curr_chain_key; |
1307 | int lockdep_depth; | 1310 | int lockdep_depth; |
1308 | unsigned int lockdep_recursion; | 1311 | unsigned int lockdep_recursion; |
1309 | struct held_lock held_locks[MAX_LOCK_DEPTH]; | 1312 | struct held_lock held_locks[MAX_LOCK_DEPTH]; |
1310 | #endif | 1313 | #endif |
1311 | 1314 | ||
1312 | /* journalling filesystem info */ | 1315 | /* journalling filesystem info */ |
1313 | void *journal_info; | 1316 | void *journal_info; |
1314 | 1317 | ||
1315 | /* stacked block device info */ | 1318 | /* stacked block device info */ |
1316 | struct bio *bio_list, **bio_tail; | 1319 | struct bio *bio_list, **bio_tail; |
1317 | 1320 | ||
1318 | /* VM state */ | 1321 | /* VM state */ |
1319 | struct reclaim_state *reclaim_state; | 1322 | struct reclaim_state *reclaim_state; |
1320 | 1323 | ||
1321 | struct backing_dev_info *backing_dev_info; | 1324 | struct backing_dev_info *backing_dev_info; |
1322 | 1325 | ||
1323 | struct io_context *io_context; | 1326 | struct io_context *io_context; |
1324 | 1327 | ||
1325 | unsigned long ptrace_message; | 1328 | unsigned long ptrace_message; |
1326 | siginfo_t *last_siginfo; /* For ptrace use. */ | 1329 | siginfo_t *last_siginfo; /* For ptrace use. */ |
1327 | struct task_io_accounting ioac; | 1330 | struct task_io_accounting ioac; |
1328 | #if defined(CONFIG_TASK_XACCT) | 1331 | #if defined(CONFIG_TASK_XACCT) |
1329 | u64 acct_rss_mem1; /* accumulated rss usage */ | 1332 | u64 acct_rss_mem1; /* accumulated rss usage */ |
1330 | u64 acct_vm_mem1; /* accumulated virtual memory usage */ | 1333 | u64 acct_vm_mem1; /* accumulated virtual memory usage */ |
1331 | cputime_t acct_timexpd; /* stime + utime since last update */ | 1334 | cputime_t acct_timexpd; /* stime + utime since last update */ |
1332 | #endif | 1335 | #endif |
1333 | #ifdef CONFIG_CPUSETS | 1336 | #ifdef CONFIG_CPUSETS |
1334 | nodemask_t mems_allowed; | 1337 | nodemask_t mems_allowed; |
1335 | int cpuset_mems_generation; | 1338 | int cpuset_mems_generation; |
1336 | int cpuset_mem_spread_rotor; | 1339 | int cpuset_mem_spread_rotor; |
1337 | #endif | 1340 | #endif |
1338 | #ifdef CONFIG_CGROUPS | 1341 | #ifdef CONFIG_CGROUPS |
1339 | /* Control Group info protected by css_set_lock */ | 1342 | /* Control Group info protected by css_set_lock */ |
1340 | struct css_set *cgroups; | 1343 | struct css_set *cgroups; |
1341 | /* cg_list protected by css_set_lock and tsk->alloc_lock */ | 1344 | /* cg_list protected by css_set_lock and tsk->alloc_lock */ |
1342 | struct list_head cg_list; | 1345 | struct list_head cg_list; |
1343 | #endif | 1346 | #endif |
1344 | #ifdef CONFIG_FUTEX | 1347 | #ifdef CONFIG_FUTEX |
1345 | struct robust_list_head __user *robust_list; | 1348 | struct robust_list_head __user *robust_list; |
1346 | #ifdef CONFIG_COMPAT | 1349 | #ifdef CONFIG_COMPAT |
1347 | struct compat_robust_list_head __user *compat_robust_list; | 1350 | struct compat_robust_list_head __user *compat_robust_list; |
1348 | #endif | 1351 | #endif |
1349 | struct list_head pi_state_list; | 1352 | struct list_head pi_state_list; |
1350 | struct futex_pi_state *pi_state_cache; | 1353 | struct futex_pi_state *pi_state_cache; |
1351 | #endif | 1354 | #endif |
1352 | #ifdef CONFIG_NUMA | 1355 | #ifdef CONFIG_NUMA |
1353 | struct mempolicy *mempolicy; | 1356 | struct mempolicy *mempolicy; |
1354 | short il_next; | 1357 | short il_next; |
1355 | #endif | 1358 | #endif |
1356 | atomic_t fs_excl; /* holding fs exclusive resources */ | 1359 | atomic_t fs_excl; /* holding fs exclusive resources */ |
1357 | struct rcu_head rcu; | 1360 | struct rcu_head rcu; |
1358 | 1361 | ||
1359 | /* | 1362 | /* |
1360 | * cache last used pipe for splice | 1363 | * cache last used pipe for splice |
1361 | */ | 1364 | */ |
1362 | struct pipe_inode_info *splice_pipe; | 1365 | struct pipe_inode_info *splice_pipe; |
1363 | #ifdef CONFIG_TASK_DELAY_ACCT | 1366 | #ifdef CONFIG_TASK_DELAY_ACCT |
1364 | struct task_delay_info *delays; | 1367 | struct task_delay_info *delays; |
1365 | #endif | 1368 | #endif |
1366 | #ifdef CONFIG_FAULT_INJECTION | 1369 | #ifdef CONFIG_FAULT_INJECTION |
1367 | int make_it_fail; | 1370 | int make_it_fail; |
1368 | #endif | 1371 | #endif |
1369 | struct prop_local_single dirties; | 1372 | struct prop_local_single dirties; |
1370 | #ifdef CONFIG_LATENCYTOP | 1373 | #ifdef CONFIG_LATENCYTOP |
1371 | int latency_record_count; | 1374 | int latency_record_count; |
1372 | struct latency_record latency_record[LT_SAVECOUNT]; | 1375 | struct latency_record latency_record[LT_SAVECOUNT]; |
1373 | #endif | 1376 | #endif |
1374 | /* | 1377 | /* |
1375 | * time slack values; these are used to round up poll() and | 1378 | * time slack values; these are used to round up poll() and |
1376 | * select() etc timeout values. These are in nanoseconds. | 1379 | * select() etc timeout values. These are in nanoseconds. |
1377 | */ | 1380 | */ |
1378 | unsigned long timer_slack_ns; | 1381 | unsigned long timer_slack_ns; |
1379 | unsigned long default_timer_slack_ns; | 1382 | unsigned long default_timer_slack_ns; |
1380 | 1383 | ||
1381 | struct list_head *scm_work_list; | 1384 | struct list_head *scm_work_list; |
1382 | #ifdef CONFIG_FUNCTION_GRAPH_TRACER | 1385 | #ifdef CONFIG_FUNCTION_GRAPH_TRACER |
1383 | /* Index of current stored adress in ret_stack */ | 1386 | /* Index of current stored adress in ret_stack */ |
1384 | int curr_ret_stack; | 1387 | int curr_ret_stack; |
1385 | /* Stack of return addresses for return function tracing */ | 1388 | /* Stack of return addresses for return function tracing */ |
1386 | struct ftrace_ret_stack *ret_stack; | 1389 | struct ftrace_ret_stack *ret_stack; |
1387 | /* | 1390 | /* |
1388 | * Number of functions that haven't been traced | 1391 | * Number of functions that haven't been traced |
1389 | * because of depth overrun. | 1392 | * because of depth overrun. |
1390 | */ | 1393 | */ |
1391 | atomic_t trace_overrun; | 1394 | atomic_t trace_overrun; |
1392 | /* Pause for the tracing */ | 1395 | /* Pause for the tracing */ |
1393 | atomic_t tracing_graph_pause; | 1396 | atomic_t tracing_graph_pause; |
1394 | #endif | 1397 | #endif |
1395 | #ifdef CONFIG_TRACING | 1398 | #ifdef CONFIG_TRACING |
1396 | /* state flags for use by tracers */ | 1399 | /* state flags for use by tracers */ |
1397 | unsigned long trace; | 1400 | unsigned long trace; |
1398 | #endif | 1401 | #endif |
1399 | }; | 1402 | }; |
1400 | 1403 | ||
1401 | /* | 1404 | /* |
1402 | * Priority of a process goes from 0..MAX_PRIO-1, valid RT | 1405 | * Priority of a process goes from 0..MAX_PRIO-1, valid RT |
1403 | * priority is 0..MAX_RT_PRIO-1, and SCHED_NORMAL/SCHED_BATCH | 1406 | * priority is 0..MAX_RT_PRIO-1, and SCHED_NORMAL/SCHED_BATCH |
1404 | * tasks are in the range MAX_RT_PRIO..MAX_PRIO-1. Priority | 1407 | * tasks are in the range MAX_RT_PRIO..MAX_PRIO-1. Priority |
1405 | * values are inverted: lower p->prio value means higher priority. | 1408 | * values are inverted: lower p->prio value means higher priority. |
1406 | * | 1409 | * |
1407 | * The MAX_USER_RT_PRIO value allows the actual maximum | 1410 | * The MAX_USER_RT_PRIO value allows the actual maximum |
1408 | * RT priority to be separate from the value exported to | 1411 | * RT priority to be separate from the value exported to |
1409 | * user-space. This allows kernel threads to set their | 1412 | * user-space. This allows kernel threads to set their |
1410 | * priority to a value higher than any user task. Note: | 1413 | * priority to a value higher than any user task. Note: |
1411 | * MAX_RT_PRIO must not be smaller than MAX_USER_RT_PRIO. | 1414 | * MAX_RT_PRIO must not be smaller than MAX_USER_RT_PRIO. |
1412 | */ | 1415 | */ |
1413 | 1416 | ||
1414 | #define MAX_USER_RT_PRIO 100 | 1417 | #define MAX_USER_RT_PRIO 100 |
1415 | #define MAX_RT_PRIO MAX_USER_RT_PRIO | 1418 | #define MAX_RT_PRIO MAX_USER_RT_PRIO |
1416 | 1419 | ||
1417 | #define MAX_PRIO (MAX_RT_PRIO + 40) | 1420 | #define MAX_PRIO (MAX_RT_PRIO + 40) |
1418 | #define DEFAULT_PRIO (MAX_RT_PRIO + 20) | 1421 | #define DEFAULT_PRIO (MAX_RT_PRIO + 20) |
1419 | 1422 | ||
1420 | static inline int rt_prio(int prio) | 1423 | static inline int rt_prio(int prio) |
1421 | { | 1424 | { |
1422 | if (unlikely(prio < MAX_RT_PRIO)) | 1425 | if (unlikely(prio < MAX_RT_PRIO)) |
1423 | return 1; | 1426 | return 1; |
1424 | return 0; | 1427 | return 0; |
1425 | } | 1428 | } |
1426 | 1429 | ||
1427 | static inline int rt_task(struct task_struct *p) | 1430 | static inline int rt_task(struct task_struct *p) |
1428 | { | 1431 | { |
1429 | return rt_prio(p->prio); | 1432 | return rt_prio(p->prio); |
1430 | } | 1433 | } |
1431 | 1434 | ||
1432 | static inline void set_task_session(struct task_struct *tsk, pid_t session) | 1435 | static inline void set_task_session(struct task_struct *tsk, pid_t session) |
1433 | { | 1436 | { |
1434 | tsk->signal->__session = session; | 1437 | tsk->signal->__session = session; |
1435 | } | 1438 | } |
1436 | 1439 | ||
1437 | static inline void set_task_pgrp(struct task_struct *tsk, pid_t pgrp) | 1440 | static inline void set_task_pgrp(struct task_struct *tsk, pid_t pgrp) |
1438 | { | 1441 | { |
1439 | tsk->signal->__pgrp = pgrp; | 1442 | tsk->signal->__pgrp = pgrp; |
1440 | } | 1443 | } |
1441 | 1444 | ||
1442 | static inline struct pid *task_pid(struct task_struct *task) | 1445 | static inline struct pid *task_pid(struct task_struct *task) |
1443 | { | 1446 | { |
1444 | return task->pids[PIDTYPE_PID].pid; | 1447 | return task->pids[PIDTYPE_PID].pid; |
1445 | } | 1448 | } |
1446 | 1449 | ||
1447 | static inline struct pid *task_tgid(struct task_struct *task) | 1450 | static inline struct pid *task_tgid(struct task_struct *task) |
1448 | { | 1451 | { |
1449 | return task->group_leader->pids[PIDTYPE_PID].pid; | 1452 | return task->group_leader->pids[PIDTYPE_PID].pid; |
1450 | } | 1453 | } |
1451 | 1454 | ||
1452 | static inline struct pid *task_pgrp(struct task_struct *task) | 1455 | static inline struct pid *task_pgrp(struct task_struct *task) |
1453 | { | 1456 | { |
1454 | return task->group_leader->pids[PIDTYPE_PGID].pid; | 1457 | return task->group_leader->pids[PIDTYPE_PGID].pid; |
1455 | } | 1458 | } |
1456 | 1459 | ||
1457 | static inline struct pid *task_session(struct task_struct *task) | 1460 | static inline struct pid *task_session(struct task_struct *task) |
1458 | { | 1461 | { |
1459 | return task->group_leader->pids[PIDTYPE_SID].pid; | 1462 | return task->group_leader->pids[PIDTYPE_SID].pid; |
1460 | } | 1463 | } |
1461 | 1464 | ||
1462 | struct pid_namespace; | 1465 | struct pid_namespace; |
1463 | 1466 | ||
1464 | /* | 1467 | /* |
1465 | * the helpers to get the task's different pids as they are seen | 1468 | * the helpers to get the task's different pids as they are seen |
1466 | * from various namespaces | 1469 | * from various namespaces |
1467 | * | 1470 | * |
1468 | * task_xid_nr() : global id, i.e. the id seen from the init namespace; | 1471 | * task_xid_nr() : global id, i.e. the id seen from the init namespace; |
1469 | * task_xid_vnr() : virtual id, i.e. the id seen from the pid namespace of | 1472 | * task_xid_vnr() : virtual id, i.e. the id seen from the pid namespace of |
1470 | * current. | 1473 | * current. |
1471 | * task_xid_nr_ns() : id seen from the ns specified; | 1474 | * task_xid_nr_ns() : id seen from the ns specified; |
1472 | * | 1475 | * |
1473 | * set_task_vxid() : assigns a virtual id to a task; | 1476 | * set_task_vxid() : assigns a virtual id to a task; |
1474 | * | 1477 | * |
1475 | * see also pid_nr() etc in include/linux/pid.h | 1478 | * see also pid_nr() etc in include/linux/pid.h |
1476 | */ | 1479 | */ |
1477 | 1480 | ||
1478 | static inline pid_t task_pid_nr(struct task_struct *tsk) | 1481 | static inline pid_t task_pid_nr(struct task_struct *tsk) |
1479 | { | 1482 | { |
1480 | return tsk->pid; | 1483 | return tsk->pid; |
1481 | } | 1484 | } |
1482 | 1485 | ||
1483 | pid_t task_pid_nr_ns(struct task_struct *tsk, struct pid_namespace *ns); | 1486 | pid_t task_pid_nr_ns(struct task_struct *tsk, struct pid_namespace *ns); |
1484 | 1487 | ||
1485 | static inline pid_t task_pid_vnr(struct task_struct *tsk) | 1488 | static inline pid_t task_pid_vnr(struct task_struct *tsk) |
1486 | { | 1489 | { |
1487 | return pid_vnr(task_pid(tsk)); | 1490 | return pid_vnr(task_pid(tsk)); |
1488 | } | 1491 | } |
1489 | 1492 | ||
1490 | 1493 | ||
1491 | static inline pid_t task_tgid_nr(struct task_struct *tsk) | 1494 | static inline pid_t task_tgid_nr(struct task_struct *tsk) |
1492 | { | 1495 | { |
1493 | return tsk->tgid; | 1496 | return tsk->tgid; |
1494 | } | 1497 | } |
1495 | 1498 | ||
1496 | pid_t task_tgid_nr_ns(struct task_struct *tsk, struct pid_namespace *ns); | 1499 | pid_t task_tgid_nr_ns(struct task_struct *tsk, struct pid_namespace *ns); |
1497 | 1500 | ||
1498 | static inline pid_t task_tgid_vnr(struct task_struct *tsk) | 1501 | static inline pid_t task_tgid_vnr(struct task_struct *tsk) |
1499 | { | 1502 | { |
1500 | return pid_vnr(task_tgid(tsk)); | 1503 | return pid_vnr(task_tgid(tsk)); |
1501 | } | 1504 | } |
1502 | 1505 | ||
1503 | 1506 | ||
1504 | static inline pid_t task_pgrp_nr(struct task_struct *tsk) | 1507 | static inline pid_t task_pgrp_nr(struct task_struct *tsk) |
1505 | { | 1508 | { |
1506 | return tsk->signal->__pgrp; | 1509 | return tsk->signal->__pgrp; |
1507 | } | 1510 | } |
1508 | 1511 | ||
1509 | pid_t task_pgrp_nr_ns(struct task_struct *tsk, struct pid_namespace *ns); | 1512 | pid_t task_pgrp_nr_ns(struct task_struct *tsk, struct pid_namespace *ns); |
1510 | 1513 | ||
1511 | static inline pid_t task_pgrp_vnr(struct task_struct *tsk) | 1514 | static inline pid_t task_pgrp_vnr(struct task_struct *tsk) |
1512 | { | 1515 | { |
1513 | return pid_vnr(task_pgrp(tsk)); | 1516 | return pid_vnr(task_pgrp(tsk)); |
1514 | } | 1517 | } |
1515 | 1518 | ||
1516 | 1519 | ||
1517 | static inline pid_t task_session_nr(struct task_struct *tsk) | 1520 | static inline pid_t task_session_nr(struct task_struct *tsk) |
1518 | { | 1521 | { |
1519 | return tsk->signal->__session; | 1522 | return tsk->signal->__session; |
1520 | } | 1523 | } |
1521 | 1524 | ||
1522 | pid_t task_session_nr_ns(struct task_struct *tsk, struct pid_namespace *ns); | 1525 | pid_t task_session_nr_ns(struct task_struct *tsk, struct pid_namespace *ns); |
1523 | 1526 | ||
1524 | static inline pid_t task_session_vnr(struct task_struct *tsk) | 1527 | static inline pid_t task_session_vnr(struct task_struct *tsk) |
1525 | { | 1528 | { |
1526 | return pid_vnr(task_session(tsk)); | 1529 | return pid_vnr(task_session(tsk)); |
1527 | } | 1530 | } |
1528 | 1531 | ||
1529 | 1532 | ||
1530 | /** | 1533 | /** |
1531 | * pid_alive - check that a task structure is not stale | 1534 | * pid_alive - check that a task structure is not stale |
1532 | * @p: Task structure to be checked. | 1535 | * @p: Task structure to be checked. |
1533 | * | 1536 | * |
1534 | * Test if a process is not yet dead (at most zombie state) | 1537 | * Test if a process is not yet dead (at most zombie state) |
1535 | * If pid_alive fails, then pointers within the task structure | 1538 | * If pid_alive fails, then pointers within the task structure |
1536 | * can be stale and must not be dereferenced. | 1539 | * can be stale and must not be dereferenced. |
1537 | */ | 1540 | */ |
1538 | static inline int pid_alive(struct task_struct *p) | 1541 | static inline int pid_alive(struct task_struct *p) |
1539 | { | 1542 | { |
1540 | return p->pids[PIDTYPE_PID].pid != NULL; | 1543 | return p->pids[PIDTYPE_PID].pid != NULL; |
1541 | } | 1544 | } |
1542 | 1545 | ||
1543 | /** | 1546 | /** |
1544 | * is_global_init - check if a task structure is init | 1547 | * is_global_init - check if a task structure is init |
1545 | * @tsk: Task structure to be checked. | 1548 | * @tsk: Task structure to be checked. |
1546 | * | 1549 | * |
1547 | * Check if a task structure is the first user space task the kernel created. | 1550 | * Check if a task structure is the first user space task the kernel created. |
1548 | */ | 1551 | */ |
1549 | static inline int is_global_init(struct task_struct *tsk) | 1552 | static inline int is_global_init(struct task_struct *tsk) |
1550 | { | 1553 | { |
1551 | return tsk->pid == 1; | 1554 | return tsk->pid == 1; |
1552 | } | 1555 | } |
1553 | 1556 | ||
1554 | /* | 1557 | /* |
1555 | * is_container_init: | 1558 | * is_container_init: |
1556 | * check whether in the task is init in its own pid namespace. | 1559 | * check whether in the task is init in its own pid namespace. |
1557 | */ | 1560 | */ |
1558 | extern int is_container_init(struct task_struct *tsk); | 1561 | extern int is_container_init(struct task_struct *tsk); |
1559 | 1562 | ||
1560 | extern struct pid *cad_pid; | 1563 | extern struct pid *cad_pid; |
1561 | 1564 | ||
1562 | extern void free_task(struct task_struct *tsk); | 1565 | extern void free_task(struct task_struct *tsk); |
1563 | #define get_task_struct(tsk) do { atomic_inc(&(tsk)->usage); } while(0) | 1566 | #define get_task_struct(tsk) do { atomic_inc(&(tsk)->usage); } while(0) |
1564 | 1567 | ||
1565 | extern void __put_task_struct(struct task_struct *t); | 1568 | extern void __put_task_struct(struct task_struct *t); |
1566 | 1569 | ||
1567 | static inline void put_task_struct(struct task_struct *t) | 1570 | static inline void put_task_struct(struct task_struct *t) |
1568 | { | 1571 | { |
1569 | if (atomic_dec_and_test(&t->usage)) | 1572 | if (atomic_dec_and_test(&t->usage)) |
1570 | __put_task_struct(t); | 1573 | __put_task_struct(t); |
1571 | } | 1574 | } |
1572 | 1575 | ||
1573 | extern cputime_t task_utime(struct task_struct *p); | 1576 | extern cputime_t task_utime(struct task_struct *p); |
1574 | extern cputime_t task_stime(struct task_struct *p); | 1577 | extern cputime_t task_stime(struct task_struct *p); |
1575 | extern cputime_t task_gtime(struct task_struct *p); | 1578 | extern cputime_t task_gtime(struct task_struct *p); |
1576 | 1579 | ||
1577 | /* | 1580 | /* |
1578 | * Per process flags | 1581 | * Per process flags |
1579 | */ | 1582 | */ |
1580 | #define PF_ALIGNWARN 0x00000001 /* Print alignment warning msgs */ | 1583 | #define PF_ALIGNWARN 0x00000001 /* Print alignment warning msgs */ |
1581 | /* Not implemented yet, only for 486*/ | 1584 | /* Not implemented yet, only for 486*/ |
1582 | #define PF_STARTING 0x00000002 /* being created */ | 1585 | #define PF_STARTING 0x00000002 /* being created */ |
1583 | #define PF_EXITING 0x00000004 /* getting shut down */ | 1586 | #define PF_EXITING 0x00000004 /* getting shut down */ |
1584 | #define PF_EXITPIDONE 0x00000008 /* pi exit done on shut down */ | 1587 | #define PF_EXITPIDONE 0x00000008 /* pi exit done on shut down */ |
1585 | #define PF_VCPU 0x00000010 /* I'm a virtual CPU */ | 1588 | #define PF_VCPU 0x00000010 /* I'm a virtual CPU */ |
1586 | #define PF_FORKNOEXEC 0x00000040 /* forked but didn't exec */ | 1589 | #define PF_FORKNOEXEC 0x00000040 /* forked but didn't exec */ |
1587 | #define PF_SUPERPRIV 0x00000100 /* used super-user privileges */ | 1590 | #define PF_SUPERPRIV 0x00000100 /* used super-user privileges */ |
1588 | #define PF_DUMPCORE 0x00000200 /* dumped core */ | 1591 | #define PF_DUMPCORE 0x00000200 /* dumped core */ |
1589 | #define PF_SIGNALED 0x00000400 /* killed by a signal */ | 1592 | #define PF_SIGNALED 0x00000400 /* killed by a signal */ |
1590 | #define PF_MEMALLOC 0x00000800 /* Allocating memory */ | 1593 | #define PF_MEMALLOC 0x00000800 /* Allocating memory */ |
1591 | #define PF_FLUSHER 0x00001000 /* responsible for disk writeback */ | 1594 | #define PF_FLUSHER 0x00001000 /* responsible for disk writeback */ |
1592 | #define PF_USED_MATH 0x00002000 /* if unset the fpu must be initialized before use */ | 1595 | #define PF_USED_MATH 0x00002000 /* if unset the fpu must be initialized before use */ |
1593 | #define PF_NOFREEZE 0x00008000 /* this thread should not be frozen */ | 1596 | #define PF_NOFREEZE 0x00008000 /* this thread should not be frozen */ |
1594 | #define PF_FROZEN 0x00010000 /* frozen for system suspend */ | 1597 | #define PF_FROZEN 0x00010000 /* frozen for system suspend */ |
1595 | #define PF_FSTRANS 0x00020000 /* inside a filesystem transaction */ | 1598 | #define PF_FSTRANS 0x00020000 /* inside a filesystem transaction */ |
1596 | #define PF_KSWAPD 0x00040000 /* I am kswapd */ | 1599 | #define PF_KSWAPD 0x00040000 /* I am kswapd */ |
1597 | #define PF_SWAPOFF 0x00080000 /* I am in swapoff */ | 1600 | #define PF_SWAPOFF 0x00080000 /* I am in swapoff */ |
1598 | #define PF_LESS_THROTTLE 0x00100000 /* Throttle me less: I clean memory */ | 1601 | #define PF_LESS_THROTTLE 0x00100000 /* Throttle me less: I clean memory */ |
1599 | #define PF_KTHREAD 0x00200000 /* I am a kernel thread */ | 1602 | #define PF_KTHREAD 0x00200000 /* I am a kernel thread */ |
1600 | #define PF_RANDOMIZE 0x00400000 /* randomize virtual address space */ | 1603 | #define PF_RANDOMIZE 0x00400000 /* randomize virtual address space */ |
1601 | #define PF_SWAPWRITE 0x00800000 /* Allowed to write to swap */ | 1604 | #define PF_SWAPWRITE 0x00800000 /* Allowed to write to swap */ |
1602 | #define PF_SPREAD_PAGE 0x01000000 /* Spread page cache over cpuset */ | 1605 | #define PF_SPREAD_PAGE 0x01000000 /* Spread page cache over cpuset */ |
1603 | #define PF_SPREAD_SLAB 0x02000000 /* Spread some slab caches over cpuset */ | 1606 | #define PF_SPREAD_SLAB 0x02000000 /* Spread some slab caches over cpuset */ |
1604 | #define PF_THREAD_BOUND 0x04000000 /* Thread bound to specific cpu */ | 1607 | #define PF_THREAD_BOUND 0x04000000 /* Thread bound to specific cpu */ |
1605 | #define PF_MEMPOLICY 0x10000000 /* Non-default NUMA mempolicy */ | 1608 | #define PF_MEMPOLICY 0x10000000 /* Non-default NUMA mempolicy */ |
1606 | #define PF_MUTEX_TESTER 0x20000000 /* Thread belongs to the rt mutex tester */ | 1609 | #define PF_MUTEX_TESTER 0x20000000 /* Thread belongs to the rt mutex tester */ |
1607 | #define PF_FREEZER_SKIP 0x40000000 /* Freezer should not count it as freezeable */ | 1610 | #define PF_FREEZER_SKIP 0x40000000 /* Freezer should not count it as freezeable */ |
1608 | #define PF_FREEZER_NOSIG 0x80000000 /* Freezer won't send signals to it */ | 1611 | #define PF_FREEZER_NOSIG 0x80000000 /* Freezer won't send signals to it */ |
1609 | 1612 | ||
1610 | /* | 1613 | /* |
1611 | * Only the _current_ task can read/write to tsk->flags, but other | 1614 | * Only the _current_ task can read/write to tsk->flags, but other |
1612 | * tasks can access tsk->flags in readonly mode for example | 1615 | * tasks can access tsk->flags in readonly mode for example |
1613 | * with tsk_used_math (like during threaded core dumping). | 1616 | * with tsk_used_math (like during threaded core dumping). |
1614 | * There is however an exception to this rule during ptrace | 1617 | * There is however an exception to this rule during ptrace |
1615 | * or during fork: the ptracer task is allowed to write to the | 1618 | * or during fork: the ptracer task is allowed to write to the |
1616 | * child->flags of its traced child (same goes for fork, the parent | 1619 | * child->flags of its traced child (same goes for fork, the parent |
1617 | * can write to the child->flags), because we're guaranteed the | 1620 | * can write to the child->flags), because we're guaranteed the |
1618 | * child is not running and in turn not changing child->flags | 1621 | * child is not running and in turn not changing child->flags |
1619 | * at the same time the parent does it. | 1622 | * at the same time the parent does it. |
1620 | */ | 1623 | */ |
1621 | #define clear_stopped_child_used_math(child) do { (child)->flags &= ~PF_USED_MATH; } while (0) | 1624 | #define clear_stopped_child_used_math(child) do { (child)->flags &= ~PF_USED_MATH; } while (0) |
1622 | #define set_stopped_child_used_math(child) do { (child)->flags |= PF_USED_MATH; } while (0) | 1625 | #define set_stopped_child_used_math(child) do { (child)->flags |= PF_USED_MATH; } while (0) |
1623 | #define clear_used_math() clear_stopped_child_used_math(current) | 1626 | #define clear_used_math() clear_stopped_child_used_math(current) |
1624 | #define set_used_math() set_stopped_child_used_math(current) | 1627 | #define set_used_math() set_stopped_child_used_math(current) |
1625 | #define conditional_stopped_child_used_math(condition, child) \ | 1628 | #define conditional_stopped_child_used_math(condition, child) \ |
1626 | do { (child)->flags &= ~PF_USED_MATH, (child)->flags |= (condition) ? PF_USED_MATH : 0; } while (0) | 1629 | do { (child)->flags &= ~PF_USED_MATH, (child)->flags |= (condition) ? PF_USED_MATH : 0; } while (0) |
1627 | #define conditional_used_math(condition) \ | 1630 | #define conditional_used_math(condition) \ |
1628 | conditional_stopped_child_used_math(condition, current) | 1631 | conditional_stopped_child_used_math(condition, current) |
1629 | #define copy_to_stopped_child_used_math(child) \ | 1632 | #define copy_to_stopped_child_used_math(child) \ |
1630 | do { (child)->flags &= ~PF_USED_MATH, (child)->flags |= current->flags & PF_USED_MATH; } while (0) | 1633 | do { (child)->flags &= ~PF_USED_MATH, (child)->flags |= current->flags & PF_USED_MATH; } while (0) |
1631 | /* NOTE: this will return 0 or PF_USED_MATH, it will never return 1 */ | 1634 | /* NOTE: this will return 0 or PF_USED_MATH, it will never return 1 */ |
1632 | #define tsk_used_math(p) ((p)->flags & PF_USED_MATH) | 1635 | #define tsk_used_math(p) ((p)->flags & PF_USED_MATH) |
1633 | #define used_math() tsk_used_math(current) | 1636 | #define used_math() tsk_used_math(current) |
1634 | 1637 | ||
1635 | #ifdef CONFIG_SMP | 1638 | #ifdef CONFIG_SMP |
1636 | extern int set_cpus_allowed_ptr(struct task_struct *p, | 1639 | extern int set_cpus_allowed_ptr(struct task_struct *p, |
1637 | const struct cpumask *new_mask); | 1640 | const struct cpumask *new_mask); |
1638 | #else | 1641 | #else |
1639 | static inline int set_cpus_allowed_ptr(struct task_struct *p, | 1642 | static inline int set_cpus_allowed_ptr(struct task_struct *p, |
1640 | const struct cpumask *new_mask) | 1643 | const struct cpumask *new_mask) |
1641 | { | 1644 | { |
1642 | if (!cpumask_test_cpu(0, new_mask)) | 1645 | if (!cpumask_test_cpu(0, new_mask)) |
1643 | return -EINVAL; | 1646 | return -EINVAL; |
1644 | return 0; | 1647 | return 0; |
1645 | } | 1648 | } |
1646 | #endif | 1649 | #endif |
1647 | static inline int set_cpus_allowed(struct task_struct *p, cpumask_t new_mask) | 1650 | static inline int set_cpus_allowed(struct task_struct *p, cpumask_t new_mask) |
1648 | { | 1651 | { |
1649 | return set_cpus_allowed_ptr(p, &new_mask); | 1652 | return set_cpus_allowed_ptr(p, &new_mask); |
1650 | } | 1653 | } |
1651 | 1654 | ||
1652 | extern unsigned long long sched_clock(void); | 1655 | extern unsigned long long sched_clock(void); |
1653 | 1656 | ||
1654 | extern void sched_clock_init(void); | 1657 | extern void sched_clock_init(void); |
1655 | extern u64 sched_clock_cpu(int cpu); | 1658 | extern u64 sched_clock_cpu(int cpu); |
1656 | 1659 | ||
1657 | #ifndef CONFIG_HAVE_UNSTABLE_SCHED_CLOCK | 1660 | #ifndef CONFIG_HAVE_UNSTABLE_SCHED_CLOCK |
1658 | static inline void sched_clock_tick(void) | 1661 | static inline void sched_clock_tick(void) |
1659 | { | 1662 | { |
1660 | } | 1663 | } |
1661 | 1664 | ||
1662 | static inline void sched_clock_idle_sleep_event(void) | 1665 | static inline void sched_clock_idle_sleep_event(void) |
1663 | { | 1666 | { |
1664 | } | 1667 | } |
1665 | 1668 | ||
1666 | static inline void sched_clock_idle_wakeup_event(u64 delta_ns) | 1669 | static inline void sched_clock_idle_wakeup_event(u64 delta_ns) |
1667 | { | 1670 | { |
1668 | } | 1671 | } |
1669 | #else | 1672 | #else |
1670 | extern void sched_clock_tick(void); | 1673 | extern void sched_clock_tick(void); |
1671 | extern void sched_clock_idle_sleep_event(void); | 1674 | extern void sched_clock_idle_sleep_event(void); |
1672 | extern void sched_clock_idle_wakeup_event(u64 delta_ns); | 1675 | extern void sched_clock_idle_wakeup_event(u64 delta_ns); |
1673 | #endif | 1676 | #endif |
1674 | 1677 | ||
1675 | /* | 1678 | /* |
1676 | * For kernel-internal use: high-speed (but slightly incorrect) per-cpu | 1679 | * For kernel-internal use: high-speed (but slightly incorrect) per-cpu |
1677 | * clock constructed from sched_clock(): | 1680 | * clock constructed from sched_clock(): |
1678 | */ | 1681 | */ |
1679 | extern unsigned long long cpu_clock(int cpu); | 1682 | extern unsigned long long cpu_clock(int cpu); |
1680 | 1683 | ||
1681 | extern unsigned long long | 1684 | extern unsigned long long |
1682 | task_sched_runtime(struct task_struct *task); | 1685 | task_sched_runtime(struct task_struct *task); |
1683 | extern unsigned long long thread_group_sched_runtime(struct task_struct *task); | 1686 | extern unsigned long long thread_group_sched_runtime(struct task_struct *task); |
1684 | 1687 | ||
1685 | /* sched_exec is called by processes performing an exec */ | 1688 | /* sched_exec is called by processes performing an exec */ |
1686 | #ifdef CONFIG_SMP | 1689 | #ifdef CONFIG_SMP |
1687 | extern void sched_exec(void); | 1690 | extern void sched_exec(void); |
1688 | #else | 1691 | #else |
1689 | #define sched_exec() {} | 1692 | #define sched_exec() {} |
1690 | #endif | 1693 | #endif |
1691 | 1694 | ||
1692 | extern void sched_clock_idle_sleep_event(void); | 1695 | extern void sched_clock_idle_sleep_event(void); |
1693 | extern void sched_clock_idle_wakeup_event(u64 delta_ns); | 1696 | extern void sched_clock_idle_wakeup_event(u64 delta_ns); |
1694 | 1697 | ||
1695 | #ifdef CONFIG_HOTPLUG_CPU | 1698 | #ifdef CONFIG_HOTPLUG_CPU |
1696 | extern void idle_task_exit(void); | 1699 | extern void idle_task_exit(void); |
1697 | #else | 1700 | #else |
1698 | static inline void idle_task_exit(void) {} | 1701 | static inline void idle_task_exit(void) {} |
1699 | #endif | 1702 | #endif |
1700 | 1703 | ||
1701 | extern void sched_idle_next(void); | 1704 | extern void sched_idle_next(void); |
1702 | 1705 | ||
1703 | #if defined(CONFIG_NO_HZ) && defined(CONFIG_SMP) | 1706 | #if defined(CONFIG_NO_HZ) && defined(CONFIG_SMP) |
1704 | extern void wake_up_idle_cpu(int cpu); | 1707 | extern void wake_up_idle_cpu(int cpu); |
1705 | #else | 1708 | #else |
1706 | static inline void wake_up_idle_cpu(int cpu) { } | 1709 | static inline void wake_up_idle_cpu(int cpu) { } |
1707 | #endif | 1710 | #endif |
1708 | 1711 | ||
1709 | extern unsigned int sysctl_sched_latency; | 1712 | extern unsigned int sysctl_sched_latency; |
1710 | extern unsigned int sysctl_sched_min_granularity; | 1713 | extern unsigned int sysctl_sched_min_granularity; |
1711 | extern unsigned int sysctl_sched_wakeup_granularity; | 1714 | extern unsigned int sysctl_sched_wakeup_granularity; |
1712 | extern unsigned int sysctl_sched_shares_ratelimit; | 1715 | extern unsigned int sysctl_sched_shares_ratelimit; |
1713 | extern unsigned int sysctl_sched_shares_thresh; | 1716 | extern unsigned int sysctl_sched_shares_thresh; |
1714 | #ifdef CONFIG_SCHED_DEBUG | 1717 | #ifdef CONFIG_SCHED_DEBUG |
1715 | extern unsigned int sysctl_sched_child_runs_first; | 1718 | extern unsigned int sysctl_sched_child_runs_first; |
1716 | extern unsigned int sysctl_sched_features; | 1719 | extern unsigned int sysctl_sched_features; |
1717 | extern unsigned int sysctl_sched_migration_cost; | 1720 | extern unsigned int sysctl_sched_migration_cost; |
1718 | extern unsigned int sysctl_sched_nr_migrate; | 1721 | extern unsigned int sysctl_sched_nr_migrate; |
1719 | 1722 | ||
1720 | int sched_nr_latency_handler(struct ctl_table *table, int write, | 1723 | int sched_nr_latency_handler(struct ctl_table *table, int write, |
1721 | struct file *file, void __user *buffer, size_t *length, | 1724 | struct file *file, void __user *buffer, size_t *length, |
1722 | loff_t *ppos); | 1725 | loff_t *ppos); |
1723 | #endif | 1726 | #endif |
1724 | extern unsigned int sysctl_sched_rt_period; | 1727 | extern unsigned int sysctl_sched_rt_period; |
1725 | extern int sysctl_sched_rt_runtime; | 1728 | extern int sysctl_sched_rt_runtime; |
1726 | 1729 | ||
1727 | int sched_rt_handler(struct ctl_table *table, int write, | 1730 | int sched_rt_handler(struct ctl_table *table, int write, |
1728 | struct file *filp, void __user *buffer, size_t *lenp, | 1731 | struct file *filp, void __user *buffer, size_t *lenp, |
1729 | loff_t *ppos); | 1732 | loff_t *ppos); |
1730 | 1733 | ||
1731 | extern unsigned int sysctl_sched_compat_yield; | 1734 | extern unsigned int sysctl_sched_compat_yield; |
1732 | 1735 | ||
1733 | #ifdef CONFIG_RT_MUTEXES | 1736 | #ifdef CONFIG_RT_MUTEXES |
1734 | extern int rt_mutex_getprio(struct task_struct *p); | 1737 | extern int rt_mutex_getprio(struct task_struct *p); |
1735 | extern void rt_mutex_setprio(struct task_struct *p, int prio); | 1738 | extern void rt_mutex_setprio(struct task_struct *p, int prio); |
1736 | extern void rt_mutex_adjust_pi(struct task_struct *p); | 1739 | extern void rt_mutex_adjust_pi(struct task_struct *p); |
1737 | #else | 1740 | #else |
1738 | static inline int rt_mutex_getprio(struct task_struct *p) | 1741 | static inline int rt_mutex_getprio(struct task_struct *p) |
1739 | { | 1742 | { |
1740 | return p->normal_prio; | 1743 | return p->normal_prio; |
1741 | } | 1744 | } |
1742 | # define rt_mutex_adjust_pi(p) do { } while (0) | 1745 | # define rt_mutex_adjust_pi(p) do { } while (0) |
1743 | #endif | 1746 | #endif |
1744 | 1747 | ||
1745 | extern void set_user_nice(struct task_struct *p, long nice); | 1748 | extern void set_user_nice(struct task_struct *p, long nice); |
1746 | extern int task_prio(const struct task_struct *p); | 1749 | extern int task_prio(const struct task_struct *p); |
1747 | extern int task_nice(const struct task_struct *p); | 1750 | extern int task_nice(const struct task_struct *p); |
1748 | extern int can_nice(const struct task_struct *p, const int nice); | 1751 | extern int can_nice(const struct task_struct *p, const int nice); |
1749 | extern int task_curr(const struct task_struct *p); | 1752 | extern int task_curr(const struct task_struct *p); |
1750 | extern int idle_cpu(int cpu); | 1753 | extern int idle_cpu(int cpu); |
1751 | extern int sched_setscheduler(struct task_struct *, int, struct sched_param *); | 1754 | extern int sched_setscheduler(struct task_struct *, int, struct sched_param *); |
1752 | extern int sched_setscheduler_nocheck(struct task_struct *, int, | 1755 | extern int sched_setscheduler_nocheck(struct task_struct *, int, |
1753 | struct sched_param *); | 1756 | struct sched_param *); |
1754 | extern struct task_struct *idle_task(int cpu); | 1757 | extern struct task_struct *idle_task(int cpu); |
1755 | extern struct task_struct *curr_task(int cpu); | 1758 | extern struct task_struct *curr_task(int cpu); |
1756 | extern void set_curr_task(int cpu, struct task_struct *p); | 1759 | extern void set_curr_task(int cpu, struct task_struct *p); |
1757 | 1760 | ||
1758 | void yield(void); | 1761 | void yield(void); |
1759 | 1762 | ||
1760 | /* | 1763 | /* |
1761 | * The default (Linux) execution domain. | 1764 | * The default (Linux) execution domain. |
1762 | */ | 1765 | */ |
1763 | extern struct exec_domain default_exec_domain; | 1766 | extern struct exec_domain default_exec_domain; |
1764 | 1767 | ||
1765 | union thread_union { | 1768 | union thread_union { |
1766 | struct thread_info thread_info; | 1769 | struct thread_info thread_info; |
1767 | unsigned long stack[THREAD_SIZE/sizeof(long)]; | 1770 | unsigned long stack[THREAD_SIZE/sizeof(long)]; |
1768 | }; | 1771 | }; |
1769 | 1772 | ||
1770 | #ifndef __HAVE_ARCH_KSTACK_END | 1773 | #ifndef __HAVE_ARCH_KSTACK_END |
1771 | static inline int kstack_end(void *addr) | 1774 | static inline int kstack_end(void *addr) |
1772 | { | 1775 | { |
1773 | /* Reliable end of stack detection: | 1776 | /* Reliable end of stack detection: |
1774 | * Some APM bios versions misalign the stack | 1777 | * Some APM bios versions misalign the stack |
1775 | */ | 1778 | */ |
1776 | return !(((unsigned long)addr+sizeof(void*)-1) & (THREAD_SIZE-sizeof(void*))); | 1779 | return !(((unsigned long)addr+sizeof(void*)-1) & (THREAD_SIZE-sizeof(void*))); |
1777 | } | 1780 | } |
1778 | #endif | 1781 | #endif |
1779 | 1782 | ||
1780 | extern union thread_union init_thread_union; | 1783 | extern union thread_union init_thread_union; |
1781 | extern struct task_struct init_task; | 1784 | extern struct task_struct init_task; |
1782 | 1785 | ||
1783 | extern struct mm_struct init_mm; | 1786 | extern struct mm_struct init_mm; |
1784 | 1787 | ||
1785 | extern struct pid_namespace init_pid_ns; | 1788 | extern struct pid_namespace init_pid_ns; |
1786 | 1789 | ||
1787 | /* | 1790 | /* |
1788 | * find a task by one of its numerical ids | 1791 | * find a task by one of its numerical ids |
1789 | * | 1792 | * |
1790 | * find_task_by_pid_type_ns(): | 1793 | * find_task_by_pid_type_ns(): |
1791 | * it is the most generic call - it finds a task by all id, | 1794 | * it is the most generic call - it finds a task by all id, |
1792 | * type and namespace specified | 1795 | * type and namespace specified |
1793 | * find_task_by_pid_ns(): | 1796 | * find_task_by_pid_ns(): |
1794 | * finds a task by its pid in the specified namespace | 1797 | * finds a task by its pid in the specified namespace |
1795 | * find_task_by_vpid(): | 1798 | * find_task_by_vpid(): |
1796 | * finds a task by its virtual pid | 1799 | * finds a task by its virtual pid |
1797 | * | 1800 | * |
1798 | * see also find_vpid() etc in include/linux/pid.h | 1801 | * see also find_vpid() etc in include/linux/pid.h |
1799 | */ | 1802 | */ |
1800 | 1803 | ||
1801 | extern struct task_struct *find_task_by_pid_type_ns(int type, int pid, | 1804 | extern struct task_struct *find_task_by_pid_type_ns(int type, int pid, |
1802 | struct pid_namespace *ns); | 1805 | struct pid_namespace *ns); |
1803 | 1806 | ||
1804 | extern struct task_struct *find_task_by_vpid(pid_t nr); | 1807 | extern struct task_struct *find_task_by_vpid(pid_t nr); |
1805 | extern struct task_struct *find_task_by_pid_ns(pid_t nr, | 1808 | extern struct task_struct *find_task_by_pid_ns(pid_t nr, |
1806 | struct pid_namespace *ns); | 1809 | struct pid_namespace *ns); |
1807 | 1810 | ||
1808 | extern void __set_special_pids(struct pid *pid); | 1811 | extern void __set_special_pids(struct pid *pid); |
1809 | 1812 | ||
1810 | /* per-UID process charging. */ | 1813 | /* per-UID process charging. */ |
1811 | extern struct user_struct * alloc_uid(struct user_namespace *, uid_t); | 1814 | extern struct user_struct * alloc_uid(struct user_namespace *, uid_t); |
1812 | static inline struct user_struct *get_uid(struct user_struct *u) | 1815 | static inline struct user_struct *get_uid(struct user_struct *u) |
1813 | { | 1816 | { |
1814 | atomic_inc(&u->__count); | 1817 | atomic_inc(&u->__count); |
1815 | return u; | 1818 | return u; |
1816 | } | 1819 | } |
1817 | extern void free_uid(struct user_struct *); | 1820 | extern void free_uid(struct user_struct *); |
1818 | extern void release_uids(struct user_namespace *ns); | 1821 | extern void release_uids(struct user_namespace *ns); |
1819 | 1822 | ||
1820 | #include <asm/current.h> | 1823 | #include <asm/current.h> |
1821 | 1824 | ||
1822 | extern void do_timer(unsigned long ticks); | 1825 | extern void do_timer(unsigned long ticks); |
1823 | 1826 | ||
1824 | extern int wake_up_state(struct task_struct *tsk, unsigned int state); | 1827 | extern int wake_up_state(struct task_struct *tsk, unsigned int state); |
1825 | extern int wake_up_process(struct task_struct *tsk); | 1828 | extern int wake_up_process(struct task_struct *tsk); |
1826 | extern void wake_up_new_task(struct task_struct *tsk, | 1829 | extern void wake_up_new_task(struct task_struct *tsk, |
1827 | unsigned long clone_flags); | 1830 | unsigned long clone_flags); |
1828 | #ifdef CONFIG_SMP | 1831 | #ifdef CONFIG_SMP |
1829 | extern void kick_process(struct task_struct *tsk); | 1832 | extern void kick_process(struct task_struct *tsk); |
1830 | #else | 1833 | #else |
1831 | static inline void kick_process(struct task_struct *tsk) { } | 1834 | static inline void kick_process(struct task_struct *tsk) { } |
1832 | #endif | 1835 | #endif |
1833 | extern void sched_fork(struct task_struct *p, int clone_flags); | 1836 | extern void sched_fork(struct task_struct *p, int clone_flags); |
1834 | extern void sched_dead(struct task_struct *p); | 1837 | extern void sched_dead(struct task_struct *p); |
1835 | 1838 | ||
1836 | extern void proc_caches_init(void); | 1839 | extern void proc_caches_init(void); |
1837 | extern void flush_signals(struct task_struct *); | 1840 | extern void flush_signals(struct task_struct *); |
1838 | extern void ignore_signals(struct task_struct *); | 1841 | extern void ignore_signals(struct task_struct *); |
1839 | extern void flush_signal_handlers(struct task_struct *, int force_default); | 1842 | extern void flush_signal_handlers(struct task_struct *, int force_default); |
1840 | extern int dequeue_signal(struct task_struct *tsk, sigset_t *mask, siginfo_t *info); | 1843 | extern int dequeue_signal(struct task_struct *tsk, sigset_t *mask, siginfo_t *info); |
1841 | 1844 | ||
1842 | static inline int dequeue_signal_lock(struct task_struct *tsk, sigset_t *mask, siginfo_t *info) | 1845 | static inline int dequeue_signal_lock(struct task_struct *tsk, sigset_t *mask, siginfo_t *info) |
1843 | { | 1846 | { |
1844 | unsigned long flags; | 1847 | unsigned long flags; |
1845 | int ret; | 1848 | int ret; |
1846 | 1849 | ||
1847 | spin_lock_irqsave(&tsk->sighand->siglock, flags); | 1850 | spin_lock_irqsave(&tsk->sighand->siglock, flags); |
1848 | ret = dequeue_signal(tsk, mask, info); | 1851 | ret = dequeue_signal(tsk, mask, info); |
1849 | spin_unlock_irqrestore(&tsk->sighand->siglock, flags); | 1852 | spin_unlock_irqrestore(&tsk->sighand->siglock, flags); |
1850 | 1853 | ||
1851 | return ret; | 1854 | return ret; |
1852 | } | 1855 | } |
1853 | 1856 | ||
1854 | extern void block_all_signals(int (*notifier)(void *priv), void *priv, | 1857 | extern void block_all_signals(int (*notifier)(void *priv), void *priv, |
1855 | sigset_t *mask); | 1858 | sigset_t *mask); |
1856 | extern void unblock_all_signals(void); | 1859 | extern void unblock_all_signals(void); |
1857 | extern void release_task(struct task_struct * p); | 1860 | extern void release_task(struct task_struct * p); |
1858 | extern int send_sig_info(int, struct siginfo *, struct task_struct *); | 1861 | extern int send_sig_info(int, struct siginfo *, struct task_struct *); |
1859 | extern int force_sigsegv(int, struct task_struct *); | 1862 | extern int force_sigsegv(int, struct task_struct *); |
1860 | extern int force_sig_info(int, struct siginfo *, struct task_struct *); | 1863 | extern int force_sig_info(int, struct siginfo *, struct task_struct *); |
1861 | extern int __kill_pgrp_info(int sig, struct siginfo *info, struct pid *pgrp); | 1864 | extern int __kill_pgrp_info(int sig, struct siginfo *info, struct pid *pgrp); |
1862 | extern int kill_pid_info(int sig, struct siginfo *info, struct pid *pid); | 1865 | extern int kill_pid_info(int sig, struct siginfo *info, struct pid *pid); |
1863 | extern int kill_pid_info_as_uid(int, struct siginfo *, struct pid *, uid_t, uid_t, u32); | 1866 | extern int kill_pid_info_as_uid(int, struct siginfo *, struct pid *, uid_t, uid_t, u32); |
1864 | extern int kill_pgrp(struct pid *pid, int sig, int priv); | 1867 | extern int kill_pgrp(struct pid *pid, int sig, int priv); |
1865 | extern int kill_pid(struct pid *pid, int sig, int priv); | 1868 | extern int kill_pid(struct pid *pid, int sig, int priv); |
1866 | extern int kill_proc_info(int, struct siginfo *, pid_t); | 1869 | extern int kill_proc_info(int, struct siginfo *, pid_t); |
1867 | extern int do_notify_parent(struct task_struct *, int); | 1870 | extern int do_notify_parent(struct task_struct *, int); |
1868 | extern void force_sig(int, struct task_struct *); | 1871 | extern void force_sig(int, struct task_struct *); |
1869 | extern void force_sig_specific(int, struct task_struct *); | 1872 | extern void force_sig_specific(int, struct task_struct *); |
1870 | extern int send_sig(int, struct task_struct *, int); | 1873 | extern int send_sig(int, struct task_struct *, int); |
1871 | extern void zap_other_threads(struct task_struct *p); | 1874 | extern void zap_other_threads(struct task_struct *p); |
1872 | extern struct sigqueue *sigqueue_alloc(void); | 1875 | extern struct sigqueue *sigqueue_alloc(void); |
1873 | extern void sigqueue_free(struct sigqueue *); | 1876 | extern void sigqueue_free(struct sigqueue *); |
1874 | extern int send_sigqueue(struct sigqueue *, struct task_struct *, int group); | 1877 | extern int send_sigqueue(struct sigqueue *, struct task_struct *, int group); |
1875 | extern int do_sigaction(int, struct k_sigaction *, struct k_sigaction *); | 1878 | extern int do_sigaction(int, struct k_sigaction *, struct k_sigaction *); |
1876 | extern int do_sigaltstack(const stack_t __user *, stack_t __user *, unsigned long); | 1879 | extern int do_sigaltstack(const stack_t __user *, stack_t __user *, unsigned long); |
1877 | 1880 | ||
1878 | static inline int kill_cad_pid(int sig, int priv) | 1881 | static inline int kill_cad_pid(int sig, int priv) |
1879 | { | 1882 | { |
1880 | return kill_pid(cad_pid, sig, priv); | 1883 | return kill_pid(cad_pid, sig, priv); |
1881 | } | 1884 | } |
1882 | 1885 | ||
1883 | /* These can be the second arg to send_sig_info/send_group_sig_info. */ | 1886 | /* These can be the second arg to send_sig_info/send_group_sig_info. */ |
1884 | #define SEND_SIG_NOINFO ((struct siginfo *) 0) | 1887 | #define SEND_SIG_NOINFO ((struct siginfo *) 0) |
1885 | #define SEND_SIG_PRIV ((struct siginfo *) 1) | 1888 | #define SEND_SIG_PRIV ((struct siginfo *) 1) |
1886 | #define SEND_SIG_FORCED ((struct siginfo *) 2) | 1889 | #define SEND_SIG_FORCED ((struct siginfo *) 2) |
1887 | 1890 | ||
1888 | static inline int is_si_special(const struct siginfo *info) | 1891 | static inline int is_si_special(const struct siginfo *info) |
1889 | { | 1892 | { |
1890 | return info <= SEND_SIG_FORCED; | 1893 | return info <= SEND_SIG_FORCED; |
1891 | } | 1894 | } |
1892 | 1895 | ||
1893 | /* True if we are on the alternate signal stack. */ | 1896 | /* True if we are on the alternate signal stack. */ |
1894 | 1897 | ||
1895 | static inline int on_sig_stack(unsigned long sp) | 1898 | static inline int on_sig_stack(unsigned long sp) |
1896 | { | 1899 | { |
1897 | return (sp - current->sas_ss_sp < current->sas_ss_size); | 1900 | return (sp - current->sas_ss_sp < current->sas_ss_size); |
1898 | } | 1901 | } |
1899 | 1902 | ||
1900 | static inline int sas_ss_flags(unsigned long sp) | 1903 | static inline int sas_ss_flags(unsigned long sp) |
1901 | { | 1904 | { |
1902 | return (current->sas_ss_size == 0 ? SS_DISABLE | 1905 | return (current->sas_ss_size == 0 ? SS_DISABLE |
1903 | : on_sig_stack(sp) ? SS_ONSTACK : 0); | 1906 | : on_sig_stack(sp) ? SS_ONSTACK : 0); |
1904 | } | 1907 | } |
1905 | 1908 | ||
1906 | /* | 1909 | /* |
1907 | * Routines for handling mm_structs | 1910 | * Routines for handling mm_structs |
1908 | */ | 1911 | */ |
1909 | extern struct mm_struct * mm_alloc(void); | 1912 | extern struct mm_struct * mm_alloc(void); |
1910 | 1913 | ||
1911 | /* mmdrop drops the mm and the page tables */ | 1914 | /* mmdrop drops the mm and the page tables */ |
1912 | extern void __mmdrop(struct mm_struct *); | 1915 | extern void __mmdrop(struct mm_struct *); |
1913 | static inline void mmdrop(struct mm_struct * mm) | 1916 | static inline void mmdrop(struct mm_struct * mm) |
1914 | { | 1917 | { |
1915 | if (unlikely(atomic_dec_and_test(&mm->mm_count))) | 1918 | if (unlikely(atomic_dec_and_test(&mm->mm_count))) |
1916 | __mmdrop(mm); | 1919 | __mmdrop(mm); |
1917 | } | 1920 | } |
1918 | 1921 | ||
1919 | /* mmput gets rid of the mappings and all user-space */ | 1922 | /* mmput gets rid of the mappings and all user-space */ |
1920 | extern void mmput(struct mm_struct *); | 1923 | extern void mmput(struct mm_struct *); |
1921 | /* Grab a reference to a task's mm, if it is not already going away */ | 1924 | /* Grab a reference to a task's mm, if it is not already going away */ |
1922 | extern struct mm_struct *get_task_mm(struct task_struct *task); | 1925 | extern struct mm_struct *get_task_mm(struct task_struct *task); |
1923 | /* Remove the current tasks stale references to the old mm_struct */ | 1926 | /* Remove the current tasks stale references to the old mm_struct */ |
1924 | extern void mm_release(struct task_struct *, struct mm_struct *); | 1927 | extern void mm_release(struct task_struct *, struct mm_struct *); |
1925 | /* Allocate a new mm structure and copy contents from tsk->mm */ | 1928 | /* Allocate a new mm structure and copy contents from tsk->mm */ |
1926 | extern struct mm_struct *dup_mm(struct task_struct *tsk); | 1929 | extern struct mm_struct *dup_mm(struct task_struct *tsk); |
1927 | 1930 | ||
1928 | extern int copy_thread(int, unsigned long, unsigned long, unsigned long, struct task_struct *, struct pt_regs *); | 1931 | extern int copy_thread(int, unsigned long, unsigned long, unsigned long, struct task_struct *, struct pt_regs *); |
1929 | extern void flush_thread(void); | 1932 | extern void flush_thread(void); |
1930 | extern void exit_thread(void); | 1933 | extern void exit_thread(void); |
1931 | 1934 | ||
1932 | extern void exit_files(struct task_struct *); | 1935 | extern void exit_files(struct task_struct *); |
1933 | extern void __cleanup_signal(struct signal_struct *); | 1936 | extern void __cleanup_signal(struct signal_struct *); |
1934 | extern void __cleanup_sighand(struct sighand_struct *); | 1937 | extern void __cleanup_sighand(struct sighand_struct *); |
1935 | 1938 | ||
1936 | extern void exit_itimers(struct signal_struct *); | 1939 | extern void exit_itimers(struct signal_struct *); |
1937 | extern void flush_itimer_signals(void); | 1940 | extern void flush_itimer_signals(void); |
1938 | 1941 | ||
1939 | extern NORET_TYPE void do_group_exit(int); | 1942 | extern NORET_TYPE void do_group_exit(int); |
1940 | 1943 | ||
1941 | extern void daemonize(const char *, ...); | 1944 | extern void daemonize(const char *, ...); |
1942 | extern int allow_signal(int); | 1945 | extern int allow_signal(int); |
1943 | extern int disallow_signal(int); | 1946 | extern int disallow_signal(int); |
1944 | 1947 | ||
1945 | extern int do_execve(char *, char __user * __user *, char __user * __user *, struct pt_regs *); | 1948 | extern int do_execve(char *, char __user * __user *, char __user * __user *, struct pt_regs *); |
1946 | extern long do_fork(unsigned long, unsigned long, struct pt_regs *, unsigned long, int __user *, int __user *); | 1949 | extern long do_fork(unsigned long, unsigned long, struct pt_regs *, unsigned long, int __user *, int __user *); |
1947 | struct task_struct *fork_idle(int); | 1950 | struct task_struct *fork_idle(int); |
1948 | 1951 | ||
1949 | extern void set_task_comm(struct task_struct *tsk, char *from); | 1952 | extern void set_task_comm(struct task_struct *tsk, char *from); |
1950 | extern char *get_task_comm(char *to, struct task_struct *tsk); | 1953 | extern char *get_task_comm(char *to, struct task_struct *tsk); |
1951 | 1954 | ||
1952 | #ifdef CONFIG_SMP | 1955 | #ifdef CONFIG_SMP |
1953 | extern unsigned long wait_task_inactive(struct task_struct *, long match_state); | 1956 | extern unsigned long wait_task_inactive(struct task_struct *, long match_state); |
1954 | #else | 1957 | #else |
1955 | static inline unsigned long wait_task_inactive(struct task_struct *p, | 1958 | static inline unsigned long wait_task_inactive(struct task_struct *p, |
1956 | long match_state) | 1959 | long match_state) |
1957 | { | 1960 | { |
1958 | return 1; | 1961 | return 1; |
1959 | } | 1962 | } |
1960 | #endif | 1963 | #endif |
1961 | 1964 | ||
1962 | #define next_task(p) list_entry(rcu_dereference((p)->tasks.next), struct task_struct, tasks) | 1965 | #define next_task(p) list_entry(rcu_dereference((p)->tasks.next), struct task_struct, tasks) |
1963 | 1966 | ||
1964 | #define for_each_process(p) \ | 1967 | #define for_each_process(p) \ |
1965 | for (p = &init_task ; (p = next_task(p)) != &init_task ; ) | 1968 | for (p = &init_task ; (p = next_task(p)) != &init_task ; ) |
1966 | 1969 | ||
1967 | extern bool is_single_threaded(struct task_struct *); | 1970 | extern bool is_single_threaded(struct task_struct *); |
1968 | 1971 | ||
1969 | /* | 1972 | /* |
1970 | * Careful: do_each_thread/while_each_thread is a double loop so | 1973 | * Careful: do_each_thread/while_each_thread is a double loop so |
1971 | * 'break' will not work as expected - use goto instead. | 1974 | * 'break' will not work as expected - use goto instead. |
1972 | */ | 1975 | */ |
1973 | #define do_each_thread(g, t) \ | 1976 | #define do_each_thread(g, t) \ |
1974 | for (g = t = &init_task ; (g = t = next_task(g)) != &init_task ; ) do | 1977 | for (g = t = &init_task ; (g = t = next_task(g)) != &init_task ; ) do |
1975 | 1978 | ||
1976 | #define while_each_thread(g, t) \ | 1979 | #define while_each_thread(g, t) \ |
1977 | while ((t = next_thread(t)) != g) | 1980 | while ((t = next_thread(t)) != g) |
1978 | 1981 | ||
1979 | /* de_thread depends on thread_group_leader not being a pid based check */ | 1982 | /* de_thread depends on thread_group_leader not being a pid based check */ |
1980 | #define thread_group_leader(p) (p == p->group_leader) | 1983 | #define thread_group_leader(p) (p == p->group_leader) |
1981 | 1984 | ||
1982 | /* Do to the insanities of de_thread it is possible for a process | 1985 | /* Do to the insanities of de_thread it is possible for a process |
1983 | * to have the pid of the thread group leader without actually being | 1986 | * to have the pid of the thread group leader without actually being |
1984 | * the thread group leader. For iteration through the pids in proc | 1987 | * the thread group leader. For iteration through the pids in proc |
1985 | * all we care about is that we have a task with the appropriate | 1988 | * all we care about is that we have a task with the appropriate |
1986 | * pid, we don't actually care if we have the right task. | 1989 | * pid, we don't actually care if we have the right task. |
1987 | */ | 1990 | */ |
1988 | static inline int has_group_leader_pid(struct task_struct *p) | 1991 | static inline int has_group_leader_pid(struct task_struct *p) |
1989 | { | 1992 | { |
1990 | return p->pid == p->tgid; | 1993 | return p->pid == p->tgid; |
1991 | } | 1994 | } |
1992 | 1995 | ||
1993 | static inline | 1996 | static inline |
1994 | int same_thread_group(struct task_struct *p1, struct task_struct *p2) | 1997 | int same_thread_group(struct task_struct *p1, struct task_struct *p2) |
1995 | { | 1998 | { |
1996 | return p1->tgid == p2->tgid; | 1999 | return p1->tgid == p2->tgid; |
1997 | } | 2000 | } |
1998 | 2001 | ||
1999 | static inline struct task_struct *next_thread(const struct task_struct *p) | 2002 | static inline struct task_struct *next_thread(const struct task_struct *p) |
2000 | { | 2003 | { |
2001 | return list_entry(rcu_dereference(p->thread_group.next), | 2004 | return list_entry(rcu_dereference(p->thread_group.next), |
2002 | struct task_struct, thread_group); | 2005 | struct task_struct, thread_group); |
2003 | } | 2006 | } |
2004 | 2007 | ||
2005 | static inline int thread_group_empty(struct task_struct *p) | 2008 | static inline int thread_group_empty(struct task_struct *p) |
2006 | { | 2009 | { |
2007 | return list_empty(&p->thread_group); | 2010 | return list_empty(&p->thread_group); |
2008 | } | 2011 | } |
2009 | 2012 | ||
2010 | #define delay_group_leader(p) \ | 2013 | #define delay_group_leader(p) \ |
2011 | (thread_group_leader(p) && !thread_group_empty(p)) | 2014 | (thread_group_leader(p) && !thread_group_empty(p)) |
2012 | 2015 | ||
2013 | /* | 2016 | /* |
2014 | * Protects ->fs, ->files, ->mm, ->group_info, ->comm, keyring | 2017 | * Protects ->fs, ->files, ->mm, ->group_info, ->comm, keyring |
2015 | * subscriptions and synchronises with wait4(). Also used in procfs. Also | 2018 | * subscriptions and synchronises with wait4(). Also used in procfs. Also |
2016 | * pins the final release of task.io_context. Also protects ->cpuset and | 2019 | * pins the final release of task.io_context. Also protects ->cpuset and |
2017 | * ->cgroup.subsys[]. | 2020 | * ->cgroup.subsys[]. |
2018 | * | 2021 | * |
2019 | * Nests both inside and outside of read_lock(&tasklist_lock). | 2022 | * Nests both inside and outside of read_lock(&tasklist_lock). |
2020 | * It must not be nested with write_lock_irq(&tasklist_lock), | 2023 | * It must not be nested with write_lock_irq(&tasklist_lock), |
2021 | * neither inside nor outside. | 2024 | * neither inside nor outside. |
2022 | */ | 2025 | */ |
2023 | static inline void task_lock(struct task_struct *p) | 2026 | static inline void task_lock(struct task_struct *p) |
2024 | { | 2027 | { |
2025 | spin_lock(&p->alloc_lock); | 2028 | spin_lock(&p->alloc_lock); |
2026 | } | 2029 | } |
2027 | 2030 | ||
2028 | static inline void task_unlock(struct task_struct *p) | 2031 | static inline void task_unlock(struct task_struct *p) |
2029 | { | 2032 | { |
2030 | spin_unlock(&p->alloc_lock); | 2033 | spin_unlock(&p->alloc_lock); |
2031 | } | 2034 | } |
2032 | 2035 | ||
2033 | extern struct sighand_struct *lock_task_sighand(struct task_struct *tsk, | 2036 | extern struct sighand_struct *lock_task_sighand(struct task_struct *tsk, |
2034 | unsigned long *flags); | 2037 | unsigned long *flags); |
2035 | 2038 | ||
2036 | static inline void unlock_task_sighand(struct task_struct *tsk, | 2039 | static inline void unlock_task_sighand(struct task_struct *tsk, |
2037 | unsigned long *flags) | 2040 | unsigned long *flags) |
2038 | { | 2041 | { |
2039 | spin_unlock_irqrestore(&tsk->sighand->siglock, *flags); | 2042 | spin_unlock_irqrestore(&tsk->sighand->siglock, *flags); |
2040 | } | 2043 | } |
2041 | 2044 | ||
2042 | #ifndef __HAVE_THREAD_FUNCTIONS | 2045 | #ifndef __HAVE_THREAD_FUNCTIONS |
2043 | 2046 | ||
2044 | #define task_thread_info(task) ((struct thread_info *)(task)->stack) | 2047 | #define task_thread_info(task) ((struct thread_info *)(task)->stack) |
2045 | #define task_stack_page(task) ((task)->stack) | 2048 | #define task_stack_page(task) ((task)->stack) |
2046 | 2049 | ||
2047 | static inline void setup_thread_stack(struct task_struct *p, struct task_struct *org) | 2050 | static inline void setup_thread_stack(struct task_struct *p, struct task_struct *org) |
2048 | { | 2051 | { |
2049 | *task_thread_info(p) = *task_thread_info(org); | 2052 | *task_thread_info(p) = *task_thread_info(org); |
2050 | task_thread_info(p)->task = p; | 2053 | task_thread_info(p)->task = p; |
2051 | } | 2054 | } |
2052 | 2055 | ||
2053 | static inline unsigned long *end_of_stack(struct task_struct *p) | 2056 | static inline unsigned long *end_of_stack(struct task_struct *p) |
2054 | { | 2057 | { |
2055 | return (unsigned long *)(task_thread_info(p) + 1); | 2058 | return (unsigned long *)(task_thread_info(p) + 1); |
2056 | } | 2059 | } |
2057 | 2060 | ||
2058 | #endif | 2061 | #endif |
2059 | 2062 | ||
2060 | static inline int object_is_on_stack(void *obj) | 2063 | static inline int object_is_on_stack(void *obj) |
2061 | { | 2064 | { |
2062 | void *stack = task_stack_page(current); | 2065 | void *stack = task_stack_page(current); |
2063 | 2066 | ||
2064 | return (obj >= stack) && (obj < (stack + THREAD_SIZE)); | 2067 | return (obj >= stack) && (obj < (stack + THREAD_SIZE)); |
2065 | } | 2068 | } |
2066 | 2069 | ||
2067 | extern void thread_info_cache_init(void); | 2070 | extern void thread_info_cache_init(void); |
2068 | 2071 | ||
2069 | /* set thread flags in other task's structures | 2072 | /* set thread flags in other task's structures |
2070 | * - see asm/thread_info.h for TIF_xxxx flags available | 2073 | * - see asm/thread_info.h for TIF_xxxx flags available |
2071 | */ | 2074 | */ |
2072 | static inline void set_tsk_thread_flag(struct task_struct *tsk, int flag) | 2075 | static inline void set_tsk_thread_flag(struct task_struct *tsk, int flag) |
2073 | { | 2076 | { |
2074 | set_ti_thread_flag(task_thread_info(tsk), flag); | 2077 | set_ti_thread_flag(task_thread_info(tsk), flag); |
2075 | } | 2078 | } |
2076 | 2079 | ||
2077 | static inline void clear_tsk_thread_flag(struct task_struct *tsk, int flag) | 2080 | static inline void clear_tsk_thread_flag(struct task_struct *tsk, int flag) |
2078 | { | 2081 | { |
2079 | clear_ti_thread_flag(task_thread_info(tsk), flag); | 2082 | clear_ti_thread_flag(task_thread_info(tsk), flag); |
2080 | } | 2083 | } |
2081 | 2084 | ||
2082 | static inline int test_and_set_tsk_thread_flag(struct task_struct *tsk, int flag) | 2085 | static inline int test_and_set_tsk_thread_flag(struct task_struct *tsk, int flag) |
2083 | { | 2086 | { |
2084 | return test_and_set_ti_thread_flag(task_thread_info(tsk), flag); | 2087 | return test_and_set_ti_thread_flag(task_thread_info(tsk), flag); |
2085 | } | 2088 | } |
2086 | 2089 | ||
2087 | static inline int test_and_clear_tsk_thread_flag(struct task_struct *tsk, int flag) | 2090 | static inline int test_and_clear_tsk_thread_flag(struct task_struct *tsk, int flag) |
2088 | { | 2091 | { |
2089 | return test_and_clear_ti_thread_flag(task_thread_info(tsk), flag); | 2092 | return test_and_clear_ti_thread_flag(task_thread_info(tsk), flag); |
2090 | } | 2093 | } |
2091 | 2094 | ||
2092 | static inline int test_tsk_thread_flag(struct task_struct *tsk, int flag) | 2095 | static inline int test_tsk_thread_flag(struct task_struct *tsk, int flag) |
2093 | { | 2096 | { |
2094 | return test_ti_thread_flag(task_thread_info(tsk), flag); | 2097 | return test_ti_thread_flag(task_thread_info(tsk), flag); |
2095 | } | 2098 | } |
2096 | 2099 | ||
2097 | static inline void set_tsk_need_resched(struct task_struct *tsk) | 2100 | static inline void set_tsk_need_resched(struct task_struct *tsk) |
2098 | { | 2101 | { |
2099 | set_tsk_thread_flag(tsk,TIF_NEED_RESCHED); | 2102 | set_tsk_thread_flag(tsk,TIF_NEED_RESCHED); |
2100 | } | 2103 | } |
2101 | 2104 | ||
2102 | static inline void clear_tsk_need_resched(struct task_struct *tsk) | 2105 | static inline void clear_tsk_need_resched(struct task_struct *tsk) |
2103 | { | 2106 | { |
2104 | clear_tsk_thread_flag(tsk,TIF_NEED_RESCHED); | 2107 | clear_tsk_thread_flag(tsk,TIF_NEED_RESCHED); |
2105 | } | 2108 | } |
2106 | 2109 | ||
2107 | static inline int test_tsk_need_resched(struct task_struct *tsk) | 2110 | static inline int test_tsk_need_resched(struct task_struct *tsk) |
2108 | { | 2111 | { |
2109 | return unlikely(test_tsk_thread_flag(tsk,TIF_NEED_RESCHED)); | 2112 | return unlikely(test_tsk_thread_flag(tsk,TIF_NEED_RESCHED)); |
2110 | } | 2113 | } |
2111 | 2114 | ||
2112 | static inline int signal_pending(struct task_struct *p) | 2115 | static inline int signal_pending(struct task_struct *p) |
2113 | { | 2116 | { |
2114 | return unlikely(test_tsk_thread_flag(p,TIF_SIGPENDING)); | 2117 | return unlikely(test_tsk_thread_flag(p,TIF_SIGPENDING)); |
2115 | } | 2118 | } |
2116 | 2119 | ||
2117 | extern int __fatal_signal_pending(struct task_struct *p); | 2120 | extern int __fatal_signal_pending(struct task_struct *p); |
2118 | 2121 | ||
2119 | static inline int fatal_signal_pending(struct task_struct *p) | 2122 | static inline int fatal_signal_pending(struct task_struct *p) |
2120 | { | 2123 | { |
2121 | return signal_pending(p) && __fatal_signal_pending(p); | 2124 | return signal_pending(p) && __fatal_signal_pending(p); |
2122 | } | 2125 | } |
2123 | 2126 | ||
2124 | static inline int signal_pending_state(long state, struct task_struct *p) | 2127 | static inline int signal_pending_state(long state, struct task_struct *p) |
2125 | { | 2128 | { |
2126 | if (!(state & (TASK_INTERRUPTIBLE | TASK_WAKEKILL))) | 2129 | if (!(state & (TASK_INTERRUPTIBLE | TASK_WAKEKILL))) |
2127 | return 0; | 2130 | return 0; |
2128 | if (!signal_pending(p)) | 2131 | if (!signal_pending(p)) |
2129 | return 0; | 2132 | return 0; |
2130 | 2133 | ||
2131 | return (state & TASK_INTERRUPTIBLE) || __fatal_signal_pending(p); | 2134 | return (state & TASK_INTERRUPTIBLE) || __fatal_signal_pending(p); |
2132 | } | 2135 | } |
2133 | 2136 | ||
2134 | static inline int need_resched(void) | 2137 | static inline int need_resched(void) |
2135 | { | 2138 | { |
2136 | return unlikely(test_thread_flag(TIF_NEED_RESCHED)); | 2139 | return unlikely(test_thread_flag(TIF_NEED_RESCHED)); |
2137 | } | 2140 | } |
2138 | 2141 | ||
2139 | /* | 2142 | /* |
2140 | * cond_resched() and cond_resched_lock(): latency reduction via | 2143 | * cond_resched() and cond_resched_lock(): latency reduction via |
2141 | * explicit rescheduling in places that are safe. The return | 2144 | * explicit rescheduling in places that are safe. The return |
2142 | * value indicates whether a reschedule was done in fact. | 2145 | * value indicates whether a reschedule was done in fact. |
2143 | * cond_resched_lock() will drop the spinlock before scheduling, | 2146 | * cond_resched_lock() will drop the spinlock before scheduling, |
2144 | * cond_resched_softirq() will enable bhs before scheduling. | 2147 | * cond_resched_softirq() will enable bhs before scheduling. |
2145 | */ | 2148 | */ |
2146 | extern int _cond_resched(void); | 2149 | extern int _cond_resched(void); |
2147 | #ifdef CONFIG_PREEMPT_BKL | 2150 | #ifdef CONFIG_PREEMPT_BKL |
2148 | static inline int cond_resched(void) | 2151 | static inline int cond_resched(void) |
2149 | { | 2152 | { |
2150 | return 0; | 2153 | return 0; |
2151 | } | 2154 | } |
2152 | #else | 2155 | #else |
2153 | static inline int cond_resched(void) | 2156 | static inline int cond_resched(void) |
2154 | { | 2157 | { |
2155 | return _cond_resched(); | 2158 | return _cond_resched(); |
2156 | } | 2159 | } |
2157 | #endif | 2160 | #endif |
2158 | extern int cond_resched_lock(spinlock_t * lock); | 2161 | extern int cond_resched_lock(spinlock_t * lock); |
2159 | extern int cond_resched_softirq(void); | 2162 | extern int cond_resched_softirq(void); |
2160 | static inline int cond_resched_bkl(void) | 2163 | static inline int cond_resched_bkl(void) |
2161 | { | 2164 | { |
2162 | return _cond_resched(); | 2165 | return _cond_resched(); |
2163 | } | 2166 | } |
2164 | 2167 | ||
2165 | /* | 2168 | /* |
2166 | * Does a critical section need to be broken due to another | 2169 | * Does a critical section need to be broken due to another |
2167 | * task waiting?: (technically does not depend on CONFIG_PREEMPT, | 2170 | * task waiting?: (technically does not depend on CONFIG_PREEMPT, |
2168 | * but a general need for low latency) | 2171 | * but a general need for low latency) |
2169 | */ | 2172 | */ |
2170 | static inline int spin_needbreak(spinlock_t *lock) | 2173 | static inline int spin_needbreak(spinlock_t *lock) |
2171 | { | 2174 | { |
2172 | #ifdef CONFIG_PREEMPT | 2175 | #ifdef CONFIG_PREEMPT |
2173 | return spin_is_contended(lock); | 2176 | return spin_is_contended(lock); |
2174 | #else | 2177 | #else |
2175 | return 0; | 2178 | return 0; |
2176 | #endif | 2179 | #endif |
2177 | } | 2180 | } |
2178 | 2181 | ||
2179 | /* | 2182 | /* |
2180 | * Thread group CPU time accounting. | 2183 | * Thread group CPU time accounting. |
2181 | */ | 2184 | */ |
2182 | 2185 | ||
2183 | extern int thread_group_cputime_alloc(struct task_struct *); | 2186 | extern int thread_group_cputime_alloc(struct task_struct *); |
2184 | extern void thread_group_cputime(struct task_struct *, struct task_cputime *); | 2187 | extern void thread_group_cputime(struct task_struct *, struct task_cputime *); |
2185 | 2188 | ||
2186 | static inline void thread_group_cputime_init(struct signal_struct *sig) | 2189 | static inline void thread_group_cputime_init(struct signal_struct *sig) |
2187 | { | 2190 | { |
2188 | sig->cputime.totals = NULL; | 2191 | sig->cputime.totals = NULL; |
2189 | } | 2192 | } |
2190 | 2193 | ||
2191 | static inline int thread_group_cputime_clone_thread(struct task_struct *curr) | 2194 | static inline int thread_group_cputime_clone_thread(struct task_struct *curr) |
2192 | { | 2195 | { |
2193 | if (curr->signal->cputime.totals) | 2196 | if (curr->signal->cputime.totals) |
2194 | return 0; | 2197 | return 0; |
2195 | return thread_group_cputime_alloc(curr); | 2198 | return thread_group_cputime_alloc(curr); |
2196 | } | 2199 | } |
2197 | 2200 | ||
2198 | static inline void thread_group_cputime_free(struct signal_struct *sig) | 2201 | static inline void thread_group_cputime_free(struct signal_struct *sig) |
2199 | { | 2202 | { |
2200 | free_percpu(sig->cputime.totals); | 2203 | free_percpu(sig->cputime.totals); |
2201 | } | 2204 | } |
2202 | 2205 | ||
2203 | /* | 2206 | /* |
2204 | * Reevaluate whether the task has signals pending delivery. | 2207 | * Reevaluate whether the task has signals pending delivery. |
2205 | * Wake the task if so. | 2208 | * Wake the task if so. |
2206 | * This is required every time the blocked sigset_t changes. | 2209 | * This is required every time the blocked sigset_t changes. |
2207 | * callers must hold sighand->siglock. | 2210 | * callers must hold sighand->siglock. |
2208 | */ | 2211 | */ |
2209 | extern void recalc_sigpending_and_wake(struct task_struct *t); | 2212 | extern void recalc_sigpending_and_wake(struct task_struct *t); |
2210 | extern void recalc_sigpending(void); | 2213 | extern void recalc_sigpending(void); |
2211 | 2214 | ||
2212 | extern void signal_wake_up(struct task_struct *t, int resume_stopped); | 2215 | extern void signal_wake_up(struct task_struct *t, int resume_stopped); |
2213 | 2216 | ||
2214 | /* | 2217 | /* |
2215 | * Wrappers for p->thread_info->cpu access. No-op on UP. | 2218 | * Wrappers for p->thread_info->cpu access. No-op on UP. |
2216 | */ | 2219 | */ |
2217 | #ifdef CONFIG_SMP | 2220 | #ifdef CONFIG_SMP |
2218 | 2221 | ||
2219 | static inline unsigned int task_cpu(const struct task_struct *p) | 2222 | static inline unsigned int task_cpu(const struct task_struct *p) |
2220 | { | 2223 | { |
2221 | return task_thread_info(p)->cpu; | 2224 | return task_thread_info(p)->cpu; |
2222 | } | 2225 | } |
2223 | 2226 | ||
2224 | extern void set_task_cpu(struct task_struct *p, unsigned int cpu); | 2227 | extern void set_task_cpu(struct task_struct *p, unsigned int cpu); |
2225 | 2228 | ||
2226 | #else | 2229 | #else |
2227 | 2230 | ||
2228 | static inline unsigned int task_cpu(const struct task_struct *p) | 2231 | static inline unsigned int task_cpu(const struct task_struct *p) |
2229 | { | 2232 | { |
2230 | return 0; | 2233 | return 0; |
2231 | } | 2234 | } |
2232 | 2235 | ||
2233 | static inline void set_task_cpu(struct task_struct *p, unsigned int cpu) | 2236 | static inline void set_task_cpu(struct task_struct *p, unsigned int cpu) |
2234 | { | 2237 | { |
2235 | } | 2238 | } |
2236 | 2239 | ||
2237 | #endif /* CONFIG_SMP */ | 2240 | #endif /* CONFIG_SMP */ |
2238 | 2241 | ||
2239 | extern void arch_pick_mmap_layout(struct mm_struct *mm); | 2242 | extern void arch_pick_mmap_layout(struct mm_struct *mm); |
2240 | 2243 | ||
2241 | #ifdef CONFIG_TRACING | 2244 | #ifdef CONFIG_TRACING |
2242 | extern void | 2245 | extern void |
2243 | __trace_special(void *__tr, void *__data, | 2246 | __trace_special(void *__tr, void *__data, |
2244 | unsigned long arg1, unsigned long arg2, unsigned long arg3); | 2247 | unsigned long arg1, unsigned long arg2, unsigned long arg3); |
2245 | #else | 2248 | #else |
2246 | static inline void | 2249 | static inline void |
2247 | __trace_special(void *__tr, void *__data, | 2250 | __trace_special(void *__tr, void *__data, |
2248 | unsigned long arg1, unsigned long arg2, unsigned long arg3) | 2251 | unsigned long arg1, unsigned long arg2, unsigned long arg3) |
2249 | { | 2252 | { |
2250 | } | 2253 | } |
2251 | #endif | 2254 | #endif |
2252 | 2255 | ||
2253 | extern long sched_setaffinity(pid_t pid, const struct cpumask *new_mask); | 2256 | extern long sched_setaffinity(pid_t pid, const struct cpumask *new_mask); |
2254 | extern long sched_getaffinity(pid_t pid, struct cpumask *mask); | 2257 | extern long sched_getaffinity(pid_t pid, struct cpumask *mask); |
2255 | 2258 | ||
2256 | extern void normalize_rt_tasks(void); | 2259 | extern void normalize_rt_tasks(void); |
2257 | 2260 | ||
2258 | #ifdef CONFIG_GROUP_SCHED | 2261 | #ifdef CONFIG_GROUP_SCHED |
2259 | 2262 | ||
2260 | extern struct task_group init_task_group; | 2263 | extern struct task_group init_task_group; |
2261 | #ifdef CONFIG_USER_SCHED | 2264 | #ifdef CONFIG_USER_SCHED |
2262 | extern struct task_group root_task_group; | 2265 | extern struct task_group root_task_group; |
2263 | extern void set_tg_uid(struct user_struct *user); | 2266 | extern void set_tg_uid(struct user_struct *user); |
2264 | #endif | 2267 | #endif |
2265 | 2268 | ||
2266 | extern struct task_group *sched_create_group(struct task_group *parent); | 2269 | extern struct task_group *sched_create_group(struct task_group *parent); |
2267 | extern void sched_destroy_group(struct task_group *tg); | 2270 | extern void sched_destroy_group(struct task_group *tg); |
2268 | extern void sched_move_task(struct task_struct *tsk); | 2271 | extern void sched_move_task(struct task_struct *tsk); |
2269 | #ifdef CONFIG_FAIR_GROUP_SCHED | 2272 | #ifdef CONFIG_FAIR_GROUP_SCHED |
2270 | extern int sched_group_set_shares(struct task_group *tg, unsigned long shares); | 2273 | extern int sched_group_set_shares(struct task_group *tg, unsigned long shares); |
2271 | extern unsigned long sched_group_shares(struct task_group *tg); | 2274 | extern unsigned long sched_group_shares(struct task_group *tg); |
2272 | #endif | 2275 | #endif |
2273 | #ifdef CONFIG_RT_GROUP_SCHED | 2276 | #ifdef CONFIG_RT_GROUP_SCHED |
2274 | extern int sched_group_set_rt_runtime(struct task_group *tg, | 2277 | extern int sched_group_set_rt_runtime(struct task_group *tg, |
2275 | long rt_runtime_us); | 2278 | long rt_runtime_us); |
2276 | extern long sched_group_rt_runtime(struct task_group *tg); | 2279 | extern long sched_group_rt_runtime(struct task_group *tg); |
2277 | extern int sched_group_set_rt_period(struct task_group *tg, | 2280 | extern int sched_group_set_rt_period(struct task_group *tg, |
2278 | long rt_period_us); | 2281 | long rt_period_us); |
2279 | extern long sched_group_rt_period(struct task_group *tg); | 2282 | extern long sched_group_rt_period(struct task_group *tg); |
2280 | #endif | 2283 | #endif |
2281 | #endif | 2284 | #endif |
2282 | 2285 | ||
2283 | #ifdef CONFIG_TASK_XACCT | 2286 | #ifdef CONFIG_TASK_XACCT |
2284 | static inline void add_rchar(struct task_struct *tsk, ssize_t amt) | 2287 | static inline void add_rchar(struct task_struct *tsk, ssize_t amt) |
2285 | { | 2288 | { |
2286 | tsk->ioac.rchar += amt; | 2289 | tsk->ioac.rchar += amt; |
2287 | } | 2290 | } |
2288 | 2291 | ||
2289 | static inline void add_wchar(struct task_struct *tsk, ssize_t amt) | 2292 | static inline void add_wchar(struct task_struct *tsk, ssize_t amt) |
2290 | { | 2293 | { |
2291 | tsk->ioac.wchar += amt; | 2294 | tsk->ioac.wchar += amt; |
2292 | } | 2295 | } |
2293 | 2296 | ||
2294 | static inline void inc_syscr(struct task_struct *tsk) | 2297 | static inline void inc_syscr(struct task_struct *tsk) |
2295 | { | 2298 | { |
2296 | tsk->ioac.syscr++; | 2299 | tsk->ioac.syscr++; |
2297 | } | 2300 | } |
2298 | 2301 | ||
2299 | static inline void inc_syscw(struct task_struct *tsk) | 2302 | static inline void inc_syscw(struct task_struct *tsk) |
2300 | { | 2303 | { |
2301 | tsk->ioac.syscw++; | 2304 | tsk->ioac.syscw++; |
2302 | } | 2305 | } |
2303 | #else | 2306 | #else |
2304 | static inline void add_rchar(struct task_struct *tsk, ssize_t amt) | 2307 | static inline void add_rchar(struct task_struct *tsk, ssize_t amt) |
2305 | { | 2308 | { |
2306 | } | 2309 | } |
2307 | 2310 | ||
2308 | static inline void add_wchar(struct task_struct *tsk, ssize_t amt) | 2311 | static inline void add_wchar(struct task_struct *tsk, ssize_t amt) |
2309 | { | 2312 | { |
2310 | } | 2313 | } |
2311 | 2314 | ||
2312 | static inline void inc_syscr(struct task_struct *tsk) | 2315 | static inline void inc_syscr(struct task_struct *tsk) |
2313 | { | 2316 | { |
2314 | } | 2317 | } |
2315 | 2318 | ||
2316 | static inline void inc_syscw(struct task_struct *tsk) | 2319 | static inline void inc_syscw(struct task_struct *tsk) |
2317 | { | 2320 | { |
2318 | } | 2321 | } |
2319 | #endif | 2322 | #endif |
2320 | 2323 | ||
2321 | #ifndef TASK_SIZE_OF | 2324 | #ifndef TASK_SIZE_OF |
2322 | #define TASK_SIZE_OF(tsk) TASK_SIZE | 2325 | #define TASK_SIZE_OF(tsk) TASK_SIZE |
2323 | #endif | 2326 | #endif |
2324 | 2327 | ||
2325 | #ifdef CONFIG_MM_OWNER | 2328 | #ifdef CONFIG_MM_OWNER |
2326 | extern void mm_update_next_owner(struct mm_struct *mm); | 2329 | extern void mm_update_next_owner(struct mm_struct *mm); |
2327 | extern void mm_init_owner(struct mm_struct *mm, struct task_struct *p); | 2330 | extern void mm_init_owner(struct mm_struct *mm, struct task_struct *p); |
2328 | #else | 2331 | #else |
2329 | static inline void mm_update_next_owner(struct mm_struct *mm) | 2332 | static inline void mm_update_next_owner(struct mm_struct *mm) |
2330 | { | 2333 | { |
2331 | } | 2334 | } |
2332 | 2335 | ||
2333 | static inline void mm_init_owner(struct mm_struct *mm, struct task_struct *p) | 2336 | static inline void mm_init_owner(struct mm_struct *mm, struct task_struct *p) |
2334 | { | 2337 | { |
2335 | } | 2338 | } |
2336 | #endif /* CONFIG_MM_OWNER */ | 2339 | #endif /* CONFIG_MM_OWNER */ |
2337 | 2340 | ||
2338 | #define TASK_STATE_TO_CHAR_STR "RSDTtZX" | 2341 | #define TASK_STATE_TO_CHAR_STR "RSDTtZX" |
2339 | 2342 | ||
2340 | #endif /* __KERNEL__ */ | 2343 | #endif /* __KERNEL__ */ |
2341 | 2344 | ||
2342 | #endif | 2345 | #endif |
2343 | 2346 |
kernel/softlockup.c
1 | /* | 1 | /* |
2 | * Detect Soft Lockups | 2 | * Detect Soft Lockups |
3 | * | 3 | * |
4 | * started by Ingo Molnar, Copyright (C) 2005, 2006 Red Hat, Inc. | 4 | * started by Ingo Molnar, Copyright (C) 2005, 2006 Red Hat, Inc. |
5 | * | 5 | * |
6 | * this code detects soft lockups: incidents in where on a CPU | 6 | * this code detects soft lockups: incidents in where on a CPU |
7 | * the kernel does not reschedule for 10 seconds or more. | 7 | * the kernel does not reschedule for 10 seconds or more. |
8 | */ | 8 | */ |
9 | #include <linux/mm.h> | 9 | #include <linux/mm.h> |
10 | #include <linux/cpu.h> | 10 | #include <linux/cpu.h> |
11 | #include <linux/nmi.h> | 11 | #include <linux/nmi.h> |
12 | #include <linux/init.h> | 12 | #include <linux/init.h> |
13 | #include <linux/delay.h> | 13 | #include <linux/delay.h> |
14 | #include <linux/freezer.h> | 14 | #include <linux/freezer.h> |
15 | #include <linux/kthread.h> | 15 | #include <linux/kthread.h> |
16 | #include <linux/lockdep.h> | 16 | #include <linux/lockdep.h> |
17 | #include <linux/notifier.h> | 17 | #include <linux/notifier.h> |
18 | #include <linux/module.h> | 18 | #include <linux/module.h> |
19 | #include <linux/sysctl.h> | ||
19 | 20 | ||
20 | #include <asm/irq_regs.h> | 21 | #include <asm/irq_regs.h> |
21 | 22 | ||
22 | static DEFINE_SPINLOCK(print_lock); | 23 | static DEFINE_SPINLOCK(print_lock); |
23 | 24 | ||
24 | static DEFINE_PER_CPU(unsigned long, touch_timestamp); | 25 | static DEFINE_PER_CPU(unsigned long, touch_timestamp); |
25 | static DEFINE_PER_CPU(unsigned long, print_timestamp); | 26 | static DEFINE_PER_CPU(unsigned long, print_timestamp); |
26 | static DEFINE_PER_CPU(struct task_struct *, watchdog_task); | 27 | static DEFINE_PER_CPU(struct task_struct *, watchdog_task); |
27 | 28 | ||
28 | static int __read_mostly did_panic; | 29 | static int __read_mostly did_panic; |
29 | int __read_mostly softlockup_thresh = 60; | 30 | int __read_mostly softlockup_thresh = 60; |
30 | 31 | ||
31 | /* | 32 | /* |
32 | * Should we panic (and reboot, if panic_timeout= is set) when a | 33 | * Should we panic (and reboot, if panic_timeout= is set) when a |
33 | * soft-lockup occurs: | 34 | * soft-lockup occurs: |
34 | */ | 35 | */ |
35 | unsigned int __read_mostly softlockup_panic = | 36 | unsigned int __read_mostly softlockup_panic = |
36 | CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE; | 37 | CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE; |
37 | 38 | ||
38 | static int __init softlockup_panic_setup(char *str) | 39 | static int __init softlockup_panic_setup(char *str) |
39 | { | 40 | { |
40 | softlockup_panic = simple_strtoul(str, NULL, 0); | 41 | softlockup_panic = simple_strtoul(str, NULL, 0); |
41 | 42 | ||
42 | return 1; | 43 | return 1; |
43 | } | 44 | } |
44 | __setup("softlockup_panic=", softlockup_panic_setup); | 45 | __setup("softlockup_panic=", softlockup_panic_setup); |
45 | 46 | ||
46 | static int | 47 | static int |
47 | softlock_panic(struct notifier_block *this, unsigned long event, void *ptr) | 48 | softlock_panic(struct notifier_block *this, unsigned long event, void *ptr) |
48 | { | 49 | { |
49 | did_panic = 1; | 50 | did_panic = 1; |
50 | 51 | ||
51 | return NOTIFY_DONE; | 52 | return NOTIFY_DONE; |
52 | } | 53 | } |
53 | 54 | ||
54 | static struct notifier_block panic_block = { | 55 | static struct notifier_block panic_block = { |
55 | .notifier_call = softlock_panic, | 56 | .notifier_call = softlock_panic, |
56 | }; | 57 | }; |
57 | 58 | ||
58 | /* | 59 | /* |
59 | * Returns seconds, approximately. We don't need nanosecond | 60 | * Returns seconds, approximately. We don't need nanosecond |
60 | * resolution, and we don't need to waste time with a big divide when | 61 | * resolution, and we don't need to waste time with a big divide when |
61 | * 2^30ns == 1.074s. | 62 | * 2^30ns == 1.074s. |
62 | */ | 63 | */ |
63 | static unsigned long get_timestamp(int this_cpu) | 64 | static unsigned long get_timestamp(int this_cpu) |
64 | { | 65 | { |
65 | return cpu_clock(this_cpu) >> 30LL; /* 2^30 ~= 10^9 */ | 66 | return cpu_clock(this_cpu) >> 30LL; /* 2^30 ~= 10^9 */ |
66 | } | 67 | } |
67 | 68 | ||
68 | static void __touch_softlockup_watchdog(void) | 69 | static void __touch_softlockup_watchdog(void) |
69 | { | 70 | { |
70 | int this_cpu = raw_smp_processor_id(); | 71 | int this_cpu = raw_smp_processor_id(); |
71 | 72 | ||
72 | __raw_get_cpu_var(touch_timestamp) = get_timestamp(this_cpu); | 73 | __raw_get_cpu_var(touch_timestamp) = get_timestamp(this_cpu); |
73 | } | 74 | } |
74 | 75 | ||
75 | void touch_softlockup_watchdog(void) | 76 | void touch_softlockup_watchdog(void) |
76 | { | 77 | { |
77 | __raw_get_cpu_var(touch_timestamp) = 0; | 78 | __raw_get_cpu_var(touch_timestamp) = 0; |
78 | } | 79 | } |
79 | EXPORT_SYMBOL(touch_softlockup_watchdog); | 80 | EXPORT_SYMBOL(touch_softlockup_watchdog); |
80 | 81 | ||
81 | void touch_all_softlockup_watchdogs(void) | 82 | void touch_all_softlockup_watchdogs(void) |
82 | { | 83 | { |
83 | int cpu; | 84 | int cpu; |
84 | 85 | ||
85 | /* Cause each CPU to re-update its timestamp rather than complain */ | 86 | /* Cause each CPU to re-update its timestamp rather than complain */ |
86 | for_each_online_cpu(cpu) | 87 | for_each_online_cpu(cpu) |
87 | per_cpu(touch_timestamp, cpu) = 0; | 88 | per_cpu(touch_timestamp, cpu) = 0; |
88 | } | 89 | } |
89 | EXPORT_SYMBOL(touch_all_softlockup_watchdogs); | 90 | EXPORT_SYMBOL(touch_all_softlockup_watchdogs); |
91 | |||
92 | int proc_dosoftlockup_thresh(struct ctl_table *table, int write, | ||
93 | struct file *filp, void __user *buffer, | ||
94 | size_t *lenp, loff_t *ppos) | ||
95 | { | ||
96 | touch_all_softlockup_watchdogs(); | ||
97 | return proc_dointvec_minmax(table, write, filp, buffer, lenp, ppos); | ||
98 | } | ||
90 | 99 | ||
91 | /* | 100 | /* |
92 | * This callback runs from the timer interrupt, and checks | 101 | * This callback runs from the timer interrupt, and checks |
93 | * whether the watchdog thread has hung or not: | 102 | * whether the watchdog thread has hung or not: |
94 | */ | 103 | */ |
95 | void softlockup_tick(void) | 104 | void softlockup_tick(void) |
96 | { | 105 | { |
97 | int this_cpu = smp_processor_id(); | 106 | int this_cpu = smp_processor_id(); |
98 | unsigned long touch_timestamp = per_cpu(touch_timestamp, this_cpu); | 107 | unsigned long touch_timestamp = per_cpu(touch_timestamp, this_cpu); |
99 | unsigned long print_timestamp; | 108 | unsigned long print_timestamp; |
100 | struct pt_regs *regs = get_irq_regs(); | 109 | struct pt_regs *regs = get_irq_regs(); |
101 | unsigned long now; | 110 | unsigned long now; |
102 | 111 | ||
103 | /* Is detection switched off? */ | 112 | /* Is detection switched off? */ |
104 | if (!per_cpu(watchdog_task, this_cpu) || softlockup_thresh <= 0) { | 113 | if (!per_cpu(watchdog_task, this_cpu) || softlockup_thresh <= 0) { |
105 | /* Be sure we don't false trigger if switched back on */ | 114 | /* Be sure we don't false trigger if switched back on */ |
106 | if (touch_timestamp) | 115 | if (touch_timestamp) |
107 | per_cpu(touch_timestamp, this_cpu) = 0; | 116 | per_cpu(touch_timestamp, this_cpu) = 0; |
108 | return; | 117 | return; |
109 | } | 118 | } |
110 | 119 | ||
111 | if (touch_timestamp == 0) { | 120 | if (touch_timestamp == 0) { |
112 | __touch_softlockup_watchdog(); | 121 | __touch_softlockup_watchdog(); |
113 | return; | 122 | return; |
114 | } | 123 | } |
115 | 124 | ||
116 | print_timestamp = per_cpu(print_timestamp, this_cpu); | 125 | print_timestamp = per_cpu(print_timestamp, this_cpu); |
117 | 126 | ||
118 | /* report at most once a second */ | 127 | /* report at most once a second */ |
119 | if (print_timestamp == touch_timestamp || did_panic) | 128 | if (print_timestamp == touch_timestamp || did_panic) |
120 | return; | 129 | return; |
121 | 130 | ||
122 | /* do not print during early bootup: */ | 131 | /* do not print during early bootup: */ |
123 | if (unlikely(system_state != SYSTEM_RUNNING)) { | 132 | if (unlikely(system_state != SYSTEM_RUNNING)) { |
124 | __touch_softlockup_watchdog(); | 133 | __touch_softlockup_watchdog(); |
125 | return; | 134 | return; |
126 | } | 135 | } |
127 | 136 | ||
128 | now = get_timestamp(this_cpu); | 137 | now = get_timestamp(this_cpu); |
129 | 138 | ||
130 | /* | 139 | /* |
131 | * Wake up the high-prio watchdog task twice per | 140 | * Wake up the high-prio watchdog task twice per |
132 | * threshold timespan. | 141 | * threshold timespan. |
133 | */ | 142 | */ |
134 | if (now > touch_timestamp + softlockup_thresh/2) | 143 | if (now > touch_timestamp + softlockup_thresh/2) |
135 | wake_up_process(per_cpu(watchdog_task, this_cpu)); | 144 | wake_up_process(per_cpu(watchdog_task, this_cpu)); |
136 | 145 | ||
137 | /* Warn about unreasonable delays: */ | 146 | /* Warn about unreasonable delays: */ |
138 | if (now <= (touch_timestamp + softlockup_thresh)) | 147 | if (now <= (touch_timestamp + softlockup_thresh)) |
139 | return; | 148 | return; |
140 | 149 | ||
141 | per_cpu(print_timestamp, this_cpu) = touch_timestamp; | 150 | per_cpu(print_timestamp, this_cpu) = touch_timestamp; |
142 | 151 | ||
143 | spin_lock(&print_lock); | 152 | spin_lock(&print_lock); |
144 | printk(KERN_ERR "BUG: soft lockup - CPU#%d stuck for %lus! [%s:%d]\n", | 153 | printk(KERN_ERR "BUG: soft lockup - CPU#%d stuck for %lus! [%s:%d]\n", |
145 | this_cpu, now - touch_timestamp, | 154 | this_cpu, now - touch_timestamp, |
146 | current->comm, task_pid_nr(current)); | 155 | current->comm, task_pid_nr(current)); |
147 | print_modules(); | 156 | print_modules(); |
148 | print_irqtrace_events(current); | 157 | print_irqtrace_events(current); |
149 | if (regs) | 158 | if (regs) |
150 | show_regs(regs); | 159 | show_regs(regs); |
151 | else | 160 | else |
152 | dump_stack(); | 161 | dump_stack(); |
153 | spin_unlock(&print_lock); | 162 | spin_unlock(&print_lock); |
154 | 163 | ||
155 | if (softlockup_panic) | 164 | if (softlockup_panic) |
156 | panic("softlockup: hung tasks"); | 165 | panic("softlockup: hung tasks"); |
157 | } | 166 | } |
158 | 167 | ||
159 | /* | 168 | /* |
160 | * Have a reasonable limit on the number of tasks checked: | 169 | * Have a reasonable limit on the number of tasks checked: |
161 | */ | 170 | */ |
162 | unsigned long __read_mostly sysctl_hung_task_check_count = 1024; | 171 | unsigned long __read_mostly sysctl_hung_task_check_count = 1024; |
163 | 172 | ||
164 | /* | 173 | /* |
165 | * Zero means infinite timeout - no checking done: | 174 | * Zero means infinite timeout - no checking done: |
166 | */ | 175 | */ |
167 | unsigned long __read_mostly sysctl_hung_task_timeout_secs = 480; | 176 | unsigned long __read_mostly sysctl_hung_task_timeout_secs = 480; |
168 | 177 | ||
169 | unsigned long __read_mostly sysctl_hung_task_warnings = 10; | 178 | unsigned long __read_mostly sysctl_hung_task_warnings = 10; |
170 | 179 | ||
171 | /* | 180 | /* |
172 | * Only do the hung-tasks check on one CPU: | 181 | * Only do the hung-tasks check on one CPU: |
173 | */ | 182 | */ |
174 | static int check_cpu __read_mostly = -1; | 183 | static int check_cpu __read_mostly = -1; |
175 | 184 | ||
176 | static void check_hung_task(struct task_struct *t, unsigned long now) | 185 | static void check_hung_task(struct task_struct *t, unsigned long now) |
177 | { | 186 | { |
178 | unsigned long switch_count = t->nvcsw + t->nivcsw; | 187 | unsigned long switch_count = t->nvcsw + t->nivcsw; |
179 | 188 | ||
180 | if (t->flags & PF_FROZEN) | 189 | if (t->flags & PF_FROZEN) |
181 | return; | 190 | return; |
182 | 191 | ||
183 | if (switch_count != t->last_switch_count || !t->last_switch_timestamp) { | 192 | if (switch_count != t->last_switch_count || !t->last_switch_timestamp) { |
184 | t->last_switch_count = switch_count; | 193 | t->last_switch_count = switch_count; |
185 | t->last_switch_timestamp = now; | 194 | t->last_switch_timestamp = now; |
186 | return; | 195 | return; |
187 | } | 196 | } |
188 | if ((long)(now - t->last_switch_timestamp) < | 197 | if ((long)(now - t->last_switch_timestamp) < |
189 | sysctl_hung_task_timeout_secs) | 198 | sysctl_hung_task_timeout_secs) |
190 | return; | 199 | return; |
191 | if (!sysctl_hung_task_warnings) | 200 | if (!sysctl_hung_task_warnings) |
192 | return; | 201 | return; |
193 | sysctl_hung_task_warnings--; | 202 | sysctl_hung_task_warnings--; |
194 | 203 | ||
195 | /* | 204 | /* |
196 | * Ok, the task did not get scheduled for more than 2 minutes, | 205 | * Ok, the task did not get scheduled for more than 2 minutes, |
197 | * complain: | 206 | * complain: |
198 | */ | 207 | */ |
199 | printk(KERN_ERR "INFO: task %s:%d blocked for more than " | 208 | printk(KERN_ERR "INFO: task %s:%d blocked for more than " |
200 | "%ld seconds.\n", t->comm, t->pid, | 209 | "%ld seconds.\n", t->comm, t->pid, |
201 | sysctl_hung_task_timeout_secs); | 210 | sysctl_hung_task_timeout_secs); |
202 | printk(KERN_ERR "\"echo 0 > /proc/sys/kernel/hung_task_timeout_secs\"" | 211 | printk(KERN_ERR "\"echo 0 > /proc/sys/kernel/hung_task_timeout_secs\"" |
203 | " disables this message.\n"); | 212 | " disables this message.\n"); |
204 | sched_show_task(t); | 213 | sched_show_task(t); |
205 | __debug_show_held_locks(t); | 214 | __debug_show_held_locks(t); |
206 | 215 | ||
207 | t->last_switch_timestamp = now; | 216 | t->last_switch_timestamp = now; |
208 | touch_nmi_watchdog(); | 217 | touch_nmi_watchdog(); |
209 | 218 | ||
210 | if (softlockup_panic) | 219 | if (softlockup_panic) |
211 | panic("softlockup: blocked tasks"); | 220 | panic("softlockup: blocked tasks"); |
212 | } | 221 | } |
213 | 222 | ||
214 | /* | 223 | /* |
215 | * Check whether a TASK_UNINTERRUPTIBLE does not get woken up for | 224 | * Check whether a TASK_UNINTERRUPTIBLE does not get woken up for |
216 | * a really long time (120 seconds). If that happens, print out | 225 | * a really long time (120 seconds). If that happens, print out |
217 | * a warning. | 226 | * a warning. |
218 | */ | 227 | */ |
219 | static void check_hung_uninterruptible_tasks(int this_cpu) | 228 | static void check_hung_uninterruptible_tasks(int this_cpu) |
220 | { | 229 | { |
221 | int max_count = sysctl_hung_task_check_count; | 230 | int max_count = sysctl_hung_task_check_count; |
222 | unsigned long now = get_timestamp(this_cpu); | 231 | unsigned long now = get_timestamp(this_cpu); |
223 | struct task_struct *g, *t; | 232 | struct task_struct *g, *t; |
224 | 233 | ||
225 | /* | 234 | /* |
226 | * If the system crashed already then all bets are off, | 235 | * If the system crashed already then all bets are off, |
227 | * do not report extra hung tasks: | 236 | * do not report extra hung tasks: |
228 | */ | 237 | */ |
229 | if (test_taint(TAINT_DIE) || did_panic) | 238 | if (test_taint(TAINT_DIE) || did_panic) |
230 | return; | 239 | return; |
231 | 240 | ||
232 | read_lock(&tasklist_lock); | 241 | read_lock(&tasklist_lock); |
233 | do_each_thread(g, t) { | 242 | do_each_thread(g, t) { |
234 | if (!--max_count) | 243 | if (!--max_count) |
235 | goto unlock; | 244 | goto unlock; |
236 | /* use "==" to skip the TASK_KILLABLE tasks waiting on NFS */ | 245 | /* use "==" to skip the TASK_KILLABLE tasks waiting on NFS */ |
237 | if (t->state == TASK_UNINTERRUPTIBLE) | 246 | if (t->state == TASK_UNINTERRUPTIBLE) |
238 | check_hung_task(t, now); | 247 | check_hung_task(t, now); |
239 | } while_each_thread(g, t); | 248 | } while_each_thread(g, t); |
240 | unlock: | 249 | unlock: |
241 | read_unlock(&tasklist_lock); | 250 | read_unlock(&tasklist_lock); |
242 | } | 251 | } |
243 | 252 | ||
244 | /* | 253 | /* |
245 | * The watchdog thread - runs every second and touches the timestamp. | 254 | * The watchdog thread - runs every second and touches the timestamp. |
246 | */ | 255 | */ |
247 | static int watchdog(void *__bind_cpu) | 256 | static int watchdog(void *__bind_cpu) |
248 | { | 257 | { |
249 | struct sched_param param = { .sched_priority = MAX_RT_PRIO-1 }; | 258 | struct sched_param param = { .sched_priority = MAX_RT_PRIO-1 }; |
250 | int this_cpu = (long)__bind_cpu; | 259 | int this_cpu = (long)__bind_cpu; |
251 | 260 | ||
252 | sched_setscheduler(current, SCHED_FIFO, ¶m); | 261 | sched_setscheduler(current, SCHED_FIFO, ¶m); |
253 | 262 | ||
254 | /* initialize timestamp */ | 263 | /* initialize timestamp */ |
255 | __touch_softlockup_watchdog(); | 264 | __touch_softlockup_watchdog(); |
256 | 265 | ||
257 | set_current_state(TASK_INTERRUPTIBLE); | 266 | set_current_state(TASK_INTERRUPTIBLE); |
258 | /* | 267 | /* |
259 | * Run briefly once per second to reset the softlockup timestamp. | 268 | * Run briefly once per second to reset the softlockup timestamp. |
260 | * If this gets delayed for more than 60 seconds then the | 269 | * If this gets delayed for more than 60 seconds then the |
261 | * debug-printout triggers in softlockup_tick(). | 270 | * debug-printout triggers in softlockup_tick(). |
262 | */ | 271 | */ |
263 | while (!kthread_should_stop()) { | 272 | while (!kthread_should_stop()) { |
264 | __touch_softlockup_watchdog(); | 273 | __touch_softlockup_watchdog(); |
265 | schedule(); | 274 | schedule(); |
266 | 275 | ||
267 | if (kthread_should_stop()) | 276 | if (kthread_should_stop()) |
268 | break; | 277 | break; |
269 | 278 | ||
270 | if (this_cpu == check_cpu) { | 279 | if (this_cpu == check_cpu) { |
271 | if (sysctl_hung_task_timeout_secs) | 280 | if (sysctl_hung_task_timeout_secs) |
272 | check_hung_uninterruptible_tasks(this_cpu); | 281 | check_hung_uninterruptible_tasks(this_cpu); |
273 | } | 282 | } |
274 | 283 | ||
275 | set_current_state(TASK_INTERRUPTIBLE); | 284 | set_current_state(TASK_INTERRUPTIBLE); |
276 | } | 285 | } |
277 | __set_current_state(TASK_RUNNING); | 286 | __set_current_state(TASK_RUNNING); |
278 | 287 | ||
279 | return 0; | 288 | return 0; |
280 | } | 289 | } |
281 | 290 | ||
282 | /* | 291 | /* |
283 | * Create/destroy watchdog threads as CPUs come and go: | 292 | * Create/destroy watchdog threads as CPUs come and go: |
284 | */ | 293 | */ |
285 | static int __cpuinit | 294 | static int __cpuinit |
286 | cpu_callback(struct notifier_block *nfb, unsigned long action, void *hcpu) | 295 | cpu_callback(struct notifier_block *nfb, unsigned long action, void *hcpu) |
287 | { | 296 | { |
288 | int hotcpu = (unsigned long)hcpu; | 297 | int hotcpu = (unsigned long)hcpu; |
289 | struct task_struct *p; | 298 | struct task_struct *p; |
290 | 299 | ||
291 | switch (action) { | 300 | switch (action) { |
292 | case CPU_UP_PREPARE: | 301 | case CPU_UP_PREPARE: |
293 | case CPU_UP_PREPARE_FROZEN: | 302 | case CPU_UP_PREPARE_FROZEN: |
294 | BUG_ON(per_cpu(watchdog_task, hotcpu)); | 303 | BUG_ON(per_cpu(watchdog_task, hotcpu)); |
295 | p = kthread_create(watchdog, hcpu, "watchdog/%d", hotcpu); | 304 | p = kthread_create(watchdog, hcpu, "watchdog/%d", hotcpu); |
296 | if (IS_ERR(p)) { | 305 | if (IS_ERR(p)) { |
297 | printk(KERN_ERR "watchdog for %i failed\n", hotcpu); | 306 | printk(KERN_ERR "watchdog for %i failed\n", hotcpu); |
298 | return NOTIFY_BAD; | 307 | return NOTIFY_BAD; |
299 | } | 308 | } |
300 | per_cpu(touch_timestamp, hotcpu) = 0; | 309 | per_cpu(touch_timestamp, hotcpu) = 0; |
301 | per_cpu(watchdog_task, hotcpu) = p; | 310 | per_cpu(watchdog_task, hotcpu) = p; |
302 | kthread_bind(p, hotcpu); | 311 | kthread_bind(p, hotcpu); |
303 | break; | 312 | break; |
304 | case CPU_ONLINE: | 313 | case CPU_ONLINE: |
305 | case CPU_ONLINE_FROZEN: | 314 | case CPU_ONLINE_FROZEN: |
306 | check_cpu = cpumask_any(cpu_online_mask); | 315 | check_cpu = cpumask_any(cpu_online_mask); |
307 | wake_up_process(per_cpu(watchdog_task, hotcpu)); | 316 | wake_up_process(per_cpu(watchdog_task, hotcpu)); |
308 | break; | 317 | break; |
309 | #ifdef CONFIG_HOTPLUG_CPU | 318 | #ifdef CONFIG_HOTPLUG_CPU |
310 | case CPU_DOWN_PREPARE: | 319 | case CPU_DOWN_PREPARE: |
311 | case CPU_DOWN_PREPARE_FROZEN: | 320 | case CPU_DOWN_PREPARE_FROZEN: |
312 | if (hotcpu == check_cpu) { | 321 | if (hotcpu == check_cpu) { |
313 | /* Pick any other online cpu. */ | 322 | /* Pick any other online cpu. */ |
314 | check_cpu = cpumask_any_but(cpu_online_mask, hotcpu); | 323 | check_cpu = cpumask_any_but(cpu_online_mask, hotcpu); |
315 | } | 324 | } |
316 | break; | 325 | break; |
317 | 326 | ||
318 | case CPU_UP_CANCELED: | 327 | case CPU_UP_CANCELED: |
319 | case CPU_UP_CANCELED_FROZEN: | 328 | case CPU_UP_CANCELED_FROZEN: |
320 | if (!per_cpu(watchdog_task, hotcpu)) | 329 | if (!per_cpu(watchdog_task, hotcpu)) |
321 | break; | 330 | break; |
322 | /* Unbind so it can run. Fall thru. */ | 331 | /* Unbind so it can run. Fall thru. */ |
323 | kthread_bind(per_cpu(watchdog_task, hotcpu), | 332 | kthread_bind(per_cpu(watchdog_task, hotcpu), |
324 | cpumask_any(cpu_online_mask)); | 333 | cpumask_any(cpu_online_mask)); |
325 | case CPU_DEAD: | 334 | case CPU_DEAD: |
326 | case CPU_DEAD_FROZEN: | 335 | case CPU_DEAD_FROZEN: |
327 | p = per_cpu(watchdog_task, hotcpu); | 336 | p = per_cpu(watchdog_task, hotcpu); |
328 | per_cpu(watchdog_task, hotcpu) = NULL; | 337 | per_cpu(watchdog_task, hotcpu) = NULL; |
329 | kthread_stop(p); | 338 | kthread_stop(p); |
330 | break; | 339 | break; |
331 | #endif /* CONFIG_HOTPLUG_CPU */ | 340 | #endif /* CONFIG_HOTPLUG_CPU */ |
332 | } | 341 | } |
333 | return NOTIFY_OK; | 342 | return NOTIFY_OK; |
334 | } | 343 | } |
335 | 344 | ||
336 | static struct notifier_block __cpuinitdata cpu_nfb = { | 345 | static struct notifier_block __cpuinitdata cpu_nfb = { |
337 | .notifier_call = cpu_callback | 346 | .notifier_call = cpu_callback |
338 | }; | 347 | }; |
339 | 348 | ||
340 | static int __initdata nosoftlockup; | 349 | static int __initdata nosoftlockup; |
341 | 350 | ||
342 | static int __init nosoftlockup_setup(char *str) | 351 | static int __init nosoftlockup_setup(char *str) |
343 | { | 352 | { |
344 | nosoftlockup = 1; | 353 | nosoftlockup = 1; |
345 | return 1; | 354 | return 1; |
346 | } | 355 | } |
347 | __setup("nosoftlockup", nosoftlockup_setup); | 356 | __setup("nosoftlockup", nosoftlockup_setup); |
348 | 357 | ||
349 | static int __init spawn_softlockup_task(void) | 358 | static int __init spawn_softlockup_task(void) |
350 | { | 359 | { |
351 | void *cpu = (void *)(long)smp_processor_id(); | 360 | void *cpu = (void *)(long)smp_processor_id(); |
352 | int err; | 361 | int err; |
353 | 362 | ||
354 | if (nosoftlockup) | 363 | if (nosoftlockup) |
355 | return 0; | 364 | return 0; |
356 | 365 | ||
357 | err = cpu_callback(&cpu_nfb, CPU_UP_PREPARE, cpu); | 366 | err = cpu_callback(&cpu_nfb, CPU_UP_PREPARE, cpu); |
358 | if (err == NOTIFY_BAD) { | 367 | if (err == NOTIFY_BAD) { |
359 | BUG(); | 368 | BUG(); |
360 | return 1; | 369 | return 1; |
361 | } | 370 | } |
362 | cpu_callback(&cpu_nfb, CPU_ONLINE, cpu); | 371 | cpu_callback(&cpu_nfb, CPU_ONLINE, cpu); |
363 | register_cpu_notifier(&cpu_nfb); | 372 | register_cpu_notifier(&cpu_nfb); |
364 | 373 | ||
365 | atomic_notifier_chain_register(&panic_notifier_list, &panic_block); | 374 | atomic_notifier_chain_register(&panic_notifier_list, &panic_block); |
366 | 375 | ||
367 | return 0; | 376 | return 0; |
368 | } | 377 | } |
369 | early_initcall(spawn_softlockup_task); | 378 | early_initcall(spawn_softlockup_task); |
370 | 379 |
kernel/sysctl.c
1 | /* | 1 | /* |
2 | * sysctl.c: General linux system control interface | 2 | * sysctl.c: General linux system control interface |
3 | * | 3 | * |
4 | * Begun 24 March 1995, Stephen Tweedie | 4 | * Begun 24 March 1995, Stephen Tweedie |
5 | * Added /proc support, Dec 1995 | 5 | * Added /proc support, Dec 1995 |
6 | * Added bdflush entry and intvec min/max checking, 2/23/96, Tom Dyas. | 6 | * Added bdflush entry and intvec min/max checking, 2/23/96, Tom Dyas. |
7 | * Added hooks for /proc/sys/net (minor, minor patch), 96/4/1, Mike Shaver. | 7 | * Added hooks for /proc/sys/net (minor, minor patch), 96/4/1, Mike Shaver. |
8 | * Added kernel/java-{interpreter,appletviewer}, 96/5/10, Mike Shaver. | 8 | * Added kernel/java-{interpreter,appletviewer}, 96/5/10, Mike Shaver. |
9 | * Dynamic registration fixes, Stephen Tweedie. | 9 | * Dynamic registration fixes, Stephen Tweedie. |
10 | * Added kswapd-interval, ctrl-alt-del, printk stuff, 1/8/97, Chris Horn. | 10 | * Added kswapd-interval, ctrl-alt-del, printk stuff, 1/8/97, Chris Horn. |
11 | * Made sysctl support optional via CONFIG_SYSCTL, 1/10/97, Chris | 11 | * Made sysctl support optional via CONFIG_SYSCTL, 1/10/97, Chris |
12 | * Horn. | 12 | * Horn. |
13 | * Added proc_doulongvec_ms_jiffies_minmax, 09/08/99, Carlos H. Bauer. | 13 | * Added proc_doulongvec_ms_jiffies_minmax, 09/08/99, Carlos H. Bauer. |
14 | * Added proc_doulongvec_minmax, 09/08/99, Carlos H. Bauer. | 14 | * Added proc_doulongvec_minmax, 09/08/99, Carlos H. Bauer. |
15 | * Changed linked lists to use list.h instead of lists.h, 02/24/00, Bill | 15 | * Changed linked lists to use list.h instead of lists.h, 02/24/00, Bill |
16 | * Wendling. | 16 | * Wendling. |
17 | * The list_for_each() macro wasn't appropriate for the sysctl loop. | 17 | * The list_for_each() macro wasn't appropriate for the sysctl loop. |
18 | * Removed it and replaced it with older style, 03/23/00, Bill Wendling | 18 | * Removed it and replaced it with older style, 03/23/00, Bill Wendling |
19 | */ | 19 | */ |
20 | 20 | ||
21 | #include <linux/module.h> | 21 | #include <linux/module.h> |
22 | #include <linux/mm.h> | 22 | #include <linux/mm.h> |
23 | #include <linux/swap.h> | 23 | #include <linux/swap.h> |
24 | #include <linux/slab.h> | 24 | #include <linux/slab.h> |
25 | #include <linux/sysctl.h> | 25 | #include <linux/sysctl.h> |
26 | #include <linux/proc_fs.h> | 26 | #include <linux/proc_fs.h> |
27 | #include <linux/security.h> | 27 | #include <linux/security.h> |
28 | #include <linux/ctype.h> | 28 | #include <linux/ctype.h> |
29 | #include <linux/utsname.h> | 29 | #include <linux/utsname.h> |
30 | #include <linux/smp_lock.h> | 30 | #include <linux/smp_lock.h> |
31 | #include <linux/fs.h> | 31 | #include <linux/fs.h> |
32 | #include <linux/init.h> | 32 | #include <linux/init.h> |
33 | #include <linux/kernel.h> | 33 | #include <linux/kernel.h> |
34 | #include <linux/kobject.h> | 34 | #include <linux/kobject.h> |
35 | #include <linux/net.h> | 35 | #include <linux/net.h> |
36 | #include <linux/sysrq.h> | 36 | #include <linux/sysrq.h> |
37 | #include <linux/highuid.h> | 37 | #include <linux/highuid.h> |
38 | #include <linux/writeback.h> | 38 | #include <linux/writeback.h> |
39 | #include <linux/hugetlb.h> | 39 | #include <linux/hugetlb.h> |
40 | #include <linux/initrd.h> | 40 | #include <linux/initrd.h> |
41 | #include <linux/key.h> | 41 | #include <linux/key.h> |
42 | #include <linux/times.h> | 42 | #include <linux/times.h> |
43 | #include <linux/limits.h> | 43 | #include <linux/limits.h> |
44 | #include <linux/dcache.h> | 44 | #include <linux/dcache.h> |
45 | #include <linux/syscalls.h> | 45 | #include <linux/syscalls.h> |
46 | #include <linux/vmstat.h> | 46 | #include <linux/vmstat.h> |
47 | #include <linux/nfs_fs.h> | 47 | #include <linux/nfs_fs.h> |
48 | #include <linux/acpi.h> | 48 | #include <linux/acpi.h> |
49 | #include <linux/reboot.h> | 49 | #include <linux/reboot.h> |
50 | #include <linux/ftrace.h> | 50 | #include <linux/ftrace.h> |
51 | 51 | ||
52 | #include <asm/uaccess.h> | 52 | #include <asm/uaccess.h> |
53 | #include <asm/processor.h> | 53 | #include <asm/processor.h> |
54 | 54 | ||
55 | #ifdef CONFIG_X86 | 55 | #ifdef CONFIG_X86 |
56 | #include <asm/nmi.h> | 56 | #include <asm/nmi.h> |
57 | #include <asm/stacktrace.h> | 57 | #include <asm/stacktrace.h> |
58 | #include <asm/io.h> | 58 | #include <asm/io.h> |
59 | #endif | 59 | #endif |
60 | 60 | ||
61 | static int deprecated_sysctl_warning(struct __sysctl_args *args); | 61 | static int deprecated_sysctl_warning(struct __sysctl_args *args); |
62 | 62 | ||
63 | #if defined(CONFIG_SYSCTL) | 63 | #if defined(CONFIG_SYSCTL) |
64 | 64 | ||
65 | /* External variables not in a header file. */ | 65 | /* External variables not in a header file. */ |
66 | extern int C_A_D; | 66 | extern int C_A_D; |
67 | extern int print_fatal_signals; | 67 | extern int print_fatal_signals; |
68 | extern int sysctl_overcommit_memory; | 68 | extern int sysctl_overcommit_memory; |
69 | extern int sysctl_overcommit_ratio; | 69 | extern int sysctl_overcommit_ratio; |
70 | extern int sysctl_panic_on_oom; | 70 | extern int sysctl_panic_on_oom; |
71 | extern int sysctl_oom_kill_allocating_task; | 71 | extern int sysctl_oom_kill_allocating_task; |
72 | extern int sysctl_oom_dump_tasks; | 72 | extern int sysctl_oom_dump_tasks; |
73 | extern int max_threads; | 73 | extern int max_threads; |
74 | extern int core_uses_pid; | 74 | extern int core_uses_pid; |
75 | extern int suid_dumpable; | 75 | extern int suid_dumpable; |
76 | extern char core_pattern[]; | 76 | extern char core_pattern[]; |
77 | extern int pid_max; | 77 | extern int pid_max; |
78 | extern int min_free_kbytes; | 78 | extern int min_free_kbytes; |
79 | extern int pid_max_min, pid_max_max; | 79 | extern int pid_max_min, pid_max_max; |
80 | extern int sysctl_drop_caches; | 80 | extern int sysctl_drop_caches; |
81 | extern int percpu_pagelist_fraction; | 81 | extern int percpu_pagelist_fraction; |
82 | extern int compat_log; | 82 | extern int compat_log; |
83 | extern int latencytop_enabled; | 83 | extern int latencytop_enabled; |
84 | extern int sysctl_nr_open_min, sysctl_nr_open_max; | 84 | extern int sysctl_nr_open_min, sysctl_nr_open_max; |
85 | #ifndef CONFIG_MMU | 85 | #ifndef CONFIG_MMU |
86 | extern int sysctl_nr_trim_pages; | 86 | extern int sysctl_nr_trim_pages; |
87 | #endif | 87 | #endif |
88 | #ifdef CONFIG_RCU_TORTURE_TEST | 88 | #ifdef CONFIG_RCU_TORTURE_TEST |
89 | extern int rcutorture_runnable; | 89 | extern int rcutorture_runnable; |
90 | #endif /* #ifdef CONFIG_RCU_TORTURE_TEST */ | 90 | #endif /* #ifdef CONFIG_RCU_TORTURE_TEST */ |
91 | 91 | ||
92 | /* Constants used for minimum and maximum */ | 92 | /* Constants used for minimum and maximum */ |
93 | #ifdef CONFIG_DETECT_SOFTLOCKUP | 93 | #ifdef CONFIG_DETECT_SOFTLOCKUP |
94 | static int sixty = 60; | 94 | static int sixty = 60; |
95 | static int neg_one = -1; | 95 | static int neg_one = -1; |
96 | #endif | 96 | #endif |
97 | 97 | ||
98 | #if defined(CONFIG_MMU) && defined(CONFIG_FILE_LOCKING) | 98 | #if defined(CONFIG_MMU) && defined(CONFIG_FILE_LOCKING) |
99 | static int two = 2; | 99 | static int two = 2; |
100 | #endif | 100 | #endif |
101 | 101 | ||
102 | static int zero; | 102 | static int zero; |
103 | static int one = 1; | 103 | static int one = 1; |
104 | static int one_hundred = 100; | 104 | static int one_hundred = 100; |
105 | 105 | ||
106 | /* this is needed for the proc_dointvec_minmax for [fs_]overflow UID and GID */ | 106 | /* this is needed for the proc_dointvec_minmax for [fs_]overflow UID and GID */ |
107 | static int maxolduid = 65535; | 107 | static int maxolduid = 65535; |
108 | static int minolduid; | 108 | static int minolduid; |
109 | static int min_percpu_pagelist_fract = 8; | 109 | static int min_percpu_pagelist_fract = 8; |
110 | 110 | ||
111 | static int ngroups_max = NGROUPS_MAX; | 111 | static int ngroups_max = NGROUPS_MAX; |
112 | 112 | ||
113 | #ifdef CONFIG_MODULES | 113 | #ifdef CONFIG_MODULES |
114 | extern char modprobe_path[]; | 114 | extern char modprobe_path[]; |
115 | #endif | 115 | #endif |
116 | #ifdef CONFIG_CHR_DEV_SG | 116 | #ifdef CONFIG_CHR_DEV_SG |
117 | extern int sg_big_buff; | 117 | extern int sg_big_buff; |
118 | #endif | 118 | #endif |
119 | 119 | ||
120 | #ifdef CONFIG_SPARC | 120 | #ifdef CONFIG_SPARC |
121 | #include <asm/system.h> | 121 | #include <asm/system.h> |
122 | #endif | 122 | #endif |
123 | 123 | ||
124 | #ifdef CONFIG_SPARC64 | 124 | #ifdef CONFIG_SPARC64 |
125 | extern int sysctl_tsb_ratio; | 125 | extern int sysctl_tsb_ratio; |
126 | #endif | 126 | #endif |
127 | 127 | ||
128 | #ifdef __hppa__ | 128 | #ifdef __hppa__ |
129 | extern int pwrsw_enabled; | 129 | extern int pwrsw_enabled; |
130 | extern int unaligned_enabled; | 130 | extern int unaligned_enabled; |
131 | #endif | 131 | #endif |
132 | 132 | ||
133 | #ifdef CONFIG_S390 | 133 | #ifdef CONFIG_S390 |
134 | #ifdef CONFIG_MATHEMU | 134 | #ifdef CONFIG_MATHEMU |
135 | extern int sysctl_ieee_emulation_warnings; | 135 | extern int sysctl_ieee_emulation_warnings; |
136 | #endif | 136 | #endif |
137 | extern int sysctl_userprocess_debug; | 137 | extern int sysctl_userprocess_debug; |
138 | extern int spin_retry; | 138 | extern int spin_retry; |
139 | #endif | 139 | #endif |
140 | 140 | ||
141 | #ifdef CONFIG_BSD_PROCESS_ACCT | 141 | #ifdef CONFIG_BSD_PROCESS_ACCT |
142 | extern int acct_parm[]; | 142 | extern int acct_parm[]; |
143 | #endif | 143 | #endif |
144 | 144 | ||
145 | #ifdef CONFIG_IA64 | 145 | #ifdef CONFIG_IA64 |
146 | extern int no_unaligned_warning; | 146 | extern int no_unaligned_warning; |
147 | #endif | 147 | #endif |
148 | 148 | ||
149 | #ifdef CONFIG_RT_MUTEXES | 149 | #ifdef CONFIG_RT_MUTEXES |
150 | extern int max_lock_depth; | 150 | extern int max_lock_depth; |
151 | #endif | 151 | #endif |
152 | 152 | ||
153 | #ifdef CONFIG_PROC_SYSCTL | 153 | #ifdef CONFIG_PROC_SYSCTL |
154 | static int proc_do_cad_pid(struct ctl_table *table, int write, struct file *filp, | 154 | static int proc_do_cad_pid(struct ctl_table *table, int write, struct file *filp, |
155 | void __user *buffer, size_t *lenp, loff_t *ppos); | 155 | void __user *buffer, size_t *lenp, loff_t *ppos); |
156 | static int proc_taint(struct ctl_table *table, int write, struct file *filp, | 156 | static int proc_taint(struct ctl_table *table, int write, struct file *filp, |
157 | void __user *buffer, size_t *lenp, loff_t *ppos); | 157 | void __user *buffer, size_t *lenp, loff_t *ppos); |
158 | #endif | 158 | #endif |
159 | 159 | ||
160 | static struct ctl_table root_table[]; | 160 | static struct ctl_table root_table[]; |
161 | static struct ctl_table_root sysctl_table_root; | 161 | static struct ctl_table_root sysctl_table_root; |
162 | static struct ctl_table_header root_table_header = { | 162 | static struct ctl_table_header root_table_header = { |
163 | .count = 1, | 163 | .count = 1, |
164 | .ctl_table = root_table, | 164 | .ctl_table = root_table, |
165 | .ctl_entry = LIST_HEAD_INIT(sysctl_table_root.default_set.list), | 165 | .ctl_entry = LIST_HEAD_INIT(sysctl_table_root.default_set.list), |
166 | .root = &sysctl_table_root, | 166 | .root = &sysctl_table_root, |
167 | .set = &sysctl_table_root.default_set, | 167 | .set = &sysctl_table_root.default_set, |
168 | }; | 168 | }; |
169 | static struct ctl_table_root sysctl_table_root = { | 169 | static struct ctl_table_root sysctl_table_root = { |
170 | .root_list = LIST_HEAD_INIT(sysctl_table_root.root_list), | 170 | .root_list = LIST_HEAD_INIT(sysctl_table_root.root_list), |
171 | .default_set.list = LIST_HEAD_INIT(root_table_header.ctl_entry), | 171 | .default_set.list = LIST_HEAD_INIT(root_table_header.ctl_entry), |
172 | }; | 172 | }; |
173 | 173 | ||
174 | static struct ctl_table kern_table[]; | 174 | static struct ctl_table kern_table[]; |
175 | static struct ctl_table vm_table[]; | 175 | static struct ctl_table vm_table[]; |
176 | static struct ctl_table fs_table[]; | 176 | static struct ctl_table fs_table[]; |
177 | static struct ctl_table debug_table[]; | 177 | static struct ctl_table debug_table[]; |
178 | static struct ctl_table dev_table[]; | 178 | static struct ctl_table dev_table[]; |
179 | extern struct ctl_table random_table[]; | 179 | extern struct ctl_table random_table[]; |
180 | #ifdef CONFIG_INOTIFY_USER | 180 | #ifdef CONFIG_INOTIFY_USER |
181 | extern struct ctl_table inotify_table[]; | 181 | extern struct ctl_table inotify_table[]; |
182 | #endif | 182 | #endif |
183 | #ifdef CONFIG_EPOLL | 183 | #ifdef CONFIG_EPOLL |
184 | extern struct ctl_table epoll_table[]; | 184 | extern struct ctl_table epoll_table[]; |
185 | #endif | 185 | #endif |
186 | 186 | ||
187 | #ifdef HAVE_ARCH_PICK_MMAP_LAYOUT | 187 | #ifdef HAVE_ARCH_PICK_MMAP_LAYOUT |
188 | int sysctl_legacy_va_layout; | 188 | int sysctl_legacy_va_layout; |
189 | #endif | 189 | #endif |
190 | 190 | ||
191 | extern int prove_locking; | 191 | extern int prove_locking; |
192 | extern int lock_stat; | 192 | extern int lock_stat; |
193 | 193 | ||
194 | /* The default sysctl tables: */ | 194 | /* The default sysctl tables: */ |
195 | 195 | ||
196 | static struct ctl_table root_table[] = { | 196 | static struct ctl_table root_table[] = { |
197 | { | 197 | { |
198 | .ctl_name = CTL_KERN, | 198 | .ctl_name = CTL_KERN, |
199 | .procname = "kernel", | 199 | .procname = "kernel", |
200 | .mode = 0555, | 200 | .mode = 0555, |
201 | .child = kern_table, | 201 | .child = kern_table, |
202 | }, | 202 | }, |
203 | { | 203 | { |
204 | .ctl_name = CTL_VM, | 204 | .ctl_name = CTL_VM, |
205 | .procname = "vm", | 205 | .procname = "vm", |
206 | .mode = 0555, | 206 | .mode = 0555, |
207 | .child = vm_table, | 207 | .child = vm_table, |
208 | }, | 208 | }, |
209 | { | 209 | { |
210 | .ctl_name = CTL_FS, | 210 | .ctl_name = CTL_FS, |
211 | .procname = "fs", | 211 | .procname = "fs", |
212 | .mode = 0555, | 212 | .mode = 0555, |
213 | .child = fs_table, | 213 | .child = fs_table, |
214 | }, | 214 | }, |
215 | { | 215 | { |
216 | .ctl_name = CTL_DEBUG, | 216 | .ctl_name = CTL_DEBUG, |
217 | .procname = "debug", | 217 | .procname = "debug", |
218 | .mode = 0555, | 218 | .mode = 0555, |
219 | .child = debug_table, | 219 | .child = debug_table, |
220 | }, | 220 | }, |
221 | { | 221 | { |
222 | .ctl_name = CTL_DEV, | 222 | .ctl_name = CTL_DEV, |
223 | .procname = "dev", | 223 | .procname = "dev", |
224 | .mode = 0555, | 224 | .mode = 0555, |
225 | .child = dev_table, | 225 | .child = dev_table, |
226 | }, | 226 | }, |
227 | /* | 227 | /* |
228 | * NOTE: do not add new entries to this table unless you have read | 228 | * NOTE: do not add new entries to this table unless you have read |
229 | * Documentation/sysctl/ctl_unnumbered.txt | 229 | * Documentation/sysctl/ctl_unnumbered.txt |
230 | */ | 230 | */ |
231 | { .ctl_name = 0 } | 231 | { .ctl_name = 0 } |
232 | }; | 232 | }; |
233 | 233 | ||
234 | #ifdef CONFIG_SCHED_DEBUG | 234 | #ifdef CONFIG_SCHED_DEBUG |
235 | static int min_sched_granularity_ns = 100000; /* 100 usecs */ | 235 | static int min_sched_granularity_ns = 100000; /* 100 usecs */ |
236 | static int max_sched_granularity_ns = NSEC_PER_SEC; /* 1 second */ | 236 | static int max_sched_granularity_ns = NSEC_PER_SEC; /* 1 second */ |
237 | static int min_wakeup_granularity_ns; /* 0 usecs */ | 237 | static int min_wakeup_granularity_ns; /* 0 usecs */ |
238 | static int max_wakeup_granularity_ns = NSEC_PER_SEC; /* 1 second */ | 238 | static int max_wakeup_granularity_ns = NSEC_PER_SEC; /* 1 second */ |
239 | #endif | 239 | #endif |
240 | 240 | ||
241 | static struct ctl_table kern_table[] = { | 241 | static struct ctl_table kern_table[] = { |
242 | #ifdef CONFIG_SCHED_DEBUG | 242 | #ifdef CONFIG_SCHED_DEBUG |
243 | { | 243 | { |
244 | .ctl_name = CTL_UNNUMBERED, | 244 | .ctl_name = CTL_UNNUMBERED, |
245 | .procname = "sched_min_granularity_ns", | 245 | .procname = "sched_min_granularity_ns", |
246 | .data = &sysctl_sched_min_granularity, | 246 | .data = &sysctl_sched_min_granularity, |
247 | .maxlen = sizeof(unsigned int), | 247 | .maxlen = sizeof(unsigned int), |
248 | .mode = 0644, | 248 | .mode = 0644, |
249 | .proc_handler = &sched_nr_latency_handler, | 249 | .proc_handler = &sched_nr_latency_handler, |
250 | .strategy = &sysctl_intvec, | 250 | .strategy = &sysctl_intvec, |
251 | .extra1 = &min_sched_granularity_ns, | 251 | .extra1 = &min_sched_granularity_ns, |
252 | .extra2 = &max_sched_granularity_ns, | 252 | .extra2 = &max_sched_granularity_ns, |
253 | }, | 253 | }, |
254 | { | 254 | { |
255 | .ctl_name = CTL_UNNUMBERED, | 255 | .ctl_name = CTL_UNNUMBERED, |
256 | .procname = "sched_latency_ns", | 256 | .procname = "sched_latency_ns", |
257 | .data = &sysctl_sched_latency, | 257 | .data = &sysctl_sched_latency, |
258 | .maxlen = sizeof(unsigned int), | 258 | .maxlen = sizeof(unsigned int), |
259 | .mode = 0644, | 259 | .mode = 0644, |
260 | .proc_handler = &sched_nr_latency_handler, | 260 | .proc_handler = &sched_nr_latency_handler, |
261 | .strategy = &sysctl_intvec, | 261 | .strategy = &sysctl_intvec, |
262 | .extra1 = &min_sched_granularity_ns, | 262 | .extra1 = &min_sched_granularity_ns, |
263 | .extra2 = &max_sched_granularity_ns, | 263 | .extra2 = &max_sched_granularity_ns, |
264 | }, | 264 | }, |
265 | { | 265 | { |
266 | .ctl_name = CTL_UNNUMBERED, | 266 | .ctl_name = CTL_UNNUMBERED, |
267 | .procname = "sched_wakeup_granularity_ns", | 267 | .procname = "sched_wakeup_granularity_ns", |
268 | .data = &sysctl_sched_wakeup_granularity, | 268 | .data = &sysctl_sched_wakeup_granularity, |
269 | .maxlen = sizeof(unsigned int), | 269 | .maxlen = sizeof(unsigned int), |
270 | .mode = 0644, | 270 | .mode = 0644, |
271 | .proc_handler = &proc_dointvec_minmax, | 271 | .proc_handler = &proc_dointvec_minmax, |
272 | .strategy = &sysctl_intvec, | 272 | .strategy = &sysctl_intvec, |
273 | .extra1 = &min_wakeup_granularity_ns, | 273 | .extra1 = &min_wakeup_granularity_ns, |
274 | .extra2 = &max_wakeup_granularity_ns, | 274 | .extra2 = &max_wakeup_granularity_ns, |
275 | }, | 275 | }, |
276 | { | 276 | { |
277 | .ctl_name = CTL_UNNUMBERED, | 277 | .ctl_name = CTL_UNNUMBERED, |
278 | .procname = "sched_shares_ratelimit", | 278 | .procname = "sched_shares_ratelimit", |
279 | .data = &sysctl_sched_shares_ratelimit, | 279 | .data = &sysctl_sched_shares_ratelimit, |
280 | .maxlen = sizeof(unsigned int), | 280 | .maxlen = sizeof(unsigned int), |
281 | .mode = 0644, | 281 | .mode = 0644, |
282 | .proc_handler = &proc_dointvec, | 282 | .proc_handler = &proc_dointvec, |
283 | }, | 283 | }, |
284 | { | 284 | { |
285 | .ctl_name = CTL_UNNUMBERED, | 285 | .ctl_name = CTL_UNNUMBERED, |
286 | .procname = "sched_shares_thresh", | 286 | .procname = "sched_shares_thresh", |
287 | .data = &sysctl_sched_shares_thresh, | 287 | .data = &sysctl_sched_shares_thresh, |
288 | .maxlen = sizeof(unsigned int), | 288 | .maxlen = sizeof(unsigned int), |
289 | .mode = 0644, | 289 | .mode = 0644, |
290 | .proc_handler = &proc_dointvec_minmax, | 290 | .proc_handler = &proc_dointvec_minmax, |
291 | .strategy = &sysctl_intvec, | 291 | .strategy = &sysctl_intvec, |
292 | .extra1 = &zero, | 292 | .extra1 = &zero, |
293 | }, | 293 | }, |
294 | { | 294 | { |
295 | .ctl_name = CTL_UNNUMBERED, | 295 | .ctl_name = CTL_UNNUMBERED, |
296 | .procname = "sched_child_runs_first", | 296 | .procname = "sched_child_runs_first", |
297 | .data = &sysctl_sched_child_runs_first, | 297 | .data = &sysctl_sched_child_runs_first, |
298 | .maxlen = sizeof(unsigned int), | 298 | .maxlen = sizeof(unsigned int), |
299 | .mode = 0644, | 299 | .mode = 0644, |
300 | .proc_handler = &proc_dointvec, | 300 | .proc_handler = &proc_dointvec, |
301 | }, | 301 | }, |
302 | { | 302 | { |
303 | .ctl_name = CTL_UNNUMBERED, | 303 | .ctl_name = CTL_UNNUMBERED, |
304 | .procname = "sched_features", | 304 | .procname = "sched_features", |
305 | .data = &sysctl_sched_features, | 305 | .data = &sysctl_sched_features, |
306 | .maxlen = sizeof(unsigned int), | 306 | .maxlen = sizeof(unsigned int), |
307 | .mode = 0644, | 307 | .mode = 0644, |
308 | .proc_handler = &proc_dointvec, | 308 | .proc_handler = &proc_dointvec, |
309 | }, | 309 | }, |
310 | { | 310 | { |
311 | .ctl_name = CTL_UNNUMBERED, | 311 | .ctl_name = CTL_UNNUMBERED, |
312 | .procname = "sched_migration_cost", | 312 | .procname = "sched_migration_cost", |
313 | .data = &sysctl_sched_migration_cost, | 313 | .data = &sysctl_sched_migration_cost, |
314 | .maxlen = sizeof(unsigned int), | 314 | .maxlen = sizeof(unsigned int), |
315 | .mode = 0644, | 315 | .mode = 0644, |
316 | .proc_handler = &proc_dointvec, | 316 | .proc_handler = &proc_dointvec, |
317 | }, | 317 | }, |
318 | { | 318 | { |
319 | .ctl_name = CTL_UNNUMBERED, | 319 | .ctl_name = CTL_UNNUMBERED, |
320 | .procname = "sched_nr_migrate", | 320 | .procname = "sched_nr_migrate", |
321 | .data = &sysctl_sched_nr_migrate, | 321 | .data = &sysctl_sched_nr_migrate, |
322 | .maxlen = sizeof(unsigned int), | 322 | .maxlen = sizeof(unsigned int), |
323 | .mode = 0644, | 323 | .mode = 0644, |
324 | .proc_handler = &proc_dointvec, | 324 | .proc_handler = &proc_dointvec, |
325 | }, | 325 | }, |
326 | #endif | 326 | #endif |
327 | { | 327 | { |
328 | .ctl_name = CTL_UNNUMBERED, | 328 | .ctl_name = CTL_UNNUMBERED, |
329 | .procname = "sched_rt_period_us", | 329 | .procname = "sched_rt_period_us", |
330 | .data = &sysctl_sched_rt_period, | 330 | .data = &sysctl_sched_rt_period, |
331 | .maxlen = sizeof(unsigned int), | 331 | .maxlen = sizeof(unsigned int), |
332 | .mode = 0644, | 332 | .mode = 0644, |
333 | .proc_handler = &sched_rt_handler, | 333 | .proc_handler = &sched_rt_handler, |
334 | }, | 334 | }, |
335 | { | 335 | { |
336 | .ctl_name = CTL_UNNUMBERED, | 336 | .ctl_name = CTL_UNNUMBERED, |
337 | .procname = "sched_rt_runtime_us", | 337 | .procname = "sched_rt_runtime_us", |
338 | .data = &sysctl_sched_rt_runtime, | 338 | .data = &sysctl_sched_rt_runtime, |
339 | .maxlen = sizeof(int), | 339 | .maxlen = sizeof(int), |
340 | .mode = 0644, | 340 | .mode = 0644, |
341 | .proc_handler = &sched_rt_handler, | 341 | .proc_handler = &sched_rt_handler, |
342 | }, | 342 | }, |
343 | { | 343 | { |
344 | .ctl_name = CTL_UNNUMBERED, | 344 | .ctl_name = CTL_UNNUMBERED, |
345 | .procname = "sched_compat_yield", | 345 | .procname = "sched_compat_yield", |
346 | .data = &sysctl_sched_compat_yield, | 346 | .data = &sysctl_sched_compat_yield, |
347 | .maxlen = sizeof(unsigned int), | 347 | .maxlen = sizeof(unsigned int), |
348 | .mode = 0644, | 348 | .mode = 0644, |
349 | .proc_handler = &proc_dointvec, | 349 | .proc_handler = &proc_dointvec, |
350 | }, | 350 | }, |
351 | #ifdef CONFIG_PROVE_LOCKING | 351 | #ifdef CONFIG_PROVE_LOCKING |
352 | { | 352 | { |
353 | .ctl_name = CTL_UNNUMBERED, | 353 | .ctl_name = CTL_UNNUMBERED, |
354 | .procname = "prove_locking", | 354 | .procname = "prove_locking", |
355 | .data = &prove_locking, | 355 | .data = &prove_locking, |
356 | .maxlen = sizeof(int), | 356 | .maxlen = sizeof(int), |
357 | .mode = 0644, | 357 | .mode = 0644, |
358 | .proc_handler = &proc_dointvec, | 358 | .proc_handler = &proc_dointvec, |
359 | }, | 359 | }, |
360 | #endif | 360 | #endif |
361 | #ifdef CONFIG_LOCK_STAT | 361 | #ifdef CONFIG_LOCK_STAT |
362 | { | 362 | { |
363 | .ctl_name = CTL_UNNUMBERED, | 363 | .ctl_name = CTL_UNNUMBERED, |
364 | .procname = "lock_stat", | 364 | .procname = "lock_stat", |
365 | .data = &lock_stat, | 365 | .data = &lock_stat, |
366 | .maxlen = sizeof(int), | 366 | .maxlen = sizeof(int), |
367 | .mode = 0644, | 367 | .mode = 0644, |
368 | .proc_handler = &proc_dointvec, | 368 | .proc_handler = &proc_dointvec, |
369 | }, | 369 | }, |
370 | #endif | 370 | #endif |
371 | { | 371 | { |
372 | .ctl_name = KERN_PANIC, | 372 | .ctl_name = KERN_PANIC, |
373 | .procname = "panic", | 373 | .procname = "panic", |
374 | .data = &panic_timeout, | 374 | .data = &panic_timeout, |
375 | .maxlen = sizeof(int), | 375 | .maxlen = sizeof(int), |
376 | .mode = 0644, | 376 | .mode = 0644, |
377 | .proc_handler = &proc_dointvec, | 377 | .proc_handler = &proc_dointvec, |
378 | }, | 378 | }, |
379 | { | 379 | { |
380 | .ctl_name = KERN_CORE_USES_PID, | 380 | .ctl_name = KERN_CORE_USES_PID, |
381 | .procname = "core_uses_pid", | 381 | .procname = "core_uses_pid", |
382 | .data = &core_uses_pid, | 382 | .data = &core_uses_pid, |
383 | .maxlen = sizeof(int), | 383 | .maxlen = sizeof(int), |
384 | .mode = 0644, | 384 | .mode = 0644, |
385 | .proc_handler = &proc_dointvec, | 385 | .proc_handler = &proc_dointvec, |
386 | }, | 386 | }, |
387 | { | 387 | { |
388 | .ctl_name = KERN_CORE_PATTERN, | 388 | .ctl_name = KERN_CORE_PATTERN, |
389 | .procname = "core_pattern", | 389 | .procname = "core_pattern", |
390 | .data = core_pattern, | 390 | .data = core_pattern, |
391 | .maxlen = CORENAME_MAX_SIZE, | 391 | .maxlen = CORENAME_MAX_SIZE, |
392 | .mode = 0644, | 392 | .mode = 0644, |
393 | .proc_handler = &proc_dostring, | 393 | .proc_handler = &proc_dostring, |
394 | .strategy = &sysctl_string, | 394 | .strategy = &sysctl_string, |
395 | }, | 395 | }, |
396 | #ifdef CONFIG_PROC_SYSCTL | 396 | #ifdef CONFIG_PROC_SYSCTL |
397 | { | 397 | { |
398 | .procname = "tainted", | 398 | .procname = "tainted", |
399 | .maxlen = sizeof(long), | 399 | .maxlen = sizeof(long), |
400 | .mode = 0644, | 400 | .mode = 0644, |
401 | .proc_handler = &proc_taint, | 401 | .proc_handler = &proc_taint, |
402 | }, | 402 | }, |
403 | #endif | 403 | #endif |
404 | #ifdef CONFIG_LATENCYTOP | 404 | #ifdef CONFIG_LATENCYTOP |
405 | { | 405 | { |
406 | .procname = "latencytop", | 406 | .procname = "latencytop", |
407 | .data = &latencytop_enabled, | 407 | .data = &latencytop_enabled, |
408 | .maxlen = sizeof(int), | 408 | .maxlen = sizeof(int), |
409 | .mode = 0644, | 409 | .mode = 0644, |
410 | .proc_handler = &proc_dointvec, | 410 | .proc_handler = &proc_dointvec, |
411 | }, | 411 | }, |
412 | #endif | 412 | #endif |
413 | #ifdef CONFIG_BLK_DEV_INITRD | 413 | #ifdef CONFIG_BLK_DEV_INITRD |
414 | { | 414 | { |
415 | .ctl_name = KERN_REALROOTDEV, | 415 | .ctl_name = KERN_REALROOTDEV, |
416 | .procname = "real-root-dev", | 416 | .procname = "real-root-dev", |
417 | .data = &real_root_dev, | 417 | .data = &real_root_dev, |
418 | .maxlen = sizeof(int), | 418 | .maxlen = sizeof(int), |
419 | .mode = 0644, | 419 | .mode = 0644, |
420 | .proc_handler = &proc_dointvec, | 420 | .proc_handler = &proc_dointvec, |
421 | }, | 421 | }, |
422 | #endif | 422 | #endif |
423 | { | 423 | { |
424 | .ctl_name = CTL_UNNUMBERED, | 424 | .ctl_name = CTL_UNNUMBERED, |
425 | .procname = "print-fatal-signals", | 425 | .procname = "print-fatal-signals", |
426 | .data = &print_fatal_signals, | 426 | .data = &print_fatal_signals, |
427 | .maxlen = sizeof(int), | 427 | .maxlen = sizeof(int), |
428 | .mode = 0644, | 428 | .mode = 0644, |
429 | .proc_handler = &proc_dointvec, | 429 | .proc_handler = &proc_dointvec, |
430 | }, | 430 | }, |
431 | #ifdef CONFIG_SPARC | 431 | #ifdef CONFIG_SPARC |
432 | { | 432 | { |
433 | .ctl_name = KERN_SPARC_REBOOT, | 433 | .ctl_name = KERN_SPARC_REBOOT, |
434 | .procname = "reboot-cmd", | 434 | .procname = "reboot-cmd", |
435 | .data = reboot_command, | 435 | .data = reboot_command, |
436 | .maxlen = 256, | 436 | .maxlen = 256, |
437 | .mode = 0644, | 437 | .mode = 0644, |
438 | .proc_handler = &proc_dostring, | 438 | .proc_handler = &proc_dostring, |
439 | .strategy = &sysctl_string, | 439 | .strategy = &sysctl_string, |
440 | }, | 440 | }, |
441 | { | 441 | { |
442 | .ctl_name = KERN_SPARC_STOP_A, | 442 | .ctl_name = KERN_SPARC_STOP_A, |
443 | .procname = "stop-a", | 443 | .procname = "stop-a", |
444 | .data = &stop_a_enabled, | 444 | .data = &stop_a_enabled, |
445 | .maxlen = sizeof (int), | 445 | .maxlen = sizeof (int), |
446 | .mode = 0644, | 446 | .mode = 0644, |
447 | .proc_handler = &proc_dointvec, | 447 | .proc_handler = &proc_dointvec, |
448 | }, | 448 | }, |
449 | { | 449 | { |
450 | .ctl_name = KERN_SPARC_SCONS_PWROFF, | 450 | .ctl_name = KERN_SPARC_SCONS_PWROFF, |
451 | .procname = "scons-poweroff", | 451 | .procname = "scons-poweroff", |
452 | .data = &scons_pwroff, | 452 | .data = &scons_pwroff, |
453 | .maxlen = sizeof (int), | 453 | .maxlen = sizeof (int), |
454 | .mode = 0644, | 454 | .mode = 0644, |
455 | .proc_handler = &proc_dointvec, | 455 | .proc_handler = &proc_dointvec, |
456 | }, | 456 | }, |
457 | #endif | 457 | #endif |
458 | #ifdef CONFIG_SPARC64 | 458 | #ifdef CONFIG_SPARC64 |
459 | { | 459 | { |
460 | .ctl_name = CTL_UNNUMBERED, | 460 | .ctl_name = CTL_UNNUMBERED, |
461 | .procname = "tsb-ratio", | 461 | .procname = "tsb-ratio", |
462 | .data = &sysctl_tsb_ratio, | 462 | .data = &sysctl_tsb_ratio, |
463 | .maxlen = sizeof (int), | 463 | .maxlen = sizeof (int), |
464 | .mode = 0644, | 464 | .mode = 0644, |
465 | .proc_handler = &proc_dointvec, | 465 | .proc_handler = &proc_dointvec, |
466 | }, | 466 | }, |
467 | #endif | 467 | #endif |
468 | #ifdef __hppa__ | 468 | #ifdef __hppa__ |
469 | { | 469 | { |
470 | .ctl_name = KERN_HPPA_PWRSW, | 470 | .ctl_name = KERN_HPPA_PWRSW, |
471 | .procname = "soft-power", | 471 | .procname = "soft-power", |
472 | .data = &pwrsw_enabled, | 472 | .data = &pwrsw_enabled, |
473 | .maxlen = sizeof (int), | 473 | .maxlen = sizeof (int), |
474 | .mode = 0644, | 474 | .mode = 0644, |
475 | .proc_handler = &proc_dointvec, | 475 | .proc_handler = &proc_dointvec, |
476 | }, | 476 | }, |
477 | { | 477 | { |
478 | .ctl_name = KERN_HPPA_UNALIGNED, | 478 | .ctl_name = KERN_HPPA_UNALIGNED, |
479 | .procname = "unaligned-trap", | 479 | .procname = "unaligned-trap", |
480 | .data = &unaligned_enabled, | 480 | .data = &unaligned_enabled, |
481 | .maxlen = sizeof (int), | 481 | .maxlen = sizeof (int), |
482 | .mode = 0644, | 482 | .mode = 0644, |
483 | .proc_handler = &proc_dointvec, | 483 | .proc_handler = &proc_dointvec, |
484 | }, | 484 | }, |
485 | #endif | 485 | #endif |
486 | { | 486 | { |
487 | .ctl_name = KERN_CTLALTDEL, | 487 | .ctl_name = KERN_CTLALTDEL, |
488 | .procname = "ctrl-alt-del", | 488 | .procname = "ctrl-alt-del", |
489 | .data = &C_A_D, | 489 | .data = &C_A_D, |
490 | .maxlen = sizeof(int), | 490 | .maxlen = sizeof(int), |
491 | .mode = 0644, | 491 | .mode = 0644, |
492 | .proc_handler = &proc_dointvec, | 492 | .proc_handler = &proc_dointvec, |
493 | }, | 493 | }, |
494 | #ifdef CONFIG_FUNCTION_TRACER | 494 | #ifdef CONFIG_FUNCTION_TRACER |
495 | { | 495 | { |
496 | .ctl_name = CTL_UNNUMBERED, | 496 | .ctl_name = CTL_UNNUMBERED, |
497 | .procname = "ftrace_enabled", | 497 | .procname = "ftrace_enabled", |
498 | .data = &ftrace_enabled, | 498 | .data = &ftrace_enabled, |
499 | .maxlen = sizeof(int), | 499 | .maxlen = sizeof(int), |
500 | .mode = 0644, | 500 | .mode = 0644, |
501 | .proc_handler = &ftrace_enable_sysctl, | 501 | .proc_handler = &ftrace_enable_sysctl, |
502 | }, | 502 | }, |
503 | #endif | 503 | #endif |
504 | #ifdef CONFIG_STACK_TRACER | 504 | #ifdef CONFIG_STACK_TRACER |
505 | { | 505 | { |
506 | .ctl_name = CTL_UNNUMBERED, | 506 | .ctl_name = CTL_UNNUMBERED, |
507 | .procname = "stack_tracer_enabled", | 507 | .procname = "stack_tracer_enabled", |
508 | .data = &stack_tracer_enabled, | 508 | .data = &stack_tracer_enabled, |
509 | .maxlen = sizeof(int), | 509 | .maxlen = sizeof(int), |
510 | .mode = 0644, | 510 | .mode = 0644, |
511 | .proc_handler = &stack_trace_sysctl, | 511 | .proc_handler = &stack_trace_sysctl, |
512 | }, | 512 | }, |
513 | #endif | 513 | #endif |
514 | #ifdef CONFIG_TRACING | 514 | #ifdef CONFIG_TRACING |
515 | { | 515 | { |
516 | .ctl_name = CTL_UNNUMBERED, | 516 | .ctl_name = CTL_UNNUMBERED, |
517 | .procname = "ftrace_dump_on_oops", | 517 | .procname = "ftrace_dump_on_oops", |
518 | .data = &ftrace_dump_on_oops, | 518 | .data = &ftrace_dump_on_oops, |
519 | .maxlen = sizeof(int), | 519 | .maxlen = sizeof(int), |
520 | .mode = 0644, | 520 | .mode = 0644, |
521 | .proc_handler = &proc_dointvec, | 521 | .proc_handler = &proc_dointvec, |
522 | }, | 522 | }, |
523 | #endif | 523 | #endif |
524 | #ifdef CONFIG_MODULES | 524 | #ifdef CONFIG_MODULES |
525 | { | 525 | { |
526 | .ctl_name = KERN_MODPROBE, | 526 | .ctl_name = KERN_MODPROBE, |
527 | .procname = "modprobe", | 527 | .procname = "modprobe", |
528 | .data = &modprobe_path, | 528 | .data = &modprobe_path, |
529 | .maxlen = KMOD_PATH_LEN, | 529 | .maxlen = KMOD_PATH_LEN, |
530 | .mode = 0644, | 530 | .mode = 0644, |
531 | .proc_handler = &proc_dostring, | 531 | .proc_handler = &proc_dostring, |
532 | .strategy = &sysctl_string, | 532 | .strategy = &sysctl_string, |
533 | }, | 533 | }, |
534 | #endif | 534 | #endif |
535 | #if defined(CONFIG_HOTPLUG) && defined(CONFIG_NET) | 535 | #if defined(CONFIG_HOTPLUG) && defined(CONFIG_NET) |
536 | { | 536 | { |
537 | .ctl_name = KERN_HOTPLUG, | 537 | .ctl_name = KERN_HOTPLUG, |
538 | .procname = "hotplug", | 538 | .procname = "hotplug", |
539 | .data = &uevent_helper, | 539 | .data = &uevent_helper, |
540 | .maxlen = UEVENT_HELPER_PATH_LEN, | 540 | .maxlen = UEVENT_HELPER_PATH_LEN, |
541 | .mode = 0644, | 541 | .mode = 0644, |
542 | .proc_handler = &proc_dostring, | 542 | .proc_handler = &proc_dostring, |
543 | .strategy = &sysctl_string, | 543 | .strategy = &sysctl_string, |
544 | }, | 544 | }, |
545 | #endif | 545 | #endif |
546 | #ifdef CONFIG_CHR_DEV_SG | 546 | #ifdef CONFIG_CHR_DEV_SG |
547 | { | 547 | { |
548 | .ctl_name = KERN_SG_BIG_BUFF, | 548 | .ctl_name = KERN_SG_BIG_BUFF, |
549 | .procname = "sg-big-buff", | 549 | .procname = "sg-big-buff", |
550 | .data = &sg_big_buff, | 550 | .data = &sg_big_buff, |
551 | .maxlen = sizeof (int), | 551 | .maxlen = sizeof (int), |
552 | .mode = 0444, | 552 | .mode = 0444, |
553 | .proc_handler = &proc_dointvec, | 553 | .proc_handler = &proc_dointvec, |
554 | }, | 554 | }, |
555 | #endif | 555 | #endif |
556 | #ifdef CONFIG_BSD_PROCESS_ACCT | 556 | #ifdef CONFIG_BSD_PROCESS_ACCT |
557 | { | 557 | { |
558 | .ctl_name = KERN_ACCT, | 558 | .ctl_name = KERN_ACCT, |
559 | .procname = "acct", | 559 | .procname = "acct", |
560 | .data = &acct_parm, | 560 | .data = &acct_parm, |
561 | .maxlen = 3*sizeof(int), | 561 | .maxlen = 3*sizeof(int), |
562 | .mode = 0644, | 562 | .mode = 0644, |
563 | .proc_handler = &proc_dointvec, | 563 | .proc_handler = &proc_dointvec, |
564 | }, | 564 | }, |
565 | #endif | 565 | #endif |
566 | #ifdef CONFIG_MAGIC_SYSRQ | 566 | #ifdef CONFIG_MAGIC_SYSRQ |
567 | { | 567 | { |
568 | .ctl_name = KERN_SYSRQ, | 568 | .ctl_name = KERN_SYSRQ, |
569 | .procname = "sysrq", | 569 | .procname = "sysrq", |
570 | .data = &__sysrq_enabled, | 570 | .data = &__sysrq_enabled, |
571 | .maxlen = sizeof (int), | 571 | .maxlen = sizeof (int), |
572 | .mode = 0644, | 572 | .mode = 0644, |
573 | .proc_handler = &proc_dointvec, | 573 | .proc_handler = &proc_dointvec, |
574 | }, | 574 | }, |
575 | #endif | 575 | #endif |
576 | #ifdef CONFIG_PROC_SYSCTL | 576 | #ifdef CONFIG_PROC_SYSCTL |
577 | { | 577 | { |
578 | .procname = "cad_pid", | 578 | .procname = "cad_pid", |
579 | .data = NULL, | 579 | .data = NULL, |
580 | .maxlen = sizeof (int), | 580 | .maxlen = sizeof (int), |
581 | .mode = 0600, | 581 | .mode = 0600, |
582 | .proc_handler = &proc_do_cad_pid, | 582 | .proc_handler = &proc_do_cad_pid, |
583 | }, | 583 | }, |
584 | #endif | 584 | #endif |
585 | { | 585 | { |
586 | .ctl_name = KERN_MAX_THREADS, | 586 | .ctl_name = KERN_MAX_THREADS, |
587 | .procname = "threads-max", | 587 | .procname = "threads-max", |
588 | .data = &max_threads, | 588 | .data = &max_threads, |
589 | .maxlen = sizeof(int), | 589 | .maxlen = sizeof(int), |
590 | .mode = 0644, | 590 | .mode = 0644, |
591 | .proc_handler = &proc_dointvec, | 591 | .proc_handler = &proc_dointvec, |
592 | }, | 592 | }, |
593 | { | 593 | { |
594 | .ctl_name = KERN_RANDOM, | 594 | .ctl_name = KERN_RANDOM, |
595 | .procname = "random", | 595 | .procname = "random", |
596 | .mode = 0555, | 596 | .mode = 0555, |
597 | .child = random_table, | 597 | .child = random_table, |
598 | }, | 598 | }, |
599 | { | 599 | { |
600 | .ctl_name = KERN_OVERFLOWUID, | 600 | .ctl_name = KERN_OVERFLOWUID, |
601 | .procname = "overflowuid", | 601 | .procname = "overflowuid", |
602 | .data = &overflowuid, | 602 | .data = &overflowuid, |
603 | .maxlen = sizeof(int), | 603 | .maxlen = sizeof(int), |
604 | .mode = 0644, | 604 | .mode = 0644, |
605 | .proc_handler = &proc_dointvec_minmax, | 605 | .proc_handler = &proc_dointvec_minmax, |
606 | .strategy = &sysctl_intvec, | 606 | .strategy = &sysctl_intvec, |
607 | .extra1 = &minolduid, | 607 | .extra1 = &minolduid, |
608 | .extra2 = &maxolduid, | 608 | .extra2 = &maxolduid, |
609 | }, | 609 | }, |
610 | { | 610 | { |
611 | .ctl_name = KERN_OVERFLOWGID, | 611 | .ctl_name = KERN_OVERFLOWGID, |
612 | .procname = "overflowgid", | 612 | .procname = "overflowgid", |
613 | .data = &overflowgid, | 613 | .data = &overflowgid, |
614 | .maxlen = sizeof(int), | 614 | .maxlen = sizeof(int), |
615 | .mode = 0644, | 615 | .mode = 0644, |
616 | .proc_handler = &proc_dointvec_minmax, | 616 | .proc_handler = &proc_dointvec_minmax, |
617 | .strategy = &sysctl_intvec, | 617 | .strategy = &sysctl_intvec, |
618 | .extra1 = &minolduid, | 618 | .extra1 = &minolduid, |
619 | .extra2 = &maxolduid, | 619 | .extra2 = &maxolduid, |
620 | }, | 620 | }, |
621 | #ifdef CONFIG_S390 | 621 | #ifdef CONFIG_S390 |
622 | #ifdef CONFIG_MATHEMU | 622 | #ifdef CONFIG_MATHEMU |
623 | { | 623 | { |
624 | .ctl_name = KERN_IEEE_EMULATION_WARNINGS, | 624 | .ctl_name = KERN_IEEE_EMULATION_WARNINGS, |
625 | .procname = "ieee_emulation_warnings", | 625 | .procname = "ieee_emulation_warnings", |
626 | .data = &sysctl_ieee_emulation_warnings, | 626 | .data = &sysctl_ieee_emulation_warnings, |
627 | .maxlen = sizeof(int), | 627 | .maxlen = sizeof(int), |
628 | .mode = 0644, | 628 | .mode = 0644, |
629 | .proc_handler = &proc_dointvec, | 629 | .proc_handler = &proc_dointvec, |
630 | }, | 630 | }, |
631 | #endif | 631 | #endif |
632 | { | 632 | { |
633 | .ctl_name = KERN_S390_USER_DEBUG_LOGGING, | 633 | .ctl_name = KERN_S390_USER_DEBUG_LOGGING, |
634 | .procname = "userprocess_debug", | 634 | .procname = "userprocess_debug", |
635 | .data = &sysctl_userprocess_debug, | 635 | .data = &sysctl_userprocess_debug, |
636 | .maxlen = sizeof(int), | 636 | .maxlen = sizeof(int), |
637 | .mode = 0644, | 637 | .mode = 0644, |
638 | .proc_handler = &proc_dointvec, | 638 | .proc_handler = &proc_dointvec, |
639 | }, | 639 | }, |
640 | #endif | 640 | #endif |
641 | { | 641 | { |
642 | .ctl_name = KERN_PIDMAX, | 642 | .ctl_name = KERN_PIDMAX, |
643 | .procname = "pid_max", | 643 | .procname = "pid_max", |
644 | .data = &pid_max, | 644 | .data = &pid_max, |
645 | .maxlen = sizeof (int), | 645 | .maxlen = sizeof (int), |
646 | .mode = 0644, | 646 | .mode = 0644, |
647 | .proc_handler = &proc_dointvec_minmax, | 647 | .proc_handler = &proc_dointvec_minmax, |
648 | .strategy = sysctl_intvec, | 648 | .strategy = sysctl_intvec, |
649 | .extra1 = &pid_max_min, | 649 | .extra1 = &pid_max_min, |
650 | .extra2 = &pid_max_max, | 650 | .extra2 = &pid_max_max, |
651 | }, | 651 | }, |
652 | { | 652 | { |
653 | .ctl_name = KERN_PANIC_ON_OOPS, | 653 | .ctl_name = KERN_PANIC_ON_OOPS, |
654 | .procname = "panic_on_oops", | 654 | .procname = "panic_on_oops", |
655 | .data = &panic_on_oops, | 655 | .data = &panic_on_oops, |
656 | .maxlen = sizeof(int), | 656 | .maxlen = sizeof(int), |
657 | .mode = 0644, | 657 | .mode = 0644, |
658 | .proc_handler = &proc_dointvec, | 658 | .proc_handler = &proc_dointvec, |
659 | }, | 659 | }, |
660 | #if defined CONFIG_PRINTK | 660 | #if defined CONFIG_PRINTK |
661 | { | 661 | { |
662 | .ctl_name = KERN_PRINTK, | 662 | .ctl_name = KERN_PRINTK, |
663 | .procname = "printk", | 663 | .procname = "printk", |
664 | .data = &console_loglevel, | 664 | .data = &console_loglevel, |
665 | .maxlen = 4*sizeof(int), | 665 | .maxlen = 4*sizeof(int), |
666 | .mode = 0644, | 666 | .mode = 0644, |
667 | .proc_handler = &proc_dointvec, | 667 | .proc_handler = &proc_dointvec, |
668 | }, | 668 | }, |
669 | { | 669 | { |
670 | .ctl_name = KERN_PRINTK_RATELIMIT, | 670 | .ctl_name = KERN_PRINTK_RATELIMIT, |
671 | .procname = "printk_ratelimit", | 671 | .procname = "printk_ratelimit", |
672 | .data = &printk_ratelimit_state.interval, | 672 | .data = &printk_ratelimit_state.interval, |
673 | .maxlen = sizeof(int), | 673 | .maxlen = sizeof(int), |
674 | .mode = 0644, | 674 | .mode = 0644, |
675 | .proc_handler = &proc_dointvec_jiffies, | 675 | .proc_handler = &proc_dointvec_jiffies, |
676 | .strategy = &sysctl_jiffies, | 676 | .strategy = &sysctl_jiffies, |
677 | }, | 677 | }, |
678 | { | 678 | { |
679 | .ctl_name = KERN_PRINTK_RATELIMIT_BURST, | 679 | .ctl_name = KERN_PRINTK_RATELIMIT_BURST, |
680 | .procname = "printk_ratelimit_burst", | 680 | .procname = "printk_ratelimit_burst", |
681 | .data = &printk_ratelimit_state.burst, | 681 | .data = &printk_ratelimit_state.burst, |
682 | .maxlen = sizeof(int), | 682 | .maxlen = sizeof(int), |
683 | .mode = 0644, | 683 | .mode = 0644, |
684 | .proc_handler = &proc_dointvec, | 684 | .proc_handler = &proc_dointvec, |
685 | }, | 685 | }, |
686 | #endif | 686 | #endif |
687 | { | 687 | { |
688 | .ctl_name = KERN_NGROUPS_MAX, | 688 | .ctl_name = KERN_NGROUPS_MAX, |
689 | .procname = "ngroups_max", | 689 | .procname = "ngroups_max", |
690 | .data = &ngroups_max, | 690 | .data = &ngroups_max, |
691 | .maxlen = sizeof (int), | 691 | .maxlen = sizeof (int), |
692 | .mode = 0444, | 692 | .mode = 0444, |
693 | .proc_handler = &proc_dointvec, | 693 | .proc_handler = &proc_dointvec, |
694 | }, | 694 | }, |
695 | #if defined(CONFIG_X86_LOCAL_APIC) && defined(CONFIG_X86) | 695 | #if defined(CONFIG_X86_LOCAL_APIC) && defined(CONFIG_X86) |
696 | { | 696 | { |
697 | .ctl_name = KERN_UNKNOWN_NMI_PANIC, | 697 | .ctl_name = KERN_UNKNOWN_NMI_PANIC, |
698 | .procname = "unknown_nmi_panic", | 698 | .procname = "unknown_nmi_panic", |
699 | .data = &unknown_nmi_panic, | 699 | .data = &unknown_nmi_panic, |
700 | .maxlen = sizeof (int), | 700 | .maxlen = sizeof (int), |
701 | .mode = 0644, | 701 | .mode = 0644, |
702 | .proc_handler = &proc_dointvec, | 702 | .proc_handler = &proc_dointvec, |
703 | }, | 703 | }, |
704 | { | 704 | { |
705 | .procname = "nmi_watchdog", | 705 | .procname = "nmi_watchdog", |
706 | .data = &nmi_watchdog_enabled, | 706 | .data = &nmi_watchdog_enabled, |
707 | .maxlen = sizeof (int), | 707 | .maxlen = sizeof (int), |
708 | .mode = 0644, | 708 | .mode = 0644, |
709 | .proc_handler = &proc_nmi_enabled, | 709 | .proc_handler = &proc_nmi_enabled, |
710 | }, | 710 | }, |
711 | #endif | 711 | #endif |
712 | #if defined(CONFIG_X86) | 712 | #if defined(CONFIG_X86) |
713 | { | 713 | { |
714 | .ctl_name = KERN_PANIC_ON_NMI, | 714 | .ctl_name = KERN_PANIC_ON_NMI, |
715 | .procname = "panic_on_unrecovered_nmi", | 715 | .procname = "panic_on_unrecovered_nmi", |
716 | .data = &panic_on_unrecovered_nmi, | 716 | .data = &panic_on_unrecovered_nmi, |
717 | .maxlen = sizeof(int), | 717 | .maxlen = sizeof(int), |
718 | .mode = 0644, | 718 | .mode = 0644, |
719 | .proc_handler = &proc_dointvec, | 719 | .proc_handler = &proc_dointvec, |
720 | }, | 720 | }, |
721 | { | 721 | { |
722 | .ctl_name = KERN_BOOTLOADER_TYPE, | 722 | .ctl_name = KERN_BOOTLOADER_TYPE, |
723 | .procname = "bootloader_type", | 723 | .procname = "bootloader_type", |
724 | .data = &bootloader_type, | 724 | .data = &bootloader_type, |
725 | .maxlen = sizeof (int), | 725 | .maxlen = sizeof (int), |
726 | .mode = 0444, | 726 | .mode = 0444, |
727 | .proc_handler = &proc_dointvec, | 727 | .proc_handler = &proc_dointvec, |
728 | }, | 728 | }, |
729 | { | 729 | { |
730 | .ctl_name = CTL_UNNUMBERED, | 730 | .ctl_name = CTL_UNNUMBERED, |
731 | .procname = "kstack_depth_to_print", | 731 | .procname = "kstack_depth_to_print", |
732 | .data = &kstack_depth_to_print, | 732 | .data = &kstack_depth_to_print, |
733 | .maxlen = sizeof(int), | 733 | .maxlen = sizeof(int), |
734 | .mode = 0644, | 734 | .mode = 0644, |
735 | .proc_handler = &proc_dointvec, | 735 | .proc_handler = &proc_dointvec, |
736 | }, | 736 | }, |
737 | { | 737 | { |
738 | .ctl_name = CTL_UNNUMBERED, | 738 | .ctl_name = CTL_UNNUMBERED, |
739 | .procname = "io_delay_type", | 739 | .procname = "io_delay_type", |
740 | .data = &io_delay_type, | 740 | .data = &io_delay_type, |
741 | .maxlen = sizeof(int), | 741 | .maxlen = sizeof(int), |
742 | .mode = 0644, | 742 | .mode = 0644, |
743 | .proc_handler = &proc_dointvec, | 743 | .proc_handler = &proc_dointvec, |
744 | }, | 744 | }, |
745 | #endif | 745 | #endif |
746 | #if defined(CONFIG_MMU) | 746 | #if defined(CONFIG_MMU) |
747 | { | 747 | { |
748 | .ctl_name = KERN_RANDOMIZE, | 748 | .ctl_name = KERN_RANDOMIZE, |
749 | .procname = "randomize_va_space", | 749 | .procname = "randomize_va_space", |
750 | .data = &randomize_va_space, | 750 | .data = &randomize_va_space, |
751 | .maxlen = sizeof(int), | 751 | .maxlen = sizeof(int), |
752 | .mode = 0644, | 752 | .mode = 0644, |
753 | .proc_handler = &proc_dointvec, | 753 | .proc_handler = &proc_dointvec, |
754 | }, | 754 | }, |
755 | #endif | 755 | #endif |
756 | #if defined(CONFIG_S390) && defined(CONFIG_SMP) | 756 | #if defined(CONFIG_S390) && defined(CONFIG_SMP) |
757 | { | 757 | { |
758 | .ctl_name = KERN_SPIN_RETRY, | 758 | .ctl_name = KERN_SPIN_RETRY, |
759 | .procname = "spin_retry", | 759 | .procname = "spin_retry", |
760 | .data = &spin_retry, | 760 | .data = &spin_retry, |
761 | .maxlen = sizeof (int), | 761 | .maxlen = sizeof (int), |
762 | .mode = 0644, | 762 | .mode = 0644, |
763 | .proc_handler = &proc_dointvec, | 763 | .proc_handler = &proc_dointvec, |
764 | }, | 764 | }, |
765 | #endif | 765 | #endif |
766 | #if defined(CONFIG_ACPI_SLEEP) && defined(CONFIG_X86) | 766 | #if defined(CONFIG_ACPI_SLEEP) && defined(CONFIG_X86) |
767 | { | 767 | { |
768 | .procname = "acpi_video_flags", | 768 | .procname = "acpi_video_flags", |
769 | .data = &acpi_realmode_flags, | 769 | .data = &acpi_realmode_flags, |
770 | .maxlen = sizeof (unsigned long), | 770 | .maxlen = sizeof (unsigned long), |
771 | .mode = 0644, | 771 | .mode = 0644, |
772 | .proc_handler = &proc_doulongvec_minmax, | 772 | .proc_handler = &proc_doulongvec_minmax, |
773 | }, | 773 | }, |
774 | #endif | 774 | #endif |
775 | #ifdef CONFIG_IA64 | 775 | #ifdef CONFIG_IA64 |
776 | { | 776 | { |
777 | .ctl_name = KERN_IA64_UNALIGNED, | 777 | .ctl_name = KERN_IA64_UNALIGNED, |
778 | .procname = "ignore-unaligned-usertrap", | 778 | .procname = "ignore-unaligned-usertrap", |
779 | .data = &no_unaligned_warning, | 779 | .data = &no_unaligned_warning, |
780 | .maxlen = sizeof (int), | 780 | .maxlen = sizeof (int), |
781 | .mode = 0644, | 781 | .mode = 0644, |
782 | .proc_handler = &proc_dointvec, | 782 | .proc_handler = &proc_dointvec, |
783 | }, | 783 | }, |
784 | #endif | 784 | #endif |
785 | #ifdef CONFIG_DETECT_SOFTLOCKUP | 785 | #ifdef CONFIG_DETECT_SOFTLOCKUP |
786 | { | 786 | { |
787 | .ctl_name = CTL_UNNUMBERED, | 787 | .ctl_name = CTL_UNNUMBERED, |
788 | .procname = "softlockup_panic", | 788 | .procname = "softlockup_panic", |
789 | .data = &softlockup_panic, | 789 | .data = &softlockup_panic, |
790 | .maxlen = sizeof(int), | 790 | .maxlen = sizeof(int), |
791 | .mode = 0644, | 791 | .mode = 0644, |
792 | .proc_handler = &proc_dointvec_minmax, | 792 | .proc_handler = &proc_dointvec_minmax, |
793 | .strategy = &sysctl_intvec, | 793 | .strategy = &sysctl_intvec, |
794 | .extra1 = &zero, | 794 | .extra1 = &zero, |
795 | .extra2 = &one, | 795 | .extra2 = &one, |
796 | }, | 796 | }, |
797 | { | 797 | { |
798 | .ctl_name = CTL_UNNUMBERED, | 798 | .ctl_name = CTL_UNNUMBERED, |
799 | .procname = "softlockup_thresh", | 799 | .procname = "softlockup_thresh", |
800 | .data = &softlockup_thresh, | 800 | .data = &softlockup_thresh, |
801 | .maxlen = sizeof(int), | 801 | .maxlen = sizeof(int), |
802 | .mode = 0644, | 802 | .mode = 0644, |
803 | .proc_handler = &proc_dointvec_minmax, | 803 | .proc_handler = &proc_dosoftlockup_thresh, |
804 | .strategy = &sysctl_intvec, | 804 | .strategy = &sysctl_intvec, |
805 | .extra1 = &neg_one, | 805 | .extra1 = &neg_one, |
806 | .extra2 = &sixty, | 806 | .extra2 = &sixty, |
807 | }, | 807 | }, |
808 | { | 808 | { |
809 | .ctl_name = CTL_UNNUMBERED, | 809 | .ctl_name = CTL_UNNUMBERED, |
810 | .procname = "hung_task_check_count", | 810 | .procname = "hung_task_check_count", |
811 | .data = &sysctl_hung_task_check_count, | 811 | .data = &sysctl_hung_task_check_count, |
812 | .maxlen = sizeof(unsigned long), | 812 | .maxlen = sizeof(unsigned long), |
813 | .mode = 0644, | 813 | .mode = 0644, |
814 | .proc_handler = &proc_doulongvec_minmax, | 814 | .proc_handler = &proc_doulongvec_minmax, |
815 | .strategy = &sysctl_intvec, | 815 | .strategy = &sysctl_intvec, |
816 | }, | 816 | }, |
817 | { | 817 | { |
818 | .ctl_name = CTL_UNNUMBERED, | 818 | .ctl_name = CTL_UNNUMBERED, |
819 | .procname = "hung_task_timeout_secs", | 819 | .procname = "hung_task_timeout_secs", |
820 | .data = &sysctl_hung_task_timeout_secs, | 820 | .data = &sysctl_hung_task_timeout_secs, |
821 | .maxlen = sizeof(unsigned long), | 821 | .maxlen = sizeof(unsigned long), |
822 | .mode = 0644, | 822 | .mode = 0644, |
823 | .proc_handler = &proc_doulongvec_minmax, | 823 | .proc_handler = &proc_doulongvec_minmax, |
824 | .strategy = &sysctl_intvec, | 824 | .strategy = &sysctl_intvec, |
825 | }, | 825 | }, |
826 | { | 826 | { |
827 | .ctl_name = CTL_UNNUMBERED, | 827 | .ctl_name = CTL_UNNUMBERED, |
828 | .procname = "hung_task_warnings", | 828 | .procname = "hung_task_warnings", |
829 | .data = &sysctl_hung_task_warnings, | 829 | .data = &sysctl_hung_task_warnings, |
830 | .maxlen = sizeof(unsigned long), | 830 | .maxlen = sizeof(unsigned long), |
831 | .mode = 0644, | 831 | .mode = 0644, |
832 | .proc_handler = &proc_doulongvec_minmax, | 832 | .proc_handler = &proc_doulongvec_minmax, |
833 | .strategy = &sysctl_intvec, | 833 | .strategy = &sysctl_intvec, |
834 | }, | 834 | }, |
835 | #endif | 835 | #endif |
836 | #ifdef CONFIG_COMPAT | 836 | #ifdef CONFIG_COMPAT |
837 | { | 837 | { |
838 | .ctl_name = KERN_COMPAT_LOG, | 838 | .ctl_name = KERN_COMPAT_LOG, |
839 | .procname = "compat-log", | 839 | .procname = "compat-log", |
840 | .data = &compat_log, | 840 | .data = &compat_log, |
841 | .maxlen = sizeof (int), | 841 | .maxlen = sizeof (int), |
842 | .mode = 0644, | 842 | .mode = 0644, |
843 | .proc_handler = &proc_dointvec, | 843 | .proc_handler = &proc_dointvec, |
844 | }, | 844 | }, |
845 | #endif | 845 | #endif |
846 | #ifdef CONFIG_RT_MUTEXES | 846 | #ifdef CONFIG_RT_MUTEXES |
847 | { | 847 | { |
848 | .ctl_name = KERN_MAX_LOCK_DEPTH, | 848 | .ctl_name = KERN_MAX_LOCK_DEPTH, |
849 | .procname = "max_lock_depth", | 849 | .procname = "max_lock_depth", |
850 | .data = &max_lock_depth, | 850 | .data = &max_lock_depth, |
851 | .maxlen = sizeof(int), | 851 | .maxlen = sizeof(int), |
852 | .mode = 0644, | 852 | .mode = 0644, |
853 | .proc_handler = &proc_dointvec, | 853 | .proc_handler = &proc_dointvec, |
854 | }, | 854 | }, |
855 | #endif | 855 | #endif |
856 | { | 856 | { |
857 | .ctl_name = CTL_UNNUMBERED, | 857 | .ctl_name = CTL_UNNUMBERED, |
858 | .procname = "poweroff_cmd", | 858 | .procname = "poweroff_cmd", |
859 | .data = &poweroff_cmd, | 859 | .data = &poweroff_cmd, |
860 | .maxlen = POWEROFF_CMD_PATH_LEN, | 860 | .maxlen = POWEROFF_CMD_PATH_LEN, |
861 | .mode = 0644, | 861 | .mode = 0644, |
862 | .proc_handler = &proc_dostring, | 862 | .proc_handler = &proc_dostring, |
863 | .strategy = &sysctl_string, | 863 | .strategy = &sysctl_string, |
864 | }, | 864 | }, |
865 | #ifdef CONFIG_KEYS | 865 | #ifdef CONFIG_KEYS |
866 | { | 866 | { |
867 | .ctl_name = CTL_UNNUMBERED, | 867 | .ctl_name = CTL_UNNUMBERED, |
868 | .procname = "keys", | 868 | .procname = "keys", |
869 | .mode = 0555, | 869 | .mode = 0555, |
870 | .child = key_sysctls, | 870 | .child = key_sysctls, |
871 | }, | 871 | }, |
872 | #endif | 872 | #endif |
873 | #ifdef CONFIG_RCU_TORTURE_TEST | 873 | #ifdef CONFIG_RCU_TORTURE_TEST |
874 | { | 874 | { |
875 | .ctl_name = CTL_UNNUMBERED, | 875 | .ctl_name = CTL_UNNUMBERED, |
876 | .procname = "rcutorture_runnable", | 876 | .procname = "rcutorture_runnable", |
877 | .data = &rcutorture_runnable, | 877 | .data = &rcutorture_runnable, |
878 | .maxlen = sizeof(int), | 878 | .maxlen = sizeof(int), |
879 | .mode = 0644, | 879 | .mode = 0644, |
880 | .proc_handler = &proc_dointvec, | 880 | .proc_handler = &proc_dointvec, |
881 | }, | 881 | }, |
882 | #endif | 882 | #endif |
883 | #ifdef CONFIG_UNEVICTABLE_LRU | 883 | #ifdef CONFIG_UNEVICTABLE_LRU |
884 | { | 884 | { |
885 | .ctl_name = CTL_UNNUMBERED, | 885 | .ctl_name = CTL_UNNUMBERED, |
886 | .procname = "scan_unevictable_pages", | 886 | .procname = "scan_unevictable_pages", |
887 | .data = &scan_unevictable_pages, | 887 | .data = &scan_unevictable_pages, |
888 | .maxlen = sizeof(scan_unevictable_pages), | 888 | .maxlen = sizeof(scan_unevictable_pages), |
889 | .mode = 0644, | 889 | .mode = 0644, |
890 | .proc_handler = &scan_unevictable_handler, | 890 | .proc_handler = &scan_unevictable_handler, |
891 | }, | 891 | }, |
892 | #endif | 892 | #endif |
893 | /* | 893 | /* |
894 | * NOTE: do not add new entries to this table unless you have read | 894 | * NOTE: do not add new entries to this table unless you have read |
895 | * Documentation/sysctl/ctl_unnumbered.txt | 895 | * Documentation/sysctl/ctl_unnumbered.txt |
896 | */ | 896 | */ |
897 | { .ctl_name = 0 } | 897 | { .ctl_name = 0 } |
898 | }; | 898 | }; |
899 | 899 | ||
900 | static struct ctl_table vm_table[] = { | 900 | static struct ctl_table vm_table[] = { |
901 | { | 901 | { |
902 | .ctl_name = VM_OVERCOMMIT_MEMORY, | 902 | .ctl_name = VM_OVERCOMMIT_MEMORY, |
903 | .procname = "overcommit_memory", | 903 | .procname = "overcommit_memory", |
904 | .data = &sysctl_overcommit_memory, | 904 | .data = &sysctl_overcommit_memory, |
905 | .maxlen = sizeof(sysctl_overcommit_memory), | 905 | .maxlen = sizeof(sysctl_overcommit_memory), |
906 | .mode = 0644, | 906 | .mode = 0644, |
907 | .proc_handler = &proc_dointvec, | 907 | .proc_handler = &proc_dointvec, |
908 | }, | 908 | }, |
909 | { | 909 | { |
910 | .ctl_name = VM_PANIC_ON_OOM, | 910 | .ctl_name = VM_PANIC_ON_OOM, |
911 | .procname = "panic_on_oom", | 911 | .procname = "panic_on_oom", |
912 | .data = &sysctl_panic_on_oom, | 912 | .data = &sysctl_panic_on_oom, |
913 | .maxlen = sizeof(sysctl_panic_on_oom), | 913 | .maxlen = sizeof(sysctl_panic_on_oom), |
914 | .mode = 0644, | 914 | .mode = 0644, |
915 | .proc_handler = &proc_dointvec, | 915 | .proc_handler = &proc_dointvec, |
916 | }, | 916 | }, |
917 | { | 917 | { |
918 | .ctl_name = CTL_UNNUMBERED, | 918 | .ctl_name = CTL_UNNUMBERED, |
919 | .procname = "oom_kill_allocating_task", | 919 | .procname = "oom_kill_allocating_task", |
920 | .data = &sysctl_oom_kill_allocating_task, | 920 | .data = &sysctl_oom_kill_allocating_task, |
921 | .maxlen = sizeof(sysctl_oom_kill_allocating_task), | 921 | .maxlen = sizeof(sysctl_oom_kill_allocating_task), |
922 | .mode = 0644, | 922 | .mode = 0644, |
923 | .proc_handler = &proc_dointvec, | 923 | .proc_handler = &proc_dointvec, |
924 | }, | 924 | }, |
925 | { | 925 | { |
926 | .ctl_name = CTL_UNNUMBERED, | 926 | .ctl_name = CTL_UNNUMBERED, |
927 | .procname = "oom_dump_tasks", | 927 | .procname = "oom_dump_tasks", |
928 | .data = &sysctl_oom_dump_tasks, | 928 | .data = &sysctl_oom_dump_tasks, |
929 | .maxlen = sizeof(sysctl_oom_dump_tasks), | 929 | .maxlen = sizeof(sysctl_oom_dump_tasks), |
930 | .mode = 0644, | 930 | .mode = 0644, |
931 | .proc_handler = &proc_dointvec, | 931 | .proc_handler = &proc_dointvec, |
932 | }, | 932 | }, |
933 | { | 933 | { |
934 | .ctl_name = VM_OVERCOMMIT_RATIO, | 934 | .ctl_name = VM_OVERCOMMIT_RATIO, |
935 | .procname = "overcommit_ratio", | 935 | .procname = "overcommit_ratio", |
936 | .data = &sysctl_overcommit_ratio, | 936 | .data = &sysctl_overcommit_ratio, |
937 | .maxlen = sizeof(sysctl_overcommit_ratio), | 937 | .maxlen = sizeof(sysctl_overcommit_ratio), |
938 | .mode = 0644, | 938 | .mode = 0644, |
939 | .proc_handler = &proc_dointvec, | 939 | .proc_handler = &proc_dointvec, |
940 | }, | 940 | }, |
941 | { | 941 | { |
942 | .ctl_name = VM_PAGE_CLUSTER, | 942 | .ctl_name = VM_PAGE_CLUSTER, |
943 | .procname = "page-cluster", | 943 | .procname = "page-cluster", |
944 | .data = &page_cluster, | 944 | .data = &page_cluster, |
945 | .maxlen = sizeof(int), | 945 | .maxlen = sizeof(int), |
946 | .mode = 0644, | 946 | .mode = 0644, |
947 | .proc_handler = &proc_dointvec, | 947 | .proc_handler = &proc_dointvec, |
948 | }, | 948 | }, |
949 | { | 949 | { |
950 | .ctl_name = VM_DIRTY_BACKGROUND, | 950 | .ctl_name = VM_DIRTY_BACKGROUND, |
951 | .procname = "dirty_background_ratio", | 951 | .procname = "dirty_background_ratio", |
952 | .data = &dirty_background_ratio, | 952 | .data = &dirty_background_ratio, |
953 | .maxlen = sizeof(dirty_background_ratio), | 953 | .maxlen = sizeof(dirty_background_ratio), |
954 | .mode = 0644, | 954 | .mode = 0644, |
955 | .proc_handler = &dirty_background_ratio_handler, | 955 | .proc_handler = &dirty_background_ratio_handler, |
956 | .strategy = &sysctl_intvec, | 956 | .strategy = &sysctl_intvec, |
957 | .extra1 = &zero, | 957 | .extra1 = &zero, |
958 | .extra2 = &one_hundred, | 958 | .extra2 = &one_hundred, |
959 | }, | 959 | }, |
960 | { | 960 | { |
961 | .ctl_name = CTL_UNNUMBERED, | 961 | .ctl_name = CTL_UNNUMBERED, |
962 | .procname = "dirty_background_bytes", | 962 | .procname = "dirty_background_bytes", |
963 | .data = &dirty_background_bytes, | 963 | .data = &dirty_background_bytes, |
964 | .maxlen = sizeof(dirty_background_bytes), | 964 | .maxlen = sizeof(dirty_background_bytes), |
965 | .mode = 0644, | 965 | .mode = 0644, |
966 | .proc_handler = &dirty_background_bytes_handler, | 966 | .proc_handler = &dirty_background_bytes_handler, |
967 | .strategy = &sysctl_intvec, | 967 | .strategy = &sysctl_intvec, |
968 | .extra1 = &one, | 968 | .extra1 = &one, |
969 | }, | 969 | }, |
970 | { | 970 | { |
971 | .ctl_name = VM_DIRTY_RATIO, | 971 | .ctl_name = VM_DIRTY_RATIO, |
972 | .procname = "dirty_ratio", | 972 | .procname = "dirty_ratio", |
973 | .data = &vm_dirty_ratio, | 973 | .data = &vm_dirty_ratio, |
974 | .maxlen = sizeof(vm_dirty_ratio), | 974 | .maxlen = sizeof(vm_dirty_ratio), |
975 | .mode = 0644, | 975 | .mode = 0644, |
976 | .proc_handler = &dirty_ratio_handler, | 976 | .proc_handler = &dirty_ratio_handler, |
977 | .strategy = &sysctl_intvec, | 977 | .strategy = &sysctl_intvec, |
978 | .extra1 = &zero, | 978 | .extra1 = &zero, |
979 | .extra2 = &one_hundred, | 979 | .extra2 = &one_hundred, |
980 | }, | 980 | }, |
981 | { | 981 | { |
982 | .ctl_name = CTL_UNNUMBERED, | 982 | .ctl_name = CTL_UNNUMBERED, |
983 | .procname = "dirty_bytes", | 983 | .procname = "dirty_bytes", |
984 | .data = &vm_dirty_bytes, | 984 | .data = &vm_dirty_bytes, |
985 | .maxlen = sizeof(vm_dirty_bytes), | 985 | .maxlen = sizeof(vm_dirty_bytes), |
986 | .mode = 0644, | 986 | .mode = 0644, |
987 | .proc_handler = &dirty_bytes_handler, | 987 | .proc_handler = &dirty_bytes_handler, |
988 | .strategy = &sysctl_intvec, | 988 | .strategy = &sysctl_intvec, |
989 | .extra1 = &one, | 989 | .extra1 = &one, |
990 | }, | 990 | }, |
991 | { | 991 | { |
992 | .procname = "dirty_writeback_centisecs", | 992 | .procname = "dirty_writeback_centisecs", |
993 | .data = &dirty_writeback_interval, | 993 | .data = &dirty_writeback_interval, |
994 | .maxlen = sizeof(dirty_writeback_interval), | 994 | .maxlen = sizeof(dirty_writeback_interval), |
995 | .mode = 0644, | 995 | .mode = 0644, |
996 | .proc_handler = &dirty_writeback_centisecs_handler, | 996 | .proc_handler = &dirty_writeback_centisecs_handler, |
997 | }, | 997 | }, |
998 | { | 998 | { |
999 | .procname = "dirty_expire_centisecs", | 999 | .procname = "dirty_expire_centisecs", |
1000 | .data = &dirty_expire_interval, | 1000 | .data = &dirty_expire_interval, |
1001 | .maxlen = sizeof(dirty_expire_interval), | 1001 | .maxlen = sizeof(dirty_expire_interval), |
1002 | .mode = 0644, | 1002 | .mode = 0644, |
1003 | .proc_handler = &proc_dointvec_userhz_jiffies, | 1003 | .proc_handler = &proc_dointvec_userhz_jiffies, |
1004 | }, | 1004 | }, |
1005 | { | 1005 | { |
1006 | .ctl_name = VM_NR_PDFLUSH_THREADS, | 1006 | .ctl_name = VM_NR_PDFLUSH_THREADS, |
1007 | .procname = "nr_pdflush_threads", | 1007 | .procname = "nr_pdflush_threads", |
1008 | .data = &nr_pdflush_threads, | 1008 | .data = &nr_pdflush_threads, |
1009 | .maxlen = sizeof nr_pdflush_threads, | 1009 | .maxlen = sizeof nr_pdflush_threads, |
1010 | .mode = 0444 /* read-only*/, | 1010 | .mode = 0444 /* read-only*/, |
1011 | .proc_handler = &proc_dointvec, | 1011 | .proc_handler = &proc_dointvec, |
1012 | }, | 1012 | }, |
1013 | { | 1013 | { |
1014 | .ctl_name = VM_SWAPPINESS, | 1014 | .ctl_name = VM_SWAPPINESS, |
1015 | .procname = "swappiness", | 1015 | .procname = "swappiness", |
1016 | .data = &vm_swappiness, | 1016 | .data = &vm_swappiness, |
1017 | .maxlen = sizeof(vm_swappiness), | 1017 | .maxlen = sizeof(vm_swappiness), |
1018 | .mode = 0644, | 1018 | .mode = 0644, |
1019 | .proc_handler = &proc_dointvec_minmax, | 1019 | .proc_handler = &proc_dointvec_minmax, |
1020 | .strategy = &sysctl_intvec, | 1020 | .strategy = &sysctl_intvec, |
1021 | .extra1 = &zero, | 1021 | .extra1 = &zero, |
1022 | .extra2 = &one_hundred, | 1022 | .extra2 = &one_hundred, |
1023 | }, | 1023 | }, |
1024 | #ifdef CONFIG_HUGETLB_PAGE | 1024 | #ifdef CONFIG_HUGETLB_PAGE |
1025 | { | 1025 | { |
1026 | .procname = "nr_hugepages", | 1026 | .procname = "nr_hugepages", |
1027 | .data = NULL, | 1027 | .data = NULL, |
1028 | .maxlen = sizeof(unsigned long), | 1028 | .maxlen = sizeof(unsigned long), |
1029 | .mode = 0644, | 1029 | .mode = 0644, |
1030 | .proc_handler = &hugetlb_sysctl_handler, | 1030 | .proc_handler = &hugetlb_sysctl_handler, |
1031 | .extra1 = (void *)&hugetlb_zero, | 1031 | .extra1 = (void *)&hugetlb_zero, |
1032 | .extra2 = (void *)&hugetlb_infinity, | 1032 | .extra2 = (void *)&hugetlb_infinity, |
1033 | }, | 1033 | }, |
1034 | { | 1034 | { |
1035 | .ctl_name = VM_HUGETLB_GROUP, | 1035 | .ctl_name = VM_HUGETLB_GROUP, |
1036 | .procname = "hugetlb_shm_group", | 1036 | .procname = "hugetlb_shm_group", |
1037 | .data = &sysctl_hugetlb_shm_group, | 1037 | .data = &sysctl_hugetlb_shm_group, |
1038 | .maxlen = sizeof(gid_t), | 1038 | .maxlen = sizeof(gid_t), |
1039 | .mode = 0644, | 1039 | .mode = 0644, |
1040 | .proc_handler = &proc_dointvec, | 1040 | .proc_handler = &proc_dointvec, |
1041 | }, | 1041 | }, |
1042 | { | 1042 | { |
1043 | .ctl_name = CTL_UNNUMBERED, | 1043 | .ctl_name = CTL_UNNUMBERED, |
1044 | .procname = "hugepages_treat_as_movable", | 1044 | .procname = "hugepages_treat_as_movable", |
1045 | .data = &hugepages_treat_as_movable, | 1045 | .data = &hugepages_treat_as_movable, |
1046 | .maxlen = sizeof(int), | 1046 | .maxlen = sizeof(int), |
1047 | .mode = 0644, | 1047 | .mode = 0644, |
1048 | .proc_handler = &hugetlb_treat_movable_handler, | 1048 | .proc_handler = &hugetlb_treat_movable_handler, |
1049 | }, | 1049 | }, |
1050 | { | 1050 | { |
1051 | .ctl_name = CTL_UNNUMBERED, | 1051 | .ctl_name = CTL_UNNUMBERED, |
1052 | .procname = "nr_overcommit_hugepages", | 1052 | .procname = "nr_overcommit_hugepages", |
1053 | .data = NULL, | 1053 | .data = NULL, |
1054 | .maxlen = sizeof(unsigned long), | 1054 | .maxlen = sizeof(unsigned long), |
1055 | .mode = 0644, | 1055 | .mode = 0644, |
1056 | .proc_handler = &hugetlb_overcommit_handler, | 1056 | .proc_handler = &hugetlb_overcommit_handler, |
1057 | .extra1 = (void *)&hugetlb_zero, | 1057 | .extra1 = (void *)&hugetlb_zero, |
1058 | .extra2 = (void *)&hugetlb_infinity, | 1058 | .extra2 = (void *)&hugetlb_infinity, |
1059 | }, | 1059 | }, |
1060 | #endif | 1060 | #endif |
1061 | { | 1061 | { |
1062 | .ctl_name = VM_LOWMEM_RESERVE_RATIO, | 1062 | .ctl_name = VM_LOWMEM_RESERVE_RATIO, |
1063 | .procname = "lowmem_reserve_ratio", | 1063 | .procname = "lowmem_reserve_ratio", |
1064 | .data = &sysctl_lowmem_reserve_ratio, | 1064 | .data = &sysctl_lowmem_reserve_ratio, |
1065 | .maxlen = sizeof(sysctl_lowmem_reserve_ratio), | 1065 | .maxlen = sizeof(sysctl_lowmem_reserve_ratio), |
1066 | .mode = 0644, | 1066 | .mode = 0644, |
1067 | .proc_handler = &lowmem_reserve_ratio_sysctl_handler, | 1067 | .proc_handler = &lowmem_reserve_ratio_sysctl_handler, |
1068 | .strategy = &sysctl_intvec, | 1068 | .strategy = &sysctl_intvec, |
1069 | }, | 1069 | }, |
1070 | { | 1070 | { |
1071 | .ctl_name = VM_DROP_PAGECACHE, | 1071 | .ctl_name = VM_DROP_PAGECACHE, |
1072 | .procname = "drop_caches", | 1072 | .procname = "drop_caches", |
1073 | .data = &sysctl_drop_caches, | 1073 | .data = &sysctl_drop_caches, |
1074 | .maxlen = sizeof(int), | 1074 | .maxlen = sizeof(int), |
1075 | .mode = 0644, | 1075 | .mode = 0644, |
1076 | .proc_handler = drop_caches_sysctl_handler, | 1076 | .proc_handler = drop_caches_sysctl_handler, |
1077 | .strategy = &sysctl_intvec, | 1077 | .strategy = &sysctl_intvec, |
1078 | }, | 1078 | }, |
1079 | { | 1079 | { |
1080 | .ctl_name = VM_MIN_FREE_KBYTES, | 1080 | .ctl_name = VM_MIN_FREE_KBYTES, |
1081 | .procname = "min_free_kbytes", | 1081 | .procname = "min_free_kbytes", |
1082 | .data = &min_free_kbytes, | 1082 | .data = &min_free_kbytes, |
1083 | .maxlen = sizeof(min_free_kbytes), | 1083 | .maxlen = sizeof(min_free_kbytes), |
1084 | .mode = 0644, | 1084 | .mode = 0644, |
1085 | .proc_handler = &min_free_kbytes_sysctl_handler, | 1085 | .proc_handler = &min_free_kbytes_sysctl_handler, |
1086 | .strategy = &sysctl_intvec, | 1086 | .strategy = &sysctl_intvec, |
1087 | .extra1 = &zero, | 1087 | .extra1 = &zero, |
1088 | }, | 1088 | }, |
1089 | { | 1089 | { |
1090 | .ctl_name = VM_PERCPU_PAGELIST_FRACTION, | 1090 | .ctl_name = VM_PERCPU_PAGELIST_FRACTION, |
1091 | .procname = "percpu_pagelist_fraction", | 1091 | .procname = "percpu_pagelist_fraction", |
1092 | .data = &percpu_pagelist_fraction, | 1092 | .data = &percpu_pagelist_fraction, |
1093 | .maxlen = sizeof(percpu_pagelist_fraction), | 1093 | .maxlen = sizeof(percpu_pagelist_fraction), |
1094 | .mode = 0644, | 1094 | .mode = 0644, |
1095 | .proc_handler = &percpu_pagelist_fraction_sysctl_handler, | 1095 | .proc_handler = &percpu_pagelist_fraction_sysctl_handler, |
1096 | .strategy = &sysctl_intvec, | 1096 | .strategy = &sysctl_intvec, |
1097 | .extra1 = &min_percpu_pagelist_fract, | 1097 | .extra1 = &min_percpu_pagelist_fract, |
1098 | }, | 1098 | }, |
1099 | #ifdef CONFIG_MMU | 1099 | #ifdef CONFIG_MMU |
1100 | { | 1100 | { |
1101 | .ctl_name = VM_MAX_MAP_COUNT, | 1101 | .ctl_name = VM_MAX_MAP_COUNT, |
1102 | .procname = "max_map_count", | 1102 | .procname = "max_map_count", |
1103 | .data = &sysctl_max_map_count, | 1103 | .data = &sysctl_max_map_count, |
1104 | .maxlen = sizeof(sysctl_max_map_count), | 1104 | .maxlen = sizeof(sysctl_max_map_count), |
1105 | .mode = 0644, | 1105 | .mode = 0644, |
1106 | .proc_handler = &proc_dointvec | 1106 | .proc_handler = &proc_dointvec |
1107 | }, | 1107 | }, |
1108 | #else | 1108 | #else |
1109 | { | 1109 | { |
1110 | .ctl_name = CTL_UNNUMBERED, | 1110 | .ctl_name = CTL_UNNUMBERED, |
1111 | .procname = "nr_trim_pages", | 1111 | .procname = "nr_trim_pages", |
1112 | .data = &sysctl_nr_trim_pages, | 1112 | .data = &sysctl_nr_trim_pages, |
1113 | .maxlen = sizeof(sysctl_nr_trim_pages), | 1113 | .maxlen = sizeof(sysctl_nr_trim_pages), |
1114 | .mode = 0644, | 1114 | .mode = 0644, |
1115 | .proc_handler = &proc_dointvec_minmax, | 1115 | .proc_handler = &proc_dointvec_minmax, |
1116 | .strategy = &sysctl_intvec, | 1116 | .strategy = &sysctl_intvec, |
1117 | .extra1 = &zero, | 1117 | .extra1 = &zero, |
1118 | }, | 1118 | }, |
1119 | #endif | 1119 | #endif |
1120 | { | 1120 | { |
1121 | .ctl_name = VM_LAPTOP_MODE, | 1121 | .ctl_name = VM_LAPTOP_MODE, |
1122 | .procname = "laptop_mode", | 1122 | .procname = "laptop_mode", |
1123 | .data = &laptop_mode, | 1123 | .data = &laptop_mode, |
1124 | .maxlen = sizeof(laptop_mode), | 1124 | .maxlen = sizeof(laptop_mode), |
1125 | .mode = 0644, | 1125 | .mode = 0644, |
1126 | .proc_handler = &proc_dointvec_jiffies, | 1126 | .proc_handler = &proc_dointvec_jiffies, |
1127 | .strategy = &sysctl_jiffies, | 1127 | .strategy = &sysctl_jiffies, |
1128 | }, | 1128 | }, |
1129 | { | 1129 | { |
1130 | .ctl_name = VM_BLOCK_DUMP, | 1130 | .ctl_name = VM_BLOCK_DUMP, |
1131 | .procname = "block_dump", | 1131 | .procname = "block_dump", |
1132 | .data = &block_dump, | 1132 | .data = &block_dump, |
1133 | .maxlen = sizeof(block_dump), | 1133 | .maxlen = sizeof(block_dump), |
1134 | .mode = 0644, | 1134 | .mode = 0644, |
1135 | .proc_handler = &proc_dointvec, | 1135 | .proc_handler = &proc_dointvec, |
1136 | .strategy = &sysctl_intvec, | 1136 | .strategy = &sysctl_intvec, |
1137 | .extra1 = &zero, | 1137 | .extra1 = &zero, |
1138 | }, | 1138 | }, |
1139 | { | 1139 | { |
1140 | .ctl_name = VM_VFS_CACHE_PRESSURE, | 1140 | .ctl_name = VM_VFS_CACHE_PRESSURE, |
1141 | .procname = "vfs_cache_pressure", | 1141 | .procname = "vfs_cache_pressure", |
1142 | .data = &sysctl_vfs_cache_pressure, | 1142 | .data = &sysctl_vfs_cache_pressure, |
1143 | .maxlen = sizeof(sysctl_vfs_cache_pressure), | 1143 | .maxlen = sizeof(sysctl_vfs_cache_pressure), |
1144 | .mode = 0644, | 1144 | .mode = 0644, |
1145 | .proc_handler = &proc_dointvec, | 1145 | .proc_handler = &proc_dointvec, |
1146 | .strategy = &sysctl_intvec, | 1146 | .strategy = &sysctl_intvec, |
1147 | .extra1 = &zero, | 1147 | .extra1 = &zero, |
1148 | }, | 1148 | }, |
1149 | #ifdef HAVE_ARCH_PICK_MMAP_LAYOUT | 1149 | #ifdef HAVE_ARCH_PICK_MMAP_LAYOUT |
1150 | { | 1150 | { |
1151 | .ctl_name = VM_LEGACY_VA_LAYOUT, | 1151 | .ctl_name = VM_LEGACY_VA_LAYOUT, |
1152 | .procname = "legacy_va_layout", | 1152 | .procname = "legacy_va_layout", |
1153 | .data = &sysctl_legacy_va_layout, | 1153 | .data = &sysctl_legacy_va_layout, |
1154 | .maxlen = sizeof(sysctl_legacy_va_layout), | 1154 | .maxlen = sizeof(sysctl_legacy_va_layout), |
1155 | .mode = 0644, | 1155 | .mode = 0644, |
1156 | .proc_handler = &proc_dointvec, | 1156 | .proc_handler = &proc_dointvec, |
1157 | .strategy = &sysctl_intvec, | 1157 | .strategy = &sysctl_intvec, |
1158 | .extra1 = &zero, | 1158 | .extra1 = &zero, |
1159 | }, | 1159 | }, |
1160 | #endif | 1160 | #endif |
1161 | #ifdef CONFIG_NUMA | 1161 | #ifdef CONFIG_NUMA |
1162 | { | 1162 | { |
1163 | .ctl_name = VM_ZONE_RECLAIM_MODE, | 1163 | .ctl_name = VM_ZONE_RECLAIM_MODE, |
1164 | .procname = "zone_reclaim_mode", | 1164 | .procname = "zone_reclaim_mode", |
1165 | .data = &zone_reclaim_mode, | 1165 | .data = &zone_reclaim_mode, |
1166 | .maxlen = sizeof(zone_reclaim_mode), | 1166 | .maxlen = sizeof(zone_reclaim_mode), |
1167 | .mode = 0644, | 1167 | .mode = 0644, |
1168 | .proc_handler = &proc_dointvec, | 1168 | .proc_handler = &proc_dointvec, |
1169 | .strategy = &sysctl_intvec, | 1169 | .strategy = &sysctl_intvec, |
1170 | .extra1 = &zero, | 1170 | .extra1 = &zero, |
1171 | }, | 1171 | }, |
1172 | { | 1172 | { |
1173 | .ctl_name = VM_MIN_UNMAPPED, | 1173 | .ctl_name = VM_MIN_UNMAPPED, |
1174 | .procname = "min_unmapped_ratio", | 1174 | .procname = "min_unmapped_ratio", |
1175 | .data = &sysctl_min_unmapped_ratio, | 1175 | .data = &sysctl_min_unmapped_ratio, |
1176 | .maxlen = sizeof(sysctl_min_unmapped_ratio), | 1176 | .maxlen = sizeof(sysctl_min_unmapped_ratio), |
1177 | .mode = 0644, | 1177 | .mode = 0644, |
1178 | .proc_handler = &sysctl_min_unmapped_ratio_sysctl_handler, | 1178 | .proc_handler = &sysctl_min_unmapped_ratio_sysctl_handler, |
1179 | .strategy = &sysctl_intvec, | 1179 | .strategy = &sysctl_intvec, |
1180 | .extra1 = &zero, | 1180 | .extra1 = &zero, |
1181 | .extra2 = &one_hundred, | 1181 | .extra2 = &one_hundred, |
1182 | }, | 1182 | }, |
1183 | { | 1183 | { |
1184 | .ctl_name = VM_MIN_SLAB, | 1184 | .ctl_name = VM_MIN_SLAB, |
1185 | .procname = "min_slab_ratio", | 1185 | .procname = "min_slab_ratio", |
1186 | .data = &sysctl_min_slab_ratio, | 1186 | .data = &sysctl_min_slab_ratio, |
1187 | .maxlen = sizeof(sysctl_min_slab_ratio), | 1187 | .maxlen = sizeof(sysctl_min_slab_ratio), |
1188 | .mode = 0644, | 1188 | .mode = 0644, |
1189 | .proc_handler = &sysctl_min_slab_ratio_sysctl_handler, | 1189 | .proc_handler = &sysctl_min_slab_ratio_sysctl_handler, |
1190 | .strategy = &sysctl_intvec, | 1190 | .strategy = &sysctl_intvec, |
1191 | .extra1 = &zero, | 1191 | .extra1 = &zero, |
1192 | .extra2 = &one_hundred, | 1192 | .extra2 = &one_hundred, |
1193 | }, | 1193 | }, |
1194 | #endif | 1194 | #endif |
1195 | #ifdef CONFIG_SMP | 1195 | #ifdef CONFIG_SMP |
1196 | { | 1196 | { |
1197 | .ctl_name = CTL_UNNUMBERED, | 1197 | .ctl_name = CTL_UNNUMBERED, |
1198 | .procname = "stat_interval", | 1198 | .procname = "stat_interval", |
1199 | .data = &sysctl_stat_interval, | 1199 | .data = &sysctl_stat_interval, |
1200 | .maxlen = sizeof(sysctl_stat_interval), | 1200 | .maxlen = sizeof(sysctl_stat_interval), |
1201 | .mode = 0644, | 1201 | .mode = 0644, |
1202 | .proc_handler = &proc_dointvec_jiffies, | 1202 | .proc_handler = &proc_dointvec_jiffies, |
1203 | .strategy = &sysctl_jiffies, | 1203 | .strategy = &sysctl_jiffies, |
1204 | }, | 1204 | }, |
1205 | #endif | 1205 | #endif |
1206 | #ifdef CONFIG_SECURITY | 1206 | #ifdef CONFIG_SECURITY |
1207 | { | 1207 | { |
1208 | .ctl_name = CTL_UNNUMBERED, | 1208 | .ctl_name = CTL_UNNUMBERED, |
1209 | .procname = "mmap_min_addr", | 1209 | .procname = "mmap_min_addr", |
1210 | .data = &mmap_min_addr, | 1210 | .data = &mmap_min_addr, |
1211 | .maxlen = sizeof(unsigned long), | 1211 | .maxlen = sizeof(unsigned long), |
1212 | .mode = 0644, | 1212 | .mode = 0644, |
1213 | .proc_handler = &proc_doulongvec_minmax, | 1213 | .proc_handler = &proc_doulongvec_minmax, |
1214 | }, | 1214 | }, |
1215 | #endif | 1215 | #endif |
1216 | #ifdef CONFIG_NUMA | 1216 | #ifdef CONFIG_NUMA |
1217 | { | 1217 | { |
1218 | .ctl_name = CTL_UNNUMBERED, | 1218 | .ctl_name = CTL_UNNUMBERED, |
1219 | .procname = "numa_zonelist_order", | 1219 | .procname = "numa_zonelist_order", |
1220 | .data = &numa_zonelist_order, | 1220 | .data = &numa_zonelist_order, |
1221 | .maxlen = NUMA_ZONELIST_ORDER_LEN, | 1221 | .maxlen = NUMA_ZONELIST_ORDER_LEN, |
1222 | .mode = 0644, | 1222 | .mode = 0644, |
1223 | .proc_handler = &numa_zonelist_order_handler, | 1223 | .proc_handler = &numa_zonelist_order_handler, |
1224 | .strategy = &sysctl_string, | 1224 | .strategy = &sysctl_string, |
1225 | }, | 1225 | }, |
1226 | #endif | 1226 | #endif |
1227 | #if (defined(CONFIG_X86_32) && !defined(CONFIG_UML))|| \ | 1227 | #if (defined(CONFIG_X86_32) && !defined(CONFIG_UML))|| \ |
1228 | (defined(CONFIG_SUPERH) && defined(CONFIG_VSYSCALL)) | 1228 | (defined(CONFIG_SUPERH) && defined(CONFIG_VSYSCALL)) |
1229 | { | 1229 | { |
1230 | .ctl_name = VM_VDSO_ENABLED, | 1230 | .ctl_name = VM_VDSO_ENABLED, |
1231 | .procname = "vdso_enabled", | 1231 | .procname = "vdso_enabled", |
1232 | .data = &vdso_enabled, | 1232 | .data = &vdso_enabled, |
1233 | .maxlen = sizeof(vdso_enabled), | 1233 | .maxlen = sizeof(vdso_enabled), |
1234 | .mode = 0644, | 1234 | .mode = 0644, |
1235 | .proc_handler = &proc_dointvec, | 1235 | .proc_handler = &proc_dointvec, |
1236 | .strategy = &sysctl_intvec, | 1236 | .strategy = &sysctl_intvec, |
1237 | .extra1 = &zero, | 1237 | .extra1 = &zero, |
1238 | }, | 1238 | }, |
1239 | #endif | 1239 | #endif |
1240 | #ifdef CONFIG_HIGHMEM | 1240 | #ifdef CONFIG_HIGHMEM |
1241 | { | 1241 | { |
1242 | .ctl_name = CTL_UNNUMBERED, | 1242 | .ctl_name = CTL_UNNUMBERED, |
1243 | .procname = "highmem_is_dirtyable", | 1243 | .procname = "highmem_is_dirtyable", |
1244 | .data = &vm_highmem_is_dirtyable, | 1244 | .data = &vm_highmem_is_dirtyable, |
1245 | .maxlen = sizeof(vm_highmem_is_dirtyable), | 1245 | .maxlen = sizeof(vm_highmem_is_dirtyable), |
1246 | .mode = 0644, | 1246 | .mode = 0644, |
1247 | .proc_handler = &proc_dointvec_minmax, | 1247 | .proc_handler = &proc_dointvec_minmax, |
1248 | .strategy = &sysctl_intvec, | 1248 | .strategy = &sysctl_intvec, |
1249 | .extra1 = &zero, | 1249 | .extra1 = &zero, |
1250 | .extra2 = &one, | 1250 | .extra2 = &one, |
1251 | }, | 1251 | }, |
1252 | #endif | 1252 | #endif |
1253 | /* | 1253 | /* |
1254 | * NOTE: do not add new entries to this table unless you have read | 1254 | * NOTE: do not add new entries to this table unless you have read |
1255 | * Documentation/sysctl/ctl_unnumbered.txt | 1255 | * Documentation/sysctl/ctl_unnumbered.txt |
1256 | */ | 1256 | */ |
1257 | { .ctl_name = 0 } | 1257 | { .ctl_name = 0 } |
1258 | }; | 1258 | }; |
1259 | 1259 | ||
1260 | #if defined(CONFIG_BINFMT_MISC) || defined(CONFIG_BINFMT_MISC_MODULE) | 1260 | #if defined(CONFIG_BINFMT_MISC) || defined(CONFIG_BINFMT_MISC_MODULE) |
1261 | static struct ctl_table binfmt_misc_table[] = { | 1261 | static struct ctl_table binfmt_misc_table[] = { |
1262 | { .ctl_name = 0 } | 1262 | { .ctl_name = 0 } |
1263 | }; | 1263 | }; |
1264 | #endif | 1264 | #endif |
1265 | 1265 | ||
1266 | static struct ctl_table fs_table[] = { | 1266 | static struct ctl_table fs_table[] = { |
1267 | { | 1267 | { |
1268 | .ctl_name = FS_NRINODE, | 1268 | .ctl_name = FS_NRINODE, |
1269 | .procname = "inode-nr", | 1269 | .procname = "inode-nr", |
1270 | .data = &inodes_stat, | 1270 | .data = &inodes_stat, |
1271 | .maxlen = 2*sizeof(int), | 1271 | .maxlen = 2*sizeof(int), |
1272 | .mode = 0444, | 1272 | .mode = 0444, |
1273 | .proc_handler = &proc_dointvec, | 1273 | .proc_handler = &proc_dointvec, |
1274 | }, | 1274 | }, |
1275 | { | 1275 | { |
1276 | .ctl_name = FS_STATINODE, | 1276 | .ctl_name = FS_STATINODE, |
1277 | .procname = "inode-state", | 1277 | .procname = "inode-state", |
1278 | .data = &inodes_stat, | 1278 | .data = &inodes_stat, |
1279 | .maxlen = 7*sizeof(int), | 1279 | .maxlen = 7*sizeof(int), |
1280 | .mode = 0444, | 1280 | .mode = 0444, |
1281 | .proc_handler = &proc_dointvec, | 1281 | .proc_handler = &proc_dointvec, |
1282 | }, | 1282 | }, |
1283 | { | 1283 | { |
1284 | .procname = "file-nr", | 1284 | .procname = "file-nr", |
1285 | .data = &files_stat, | 1285 | .data = &files_stat, |
1286 | .maxlen = 3*sizeof(int), | 1286 | .maxlen = 3*sizeof(int), |
1287 | .mode = 0444, | 1287 | .mode = 0444, |
1288 | .proc_handler = &proc_nr_files, | 1288 | .proc_handler = &proc_nr_files, |
1289 | }, | 1289 | }, |
1290 | { | 1290 | { |
1291 | .ctl_name = FS_MAXFILE, | 1291 | .ctl_name = FS_MAXFILE, |
1292 | .procname = "file-max", | 1292 | .procname = "file-max", |
1293 | .data = &files_stat.max_files, | 1293 | .data = &files_stat.max_files, |
1294 | .maxlen = sizeof(int), | 1294 | .maxlen = sizeof(int), |
1295 | .mode = 0644, | 1295 | .mode = 0644, |
1296 | .proc_handler = &proc_dointvec, | 1296 | .proc_handler = &proc_dointvec, |
1297 | }, | 1297 | }, |
1298 | { | 1298 | { |
1299 | .ctl_name = CTL_UNNUMBERED, | 1299 | .ctl_name = CTL_UNNUMBERED, |
1300 | .procname = "nr_open", | 1300 | .procname = "nr_open", |
1301 | .data = &sysctl_nr_open, | 1301 | .data = &sysctl_nr_open, |
1302 | .maxlen = sizeof(int), | 1302 | .maxlen = sizeof(int), |
1303 | .mode = 0644, | 1303 | .mode = 0644, |
1304 | .proc_handler = &proc_dointvec_minmax, | 1304 | .proc_handler = &proc_dointvec_minmax, |
1305 | .extra1 = &sysctl_nr_open_min, | 1305 | .extra1 = &sysctl_nr_open_min, |
1306 | .extra2 = &sysctl_nr_open_max, | 1306 | .extra2 = &sysctl_nr_open_max, |
1307 | }, | 1307 | }, |
1308 | { | 1308 | { |
1309 | .ctl_name = FS_DENTRY, | 1309 | .ctl_name = FS_DENTRY, |
1310 | .procname = "dentry-state", | 1310 | .procname = "dentry-state", |
1311 | .data = &dentry_stat, | 1311 | .data = &dentry_stat, |
1312 | .maxlen = 6*sizeof(int), | 1312 | .maxlen = 6*sizeof(int), |
1313 | .mode = 0444, | 1313 | .mode = 0444, |
1314 | .proc_handler = &proc_dointvec, | 1314 | .proc_handler = &proc_dointvec, |
1315 | }, | 1315 | }, |
1316 | { | 1316 | { |
1317 | .ctl_name = FS_OVERFLOWUID, | 1317 | .ctl_name = FS_OVERFLOWUID, |
1318 | .procname = "overflowuid", | 1318 | .procname = "overflowuid", |
1319 | .data = &fs_overflowuid, | 1319 | .data = &fs_overflowuid, |
1320 | .maxlen = sizeof(int), | 1320 | .maxlen = sizeof(int), |
1321 | .mode = 0644, | 1321 | .mode = 0644, |
1322 | .proc_handler = &proc_dointvec_minmax, | 1322 | .proc_handler = &proc_dointvec_minmax, |
1323 | .strategy = &sysctl_intvec, | 1323 | .strategy = &sysctl_intvec, |
1324 | .extra1 = &minolduid, | 1324 | .extra1 = &minolduid, |
1325 | .extra2 = &maxolduid, | 1325 | .extra2 = &maxolduid, |
1326 | }, | 1326 | }, |
1327 | { | 1327 | { |
1328 | .ctl_name = FS_OVERFLOWGID, | 1328 | .ctl_name = FS_OVERFLOWGID, |
1329 | .procname = "overflowgid", | 1329 | .procname = "overflowgid", |
1330 | .data = &fs_overflowgid, | 1330 | .data = &fs_overflowgid, |
1331 | .maxlen = sizeof(int), | 1331 | .maxlen = sizeof(int), |
1332 | .mode = 0644, | 1332 | .mode = 0644, |
1333 | .proc_handler = &proc_dointvec_minmax, | 1333 | .proc_handler = &proc_dointvec_minmax, |
1334 | .strategy = &sysctl_intvec, | 1334 | .strategy = &sysctl_intvec, |
1335 | .extra1 = &minolduid, | 1335 | .extra1 = &minolduid, |
1336 | .extra2 = &maxolduid, | 1336 | .extra2 = &maxolduid, |
1337 | }, | 1337 | }, |
1338 | #ifdef CONFIG_FILE_LOCKING | 1338 | #ifdef CONFIG_FILE_LOCKING |
1339 | { | 1339 | { |
1340 | .ctl_name = FS_LEASES, | 1340 | .ctl_name = FS_LEASES, |
1341 | .procname = "leases-enable", | 1341 | .procname = "leases-enable", |
1342 | .data = &leases_enable, | 1342 | .data = &leases_enable, |
1343 | .maxlen = sizeof(int), | 1343 | .maxlen = sizeof(int), |
1344 | .mode = 0644, | 1344 | .mode = 0644, |
1345 | .proc_handler = &proc_dointvec, | 1345 | .proc_handler = &proc_dointvec, |
1346 | }, | 1346 | }, |
1347 | #endif | 1347 | #endif |
1348 | #ifdef CONFIG_DNOTIFY | 1348 | #ifdef CONFIG_DNOTIFY |
1349 | { | 1349 | { |
1350 | .ctl_name = FS_DIR_NOTIFY, | 1350 | .ctl_name = FS_DIR_NOTIFY, |
1351 | .procname = "dir-notify-enable", | 1351 | .procname = "dir-notify-enable", |
1352 | .data = &dir_notify_enable, | 1352 | .data = &dir_notify_enable, |
1353 | .maxlen = sizeof(int), | 1353 | .maxlen = sizeof(int), |
1354 | .mode = 0644, | 1354 | .mode = 0644, |
1355 | .proc_handler = &proc_dointvec, | 1355 | .proc_handler = &proc_dointvec, |
1356 | }, | 1356 | }, |
1357 | #endif | 1357 | #endif |
1358 | #ifdef CONFIG_MMU | 1358 | #ifdef CONFIG_MMU |
1359 | #ifdef CONFIG_FILE_LOCKING | 1359 | #ifdef CONFIG_FILE_LOCKING |
1360 | { | 1360 | { |
1361 | .ctl_name = FS_LEASE_TIME, | 1361 | .ctl_name = FS_LEASE_TIME, |
1362 | .procname = "lease-break-time", | 1362 | .procname = "lease-break-time", |
1363 | .data = &lease_break_time, | 1363 | .data = &lease_break_time, |
1364 | .maxlen = sizeof(int), | 1364 | .maxlen = sizeof(int), |
1365 | .mode = 0644, | 1365 | .mode = 0644, |
1366 | .proc_handler = &proc_dointvec_minmax, | 1366 | .proc_handler = &proc_dointvec_minmax, |
1367 | .strategy = &sysctl_intvec, | 1367 | .strategy = &sysctl_intvec, |
1368 | .extra1 = &zero, | 1368 | .extra1 = &zero, |
1369 | .extra2 = &two, | 1369 | .extra2 = &two, |
1370 | }, | 1370 | }, |
1371 | #endif | 1371 | #endif |
1372 | #ifdef CONFIG_AIO | 1372 | #ifdef CONFIG_AIO |
1373 | { | 1373 | { |
1374 | .procname = "aio-nr", | 1374 | .procname = "aio-nr", |
1375 | .data = &aio_nr, | 1375 | .data = &aio_nr, |
1376 | .maxlen = sizeof(aio_nr), | 1376 | .maxlen = sizeof(aio_nr), |
1377 | .mode = 0444, | 1377 | .mode = 0444, |
1378 | .proc_handler = &proc_doulongvec_minmax, | 1378 | .proc_handler = &proc_doulongvec_minmax, |
1379 | }, | 1379 | }, |
1380 | { | 1380 | { |
1381 | .procname = "aio-max-nr", | 1381 | .procname = "aio-max-nr", |
1382 | .data = &aio_max_nr, | 1382 | .data = &aio_max_nr, |
1383 | .maxlen = sizeof(aio_max_nr), | 1383 | .maxlen = sizeof(aio_max_nr), |
1384 | .mode = 0644, | 1384 | .mode = 0644, |
1385 | .proc_handler = &proc_doulongvec_minmax, | 1385 | .proc_handler = &proc_doulongvec_minmax, |
1386 | }, | 1386 | }, |
1387 | #endif /* CONFIG_AIO */ | 1387 | #endif /* CONFIG_AIO */ |
1388 | #ifdef CONFIG_INOTIFY_USER | 1388 | #ifdef CONFIG_INOTIFY_USER |
1389 | { | 1389 | { |
1390 | .ctl_name = FS_INOTIFY, | 1390 | .ctl_name = FS_INOTIFY, |
1391 | .procname = "inotify", | 1391 | .procname = "inotify", |
1392 | .mode = 0555, | 1392 | .mode = 0555, |
1393 | .child = inotify_table, | 1393 | .child = inotify_table, |
1394 | }, | 1394 | }, |
1395 | #endif | 1395 | #endif |
1396 | #ifdef CONFIG_EPOLL | 1396 | #ifdef CONFIG_EPOLL |
1397 | { | 1397 | { |
1398 | .procname = "epoll", | 1398 | .procname = "epoll", |
1399 | .mode = 0555, | 1399 | .mode = 0555, |
1400 | .child = epoll_table, | 1400 | .child = epoll_table, |
1401 | }, | 1401 | }, |
1402 | #endif | 1402 | #endif |
1403 | #endif | 1403 | #endif |
1404 | { | 1404 | { |
1405 | .ctl_name = KERN_SETUID_DUMPABLE, | 1405 | .ctl_name = KERN_SETUID_DUMPABLE, |
1406 | .procname = "suid_dumpable", | 1406 | .procname = "suid_dumpable", |
1407 | .data = &suid_dumpable, | 1407 | .data = &suid_dumpable, |
1408 | .maxlen = sizeof(int), | 1408 | .maxlen = sizeof(int), |
1409 | .mode = 0644, | 1409 | .mode = 0644, |
1410 | .proc_handler = &proc_dointvec, | 1410 | .proc_handler = &proc_dointvec, |
1411 | }, | 1411 | }, |
1412 | #if defined(CONFIG_BINFMT_MISC) || defined(CONFIG_BINFMT_MISC_MODULE) | 1412 | #if defined(CONFIG_BINFMT_MISC) || defined(CONFIG_BINFMT_MISC_MODULE) |
1413 | { | 1413 | { |
1414 | .ctl_name = CTL_UNNUMBERED, | 1414 | .ctl_name = CTL_UNNUMBERED, |
1415 | .procname = "binfmt_misc", | 1415 | .procname = "binfmt_misc", |
1416 | .mode = 0555, | 1416 | .mode = 0555, |
1417 | .child = binfmt_misc_table, | 1417 | .child = binfmt_misc_table, |
1418 | }, | 1418 | }, |
1419 | #endif | 1419 | #endif |
1420 | /* | 1420 | /* |
1421 | * NOTE: do not add new entries to this table unless you have read | 1421 | * NOTE: do not add new entries to this table unless you have read |
1422 | * Documentation/sysctl/ctl_unnumbered.txt | 1422 | * Documentation/sysctl/ctl_unnumbered.txt |
1423 | */ | 1423 | */ |
1424 | { .ctl_name = 0 } | 1424 | { .ctl_name = 0 } |
1425 | }; | 1425 | }; |
1426 | 1426 | ||
1427 | static struct ctl_table debug_table[] = { | 1427 | static struct ctl_table debug_table[] = { |
1428 | #if defined(CONFIG_X86) || defined(CONFIG_PPC) | 1428 | #if defined(CONFIG_X86) || defined(CONFIG_PPC) |
1429 | { | 1429 | { |
1430 | .ctl_name = CTL_UNNUMBERED, | 1430 | .ctl_name = CTL_UNNUMBERED, |
1431 | .procname = "exception-trace", | 1431 | .procname = "exception-trace", |
1432 | .data = &show_unhandled_signals, | 1432 | .data = &show_unhandled_signals, |
1433 | .maxlen = sizeof(int), | 1433 | .maxlen = sizeof(int), |
1434 | .mode = 0644, | 1434 | .mode = 0644, |
1435 | .proc_handler = proc_dointvec | 1435 | .proc_handler = proc_dointvec |
1436 | }, | 1436 | }, |
1437 | #endif | 1437 | #endif |
1438 | { .ctl_name = 0 } | 1438 | { .ctl_name = 0 } |
1439 | }; | 1439 | }; |
1440 | 1440 | ||
1441 | static struct ctl_table dev_table[] = { | 1441 | static struct ctl_table dev_table[] = { |
1442 | { .ctl_name = 0 } | 1442 | { .ctl_name = 0 } |
1443 | }; | 1443 | }; |
1444 | 1444 | ||
1445 | static DEFINE_SPINLOCK(sysctl_lock); | 1445 | static DEFINE_SPINLOCK(sysctl_lock); |
1446 | 1446 | ||
1447 | /* called under sysctl_lock */ | 1447 | /* called under sysctl_lock */ |
1448 | static int use_table(struct ctl_table_header *p) | 1448 | static int use_table(struct ctl_table_header *p) |
1449 | { | 1449 | { |
1450 | if (unlikely(p->unregistering)) | 1450 | if (unlikely(p->unregistering)) |
1451 | return 0; | 1451 | return 0; |
1452 | p->used++; | 1452 | p->used++; |
1453 | return 1; | 1453 | return 1; |
1454 | } | 1454 | } |
1455 | 1455 | ||
1456 | /* called under sysctl_lock */ | 1456 | /* called under sysctl_lock */ |
1457 | static void unuse_table(struct ctl_table_header *p) | 1457 | static void unuse_table(struct ctl_table_header *p) |
1458 | { | 1458 | { |
1459 | if (!--p->used) | 1459 | if (!--p->used) |
1460 | if (unlikely(p->unregistering)) | 1460 | if (unlikely(p->unregistering)) |
1461 | complete(p->unregistering); | 1461 | complete(p->unregistering); |
1462 | } | 1462 | } |
1463 | 1463 | ||
1464 | /* called under sysctl_lock, will reacquire if has to wait */ | 1464 | /* called under sysctl_lock, will reacquire if has to wait */ |
1465 | static void start_unregistering(struct ctl_table_header *p) | 1465 | static void start_unregistering(struct ctl_table_header *p) |
1466 | { | 1466 | { |
1467 | /* | 1467 | /* |
1468 | * if p->used is 0, nobody will ever touch that entry again; | 1468 | * if p->used is 0, nobody will ever touch that entry again; |
1469 | * we'll eliminate all paths to it before dropping sysctl_lock | 1469 | * we'll eliminate all paths to it before dropping sysctl_lock |
1470 | */ | 1470 | */ |
1471 | if (unlikely(p->used)) { | 1471 | if (unlikely(p->used)) { |
1472 | struct completion wait; | 1472 | struct completion wait; |
1473 | init_completion(&wait); | 1473 | init_completion(&wait); |
1474 | p->unregistering = &wait; | 1474 | p->unregistering = &wait; |
1475 | spin_unlock(&sysctl_lock); | 1475 | spin_unlock(&sysctl_lock); |
1476 | wait_for_completion(&wait); | 1476 | wait_for_completion(&wait); |
1477 | spin_lock(&sysctl_lock); | 1477 | spin_lock(&sysctl_lock); |
1478 | } else { | 1478 | } else { |
1479 | /* anything non-NULL; we'll never dereference it */ | 1479 | /* anything non-NULL; we'll never dereference it */ |
1480 | p->unregistering = ERR_PTR(-EINVAL); | 1480 | p->unregistering = ERR_PTR(-EINVAL); |
1481 | } | 1481 | } |
1482 | /* | 1482 | /* |
1483 | * do not remove from the list until nobody holds it; walking the | 1483 | * do not remove from the list until nobody holds it; walking the |
1484 | * list in do_sysctl() relies on that. | 1484 | * list in do_sysctl() relies on that. |
1485 | */ | 1485 | */ |
1486 | list_del_init(&p->ctl_entry); | 1486 | list_del_init(&p->ctl_entry); |
1487 | } | 1487 | } |
1488 | 1488 | ||
1489 | void sysctl_head_get(struct ctl_table_header *head) | 1489 | void sysctl_head_get(struct ctl_table_header *head) |
1490 | { | 1490 | { |
1491 | spin_lock(&sysctl_lock); | 1491 | spin_lock(&sysctl_lock); |
1492 | head->count++; | 1492 | head->count++; |
1493 | spin_unlock(&sysctl_lock); | 1493 | spin_unlock(&sysctl_lock); |
1494 | } | 1494 | } |
1495 | 1495 | ||
1496 | void sysctl_head_put(struct ctl_table_header *head) | 1496 | void sysctl_head_put(struct ctl_table_header *head) |
1497 | { | 1497 | { |
1498 | spin_lock(&sysctl_lock); | 1498 | spin_lock(&sysctl_lock); |
1499 | if (!--head->count) | 1499 | if (!--head->count) |
1500 | kfree(head); | 1500 | kfree(head); |
1501 | spin_unlock(&sysctl_lock); | 1501 | spin_unlock(&sysctl_lock); |
1502 | } | 1502 | } |
1503 | 1503 | ||
1504 | struct ctl_table_header *sysctl_head_grab(struct ctl_table_header *head) | 1504 | struct ctl_table_header *sysctl_head_grab(struct ctl_table_header *head) |
1505 | { | 1505 | { |
1506 | if (!head) | 1506 | if (!head) |
1507 | BUG(); | 1507 | BUG(); |
1508 | spin_lock(&sysctl_lock); | 1508 | spin_lock(&sysctl_lock); |
1509 | if (!use_table(head)) | 1509 | if (!use_table(head)) |
1510 | head = ERR_PTR(-ENOENT); | 1510 | head = ERR_PTR(-ENOENT); |
1511 | spin_unlock(&sysctl_lock); | 1511 | spin_unlock(&sysctl_lock); |
1512 | return head; | 1512 | return head; |
1513 | } | 1513 | } |
1514 | 1514 | ||
1515 | void sysctl_head_finish(struct ctl_table_header *head) | 1515 | void sysctl_head_finish(struct ctl_table_header *head) |
1516 | { | 1516 | { |
1517 | if (!head) | 1517 | if (!head) |
1518 | return; | 1518 | return; |
1519 | spin_lock(&sysctl_lock); | 1519 | spin_lock(&sysctl_lock); |
1520 | unuse_table(head); | 1520 | unuse_table(head); |
1521 | spin_unlock(&sysctl_lock); | 1521 | spin_unlock(&sysctl_lock); |
1522 | } | 1522 | } |
1523 | 1523 | ||
1524 | static struct ctl_table_set * | 1524 | static struct ctl_table_set * |
1525 | lookup_header_set(struct ctl_table_root *root, struct nsproxy *namespaces) | 1525 | lookup_header_set(struct ctl_table_root *root, struct nsproxy *namespaces) |
1526 | { | 1526 | { |
1527 | struct ctl_table_set *set = &root->default_set; | 1527 | struct ctl_table_set *set = &root->default_set; |
1528 | if (root->lookup) | 1528 | if (root->lookup) |
1529 | set = root->lookup(root, namespaces); | 1529 | set = root->lookup(root, namespaces); |
1530 | return set; | 1530 | return set; |
1531 | } | 1531 | } |
1532 | 1532 | ||
1533 | static struct list_head * | 1533 | static struct list_head * |
1534 | lookup_header_list(struct ctl_table_root *root, struct nsproxy *namespaces) | 1534 | lookup_header_list(struct ctl_table_root *root, struct nsproxy *namespaces) |
1535 | { | 1535 | { |
1536 | struct ctl_table_set *set = lookup_header_set(root, namespaces); | 1536 | struct ctl_table_set *set = lookup_header_set(root, namespaces); |
1537 | return &set->list; | 1537 | return &set->list; |
1538 | } | 1538 | } |
1539 | 1539 | ||
1540 | struct ctl_table_header *__sysctl_head_next(struct nsproxy *namespaces, | 1540 | struct ctl_table_header *__sysctl_head_next(struct nsproxy *namespaces, |
1541 | struct ctl_table_header *prev) | 1541 | struct ctl_table_header *prev) |
1542 | { | 1542 | { |
1543 | struct ctl_table_root *root; | 1543 | struct ctl_table_root *root; |
1544 | struct list_head *header_list; | 1544 | struct list_head *header_list; |
1545 | struct ctl_table_header *head; | 1545 | struct ctl_table_header *head; |
1546 | struct list_head *tmp; | 1546 | struct list_head *tmp; |
1547 | 1547 | ||
1548 | spin_lock(&sysctl_lock); | 1548 | spin_lock(&sysctl_lock); |
1549 | if (prev) { | 1549 | if (prev) { |
1550 | head = prev; | 1550 | head = prev; |
1551 | tmp = &prev->ctl_entry; | 1551 | tmp = &prev->ctl_entry; |
1552 | unuse_table(prev); | 1552 | unuse_table(prev); |
1553 | goto next; | 1553 | goto next; |
1554 | } | 1554 | } |
1555 | tmp = &root_table_header.ctl_entry; | 1555 | tmp = &root_table_header.ctl_entry; |
1556 | for (;;) { | 1556 | for (;;) { |
1557 | head = list_entry(tmp, struct ctl_table_header, ctl_entry); | 1557 | head = list_entry(tmp, struct ctl_table_header, ctl_entry); |
1558 | 1558 | ||
1559 | if (!use_table(head)) | 1559 | if (!use_table(head)) |
1560 | goto next; | 1560 | goto next; |
1561 | spin_unlock(&sysctl_lock); | 1561 | spin_unlock(&sysctl_lock); |
1562 | return head; | 1562 | return head; |
1563 | next: | 1563 | next: |
1564 | root = head->root; | 1564 | root = head->root; |
1565 | tmp = tmp->next; | 1565 | tmp = tmp->next; |
1566 | header_list = lookup_header_list(root, namespaces); | 1566 | header_list = lookup_header_list(root, namespaces); |
1567 | if (tmp != header_list) | 1567 | if (tmp != header_list) |
1568 | continue; | 1568 | continue; |
1569 | 1569 | ||
1570 | do { | 1570 | do { |
1571 | root = list_entry(root->root_list.next, | 1571 | root = list_entry(root->root_list.next, |
1572 | struct ctl_table_root, root_list); | 1572 | struct ctl_table_root, root_list); |
1573 | if (root == &sysctl_table_root) | 1573 | if (root == &sysctl_table_root) |
1574 | goto out; | 1574 | goto out; |
1575 | header_list = lookup_header_list(root, namespaces); | 1575 | header_list = lookup_header_list(root, namespaces); |
1576 | } while (list_empty(header_list)); | 1576 | } while (list_empty(header_list)); |
1577 | tmp = header_list->next; | 1577 | tmp = header_list->next; |
1578 | } | 1578 | } |
1579 | out: | 1579 | out: |
1580 | spin_unlock(&sysctl_lock); | 1580 | spin_unlock(&sysctl_lock); |
1581 | return NULL; | 1581 | return NULL; |
1582 | } | 1582 | } |
1583 | 1583 | ||
1584 | struct ctl_table_header *sysctl_head_next(struct ctl_table_header *prev) | 1584 | struct ctl_table_header *sysctl_head_next(struct ctl_table_header *prev) |
1585 | { | 1585 | { |
1586 | return __sysctl_head_next(current->nsproxy, prev); | 1586 | return __sysctl_head_next(current->nsproxy, prev); |
1587 | } | 1587 | } |
1588 | 1588 | ||
1589 | void register_sysctl_root(struct ctl_table_root *root) | 1589 | void register_sysctl_root(struct ctl_table_root *root) |
1590 | { | 1590 | { |
1591 | spin_lock(&sysctl_lock); | 1591 | spin_lock(&sysctl_lock); |
1592 | list_add_tail(&root->root_list, &sysctl_table_root.root_list); | 1592 | list_add_tail(&root->root_list, &sysctl_table_root.root_list); |
1593 | spin_unlock(&sysctl_lock); | 1593 | spin_unlock(&sysctl_lock); |
1594 | } | 1594 | } |
1595 | 1595 | ||
1596 | #ifdef CONFIG_SYSCTL_SYSCALL | 1596 | #ifdef CONFIG_SYSCTL_SYSCALL |
1597 | /* Perform the actual read/write of a sysctl table entry. */ | 1597 | /* Perform the actual read/write of a sysctl table entry. */ |
1598 | static int do_sysctl_strategy(struct ctl_table_root *root, | 1598 | static int do_sysctl_strategy(struct ctl_table_root *root, |
1599 | struct ctl_table *table, | 1599 | struct ctl_table *table, |
1600 | void __user *oldval, size_t __user *oldlenp, | 1600 | void __user *oldval, size_t __user *oldlenp, |
1601 | void __user *newval, size_t newlen) | 1601 | void __user *newval, size_t newlen) |
1602 | { | 1602 | { |
1603 | int op = 0, rc; | 1603 | int op = 0, rc; |
1604 | 1604 | ||
1605 | if (oldval) | 1605 | if (oldval) |
1606 | op |= MAY_READ; | 1606 | op |= MAY_READ; |
1607 | if (newval) | 1607 | if (newval) |
1608 | op |= MAY_WRITE; | 1608 | op |= MAY_WRITE; |
1609 | if (sysctl_perm(root, table, op)) | 1609 | if (sysctl_perm(root, table, op)) |
1610 | return -EPERM; | 1610 | return -EPERM; |
1611 | 1611 | ||
1612 | if (table->strategy) { | 1612 | if (table->strategy) { |
1613 | rc = table->strategy(table, oldval, oldlenp, newval, newlen); | 1613 | rc = table->strategy(table, oldval, oldlenp, newval, newlen); |
1614 | if (rc < 0) | 1614 | if (rc < 0) |
1615 | return rc; | 1615 | return rc; |
1616 | if (rc > 0) | 1616 | if (rc > 0) |
1617 | return 0; | 1617 | return 0; |
1618 | } | 1618 | } |
1619 | 1619 | ||
1620 | /* If there is no strategy routine, or if the strategy returns | 1620 | /* If there is no strategy routine, or if the strategy returns |
1621 | * zero, proceed with automatic r/w */ | 1621 | * zero, proceed with automatic r/w */ |
1622 | if (table->data && table->maxlen) { | 1622 | if (table->data && table->maxlen) { |
1623 | rc = sysctl_data(table, oldval, oldlenp, newval, newlen); | 1623 | rc = sysctl_data(table, oldval, oldlenp, newval, newlen); |
1624 | if (rc < 0) | 1624 | if (rc < 0) |
1625 | return rc; | 1625 | return rc; |
1626 | } | 1626 | } |
1627 | return 0; | 1627 | return 0; |
1628 | } | 1628 | } |
1629 | 1629 | ||
1630 | static int parse_table(int __user *name, int nlen, | 1630 | static int parse_table(int __user *name, int nlen, |
1631 | void __user *oldval, size_t __user *oldlenp, | 1631 | void __user *oldval, size_t __user *oldlenp, |
1632 | void __user *newval, size_t newlen, | 1632 | void __user *newval, size_t newlen, |
1633 | struct ctl_table_root *root, | 1633 | struct ctl_table_root *root, |
1634 | struct ctl_table *table) | 1634 | struct ctl_table *table) |
1635 | { | 1635 | { |
1636 | int n; | 1636 | int n; |
1637 | repeat: | 1637 | repeat: |
1638 | if (!nlen) | 1638 | if (!nlen) |
1639 | return -ENOTDIR; | 1639 | return -ENOTDIR; |
1640 | if (get_user(n, name)) | 1640 | if (get_user(n, name)) |
1641 | return -EFAULT; | 1641 | return -EFAULT; |
1642 | for ( ; table->ctl_name || table->procname; table++) { | 1642 | for ( ; table->ctl_name || table->procname; table++) { |
1643 | if (!table->ctl_name) | 1643 | if (!table->ctl_name) |
1644 | continue; | 1644 | continue; |
1645 | if (n == table->ctl_name) { | 1645 | if (n == table->ctl_name) { |
1646 | int error; | 1646 | int error; |
1647 | if (table->child) { | 1647 | if (table->child) { |
1648 | if (sysctl_perm(root, table, MAY_EXEC)) | 1648 | if (sysctl_perm(root, table, MAY_EXEC)) |
1649 | return -EPERM; | 1649 | return -EPERM; |
1650 | name++; | 1650 | name++; |
1651 | nlen--; | 1651 | nlen--; |
1652 | table = table->child; | 1652 | table = table->child; |
1653 | goto repeat; | 1653 | goto repeat; |
1654 | } | 1654 | } |
1655 | error = do_sysctl_strategy(root, table, | 1655 | error = do_sysctl_strategy(root, table, |
1656 | oldval, oldlenp, | 1656 | oldval, oldlenp, |
1657 | newval, newlen); | 1657 | newval, newlen); |
1658 | return error; | 1658 | return error; |
1659 | } | 1659 | } |
1660 | } | 1660 | } |
1661 | return -ENOTDIR; | 1661 | return -ENOTDIR; |
1662 | } | 1662 | } |
1663 | 1663 | ||
1664 | int do_sysctl(int __user *name, int nlen, void __user *oldval, size_t __user *oldlenp, | 1664 | int do_sysctl(int __user *name, int nlen, void __user *oldval, size_t __user *oldlenp, |
1665 | void __user *newval, size_t newlen) | 1665 | void __user *newval, size_t newlen) |
1666 | { | 1666 | { |
1667 | struct ctl_table_header *head; | 1667 | struct ctl_table_header *head; |
1668 | int error = -ENOTDIR; | 1668 | int error = -ENOTDIR; |
1669 | 1669 | ||
1670 | if (nlen <= 0 || nlen >= CTL_MAXNAME) | 1670 | if (nlen <= 0 || nlen >= CTL_MAXNAME) |
1671 | return -ENOTDIR; | 1671 | return -ENOTDIR; |
1672 | if (oldval) { | 1672 | if (oldval) { |
1673 | int old_len; | 1673 | int old_len; |
1674 | if (!oldlenp || get_user(old_len, oldlenp)) | 1674 | if (!oldlenp || get_user(old_len, oldlenp)) |
1675 | return -EFAULT; | 1675 | return -EFAULT; |
1676 | } | 1676 | } |
1677 | 1677 | ||
1678 | for (head = sysctl_head_next(NULL); head; | 1678 | for (head = sysctl_head_next(NULL); head; |
1679 | head = sysctl_head_next(head)) { | 1679 | head = sysctl_head_next(head)) { |
1680 | error = parse_table(name, nlen, oldval, oldlenp, | 1680 | error = parse_table(name, nlen, oldval, oldlenp, |
1681 | newval, newlen, | 1681 | newval, newlen, |
1682 | head->root, head->ctl_table); | 1682 | head->root, head->ctl_table); |
1683 | if (error != -ENOTDIR) { | 1683 | if (error != -ENOTDIR) { |
1684 | sysctl_head_finish(head); | 1684 | sysctl_head_finish(head); |
1685 | break; | 1685 | break; |
1686 | } | 1686 | } |
1687 | } | 1687 | } |
1688 | return error; | 1688 | return error; |
1689 | } | 1689 | } |
1690 | 1690 | ||
1691 | asmlinkage long sys_sysctl(struct __sysctl_args __user *args) | 1691 | asmlinkage long sys_sysctl(struct __sysctl_args __user *args) |
1692 | { | 1692 | { |
1693 | struct __sysctl_args tmp; | 1693 | struct __sysctl_args tmp; |
1694 | int error; | 1694 | int error; |
1695 | 1695 | ||
1696 | if (copy_from_user(&tmp, args, sizeof(tmp))) | 1696 | if (copy_from_user(&tmp, args, sizeof(tmp))) |
1697 | return -EFAULT; | 1697 | return -EFAULT; |
1698 | 1698 | ||
1699 | error = deprecated_sysctl_warning(&tmp); | 1699 | error = deprecated_sysctl_warning(&tmp); |
1700 | if (error) | 1700 | if (error) |
1701 | goto out; | 1701 | goto out; |
1702 | 1702 | ||
1703 | lock_kernel(); | 1703 | lock_kernel(); |
1704 | error = do_sysctl(tmp.name, tmp.nlen, tmp.oldval, tmp.oldlenp, | 1704 | error = do_sysctl(tmp.name, tmp.nlen, tmp.oldval, tmp.oldlenp, |
1705 | tmp.newval, tmp.newlen); | 1705 | tmp.newval, tmp.newlen); |
1706 | unlock_kernel(); | 1706 | unlock_kernel(); |
1707 | out: | 1707 | out: |
1708 | return error; | 1708 | return error; |
1709 | } | 1709 | } |
1710 | #endif /* CONFIG_SYSCTL_SYSCALL */ | 1710 | #endif /* CONFIG_SYSCTL_SYSCALL */ |
1711 | 1711 | ||
1712 | /* | 1712 | /* |
1713 | * sysctl_perm does NOT grant the superuser all rights automatically, because | 1713 | * sysctl_perm does NOT grant the superuser all rights automatically, because |
1714 | * some sysctl variables are readonly even to root. | 1714 | * some sysctl variables are readonly even to root. |
1715 | */ | 1715 | */ |
1716 | 1716 | ||
1717 | static int test_perm(int mode, int op) | 1717 | static int test_perm(int mode, int op) |
1718 | { | 1718 | { |
1719 | if (!current_euid()) | 1719 | if (!current_euid()) |
1720 | mode >>= 6; | 1720 | mode >>= 6; |
1721 | else if (in_egroup_p(0)) | 1721 | else if (in_egroup_p(0)) |
1722 | mode >>= 3; | 1722 | mode >>= 3; |
1723 | if ((op & ~mode & (MAY_READ|MAY_WRITE|MAY_EXEC)) == 0) | 1723 | if ((op & ~mode & (MAY_READ|MAY_WRITE|MAY_EXEC)) == 0) |
1724 | return 0; | 1724 | return 0; |
1725 | return -EACCES; | 1725 | return -EACCES; |
1726 | } | 1726 | } |
1727 | 1727 | ||
1728 | int sysctl_perm(struct ctl_table_root *root, struct ctl_table *table, int op) | 1728 | int sysctl_perm(struct ctl_table_root *root, struct ctl_table *table, int op) |
1729 | { | 1729 | { |
1730 | int error; | 1730 | int error; |
1731 | int mode; | 1731 | int mode; |
1732 | 1732 | ||
1733 | error = security_sysctl(table, op & (MAY_READ | MAY_WRITE | MAY_EXEC)); | 1733 | error = security_sysctl(table, op & (MAY_READ | MAY_WRITE | MAY_EXEC)); |
1734 | if (error) | 1734 | if (error) |
1735 | return error; | 1735 | return error; |
1736 | 1736 | ||
1737 | if (root->permissions) | 1737 | if (root->permissions) |
1738 | mode = root->permissions(root, current->nsproxy, table); | 1738 | mode = root->permissions(root, current->nsproxy, table); |
1739 | else | 1739 | else |
1740 | mode = table->mode; | 1740 | mode = table->mode; |
1741 | 1741 | ||
1742 | return test_perm(mode, op); | 1742 | return test_perm(mode, op); |
1743 | } | 1743 | } |
1744 | 1744 | ||
1745 | static void sysctl_set_parent(struct ctl_table *parent, struct ctl_table *table) | 1745 | static void sysctl_set_parent(struct ctl_table *parent, struct ctl_table *table) |
1746 | { | 1746 | { |
1747 | for (; table->ctl_name || table->procname; table++) { | 1747 | for (; table->ctl_name || table->procname; table++) { |
1748 | table->parent = parent; | 1748 | table->parent = parent; |
1749 | if (table->child) | 1749 | if (table->child) |
1750 | sysctl_set_parent(table, table->child); | 1750 | sysctl_set_parent(table, table->child); |
1751 | } | 1751 | } |
1752 | } | 1752 | } |
1753 | 1753 | ||
1754 | static __init int sysctl_init(void) | 1754 | static __init int sysctl_init(void) |
1755 | { | 1755 | { |
1756 | sysctl_set_parent(NULL, root_table); | 1756 | sysctl_set_parent(NULL, root_table); |
1757 | #ifdef CONFIG_SYSCTL_SYSCALL_CHECK | 1757 | #ifdef CONFIG_SYSCTL_SYSCALL_CHECK |
1758 | { | 1758 | { |
1759 | int err; | 1759 | int err; |
1760 | err = sysctl_check_table(current->nsproxy, root_table); | 1760 | err = sysctl_check_table(current->nsproxy, root_table); |
1761 | } | 1761 | } |
1762 | #endif | 1762 | #endif |
1763 | return 0; | 1763 | return 0; |
1764 | } | 1764 | } |
1765 | 1765 | ||
1766 | core_initcall(sysctl_init); | 1766 | core_initcall(sysctl_init); |
1767 | 1767 | ||
1768 | static struct ctl_table *is_branch_in(struct ctl_table *branch, | 1768 | static struct ctl_table *is_branch_in(struct ctl_table *branch, |
1769 | struct ctl_table *table) | 1769 | struct ctl_table *table) |
1770 | { | 1770 | { |
1771 | struct ctl_table *p; | 1771 | struct ctl_table *p; |
1772 | const char *s = branch->procname; | 1772 | const char *s = branch->procname; |
1773 | 1773 | ||
1774 | /* branch should have named subdirectory as its first element */ | 1774 | /* branch should have named subdirectory as its first element */ |
1775 | if (!s || !branch->child) | 1775 | if (!s || !branch->child) |
1776 | return NULL; | 1776 | return NULL; |
1777 | 1777 | ||
1778 | /* ... and nothing else */ | 1778 | /* ... and nothing else */ |
1779 | if (branch[1].procname || branch[1].ctl_name) | 1779 | if (branch[1].procname || branch[1].ctl_name) |
1780 | return NULL; | 1780 | return NULL; |
1781 | 1781 | ||
1782 | /* table should contain subdirectory with the same name */ | 1782 | /* table should contain subdirectory with the same name */ |
1783 | for (p = table; p->procname || p->ctl_name; p++) { | 1783 | for (p = table; p->procname || p->ctl_name; p++) { |
1784 | if (!p->child) | 1784 | if (!p->child) |
1785 | continue; | 1785 | continue; |
1786 | if (p->procname && strcmp(p->procname, s) == 0) | 1786 | if (p->procname && strcmp(p->procname, s) == 0) |
1787 | return p; | 1787 | return p; |
1788 | } | 1788 | } |
1789 | return NULL; | 1789 | return NULL; |
1790 | } | 1790 | } |
1791 | 1791 | ||
1792 | /* see if attaching q to p would be an improvement */ | 1792 | /* see if attaching q to p would be an improvement */ |
1793 | static void try_attach(struct ctl_table_header *p, struct ctl_table_header *q) | 1793 | static void try_attach(struct ctl_table_header *p, struct ctl_table_header *q) |
1794 | { | 1794 | { |
1795 | struct ctl_table *to = p->ctl_table, *by = q->ctl_table; | 1795 | struct ctl_table *to = p->ctl_table, *by = q->ctl_table; |
1796 | struct ctl_table *next; | 1796 | struct ctl_table *next; |
1797 | int is_better = 0; | 1797 | int is_better = 0; |
1798 | int not_in_parent = !p->attached_by; | 1798 | int not_in_parent = !p->attached_by; |
1799 | 1799 | ||
1800 | while ((next = is_branch_in(by, to)) != NULL) { | 1800 | while ((next = is_branch_in(by, to)) != NULL) { |
1801 | if (by == q->attached_by) | 1801 | if (by == q->attached_by) |
1802 | is_better = 1; | 1802 | is_better = 1; |
1803 | if (to == p->attached_by) | 1803 | if (to == p->attached_by) |
1804 | not_in_parent = 1; | 1804 | not_in_parent = 1; |
1805 | by = by->child; | 1805 | by = by->child; |
1806 | to = next->child; | 1806 | to = next->child; |
1807 | } | 1807 | } |
1808 | 1808 | ||
1809 | if (is_better && not_in_parent) { | 1809 | if (is_better && not_in_parent) { |
1810 | q->attached_by = by; | 1810 | q->attached_by = by; |
1811 | q->attached_to = to; | 1811 | q->attached_to = to; |
1812 | q->parent = p; | 1812 | q->parent = p; |
1813 | } | 1813 | } |
1814 | } | 1814 | } |
1815 | 1815 | ||
1816 | /** | 1816 | /** |
1817 | * __register_sysctl_paths - register a sysctl hierarchy | 1817 | * __register_sysctl_paths - register a sysctl hierarchy |
1818 | * @root: List of sysctl headers to register on | 1818 | * @root: List of sysctl headers to register on |
1819 | * @namespaces: Data to compute which lists of sysctl entries are visible | 1819 | * @namespaces: Data to compute which lists of sysctl entries are visible |
1820 | * @path: The path to the directory the sysctl table is in. | 1820 | * @path: The path to the directory the sysctl table is in. |
1821 | * @table: the top-level table structure | 1821 | * @table: the top-level table structure |
1822 | * | 1822 | * |
1823 | * Register a sysctl table hierarchy. @table should be a filled in ctl_table | 1823 | * Register a sysctl table hierarchy. @table should be a filled in ctl_table |
1824 | * array. A completely 0 filled entry terminates the table. | 1824 | * array. A completely 0 filled entry terminates the table. |
1825 | * | 1825 | * |
1826 | * The members of the &struct ctl_table structure are used as follows: | 1826 | * The members of the &struct ctl_table structure are used as follows: |
1827 | * | 1827 | * |
1828 | * ctl_name - This is the numeric sysctl value used by sysctl(2). The number | 1828 | * ctl_name - This is the numeric sysctl value used by sysctl(2). The number |
1829 | * must be unique within that level of sysctl | 1829 | * must be unique within that level of sysctl |
1830 | * | 1830 | * |
1831 | * procname - the name of the sysctl file under /proc/sys. Set to %NULL to not | 1831 | * procname - the name of the sysctl file under /proc/sys. Set to %NULL to not |
1832 | * enter a sysctl file | 1832 | * enter a sysctl file |
1833 | * | 1833 | * |
1834 | * data - a pointer to data for use by proc_handler | 1834 | * data - a pointer to data for use by proc_handler |
1835 | * | 1835 | * |
1836 | * maxlen - the maximum size in bytes of the data | 1836 | * maxlen - the maximum size in bytes of the data |
1837 | * | 1837 | * |
1838 | * mode - the file permissions for the /proc/sys file, and for sysctl(2) | 1838 | * mode - the file permissions for the /proc/sys file, and for sysctl(2) |
1839 | * | 1839 | * |
1840 | * child - a pointer to the child sysctl table if this entry is a directory, or | 1840 | * child - a pointer to the child sysctl table if this entry is a directory, or |
1841 | * %NULL. | 1841 | * %NULL. |
1842 | * | 1842 | * |
1843 | * proc_handler - the text handler routine (described below) | 1843 | * proc_handler - the text handler routine (described below) |
1844 | * | 1844 | * |
1845 | * strategy - the strategy routine (described below) | 1845 | * strategy - the strategy routine (described below) |
1846 | * | 1846 | * |
1847 | * de - for internal use by the sysctl routines | 1847 | * de - for internal use by the sysctl routines |
1848 | * | 1848 | * |
1849 | * extra1, extra2 - extra pointers usable by the proc handler routines | 1849 | * extra1, extra2 - extra pointers usable by the proc handler routines |
1850 | * | 1850 | * |
1851 | * Leaf nodes in the sysctl tree will be represented by a single file | 1851 | * Leaf nodes in the sysctl tree will be represented by a single file |
1852 | * under /proc; non-leaf nodes will be represented by directories. | 1852 | * under /proc; non-leaf nodes will be represented by directories. |
1853 | * | 1853 | * |
1854 | * sysctl(2) can automatically manage read and write requests through | 1854 | * sysctl(2) can automatically manage read and write requests through |
1855 | * the sysctl table. The data and maxlen fields of the ctl_table | 1855 | * the sysctl table. The data and maxlen fields of the ctl_table |
1856 | * struct enable minimal validation of the values being written to be | 1856 | * struct enable minimal validation of the values being written to be |
1857 | * performed, and the mode field allows minimal authentication. | 1857 | * performed, and the mode field allows minimal authentication. |
1858 | * | 1858 | * |
1859 | * More sophisticated management can be enabled by the provision of a | 1859 | * More sophisticated management can be enabled by the provision of a |
1860 | * strategy routine with the table entry. This will be called before | 1860 | * strategy routine with the table entry. This will be called before |
1861 | * any automatic read or write of the data is performed. | 1861 | * any automatic read or write of the data is performed. |
1862 | * | 1862 | * |
1863 | * The strategy routine may return | 1863 | * The strategy routine may return |
1864 | * | 1864 | * |
1865 | * < 0 - Error occurred (error is passed to user process) | 1865 | * < 0 - Error occurred (error is passed to user process) |
1866 | * | 1866 | * |
1867 | * 0 - OK - proceed with automatic read or write. | 1867 | * 0 - OK - proceed with automatic read or write. |
1868 | * | 1868 | * |
1869 | * > 0 - OK - read or write has been done by the strategy routine, so | 1869 | * > 0 - OK - read or write has been done by the strategy routine, so |
1870 | * return immediately. | 1870 | * return immediately. |
1871 | * | 1871 | * |
1872 | * There must be a proc_handler routine for any terminal nodes | 1872 | * There must be a proc_handler routine for any terminal nodes |
1873 | * mirrored under /proc/sys (non-terminals are handled by a built-in | 1873 | * mirrored under /proc/sys (non-terminals are handled by a built-in |
1874 | * directory handler). Several default handlers are available to | 1874 | * directory handler). Several default handlers are available to |
1875 | * cover common cases - | 1875 | * cover common cases - |
1876 | * | 1876 | * |
1877 | * proc_dostring(), proc_dointvec(), proc_dointvec_jiffies(), | 1877 | * proc_dostring(), proc_dointvec(), proc_dointvec_jiffies(), |
1878 | * proc_dointvec_userhz_jiffies(), proc_dointvec_minmax(), | 1878 | * proc_dointvec_userhz_jiffies(), proc_dointvec_minmax(), |
1879 | * proc_doulongvec_ms_jiffies_minmax(), proc_doulongvec_minmax() | 1879 | * proc_doulongvec_ms_jiffies_minmax(), proc_doulongvec_minmax() |
1880 | * | 1880 | * |
1881 | * It is the handler's job to read the input buffer from user memory | 1881 | * It is the handler's job to read the input buffer from user memory |
1882 | * and process it. The handler should return 0 on success. | 1882 | * and process it. The handler should return 0 on success. |
1883 | * | 1883 | * |
1884 | * This routine returns %NULL on a failure to register, and a pointer | 1884 | * This routine returns %NULL on a failure to register, and a pointer |
1885 | * to the table header on success. | 1885 | * to the table header on success. |
1886 | */ | 1886 | */ |
1887 | struct ctl_table_header *__register_sysctl_paths( | 1887 | struct ctl_table_header *__register_sysctl_paths( |
1888 | struct ctl_table_root *root, | 1888 | struct ctl_table_root *root, |
1889 | struct nsproxy *namespaces, | 1889 | struct nsproxy *namespaces, |
1890 | const struct ctl_path *path, struct ctl_table *table) | 1890 | const struct ctl_path *path, struct ctl_table *table) |
1891 | { | 1891 | { |
1892 | struct ctl_table_header *header; | 1892 | struct ctl_table_header *header; |
1893 | struct ctl_table *new, **prevp; | 1893 | struct ctl_table *new, **prevp; |
1894 | unsigned int n, npath; | 1894 | unsigned int n, npath; |
1895 | struct ctl_table_set *set; | 1895 | struct ctl_table_set *set; |
1896 | 1896 | ||
1897 | /* Count the path components */ | 1897 | /* Count the path components */ |
1898 | for (npath = 0; path[npath].ctl_name || path[npath].procname; ++npath) | 1898 | for (npath = 0; path[npath].ctl_name || path[npath].procname; ++npath) |
1899 | ; | 1899 | ; |
1900 | 1900 | ||
1901 | /* | 1901 | /* |
1902 | * For each path component, allocate a 2-element ctl_table array. | 1902 | * For each path component, allocate a 2-element ctl_table array. |
1903 | * The first array element will be filled with the sysctl entry | 1903 | * The first array element will be filled with the sysctl entry |
1904 | * for this, the second will be the sentinel (ctl_name == 0). | 1904 | * for this, the second will be the sentinel (ctl_name == 0). |
1905 | * | 1905 | * |
1906 | * We allocate everything in one go so that we don't have to | 1906 | * We allocate everything in one go so that we don't have to |
1907 | * worry about freeing additional memory in unregister_sysctl_table. | 1907 | * worry about freeing additional memory in unregister_sysctl_table. |
1908 | */ | 1908 | */ |
1909 | header = kzalloc(sizeof(struct ctl_table_header) + | 1909 | header = kzalloc(sizeof(struct ctl_table_header) + |
1910 | (2 * npath * sizeof(struct ctl_table)), GFP_KERNEL); | 1910 | (2 * npath * sizeof(struct ctl_table)), GFP_KERNEL); |
1911 | if (!header) | 1911 | if (!header) |
1912 | return NULL; | 1912 | return NULL; |
1913 | 1913 | ||
1914 | new = (struct ctl_table *) (header + 1); | 1914 | new = (struct ctl_table *) (header + 1); |
1915 | 1915 | ||
1916 | /* Now connect the dots */ | 1916 | /* Now connect the dots */ |
1917 | prevp = &header->ctl_table; | 1917 | prevp = &header->ctl_table; |
1918 | for (n = 0; n < npath; ++n, ++path) { | 1918 | for (n = 0; n < npath; ++n, ++path) { |
1919 | /* Copy the procname */ | 1919 | /* Copy the procname */ |
1920 | new->procname = path->procname; | 1920 | new->procname = path->procname; |
1921 | new->ctl_name = path->ctl_name; | 1921 | new->ctl_name = path->ctl_name; |
1922 | new->mode = 0555; | 1922 | new->mode = 0555; |
1923 | 1923 | ||
1924 | *prevp = new; | 1924 | *prevp = new; |
1925 | prevp = &new->child; | 1925 | prevp = &new->child; |
1926 | 1926 | ||
1927 | new += 2; | 1927 | new += 2; |
1928 | } | 1928 | } |
1929 | *prevp = table; | 1929 | *prevp = table; |
1930 | header->ctl_table_arg = table; | 1930 | header->ctl_table_arg = table; |
1931 | 1931 | ||
1932 | INIT_LIST_HEAD(&header->ctl_entry); | 1932 | INIT_LIST_HEAD(&header->ctl_entry); |
1933 | header->used = 0; | 1933 | header->used = 0; |
1934 | header->unregistering = NULL; | 1934 | header->unregistering = NULL; |
1935 | header->root = root; | 1935 | header->root = root; |
1936 | sysctl_set_parent(NULL, header->ctl_table); | 1936 | sysctl_set_parent(NULL, header->ctl_table); |
1937 | header->count = 1; | 1937 | header->count = 1; |
1938 | #ifdef CONFIG_SYSCTL_SYSCALL_CHECK | 1938 | #ifdef CONFIG_SYSCTL_SYSCALL_CHECK |
1939 | if (sysctl_check_table(namespaces, header->ctl_table)) { | 1939 | if (sysctl_check_table(namespaces, header->ctl_table)) { |
1940 | kfree(header); | 1940 | kfree(header); |
1941 | return NULL; | 1941 | return NULL; |
1942 | } | 1942 | } |
1943 | #endif | 1943 | #endif |
1944 | spin_lock(&sysctl_lock); | 1944 | spin_lock(&sysctl_lock); |
1945 | header->set = lookup_header_set(root, namespaces); | 1945 | header->set = lookup_header_set(root, namespaces); |
1946 | header->attached_by = header->ctl_table; | 1946 | header->attached_by = header->ctl_table; |
1947 | header->attached_to = root_table; | 1947 | header->attached_to = root_table; |
1948 | header->parent = &root_table_header; | 1948 | header->parent = &root_table_header; |
1949 | for (set = header->set; set; set = set->parent) { | 1949 | for (set = header->set; set; set = set->parent) { |
1950 | struct ctl_table_header *p; | 1950 | struct ctl_table_header *p; |
1951 | list_for_each_entry(p, &set->list, ctl_entry) { | 1951 | list_for_each_entry(p, &set->list, ctl_entry) { |
1952 | if (p->unregistering) | 1952 | if (p->unregistering) |
1953 | continue; | 1953 | continue; |
1954 | try_attach(p, header); | 1954 | try_attach(p, header); |
1955 | } | 1955 | } |
1956 | } | 1956 | } |
1957 | header->parent->count++; | 1957 | header->parent->count++; |
1958 | list_add_tail(&header->ctl_entry, &header->set->list); | 1958 | list_add_tail(&header->ctl_entry, &header->set->list); |
1959 | spin_unlock(&sysctl_lock); | 1959 | spin_unlock(&sysctl_lock); |
1960 | 1960 | ||
1961 | return header; | 1961 | return header; |
1962 | } | 1962 | } |
1963 | 1963 | ||
1964 | /** | 1964 | /** |
1965 | * register_sysctl_table_path - register a sysctl table hierarchy | 1965 | * register_sysctl_table_path - register a sysctl table hierarchy |
1966 | * @path: The path to the directory the sysctl table is in. | 1966 | * @path: The path to the directory the sysctl table is in. |
1967 | * @table: the top-level table structure | 1967 | * @table: the top-level table structure |
1968 | * | 1968 | * |
1969 | * Register a sysctl table hierarchy. @table should be a filled in ctl_table | 1969 | * Register a sysctl table hierarchy. @table should be a filled in ctl_table |
1970 | * array. A completely 0 filled entry terminates the table. | 1970 | * array. A completely 0 filled entry terminates the table. |
1971 | * | 1971 | * |
1972 | * See __register_sysctl_paths for more details. | 1972 | * See __register_sysctl_paths for more details. |
1973 | */ | 1973 | */ |
1974 | struct ctl_table_header *register_sysctl_paths(const struct ctl_path *path, | 1974 | struct ctl_table_header *register_sysctl_paths(const struct ctl_path *path, |
1975 | struct ctl_table *table) | 1975 | struct ctl_table *table) |
1976 | { | 1976 | { |
1977 | return __register_sysctl_paths(&sysctl_table_root, current->nsproxy, | 1977 | return __register_sysctl_paths(&sysctl_table_root, current->nsproxy, |
1978 | path, table); | 1978 | path, table); |
1979 | } | 1979 | } |
1980 | 1980 | ||
1981 | /** | 1981 | /** |
1982 | * register_sysctl_table - register a sysctl table hierarchy | 1982 | * register_sysctl_table - register a sysctl table hierarchy |
1983 | * @table: the top-level table structure | 1983 | * @table: the top-level table structure |
1984 | * | 1984 | * |
1985 | * Register a sysctl table hierarchy. @table should be a filled in ctl_table | 1985 | * Register a sysctl table hierarchy. @table should be a filled in ctl_table |
1986 | * array. A completely 0 filled entry terminates the table. | 1986 | * array. A completely 0 filled entry terminates the table. |
1987 | * | 1987 | * |
1988 | * See register_sysctl_paths for more details. | 1988 | * See register_sysctl_paths for more details. |
1989 | */ | 1989 | */ |
1990 | struct ctl_table_header *register_sysctl_table(struct ctl_table *table) | 1990 | struct ctl_table_header *register_sysctl_table(struct ctl_table *table) |
1991 | { | 1991 | { |
1992 | static const struct ctl_path null_path[] = { {} }; | 1992 | static const struct ctl_path null_path[] = { {} }; |
1993 | 1993 | ||
1994 | return register_sysctl_paths(null_path, table); | 1994 | return register_sysctl_paths(null_path, table); |
1995 | } | 1995 | } |
1996 | 1996 | ||
1997 | /** | 1997 | /** |
1998 | * unregister_sysctl_table - unregister a sysctl table hierarchy | 1998 | * unregister_sysctl_table - unregister a sysctl table hierarchy |
1999 | * @header: the header returned from register_sysctl_table | 1999 | * @header: the header returned from register_sysctl_table |
2000 | * | 2000 | * |
2001 | * Unregisters the sysctl table and all children. proc entries may not | 2001 | * Unregisters the sysctl table and all children. proc entries may not |
2002 | * actually be removed until they are no longer used by anyone. | 2002 | * actually be removed until they are no longer used by anyone. |
2003 | */ | 2003 | */ |
2004 | void unregister_sysctl_table(struct ctl_table_header * header) | 2004 | void unregister_sysctl_table(struct ctl_table_header * header) |
2005 | { | 2005 | { |
2006 | might_sleep(); | 2006 | might_sleep(); |
2007 | 2007 | ||
2008 | if (header == NULL) | 2008 | if (header == NULL) |
2009 | return; | 2009 | return; |
2010 | 2010 | ||
2011 | spin_lock(&sysctl_lock); | 2011 | spin_lock(&sysctl_lock); |
2012 | start_unregistering(header); | 2012 | start_unregistering(header); |
2013 | if (!--header->parent->count) { | 2013 | if (!--header->parent->count) { |
2014 | WARN_ON(1); | 2014 | WARN_ON(1); |
2015 | kfree(header->parent); | 2015 | kfree(header->parent); |
2016 | } | 2016 | } |
2017 | if (!--header->count) | 2017 | if (!--header->count) |
2018 | kfree(header); | 2018 | kfree(header); |
2019 | spin_unlock(&sysctl_lock); | 2019 | spin_unlock(&sysctl_lock); |
2020 | } | 2020 | } |
2021 | 2021 | ||
2022 | int sysctl_is_seen(struct ctl_table_header *p) | 2022 | int sysctl_is_seen(struct ctl_table_header *p) |
2023 | { | 2023 | { |
2024 | struct ctl_table_set *set = p->set; | 2024 | struct ctl_table_set *set = p->set; |
2025 | int res; | 2025 | int res; |
2026 | spin_lock(&sysctl_lock); | 2026 | spin_lock(&sysctl_lock); |
2027 | if (p->unregistering) | 2027 | if (p->unregistering) |
2028 | res = 0; | 2028 | res = 0; |
2029 | else if (!set->is_seen) | 2029 | else if (!set->is_seen) |
2030 | res = 1; | 2030 | res = 1; |
2031 | else | 2031 | else |
2032 | res = set->is_seen(set); | 2032 | res = set->is_seen(set); |
2033 | spin_unlock(&sysctl_lock); | 2033 | spin_unlock(&sysctl_lock); |
2034 | return res; | 2034 | return res; |
2035 | } | 2035 | } |
2036 | 2036 | ||
2037 | void setup_sysctl_set(struct ctl_table_set *p, | 2037 | void setup_sysctl_set(struct ctl_table_set *p, |
2038 | struct ctl_table_set *parent, | 2038 | struct ctl_table_set *parent, |
2039 | int (*is_seen)(struct ctl_table_set *)) | 2039 | int (*is_seen)(struct ctl_table_set *)) |
2040 | { | 2040 | { |
2041 | INIT_LIST_HEAD(&p->list); | 2041 | INIT_LIST_HEAD(&p->list); |
2042 | p->parent = parent ? parent : &sysctl_table_root.default_set; | 2042 | p->parent = parent ? parent : &sysctl_table_root.default_set; |
2043 | p->is_seen = is_seen; | 2043 | p->is_seen = is_seen; |
2044 | } | 2044 | } |
2045 | 2045 | ||
2046 | #else /* !CONFIG_SYSCTL */ | 2046 | #else /* !CONFIG_SYSCTL */ |
2047 | struct ctl_table_header *register_sysctl_table(struct ctl_table * table) | 2047 | struct ctl_table_header *register_sysctl_table(struct ctl_table * table) |
2048 | { | 2048 | { |
2049 | return NULL; | 2049 | return NULL; |
2050 | } | 2050 | } |
2051 | 2051 | ||
2052 | struct ctl_table_header *register_sysctl_paths(const struct ctl_path *path, | 2052 | struct ctl_table_header *register_sysctl_paths(const struct ctl_path *path, |
2053 | struct ctl_table *table) | 2053 | struct ctl_table *table) |
2054 | { | 2054 | { |
2055 | return NULL; | 2055 | return NULL; |
2056 | } | 2056 | } |
2057 | 2057 | ||
2058 | void unregister_sysctl_table(struct ctl_table_header * table) | 2058 | void unregister_sysctl_table(struct ctl_table_header * table) |
2059 | { | 2059 | { |
2060 | } | 2060 | } |
2061 | 2061 | ||
2062 | void setup_sysctl_set(struct ctl_table_set *p, | 2062 | void setup_sysctl_set(struct ctl_table_set *p, |
2063 | struct ctl_table_set *parent, | 2063 | struct ctl_table_set *parent, |
2064 | int (*is_seen)(struct ctl_table_set *)) | 2064 | int (*is_seen)(struct ctl_table_set *)) |
2065 | { | 2065 | { |
2066 | } | 2066 | } |
2067 | 2067 | ||
2068 | void sysctl_head_put(struct ctl_table_header *head) | 2068 | void sysctl_head_put(struct ctl_table_header *head) |
2069 | { | 2069 | { |
2070 | } | 2070 | } |
2071 | 2071 | ||
2072 | #endif /* CONFIG_SYSCTL */ | 2072 | #endif /* CONFIG_SYSCTL */ |
2073 | 2073 | ||
2074 | /* | 2074 | /* |
2075 | * /proc/sys support | 2075 | * /proc/sys support |
2076 | */ | 2076 | */ |
2077 | 2077 | ||
2078 | #ifdef CONFIG_PROC_SYSCTL | 2078 | #ifdef CONFIG_PROC_SYSCTL |
2079 | 2079 | ||
2080 | static int _proc_do_string(void* data, int maxlen, int write, | 2080 | static int _proc_do_string(void* data, int maxlen, int write, |
2081 | struct file *filp, void __user *buffer, | 2081 | struct file *filp, void __user *buffer, |
2082 | size_t *lenp, loff_t *ppos) | 2082 | size_t *lenp, loff_t *ppos) |
2083 | { | 2083 | { |
2084 | size_t len; | 2084 | size_t len; |
2085 | char __user *p; | 2085 | char __user *p; |
2086 | char c; | 2086 | char c; |
2087 | 2087 | ||
2088 | if (!data || !maxlen || !*lenp) { | 2088 | if (!data || !maxlen || !*lenp) { |
2089 | *lenp = 0; | 2089 | *lenp = 0; |
2090 | return 0; | 2090 | return 0; |
2091 | } | 2091 | } |
2092 | 2092 | ||
2093 | if (write) { | 2093 | if (write) { |
2094 | len = 0; | 2094 | len = 0; |
2095 | p = buffer; | 2095 | p = buffer; |
2096 | while (len < *lenp) { | 2096 | while (len < *lenp) { |
2097 | if (get_user(c, p++)) | 2097 | if (get_user(c, p++)) |
2098 | return -EFAULT; | 2098 | return -EFAULT; |
2099 | if (c == 0 || c == '\n') | 2099 | if (c == 0 || c == '\n') |
2100 | break; | 2100 | break; |
2101 | len++; | 2101 | len++; |
2102 | } | 2102 | } |
2103 | if (len >= maxlen) | 2103 | if (len >= maxlen) |
2104 | len = maxlen-1; | 2104 | len = maxlen-1; |
2105 | if(copy_from_user(data, buffer, len)) | 2105 | if(copy_from_user(data, buffer, len)) |
2106 | return -EFAULT; | 2106 | return -EFAULT; |
2107 | ((char *) data)[len] = 0; | 2107 | ((char *) data)[len] = 0; |
2108 | *ppos += *lenp; | 2108 | *ppos += *lenp; |
2109 | } else { | 2109 | } else { |
2110 | len = strlen(data); | 2110 | len = strlen(data); |
2111 | if (len > maxlen) | 2111 | if (len > maxlen) |
2112 | len = maxlen; | 2112 | len = maxlen; |
2113 | 2113 | ||
2114 | if (*ppos > len) { | 2114 | if (*ppos > len) { |
2115 | *lenp = 0; | 2115 | *lenp = 0; |
2116 | return 0; | 2116 | return 0; |
2117 | } | 2117 | } |
2118 | 2118 | ||
2119 | data += *ppos; | 2119 | data += *ppos; |
2120 | len -= *ppos; | 2120 | len -= *ppos; |
2121 | 2121 | ||
2122 | if (len > *lenp) | 2122 | if (len > *lenp) |
2123 | len = *lenp; | 2123 | len = *lenp; |
2124 | if (len) | 2124 | if (len) |
2125 | if(copy_to_user(buffer, data, len)) | 2125 | if(copy_to_user(buffer, data, len)) |
2126 | return -EFAULT; | 2126 | return -EFAULT; |
2127 | if (len < *lenp) { | 2127 | if (len < *lenp) { |
2128 | if(put_user('\n', ((char __user *) buffer) + len)) | 2128 | if(put_user('\n', ((char __user *) buffer) + len)) |
2129 | return -EFAULT; | 2129 | return -EFAULT; |
2130 | len++; | 2130 | len++; |
2131 | } | 2131 | } |
2132 | *lenp = len; | 2132 | *lenp = len; |
2133 | *ppos += len; | 2133 | *ppos += len; |
2134 | } | 2134 | } |
2135 | return 0; | 2135 | return 0; |
2136 | } | 2136 | } |
2137 | 2137 | ||
2138 | /** | 2138 | /** |
2139 | * proc_dostring - read a string sysctl | 2139 | * proc_dostring - read a string sysctl |
2140 | * @table: the sysctl table | 2140 | * @table: the sysctl table |
2141 | * @write: %TRUE if this is a write to the sysctl file | 2141 | * @write: %TRUE if this is a write to the sysctl file |
2142 | * @filp: the file structure | 2142 | * @filp: the file structure |
2143 | * @buffer: the user buffer | 2143 | * @buffer: the user buffer |
2144 | * @lenp: the size of the user buffer | 2144 | * @lenp: the size of the user buffer |
2145 | * @ppos: file position | 2145 | * @ppos: file position |
2146 | * | 2146 | * |
2147 | * Reads/writes a string from/to the user buffer. If the kernel | 2147 | * Reads/writes a string from/to the user buffer. If the kernel |
2148 | * buffer provided is not large enough to hold the string, the | 2148 | * buffer provided is not large enough to hold the string, the |
2149 | * string is truncated. The copied string is %NULL-terminated. | 2149 | * string is truncated. The copied string is %NULL-terminated. |
2150 | * If the string is being read by the user process, it is copied | 2150 | * If the string is being read by the user process, it is copied |
2151 | * and a newline '\n' is added. It is truncated if the buffer is | 2151 | * and a newline '\n' is added. It is truncated if the buffer is |
2152 | * not large enough. | 2152 | * not large enough. |
2153 | * | 2153 | * |
2154 | * Returns 0 on success. | 2154 | * Returns 0 on success. |
2155 | */ | 2155 | */ |
2156 | int proc_dostring(struct ctl_table *table, int write, struct file *filp, | 2156 | int proc_dostring(struct ctl_table *table, int write, struct file *filp, |
2157 | void __user *buffer, size_t *lenp, loff_t *ppos) | 2157 | void __user *buffer, size_t *lenp, loff_t *ppos) |
2158 | { | 2158 | { |
2159 | return _proc_do_string(table->data, table->maxlen, write, filp, | 2159 | return _proc_do_string(table->data, table->maxlen, write, filp, |
2160 | buffer, lenp, ppos); | 2160 | buffer, lenp, ppos); |
2161 | } | 2161 | } |
2162 | 2162 | ||
2163 | 2163 | ||
2164 | static int do_proc_dointvec_conv(int *negp, unsigned long *lvalp, | 2164 | static int do_proc_dointvec_conv(int *negp, unsigned long *lvalp, |
2165 | int *valp, | 2165 | int *valp, |
2166 | int write, void *data) | 2166 | int write, void *data) |
2167 | { | 2167 | { |
2168 | if (write) { | 2168 | if (write) { |
2169 | *valp = *negp ? -*lvalp : *lvalp; | 2169 | *valp = *negp ? -*lvalp : *lvalp; |
2170 | } else { | 2170 | } else { |
2171 | int val = *valp; | 2171 | int val = *valp; |
2172 | if (val < 0) { | 2172 | if (val < 0) { |
2173 | *negp = -1; | 2173 | *negp = -1; |
2174 | *lvalp = (unsigned long)-val; | 2174 | *lvalp = (unsigned long)-val; |
2175 | } else { | 2175 | } else { |
2176 | *negp = 0; | 2176 | *negp = 0; |
2177 | *lvalp = (unsigned long)val; | 2177 | *lvalp = (unsigned long)val; |
2178 | } | 2178 | } |
2179 | } | 2179 | } |
2180 | return 0; | 2180 | return 0; |
2181 | } | 2181 | } |
2182 | 2182 | ||
2183 | static int __do_proc_dointvec(void *tbl_data, struct ctl_table *table, | 2183 | static int __do_proc_dointvec(void *tbl_data, struct ctl_table *table, |
2184 | int write, struct file *filp, void __user *buffer, | 2184 | int write, struct file *filp, void __user *buffer, |
2185 | size_t *lenp, loff_t *ppos, | 2185 | size_t *lenp, loff_t *ppos, |
2186 | int (*conv)(int *negp, unsigned long *lvalp, int *valp, | 2186 | int (*conv)(int *negp, unsigned long *lvalp, int *valp, |
2187 | int write, void *data), | 2187 | int write, void *data), |
2188 | void *data) | 2188 | void *data) |
2189 | { | 2189 | { |
2190 | #define TMPBUFLEN 21 | 2190 | #define TMPBUFLEN 21 |
2191 | int *i, vleft, first=1, neg, val; | 2191 | int *i, vleft, first=1, neg, val; |
2192 | unsigned long lval; | 2192 | unsigned long lval; |
2193 | size_t left, len; | 2193 | size_t left, len; |
2194 | 2194 | ||
2195 | char buf[TMPBUFLEN], *p; | 2195 | char buf[TMPBUFLEN], *p; |
2196 | char __user *s = buffer; | 2196 | char __user *s = buffer; |
2197 | 2197 | ||
2198 | if (!tbl_data || !table->maxlen || !*lenp || | 2198 | if (!tbl_data || !table->maxlen || !*lenp || |
2199 | (*ppos && !write)) { | 2199 | (*ppos && !write)) { |
2200 | *lenp = 0; | 2200 | *lenp = 0; |
2201 | return 0; | 2201 | return 0; |
2202 | } | 2202 | } |
2203 | 2203 | ||
2204 | i = (int *) tbl_data; | 2204 | i = (int *) tbl_data; |
2205 | vleft = table->maxlen / sizeof(*i); | 2205 | vleft = table->maxlen / sizeof(*i); |
2206 | left = *lenp; | 2206 | left = *lenp; |
2207 | 2207 | ||
2208 | if (!conv) | 2208 | if (!conv) |
2209 | conv = do_proc_dointvec_conv; | 2209 | conv = do_proc_dointvec_conv; |
2210 | 2210 | ||
2211 | for (; left && vleft--; i++, first=0) { | 2211 | for (; left && vleft--; i++, first=0) { |
2212 | if (write) { | 2212 | if (write) { |
2213 | while (left) { | 2213 | while (left) { |
2214 | char c; | 2214 | char c; |
2215 | if (get_user(c, s)) | 2215 | if (get_user(c, s)) |
2216 | return -EFAULT; | 2216 | return -EFAULT; |
2217 | if (!isspace(c)) | 2217 | if (!isspace(c)) |
2218 | break; | 2218 | break; |
2219 | left--; | 2219 | left--; |
2220 | s++; | 2220 | s++; |
2221 | } | 2221 | } |
2222 | if (!left) | 2222 | if (!left) |
2223 | break; | 2223 | break; |
2224 | neg = 0; | 2224 | neg = 0; |
2225 | len = left; | 2225 | len = left; |
2226 | if (len > sizeof(buf) - 1) | 2226 | if (len > sizeof(buf) - 1) |
2227 | len = sizeof(buf) - 1; | 2227 | len = sizeof(buf) - 1; |
2228 | if (copy_from_user(buf, s, len)) | 2228 | if (copy_from_user(buf, s, len)) |
2229 | return -EFAULT; | 2229 | return -EFAULT; |
2230 | buf[len] = 0; | 2230 | buf[len] = 0; |
2231 | p = buf; | 2231 | p = buf; |
2232 | if (*p == '-' && left > 1) { | 2232 | if (*p == '-' && left > 1) { |
2233 | neg = 1; | 2233 | neg = 1; |
2234 | p++; | 2234 | p++; |
2235 | } | 2235 | } |
2236 | if (*p < '0' || *p > '9') | 2236 | if (*p < '0' || *p > '9') |
2237 | break; | 2237 | break; |
2238 | 2238 | ||
2239 | lval = simple_strtoul(p, &p, 0); | 2239 | lval = simple_strtoul(p, &p, 0); |
2240 | 2240 | ||
2241 | len = p-buf; | 2241 | len = p-buf; |
2242 | if ((len < left) && *p && !isspace(*p)) | 2242 | if ((len < left) && *p && !isspace(*p)) |
2243 | break; | 2243 | break; |
2244 | if (neg) | 2244 | if (neg) |
2245 | val = -val; | 2245 | val = -val; |
2246 | s += len; | 2246 | s += len; |
2247 | left -= len; | 2247 | left -= len; |
2248 | 2248 | ||
2249 | if (conv(&neg, &lval, i, 1, data)) | 2249 | if (conv(&neg, &lval, i, 1, data)) |
2250 | break; | 2250 | break; |
2251 | } else { | 2251 | } else { |
2252 | p = buf; | 2252 | p = buf; |
2253 | if (!first) | 2253 | if (!first) |
2254 | *p++ = '\t'; | 2254 | *p++ = '\t'; |
2255 | 2255 | ||
2256 | if (conv(&neg, &lval, i, 0, data)) | 2256 | if (conv(&neg, &lval, i, 0, data)) |
2257 | break; | 2257 | break; |
2258 | 2258 | ||
2259 | sprintf(p, "%s%lu", neg ? "-" : "", lval); | 2259 | sprintf(p, "%s%lu", neg ? "-" : "", lval); |
2260 | len = strlen(buf); | 2260 | len = strlen(buf); |
2261 | if (len > left) | 2261 | if (len > left) |
2262 | len = left; | 2262 | len = left; |
2263 | if(copy_to_user(s, buf, len)) | 2263 | if(copy_to_user(s, buf, len)) |
2264 | return -EFAULT; | 2264 | return -EFAULT; |
2265 | left -= len; | 2265 | left -= len; |
2266 | s += len; | 2266 | s += len; |
2267 | } | 2267 | } |
2268 | } | 2268 | } |
2269 | 2269 | ||
2270 | if (!write && !first && left) { | 2270 | if (!write && !first && left) { |
2271 | if(put_user('\n', s)) | 2271 | if(put_user('\n', s)) |
2272 | return -EFAULT; | 2272 | return -EFAULT; |
2273 | left--, s++; | 2273 | left--, s++; |
2274 | } | 2274 | } |
2275 | if (write) { | 2275 | if (write) { |
2276 | while (left) { | 2276 | while (left) { |
2277 | char c; | 2277 | char c; |
2278 | if (get_user(c, s++)) | 2278 | if (get_user(c, s++)) |
2279 | return -EFAULT; | 2279 | return -EFAULT; |
2280 | if (!isspace(c)) | 2280 | if (!isspace(c)) |
2281 | break; | 2281 | break; |
2282 | left--; | 2282 | left--; |
2283 | } | 2283 | } |
2284 | } | 2284 | } |
2285 | if (write && first) | 2285 | if (write && first) |
2286 | return -EINVAL; | 2286 | return -EINVAL; |
2287 | *lenp -= left; | 2287 | *lenp -= left; |
2288 | *ppos += *lenp; | 2288 | *ppos += *lenp; |
2289 | return 0; | 2289 | return 0; |
2290 | #undef TMPBUFLEN | 2290 | #undef TMPBUFLEN |
2291 | } | 2291 | } |
2292 | 2292 | ||
2293 | static int do_proc_dointvec(struct ctl_table *table, int write, struct file *filp, | 2293 | static int do_proc_dointvec(struct ctl_table *table, int write, struct file *filp, |
2294 | void __user *buffer, size_t *lenp, loff_t *ppos, | 2294 | void __user *buffer, size_t *lenp, loff_t *ppos, |
2295 | int (*conv)(int *negp, unsigned long *lvalp, int *valp, | 2295 | int (*conv)(int *negp, unsigned long *lvalp, int *valp, |
2296 | int write, void *data), | 2296 | int write, void *data), |
2297 | void *data) | 2297 | void *data) |
2298 | { | 2298 | { |
2299 | return __do_proc_dointvec(table->data, table, write, filp, | 2299 | return __do_proc_dointvec(table->data, table, write, filp, |
2300 | buffer, lenp, ppos, conv, data); | 2300 | buffer, lenp, ppos, conv, data); |
2301 | } | 2301 | } |
2302 | 2302 | ||
2303 | /** | 2303 | /** |
2304 | * proc_dointvec - read a vector of integers | 2304 | * proc_dointvec - read a vector of integers |
2305 | * @table: the sysctl table | 2305 | * @table: the sysctl table |
2306 | * @write: %TRUE if this is a write to the sysctl file | 2306 | * @write: %TRUE if this is a write to the sysctl file |
2307 | * @filp: the file structure | 2307 | * @filp: the file structure |
2308 | * @buffer: the user buffer | 2308 | * @buffer: the user buffer |
2309 | * @lenp: the size of the user buffer | 2309 | * @lenp: the size of the user buffer |
2310 | * @ppos: file position | 2310 | * @ppos: file position |
2311 | * | 2311 | * |
2312 | * Reads/writes up to table->maxlen/sizeof(unsigned int) integer | 2312 | * Reads/writes up to table->maxlen/sizeof(unsigned int) integer |
2313 | * values from/to the user buffer, treated as an ASCII string. | 2313 | * values from/to the user buffer, treated as an ASCII string. |
2314 | * | 2314 | * |
2315 | * Returns 0 on success. | 2315 | * Returns 0 on success. |
2316 | */ | 2316 | */ |
2317 | int proc_dointvec(struct ctl_table *table, int write, struct file *filp, | 2317 | int proc_dointvec(struct ctl_table *table, int write, struct file *filp, |
2318 | void __user *buffer, size_t *lenp, loff_t *ppos) | 2318 | void __user *buffer, size_t *lenp, loff_t *ppos) |
2319 | { | 2319 | { |
2320 | return do_proc_dointvec(table,write,filp,buffer,lenp,ppos, | 2320 | return do_proc_dointvec(table,write,filp,buffer,lenp,ppos, |
2321 | NULL,NULL); | 2321 | NULL,NULL); |
2322 | } | 2322 | } |
2323 | 2323 | ||
2324 | /* | 2324 | /* |
2325 | * Taint values can only be increased | 2325 | * Taint values can only be increased |
2326 | * This means we can safely use a temporary. | 2326 | * This means we can safely use a temporary. |
2327 | */ | 2327 | */ |
2328 | static int proc_taint(struct ctl_table *table, int write, struct file *filp, | 2328 | static int proc_taint(struct ctl_table *table, int write, struct file *filp, |
2329 | void __user *buffer, size_t *lenp, loff_t *ppos) | 2329 | void __user *buffer, size_t *lenp, loff_t *ppos) |
2330 | { | 2330 | { |
2331 | struct ctl_table t; | 2331 | struct ctl_table t; |
2332 | unsigned long tmptaint = get_taint(); | 2332 | unsigned long tmptaint = get_taint(); |
2333 | int err; | 2333 | int err; |
2334 | 2334 | ||
2335 | if (write && !capable(CAP_SYS_ADMIN)) | 2335 | if (write && !capable(CAP_SYS_ADMIN)) |
2336 | return -EPERM; | 2336 | return -EPERM; |
2337 | 2337 | ||
2338 | t = *table; | 2338 | t = *table; |
2339 | t.data = &tmptaint; | 2339 | t.data = &tmptaint; |
2340 | err = proc_doulongvec_minmax(&t, write, filp, buffer, lenp, ppos); | 2340 | err = proc_doulongvec_minmax(&t, write, filp, buffer, lenp, ppos); |
2341 | if (err < 0) | 2341 | if (err < 0) |
2342 | return err; | 2342 | return err; |
2343 | 2343 | ||
2344 | if (write) { | 2344 | if (write) { |
2345 | /* | 2345 | /* |
2346 | * Poor man's atomic or. Not worth adding a primitive | 2346 | * Poor man's atomic or. Not worth adding a primitive |
2347 | * to everyone's atomic.h for this | 2347 | * to everyone's atomic.h for this |
2348 | */ | 2348 | */ |
2349 | int i; | 2349 | int i; |
2350 | for (i = 0; i < BITS_PER_LONG && tmptaint >> i; i++) { | 2350 | for (i = 0; i < BITS_PER_LONG && tmptaint >> i; i++) { |
2351 | if ((tmptaint >> i) & 1) | 2351 | if ((tmptaint >> i) & 1) |
2352 | add_taint(i); | 2352 | add_taint(i); |
2353 | } | 2353 | } |
2354 | } | 2354 | } |
2355 | 2355 | ||
2356 | return err; | 2356 | return err; |
2357 | } | 2357 | } |
2358 | 2358 | ||
2359 | struct do_proc_dointvec_minmax_conv_param { | 2359 | struct do_proc_dointvec_minmax_conv_param { |
2360 | int *min; | 2360 | int *min; |
2361 | int *max; | 2361 | int *max; |
2362 | }; | 2362 | }; |
2363 | 2363 | ||
2364 | static int do_proc_dointvec_minmax_conv(int *negp, unsigned long *lvalp, | 2364 | static int do_proc_dointvec_minmax_conv(int *negp, unsigned long *lvalp, |
2365 | int *valp, | 2365 | int *valp, |
2366 | int write, void *data) | 2366 | int write, void *data) |
2367 | { | 2367 | { |
2368 | struct do_proc_dointvec_minmax_conv_param *param = data; | 2368 | struct do_proc_dointvec_minmax_conv_param *param = data; |
2369 | if (write) { | 2369 | if (write) { |
2370 | int val = *negp ? -*lvalp : *lvalp; | 2370 | int val = *negp ? -*lvalp : *lvalp; |
2371 | if ((param->min && *param->min > val) || | 2371 | if ((param->min && *param->min > val) || |
2372 | (param->max && *param->max < val)) | 2372 | (param->max && *param->max < val)) |
2373 | return -EINVAL; | 2373 | return -EINVAL; |
2374 | *valp = val; | 2374 | *valp = val; |
2375 | } else { | 2375 | } else { |
2376 | int val = *valp; | 2376 | int val = *valp; |
2377 | if (val < 0) { | 2377 | if (val < 0) { |
2378 | *negp = -1; | 2378 | *negp = -1; |
2379 | *lvalp = (unsigned long)-val; | 2379 | *lvalp = (unsigned long)-val; |
2380 | } else { | 2380 | } else { |
2381 | *negp = 0; | 2381 | *negp = 0; |
2382 | *lvalp = (unsigned long)val; | 2382 | *lvalp = (unsigned long)val; |
2383 | } | 2383 | } |
2384 | } | 2384 | } |
2385 | return 0; | 2385 | return 0; |
2386 | } | 2386 | } |
2387 | 2387 | ||
2388 | /** | 2388 | /** |
2389 | * proc_dointvec_minmax - read a vector of integers with min/max values | 2389 | * proc_dointvec_minmax - read a vector of integers with min/max values |
2390 | * @table: the sysctl table | 2390 | * @table: the sysctl table |
2391 | * @write: %TRUE if this is a write to the sysctl file | 2391 | * @write: %TRUE if this is a write to the sysctl file |
2392 | * @filp: the file structure | 2392 | * @filp: the file structure |
2393 | * @buffer: the user buffer | 2393 | * @buffer: the user buffer |
2394 | * @lenp: the size of the user buffer | 2394 | * @lenp: the size of the user buffer |
2395 | * @ppos: file position | 2395 | * @ppos: file position |
2396 | * | 2396 | * |
2397 | * Reads/writes up to table->maxlen/sizeof(unsigned int) integer | 2397 | * Reads/writes up to table->maxlen/sizeof(unsigned int) integer |
2398 | * values from/to the user buffer, treated as an ASCII string. | 2398 | * values from/to the user buffer, treated as an ASCII string. |
2399 | * | 2399 | * |
2400 | * This routine will ensure the values are within the range specified by | 2400 | * This routine will ensure the values are within the range specified by |
2401 | * table->extra1 (min) and table->extra2 (max). | 2401 | * table->extra1 (min) and table->extra2 (max). |
2402 | * | 2402 | * |
2403 | * Returns 0 on success. | 2403 | * Returns 0 on success. |
2404 | */ | 2404 | */ |
2405 | int proc_dointvec_minmax(struct ctl_table *table, int write, struct file *filp, | 2405 | int proc_dointvec_minmax(struct ctl_table *table, int write, struct file *filp, |
2406 | void __user *buffer, size_t *lenp, loff_t *ppos) | 2406 | void __user *buffer, size_t *lenp, loff_t *ppos) |
2407 | { | 2407 | { |
2408 | struct do_proc_dointvec_minmax_conv_param param = { | 2408 | struct do_proc_dointvec_minmax_conv_param param = { |
2409 | .min = (int *) table->extra1, | 2409 | .min = (int *) table->extra1, |
2410 | .max = (int *) table->extra2, | 2410 | .max = (int *) table->extra2, |
2411 | }; | 2411 | }; |
2412 | return do_proc_dointvec(table, write, filp, buffer, lenp, ppos, | 2412 | return do_proc_dointvec(table, write, filp, buffer, lenp, ppos, |
2413 | do_proc_dointvec_minmax_conv, ¶m); | 2413 | do_proc_dointvec_minmax_conv, ¶m); |
2414 | } | 2414 | } |
2415 | 2415 | ||
2416 | static int __do_proc_doulongvec_minmax(void *data, struct ctl_table *table, int write, | 2416 | static int __do_proc_doulongvec_minmax(void *data, struct ctl_table *table, int write, |
2417 | struct file *filp, | 2417 | struct file *filp, |
2418 | void __user *buffer, | 2418 | void __user *buffer, |
2419 | size_t *lenp, loff_t *ppos, | 2419 | size_t *lenp, loff_t *ppos, |
2420 | unsigned long convmul, | 2420 | unsigned long convmul, |
2421 | unsigned long convdiv) | 2421 | unsigned long convdiv) |
2422 | { | 2422 | { |
2423 | #define TMPBUFLEN 21 | 2423 | #define TMPBUFLEN 21 |
2424 | unsigned long *i, *min, *max, val; | 2424 | unsigned long *i, *min, *max, val; |
2425 | int vleft, first=1, neg; | 2425 | int vleft, first=1, neg; |
2426 | size_t len, left; | 2426 | size_t len, left; |
2427 | char buf[TMPBUFLEN], *p; | 2427 | char buf[TMPBUFLEN], *p; |
2428 | char __user *s = buffer; | 2428 | char __user *s = buffer; |
2429 | 2429 | ||
2430 | if (!data || !table->maxlen || !*lenp || | 2430 | if (!data || !table->maxlen || !*lenp || |
2431 | (*ppos && !write)) { | 2431 | (*ppos && !write)) { |
2432 | *lenp = 0; | 2432 | *lenp = 0; |
2433 | return 0; | 2433 | return 0; |
2434 | } | 2434 | } |
2435 | 2435 | ||
2436 | i = (unsigned long *) data; | 2436 | i = (unsigned long *) data; |
2437 | min = (unsigned long *) table->extra1; | 2437 | min = (unsigned long *) table->extra1; |
2438 | max = (unsigned long *) table->extra2; | 2438 | max = (unsigned long *) table->extra2; |
2439 | vleft = table->maxlen / sizeof(unsigned long); | 2439 | vleft = table->maxlen / sizeof(unsigned long); |
2440 | left = *lenp; | 2440 | left = *lenp; |
2441 | 2441 | ||
2442 | for (; left && vleft--; i++, min++, max++, first=0) { | 2442 | for (; left && vleft--; i++, min++, max++, first=0) { |
2443 | if (write) { | 2443 | if (write) { |
2444 | while (left) { | 2444 | while (left) { |
2445 | char c; | 2445 | char c; |
2446 | if (get_user(c, s)) | 2446 | if (get_user(c, s)) |
2447 | return -EFAULT; | 2447 | return -EFAULT; |
2448 | if (!isspace(c)) | 2448 | if (!isspace(c)) |
2449 | break; | 2449 | break; |
2450 | left--; | 2450 | left--; |
2451 | s++; | 2451 | s++; |
2452 | } | 2452 | } |
2453 | if (!left) | 2453 | if (!left) |
2454 | break; | 2454 | break; |
2455 | neg = 0; | 2455 | neg = 0; |
2456 | len = left; | 2456 | len = left; |
2457 | if (len > TMPBUFLEN-1) | 2457 | if (len > TMPBUFLEN-1) |
2458 | len = TMPBUFLEN-1; | 2458 | len = TMPBUFLEN-1; |
2459 | if (copy_from_user(buf, s, len)) | 2459 | if (copy_from_user(buf, s, len)) |
2460 | return -EFAULT; | 2460 | return -EFAULT; |
2461 | buf[len] = 0; | 2461 | buf[len] = 0; |
2462 | p = buf; | 2462 | p = buf; |
2463 | if (*p == '-' && left > 1) { | 2463 | if (*p == '-' && left > 1) { |
2464 | neg = 1; | 2464 | neg = 1; |
2465 | p++; | 2465 | p++; |
2466 | } | 2466 | } |
2467 | if (*p < '0' || *p > '9') | 2467 | if (*p < '0' || *p > '9') |
2468 | break; | 2468 | break; |
2469 | val = simple_strtoul(p, &p, 0) * convmul / convdiv ; | 2469 | val = simple_strtoul(p, &p, 0) * convmul / convdiv ; |
2470 | len = p-buf; | 2470 | len = p-buf; |
2471 | if ((len < left) && *p && !isspace(*p)) | 2471 | if ((len < left) && *p && !isspace(*p)) |
2472 | break; | 2472 | break; |
2473 | if (neg) | 2473 | if (neg) |
2474 | val = -val; | 2474 | val = -val; |
2475 | s += len; | 2475 | s += len; |
2476 | left -= len; | 2476 | left -= len; |
2477 | 2477 | ||
2478 | if(neg) | 2478 | if(neg) |
2479 | continue; | 2479 | continue; |
2480 | if ((min && val < *min) || (max && val > *max)) | 2480 | if ((min && val < *min) || (max && val > *max)) |
2481 | continue; | 2481 | continue; |
2482 | *i = val; | 2482 | *i = val; |
2483 | } else { | 2483 | } else { |
2484 | p = buf; | 2484 | p = buf; |
2485 | if (!first) | 2485 | if (!first) |
2486 | *p++ = '\t'; | 2486 | *p++ = '\t'; |
2487 | sprintf(p, "%lu", convdiv * (*i) / convmul); | 2487 | sprintf(p, "%lu", convdiv * (*i) / convmul); |
2488 | len = strlen(buf); | 2488 | len = strlen(buf); |
2489 | if (len > left) | 2489 | if (len > left) |
2490 | len = left; | 2490 | len = left; |
2491 | if(copy_to_user(s, buf, len)) | 2491 | if(copy_to_user(s, buf, len)) |
2492 | return -EFAULT; | 2492 | return -EFAULT; |
2493 | left -= len; | 2493 | left -= len; |
2494 | s += len; | 2494 | s += len; |
2495 | } | 2495 | } |
2496 | } | 2496 | } |
2497 | 2497 | ||
2498 | if (!write && !first && left) { | 2498 | if (!write && !first && left) { |
2499 | if(put_user('\n', s)) | 2499 | if(put_user('\n', s)) |
2500 | return -EFAULT; | 2500 | return -EFAULT; |
2501 | left--, s++; | 2501 | left--, s++; |
2502 | } | 2502 | } |
2503 | if (write) { | 2503 | if (write) { |
2504 | while (left) { | 2504 | while (left) { |
2505 | char c; | 2505 | char c; |
2506 | if (get_user(c, s++)) | 2506 | if (get_user(c, s++)) |
2507 | return -EFAULT; | 2507 | return -EFAULT; |
2508 | if (!isspace(c)) | 2508 | if (!isspace(c)) |
2509 | break; | 2509 | break; |
2510 | left--; | 2510 | left--; |
2511 | } | 2511 | } |
2512 | } | 2512 | } |
2513 | if (write && first) | 2513 | if (write && first) |
2514 | return -EINVAL; | 2514 | return -EINVAL; |
2515 | *lenp -= left; | 2515 | *lenp -= left; |
2516 | *ppos += *lenp; | 2516 | *ppos += *lenp; |
2517 | return 0; | 2517 | return 0; |
2518 | #undef TMPBUFLEN | 2518 | #undef TMPBUFLEN |
2519 | } | 2519 | } |
2520 | 2520 | ||
2521 | static int do_proc_doulongvec_minmax(struct ctl_table *table, int write, | 2521 | static int do_proc_doulongvec_minmax(struct ctl_table *table, int write, |
2522 | struct file *filp, | 2522 | struct file *filp, |
2523 | void __user *buffer, | 2523 | void __user *buffer, |
2524 | size_t *lenp, loff_t *ppos, | 2524 | size_t *lenp, loff_t *ppos, |
2525 | unsigned long convmul, | 2525 | unsigned long convmul, |
2526 | unsigned long convdiv) | 2526 | unsigned long convdiv) |
2527 | { | 2527 | { |
2528 | return __do_proc_doulongvec_minmax(table->data, table, write, | 2528 | return __do_proc_doulongvec_minmax(table->data, table, write, |
2529 | filp, buffer, lenp, ppos, convmul, convdiv); | 2529 | filp, buffer, lenp, ppos, convmul, convdiv); |
2530 | } | 2530 | } |
2531 | 2531 | ||
2532 | /** | 2532 | /** |
2533 | * proc_doulongvec_minmax - read a vector of long integers with min/max values | 2533 | * proc_doulongvec_minmax - read a vector of long integers with min/max values |
2534 | * @table: the sysctl table | 2534 | * @table: the sysctl table |
2535 | * @write: %TRUE if this is a write to the sysctl file | 2535 | * @write: %TRUE if this is a write to the sysctl file |
2536 | * @filp: the file structure | 2536 | * @filp: the file structure |
2537 | * @buffer: the user buffer | 2537 | * @buffer: the user buffer |
2538 | * @lenp: the size of the user buffer | 2538 | * @lenp: the size of the user buffer |
2539 | * @ppos: file position | 2539 | * @ppos: file position |
2540 | * | 2540 | * |
2541 | * Reads/writes up to table->maxlen/sizeof(unsigned long) unsigned long | 2541 | * Reads/writes up to table->maxlen/sizeof(unsigned long) unsigned long |
2542 | * values from/to the user buffer, treated as an ASCII string. | 2542 | * values from/to the user buffer, treated as an ASCII string. |
2543 | * | 2543 | * |
2544 | * This routine will ensure the values are within the range specified by | 2544 | * This routine will ensure the values are within the range specified by |
2545 | * table->extra1 (min) and table->extra2 (max). | 2545 | * table->extra1 (min) and table->extra2 (max). |
2546 | * | 2546 | * |
2547 | * Returns 0 on success. | 2547 | * Returns 0 on success. |
2548 | */ | 2548 | */ |
2549 | int proc_doulongvec_minmax(struct ctl_table *table, int write, struct file *filp, | 2549 | int proc_doulongvec_minmax(struct ctl_table *table, int write, struct file *filp, |
2550 | void __user *buffer, size_t *lenp, loff_t *ppos) | 2550 | void __user *buffer, size_t *lenp, loff_t *ppos) |
2551 | { | 2551 | { |
2552 | return do_proc_doulongvec_minmax(table, write, filp, buffer, lenp, ppos, 1l, 1l); | 2552 | return do_proc_doulongvec_minmax(table, write, filp, buffer, lenp, ppos, 1l, 1l); |
2553 | } | 2553 | } |
2554 | 2554 | ||
2555 | /** | 2555 | /** |
2556 | * proc_doulongvec_ms_jiffies_minmax - read a vector of millisecond values with min/max values | 2556 | * proc_doulongvec_ms_jiffies_minmax - read a vector of millisecond values with min/max values |
2557 | * @table: the sysctl table | 2557 | * @table: the sysctl table |
2558 | * @write: %TRUE if this is a write to the sysctl file | 2558 | * @write: %TRUE if this is a write to the sysctl file |
2559 | * @filp: the file structure | 2559 | * @filp: the file structure |
2560 | * @buffer: the user buffer | 2560 | * @buffer: the user buffer |
2561 | * @lenp: the size of the user buffer | 2561 | * @lenp: the size of the user buffer |
2562 | * @ppos: file position | 2562 | * @ppos: file position |
2563 | * | 2563 | * |
2564 | * Reads/writes up to table->maxlen/sizeof(unsigned long) unsigned long | 2564 | * Reads/writes up to table->maxlen/sizeof(unsigned long) unsigned long |
2565 | * values from/to the user buffer, treated as an ASCII string. The values | 2565 | * values from/to the user buffer, treated as an ASCII string. The values |
2566 | * are treated as milliseconds, and converted to jiffies when they are stored. | 2566 | * are treated as milliseconds, and converted to jiffies when they are stored. |
2567 | * | 2567 | * |
2568 | * This routine will ensure the values are within the range specified by | 2568 | * This routine will ensure the values are within the range specified by |
2569 | * table->extra1 (min) and table->extra2 (max). | 2569 | * table->extra1 (min) and table->extra2 (max). |
2570 | * | 2570 | * |
2571 | * Returns 0 on success. | 2571 | * Returns 0 on success. |
2572 | */ | 2572 | */ |
2573 | int proc_doulongvec_ms_jiffies_minmax(struct ctl_table *table, int write, | 2573 | int proc_doulongvec_ms_jiffies_minmax(struct ctl_table *table, int write, |
2574 | struct file *filp, | 2574 | struct file *filp, |
2575 | void __user *buffer, | 2575 | void __user *buffer, |
2576 | size_t *lenp, loff_t *ppos) | 2576 | size_t *lenp, loff_t *ppos) |
2577 | { | 2577 | { |
2578 | return do_proc_doulongvec_minmax(table, write, filp, buffer, | 2578 | return do_proc_doulongvec_minmax(table, write, filp, buffer, |
2579 | lenp, ppos, HZ, 1000l); | 2579 | lenp, ppos, HZ, 1000l); |
2580 | } | 2580 | } |
2581 | 2581 | ||
2582 | 2582 | ||
2583 | static int do_proc_dointvec_jiffies_conv(int *negp, unsigned long *lvalp, | 2583 | static int do_proc_dointvec_jiffies_conv(int *negp, unsigned long *lvalp, |
2584 | int *valp, | 2584 | int *valp, |
2585 | int write, void *data) | 2585 | int write, void *data) |
2586 | { | 2586 | { |
2587 | if (write) { | 2587 | if (write) { |
2588 | if (*lvalp > LONG_MAX / HZ) | 2588 | if (*lvalp > LONG_MAX / HZ) |
2589 | return 1; | 2589 | return 1; |
2590 | *valp = *negp ? -(*lvalp*HZ) : (*lvalp*HZ); | 2590 | *valp = *negp ? -(*lvalp*HZ) : (*lvalp*HZ); |
2591 | } else { | 2591 | } else { |
2592 | int val = *valp; | 2592 | int val = *valp; |
2593 | unsigned long lval; | 2593 | unsigned long lval; |
2594 | if (val < 0) { | 2594 | if (val < 0) { |
2595 | *negp = -1; | 2595 | *negp = -1; |
2596 | lval = (unsigned long)-val; | 2596 | lval = (unsigned long)-val; |
2597 | } else { | 2597 | } else { |
2598 | *negp = 0; | 2598 | *negp = 0; |
2599 | lval = (unsigned long)val; | 2599 | lval = (unsigned long)val; |
2600 | } | 2600 | } |
2601 | *lvalp = lval / HZ; | 2601 | *lvalp = lval / HZ; |
2602 | } | 2602 | } |
2603 | return 0; | 2603 | return 0; |
2604 | } | 2604 | } |
2605 | 2605 | ||
2606 | static int do_proc_dointvec_userhz_jiffies_conv(int *negp, unsigned long *lvalp, | 2606 | static int do_proc_dointvec_userhz_jiffies_conv(int *negp, unsigned long *lvalp, |
2607 | int *valp, | 2607 | int *valp, |
2608 | int write, void *data) | 2608 | int write, void *data) |
2609 | { | 2609 | { |
2610 | if (write) { | 2610 | if (write) { |
2611 | if (USER_HZ < HZ && *lvalp > (LONG_MAX / HZ) * USER_HZ) | 2611 | if (USER_HZ < HZ && *lvalp > (LONG_MAX / HZ) * USER_HZ) |
2612 | return 1; | 2612 | return 1; |
2613 | *valp = clock_t_to_jiffies(*negp ? -*lvalp : *lvalp); | 2613 | *valp = clock_t_to_jiffies(*negp ? -*lvalp : *lvalp); |
2614 | } else { | 2614 | } else { |
2615 | int val = *valp; | 2615 | int val = *valp; |
2616 | unsigned long lval; | 2616 | unsigned long lval; |
2617 | if (val < 0) { | 2617 | if (val < 0) { |
2618 | *negp = -1; | 2618 | *negp = -1; |
2619 | lval = (unsigned long)-val; | 2619 | lval = (unsigned long)-val; |
2620 | } else { | 2620 | } else { |
2621 | *negp = 0; | 2621 | *negp = 0; |
2622 | lval = (unsigned long)val; | 2622 | lval = (unsigned long)val; |
2623 | } | 2623 | } |
2624 | *lvalp = jiffies_to_clock_t(lval); | 2624 | *lvalp = jiffies_to_clock_t(lval); |
2625 | } | 2625 | } |
2626 | return 0; | 2626 | return 0; |
2627 | } | 2627 | } |
2628 | 2628 | ||
2629 | static int do_proc_dointvec_ms_jiffies_conv(int *negp, unsigned long *lvalp, | 2629 | static int do_proc_dointvec_ms_jiffies_conv(int *negp, unsigned long *lvalp, |
2630 | int *valp, | 2630 | int *valp, |
2631 | int write, void *data) | 2631 | int write, void *data) |
2632 | { | 2632 | { |
2633 | if (write) { | 2633 | if (write) { |
2634 | *valp = msecs_to_jiffies(*negp ? -*lvalp : *lvalp); | 2634 | *valp = msecs_to_jiffies(*negp ? -*lvalp : *lvalp); |
2635 | } else { | 2635 | } else { |
2636 | int val = *valp; | 2636 | int val = *valp; |
2637 | unsigned long lval; | 2637 | unsigned long lval; |
2638 | if (val < 0) { | 2638 | if (val < 0) { |
2639 | *negp = -1; | 2639 | *negp = -1; |
2640 | lval = (unsigned long)-val; | 2640 | lval = (unsigned long)-val; |
2641 | } else { | 2641 | } else { |
2642 | *negp = 0; | 2642 | *negp = 0; |
2643 | lval = (unsigned long)val; | 2643 | lval = (unsigned long)val; |
2644 | } | 2644 | } |
2645 | *lvalp = jiffies_to_msecs(lval); | 2645 | *lvalp = jiffies_to_msecs(lval); |
2646 | } | 2646 | } |
2647 | return 0; | 2647 | return 0; |
2648 | } | 2648 | } |
2649 | 2649 | ||
2650 | /** | 2650 | /** |
2651 | * proc_dointvec_jiffies - read a vector of integers as seconds | 2651 | * proc_dointvec_jiffies - read a vector of integers as seconds |
2652 | * @table: the sysctl table | 2652 | * @table: the sysctl table |
2653 | * @write: %TRUE if this is a write to the sysctl file | 2653 | * @write: %TRUE if this is a write to the sysctl file |
2654 | * @filp: the file structure | 2654 | * @filp: the file structure |
2655 | * @buffer: the user buffer | 2655 | * @buffer: the user buffer |
2656 | * @lenp: the size of the user buffer | 2656 | * @lenp: the size of the user buffer |
2657 | * @ppos: file position | 2657 | * @ppos: file position |
2658 | * | 2658 | * |
2659 | * Reads/writes up to table->maxlen/sizeof(unsigned int) integer | 2659 | * Reads/writes up to table->maxlen/sizeof(unsigned int) integer |
2660 | * values from/to the user buffer, treated as an ASCII string. | 2660 | * values from/to the user buffer, treated as an ASCII string. |
2661 | * The values read are assumed to be in seconds, and are converted into | 2661 | * The values read are assumed to be in seconds, and are converted into |
2662 | * jiffies. | 2662 | * jiffies. |
2663 | * | 2663 | * |
2664 | * Returns 0 on success. | 2664 | * Returns 0 on success. |
2665 | */ | 2665 | */ |
2666 | int proc_dointvec_jiffies(struct ctl_table *table, int write, struct file *filp, | 2666 | int proc_dointvec_jiffies(struct ctl_table *table, int write, struct file *filp, |
2667 | void __user *buffer, size_t *lenp, loff_t *ppos) | 2667 | void __user *buffer, size_t *lenp, loff_t *ppos) |
2668 | { | 2668 | { |
2669 | return do_proc_dointvec(table,write,filp,buffer,lenp,ppos, | 2669 | return do_proc_dointvec(table,write,filp,buffer,lenp,ppos, |
2670 | do_proc_dointvec_jiffies_conv,NULL); | 2670 | do_proc_dointvec_jiffies_conv,NULL); |
2671 | } | 2671 | } |
2672 | 2672 | ||
2673 | /** | 2673 | /** |
2674 | * proc_dointvec_userhz_jiffies - read a vector of integers as 1/USER_HZ seconds | 2674 | * proc_dointvec_userhz_jiffies - read a vector of integers as 1/USER_HZ seconds |
2675 | * @table: the sysctl table | 2675 | * @table: the sysctl table |
2676 | * @write: %TRUE if this is a write to the sysctl file | 2676 | * @write: %TRUE if this is a write to the sysctl file |
2677 | * @filp: the file structure | 2677 | * @filp: the file structure |
2678 | * @buffer: the user buffer | 2678 | * @buffer: the user buffer |
2679 | * @lenp: the size of the user buffer | 2679 | * @lenp: the size of the user buffer |
2680 | * @ppos: pointer to the file position | 2680 | * @ppos: pointer to the file position |
2681 | * | 2681 | * |
2682 | * Reads/writes up to table->maxlen/sizeof(unsigned int) integer | 2682 | * Reads/writes up to table->maxlen/sizeof(unsigned int) integer |
2683 | * values from/to the user buffer, treated as an ASCII string. | 2683 | * values from/to the user buffer, treated as an ASCII string. |
2684 | * The values read are assumed to be in 1/USER_HZ seconds, and | 2684 | * The values read are assumed to be in 1/USER_HZ seconds, and |
2685 | * are converted into jiffies. | 2685 | * are converted into jiffies. |
2686 | * | 2686 | * |
2687 | * Returns 0 on success. | 2687 | * Returns 0 on success. |
2688 | */ | 2688 | */ |
2689 | int proc_dointvec_userhz_jiffies(struct ctl_table *table, int write, struct file *filp, | 2689 | int proc_dointvec_userhz_jiffies(struct ctl_table *table, int write, struct file *filp, |
2690 | void __user *buffer, size_t *lenp, loff_t *ppos) | 2690 | void __user *buffer, size_t *lenp, loff_t *ppos) |
2691 | { | 2691 | { |
2692 | return do_proc_dointvec(table,write,filp,buffer,lenp,ppos, | 2692 | return do_proc_dointvec(table,write,filp,buffer,lenp,ppos, |
2693 | do_proc_dointvec_userhz_jiffies_conv,NULL); | 2693 | do_proc_dointvec_userhz_jiffies_conv,NULL); |
2694 | } | 2694 | } |
2695 | 2695 | ||
2696 | /** | 2696 | /** |
2697 | * proc_dointvec_ms_jiffies - read a vector of integers as 1 milliseconds | 2697 | * proc_dointvec_ms_jiffies - read a vector of integers as 1 milliseconds |
2698 | * @table: the sysctl table | 2698 | * @table: the sysctl table |
2699 | * @write: %TRUE if this is a write to the sysctl file | 2699 | * @write: %TRUE if this is a write to the sysctl file |
2700 | * @filp: the file structure | 2700 | * @filp: the file structure |
2701 | * @buffer: the user buffer | 2701 | * @buffer: the user buffer |
2702 | * @lenp: the size of the user buffer | 2702 | * @lenp: the size of the user buffer |
2703 | * @ppos: file position | 2703 | * @ppos: file position |
2704 | * @ppos: the current position in the file | 2704 | * @ppos: the current position in the file |
2705 | * | 2705 | * |
2706 | * Reads/writes up to table->maxlen/sizeof(unsigned int) integer | 2706 | * Reads/writes up to table->maxlen/sizeof(unsigned int) integer |
2707 | * values from/to the user buffer, treated as an ASCII string. | 2707 | * values from/to the user buffer, treated as an ASCII string. |
2708 | * The values read are assumed to be in 1/1000 seconds, and | 2708 | * The values read are assumed to be in 1/1000 seconds, and |
2709 | * are converted into jiffies. | 2709 | * are converted into jiffies. |
2710 | * | 2710 | * |
2711 | * Returns 0 on success. | 2711 | * Returns 0 on success. |
2712 | */ | 2712 | */ |
2713 | int proc_dointvec_ms_jiffies(struct ctl_table *table, int write, struct file *filp, | 2713 | int proc_dointvec_ms_jiffies(struct ctl_table *table, int write, struct file *filp, |
2714 | void __user *buffer, size_t *lenp, loff_t *ppos) | 2714 | void __user *buffer, size_t *lenp, loff_t *ppos) |
2715 | { | 2715 | { |
2716 | return do_proc_dointvec(table, write, filp, buffer, lenp, ppos, | 2716 | return do_proc_dointvec(table, write, filp, buffer, lenp, ppos, |
2717 | do_proc_dointvec_ms_jiffies_conv, NULL); | 2717 | do_proc_dointvec_ms_jiffies_conv, NULL); |
2718 | } | 2718 | } |
2719 | 2719 | ||
2720 | static int proc_do_cad_pid(struct ctl_table *table, int write, struct file *filp, | 2720 | static int proc_do_cad_pid(struct ctl_table *table, int write, struct file *filp, |
2721 | void __user *buffer, size_t *lenp, loff_t *ppos) | 2721 | void __user *buffer, size_t *lenp, loff_t *ppos) |
2722 | { | 2722 | { |
2723 | struct pid *new_pid; | 2723 | struct pid *new_pid; |
2724 | pid_t tmp; | 2724 | pid_t tmp; |
2725 | int r; | 2725 | int r; |
2726 | 2726 | ||
2727 | tmp = pid_vnr(cad_pid); | 2727 | tmp = pid_vnr(cad_pid); |
2728 | 2728 | ||
2729 | r = __do_proc_dointvec(&tmp, table, write, filp, buffer, | 2729 | r = __do_proc_dointvec(&tmp, table, write, filp, buffer, |
2730 | lenp, ppos, NULL, NULL); | 2730 | lenp, ppos, NULL, NULL); |
2731 | if (r || !write) | 2731 | if (r || !write) |
2732 | return r; | 2732 | return r; |
2733 | 2733 | ||
2734 | new_pid = find_get_pid(tmp); | 2734 | new_pid = find_get_pid(tmp); |
2735 | if (!new_pid) | 2735 | if (!new_pid) |
2736 | return -ESRCH; | 2736 | return -ESRCH; |
2737 | 2737 | ||
2738 | put_pid(xchg(&cad_pid, new_pid)); | 2738 | put_pid(xchg(&cad_pid, new_pid)); |
2739 | return 0; | 2739 | return 0; |
2740 | } | 2740 | } |
2741 | 2741 | ||
2742 | #else /* CONFIG_PROC_FS */ | 2742 | #else /* CONFIG_PROC_FS */ |
2743 | 2743 | ||
2744 | int proc_dostring(struct ctl_table *table, int write, struct file *filp, | 2744 | int proc_dostring(struct ctl_table *table, int write, struct file *filp, |
2745 | void __user *buffer, size_t *lenp, loff_t *ppos) | 2745 | void __user *buffer, size_t *lenp, loff_t *ppos) |
2746 | { | 2746 | { |
2747 | return -ENOSYS; | 2747 | return -ENOSYS; |
2748 | } | 2748 | } |
2749 | 2749 | ||
2750 | int proc_dointvec(struct ctl_table *table, int write, struct file *filp, | 2750 | int proc_dointvec(struct ctl_table *table, int write, struct file *filp, |
2751 | void __user *buffer, size_t *lenp, loff_t *ppos) | 2751 | void __user *buffer, size_t *lenp, loff_t *ppos) |
2752 | { | 2752 | { |
2753 | return -ENOSYS; | 2753 | return -ENOSYS; |
2754 | } | 2754 | } |
2755 | 2755 | ||
2756 | int proc_dointvec_minmax(struct ctl_table *table, int write, struct file *filp, | 2756 | int proc_dointvec_minmax(struct ctl_table *table, int write, struct file *filp, |
2757 | void __user *buffer, size_t *lenp, loff_t *ppos) | 2757 | void __user *buffer, size_t *lenp, loff_t *ppos) |
2758 | { | 2758 | { |
2759 | return -ENOSYS; | 2759 | return -ENOSYS; |
2760 | } | 2760 | } |
2761 | 2761 | ||
2762 | int proc_dointvec_jiffies(struct ctl_table *table, int write, struct file *filp, | 2762 | int proc_dointvec_jiffies(struct ctl_table *table, int write, struct file *filp, |
2763 | void __user *buffer, size_t *lenp, loff_t *ppos) | 2763 | void __user *buffer, size_t *lenp, loff_t *ppos) |
2764 | { | 2764 | { |
2765 | return -ENOSYS; | 2765 | return -ENOSYS; |
2766 | } | 2766 | } |
2767 | 2767 | ||
2768 | int proc_dointvec_userhz_jiffies(struct ctl_table *table, int write, struct file *filp, | 2768 | int proc_dointvec_userhz_jiffies(struct ctl_table *table, int write, struct file *filp, |
2769 | void __user *buffer, size_t *lenp, loff_t *ppos) | 2769 | void __user *buffer, size_t *lenp, loff_t *ppos) |
2770 | { | 2770 | { |
2771 | return -ENOSYS; | 2771 | return -ENOSYS; |
2772 | } | 2772 | } |
2773 | 2773 | ||
2774 | int proc_dointvec_ms_jiffies(struct ctl_table *table, int write, struct file *filp, | 2774 | int proc_dointvec_ms_jiffies(struct ctl_table *table, int write, struct file *filp, |
2775 | void __user *buffer, size_t *lenp, loff_t *ppos) | 2775 | void __user *buffer, size_t *lenp, loff_t *ppos) |
2776 | { | 2776 | { |
2777 | return -ENOSYS; | 2777 | return -ENOSYS; |
2778 | } | 2778 | } |
2779 | 2779 | ||
2780 | int proc_doulongvec_minmax(struct ctl_table *table, int write, struct file *filp, | 2780 | int proc_doulongvec_minmax(struct ctl_table *table, int write, struct file *filp, |
2781 | void __user *buffer, size_t *lenp, loff_t *ppos) | 2781 | void __user *buffer, size_t *lenp, loff_t *ppos) |
2782 | { | 2782 | { |
2783 | return -ENOSYS; | 2783 | return -ENOSYS; |
2784 | } | 2784 | } |
2785 | 2785 | ||
2786 | int proc_doulongvec_ms_jiffies_minmax(struct ctl_table *table, int write, | 2786 | int proc_doulongvec_ms_jiffies_minmax(struct ctl_table *table, int write, |
2787 | struct file *filp, | 2787 | struct file *filp, |
2788 | void __user *buffer, | 2788 | void __user *buffer, |
2789 | size_t *lenp, loff_t *ppos) | 2789 | size_t *lenp, loff_t *ppos) |
2790 | { | 2790 | { |
2791 | return -ENOSYS; | 2791 | return -ENOSYS; |
2792 | } | 2792 | } |
2793 | 2793 | ||
2794 | 2794 | ||
2795 | #endif /* CONFIG_PROC_FS */ | 2795 | #endif /* CONFIG_PROC_FS */ |
2796 | 2796 | ||
2797 | 2797 | ||
2798 | #ifdef CONFIG_SYSCTL_SYSCALL | 2798 | #ifdef CONFIG_SYSCTL_SYSCALL |
2799 | /* | 2799 | /* |
2800 | * General sysctl support routines | 2800 | * General sysctl support routines |
2801 | */ | 2801 | */ |
2802 | 2802 | ||
2803 | /* The generic sysctl data routine (used if no strategy routine supplied) */ | 2803 | /* The generic sysctl data routine (used if no strategy routine supplied) */ |
2804 | int sysctl_data(struct ctl_table *table, | 2804 | int sysctl_data(struct ctl_table *table, |
2805 | void __user *oldval, size_t __user *oldlenp, | 2805 | void __user *oldval, size_t __user *oldlenp, |
2806 | void __user *newval, size_t newlen) | 2806 | void __user *newval, size_t newlen) |
2807 | { | 2807 | { |
2808 | size_t len; | 2808 | size_t len; |
2809 | 2809 | ||
2810 | /* Get out of I don't have a variable */ | 2810 | /* Get out of I don't have a variable */ |
2811 | if (!table->data || !table->maxlen) | 2811 | if (!table->data || !table->maxlen) |
2812 | return -ENOTDIR; | 2812 | return -ENOTDIR; |
2813 | 2813 | ||
2814 | if (oldval && oldlenp) { | 2814 | if (oldval && oldlenp) { |
2815 | if (get_user(len, oldlenp)) | 2815 | if (get_user(len, oldlenp)) |
2816 | return -EFAULT; | 2816 | return -EFAULT; |
2817 | if (len) { | 2817 | if (len) { |
2818 | if (len > table->maxlen) | 2818 | if (len > table->maxlen) |
2819 | len = table->maxlen; | 2819 | len = table->maxlen; |
2820 | if (copy_to_user(oldval, table->data, len)) | 2820 | if (copy_to_user(oldval, table->data, len)) |
2821 | return -EFAULT; | 2821 | return -EFAULT; |
2822 | if (put_user(len, oldlenp)) | 2822 | if (put_user(len, oldlenp)) |
2823 | return -EFAULT; | 2823 | return -EFAULT; |
2824 | } | 2824 | } |
2825 | } | 2825 | } |
2826 | 2826 | ||
2827 | if (newval && newlen) { | 2827 | if (newval && newlen) { |
2828 | if (newlen > table->maxlen) | 2828 | if (newlen > table->maxlen) |
2829 | newlen = table->maxlen; | 2829 | newlen = table->maxlen; |
2830 | 2830 | ||
2831 | if (copy_from_user(table->data, newval, newlen)) | 2831 | if (copy_from_user(table->data, newval, newlen)) |
2832 | return -EFAULT; | 2832 | return -EFAULT; |
2833 | } | 2833 | } |
2834 | return 1; | 2834 | return 1; |
2835 | } | 2835 | } |
2836 | 2836 | ||
2837 | /* The generic string strategy routine: */ | 2837 | /* The generic string strategy routine: */ |
2838 | int sysctl_string(struct ctl_table *table, | 2838 | int sysctl_string(struct ctl_table *table, |
2839 | void __user *oldval, size_t __user *oldlenp, | 2839 | void __user *oldval, size_t __user *oldlenp, |
2840 | void __user *newval, size_t newlen) | 2840 | void __user *newval, size_t newlen) |
2841 | { | 2841 | { |
2842 | if (!table->data || !table->maxlen) | 2842 | if (!table->data || !table->maxlen) |
2843 | return -ENOTDIR; | 2843 | return -ENOTDIR; |
2844 | 2844 | ||
2845 | if (oldval && oldlenp) { | 2845 | if (oldval && oldlenp) { |
2846 | size_t bufsize; | 2846 | size_t bufsize; |
2847 | if (get_user(bufsize, oldlenp)) | 2847 | if (get_user(bufsize, oldlenp)) |
2848 | return -EFAULT; | 2848 | return -EFAULT; |
2849 | if (bufsize) { | 2849 | if (bufsize) { |
2850 | size_t len = strlen(table->data), copied; | 2850 | size_t len = strlen(table->data), copied; |
2851 | 2851 | ||
2852 | /* This shouldn't trigger for a well-formed sysctl */ | 2852 | /* This shouldn't trigger for a well-formed sysctl */ |
2853 | if (len > table->maxlen) | 2853 | if (len > table->maxlen) |
2854 | len = table->maxlen; | 2854 | len = table->maxlen; |
2855 | 2855 | ||
2856 | /* Copy up to a max of bufsize-1 bytes of the string */ | 2856 | /* Copy up to a max of bufsize-1 bytes of the string */ |
2857 | copied = (len >= bufsize) ? bufsize - 1 : len; | 2857 | copied = (len >= bufsize) ? bufsize - 1 : len; |
2858 | 2858 | ||
2859 | if (copy_to_user(oldval, table->data, copied) || | 2859 | if (copy_to_user(oldval, table->data, copied) || |
2860 | put_user(0, (char __user *)(oldval + copied))) | 2860 | put_user(0, (char __user *)(oldval + copied))) |
2861 | return -EFAULT; | 2861 | return -EFAULT; |
2862 | if (put_user(len, oldlenp)) | 2862 | if (put_user(len, oldlenp)) |
2863 | return -EFAULT; | 2863 | return -EFAULT; |
2864 | } | 2864 | } |
2865 | } | 2865 | } |
2866 | if (newval && newlen) { | 2866 | if (newval && newlen) { |
2867 | size_t len = newlen; | 2867 | size_t len = newlen; |
2868 | if (len > table->maxlen) | 2868 | if (len > table->maxlen) |
2869 | len = table->maxlen; | 2869 | len = table->maxlen; |
2870 | if(copy_from_user(table->data, newval, len)) | 2870 | if(copy_from_user(table->data, newval, len)) |
2871 | return -EFAULT; | 2871 | return -EFAULT; |
2872 | if (len == table->maxlen) | 2872 | if (len == table->maxlen) |
2873 | len--; | 2873 | len--; |
2874 | ((char *) table->data)[len] = 0; | 2874 | ((char *) table->data)[len] = 0; |
2875 | } | 2875 | } |
2876 | return 1; | 2876 | return 1; |
2877 | } | 2877 | } |
2878 | 2878 | ||
2879 | /* | 2879 | /* |
2880 | * This function makes sure that all of the integers in the vector | 2880 | * This function makes sure that all of the integers in the vector |
2881 | * are between the minimum and maximum values given in the arrays | 2881 | * are between the minimum and maximum values given in the arrays |
2882 | * table->extra1 and table->extra2, respectively. | 2882 | * table->extra1 and table->extra2, respectively. |
2883 | */ | 2883 | */ |
2884 | int sysctl_intvec(struct ctl_table *table, | 2884 | int sysctl_intvec(struct ctl_table *table, |
2885 | void __user *oldval, size_t __user *oldlenp, | 2885 | void __user *oldval, size_t __user *oldlenp, |
2886 | void __user *newval, size_t newlen) | 2886 | void __user *newval, size_t newlen) |
2887 | { | 2887 | { |
2888 | 2888 | ||
2889 | if (newval && newlen) { | 2889 | if (newval && newlen) { |
2890 | int __user *vec = (int __user *) newval; | 2890 | int __user *vec = (int __user *) newval; |
2891 | int *min = (int *) table->extra1; | 2891 | int *min = (int *) table->extra1; |
2892 | int *max = (int *) table->extra2; | 2892 | int *max = (int *) table->extra2; |
2893 | size_t length; | 2893 | size_t length; |
2894 | int i; | 2894 | int i; |
2895 | 2895 | ||
2896 | if (newlen % sizeof(int) != 0) | 2896 | if (newlen % sizeof(int) != 0) |
2897 | return -EINVAL; | 2897 | return -EINVAL; |
2898 | 2898 | ||
2899 | if (!table->extra1 && !table->extra2) | 2899 | if (!table->extra1 && !table->extra2) |
2900 | return 0; | 2900 | return 0; |
2901 | 2901 | ||
2902 | if (newlen > table->maxlen) | 2902 | if (newlen > table->maxlen) |
2903 | newlen = table->maxlen; | 2903 | newlen = table->maxlen; |
2904 | length = newlen / sizeof(int); | 2904 | length = newlen / sizeof(int); |
2905 | 2905 | ||
2906 | for (i = 0; i < length; i++) { | 2906 | for (i = 0; i < length; i++) { |
2907 | int value; | 2907 | int value; |
2908 | if (get_user(value, vec + i)) | 2908 | if (get_user(value, vec + i)) |
2909 | return -EFAULT; | 2909 | return -EFAULT; |
2910 | if (min && value < min[i]) | 2910 | if (min && value < min[i]) |
2911 | return -EINVAL; | 2911 | return -EINVAL; |
2912 | if (max && value > max[i]) | 2912 | if (max && value > max[i]) |
2913 | return -EINVAL; | 2913 | return -EINVAL; |
2914 | } | 2914 | } |
2915 | } | 2915 | } |
2916 | return 0; | 2916 | return 0; |
2917 | } | 2917 | } |
2918 | 2918 | ||
2919 | /* Strategy function to convert jiffies to seconds */ | 2919 | /* Strategy function to convert jiffies to seconds */ |
2920 | int sysctl_jiffies(struct ctl_table *table, | 2920 | int sysctl_jiffies(struct ctl_table *table, |
2921 | void __user *oldval, size_t __user *oldlenp, | 2921 | void __user *oldval, size_t __user *oldlenp, |
2922 | void __user *newval, size_t newlen) | 2922 | void __user *newval, size_t newlen) |
2923 | { | 2923 | { |
2924 | if (oldval && oldlenp) { | 2924 | if (oldval && oldlenp) { |
2925 | size_t olen; | 2925 | size_t olen; |
2926 | 2926 | ||
2927 | if (get_user(olen, oldlenp)) | 2927 | if (get_user(olen, oldlenp)) |
2928 | return -EFAULT; | 2928 | return -EFAULT; |
2929 | if (olen) { | 2929 | if (olen) { |
2930 | int val; | 2930 | int val; |
2931 | 2931 | ||
2932 | if (olen < sizeof(int)) | 2932 | if (olen < sizeof(int)) |
2933 | return -EINVAL; | 2933 | return -EINVAL; |
2934 | 2934 | ||
2935 | val = *(int *)(table->data) / HZ; | 2935 | val = *(int *)(table->data) / HZ; |
2936 | if (put_user(val, (int __user *)oldval)) | 2936 | if (put_user(val, (int __user *)oldval)) |
2937 | return -EFAULT; | 2937 | return -EFAULT; |
2938 | if (put_user(sizeof(int), oldlenp)) | 2938 | if (put_user(sizeof(int), oldlenp)) |
2939 | return -EFAULT; | 2939 | return -EFAULT; |
2940 | } | 2940 | } |
2941 | } | 2941 | } |
2942 | if (newval && newlen) { | 2942 | if (newval && newlen) { |
2943 | int new; | 2943 | int new; |
2944 | if (newlen != sizeof(int)) | 2944 | if (newlen != sizeof(int)) |
2945 | return -EINVAL; | 2945 | return -EINVAL; |
2946 | if (get_user(new, (int __user *)newval)) | 2946 | if (get_user(new, (int __user *)newval)) |
2947 | return -EFAULT; | 2947 | return -EFAULT; |
2948 | *(int *)(table->data) = new*HZ; | 2948 | *(int *)(table->data) = new*HZ; |
2949 | } | 2949 | } |
2950 | return 1; | 2950 | return 1; |
2951 | } | 2951 | } |
2952 | 2952 | ||
2953 | /* Strategy function to convert jiffies to seconds */ | 2953 | /* Strategy function to convert jiffies to seconds */ |
2954 | int sysctl_ms_jiffies(struct ctl_table *table, | 2954 | int sysctl_ms_jiffies(struct ctl_table *table, |
2955 | void __user *oldval, size_t __user *oldlenp, | 2955 | void __user *oldval, size_t __user *oldlenp, |
2956 | void __user *newval, size_t newlen) | 2956 | void __user *newval, size_t newlen) |
2957 | { | 2957 | { |
2958 | if (oldval && oldlenp) { | 2958 | if (oldval && oldlenp) { |
2959 | size_t olen; | 2959 | size_t olen; |
2960 | 2960 | ||
2961 | if (get_user(olen, oldlenp)) | 2961 | if (get_user(olen, oldlenp)) |
2962 | return -EFAULT; | 2962 | return -EFAULT; |
2963 | if (olen) { | 2963 | if (olen) { |
2964 | int val; | 2964 | int val; |
2965 | 2965 | ||
2966 | if (olen < sizeof(int)) | 2966 | if (olen < sizeof(int)) |
2967 | return -EINVAL; | 2967 | return -EINVAL; |
2968 | 2968 | ||
2969 | val = jiffies_to_msecs(*(int *)(table->data)); | 2969 | val = jiffies_to_msecs(*(int *)(table->data)); |
2970 | if (put_user(val, (int __user *)oldval)) | 2970 | if (put_user(val, (int __user *)oldval)) |
2971 | return -EFAULT; | 2971 | return -EFAULT; |
2972 | if (put_user(sizeof(int), oldlenp)) | 2972 | if (put_user(sizeof(int), oldlenp)) |
2973 | return -EFAULT; | 2973 | return -EFAULT; |
2974 | } | 2974 | } |
2975 | } | 2975 | } |
2976 | if (newval && newlen) { | 2976 | if (newval && newlen) { |
2977 | int new; | 2977 | int new; |
2978 | if (newlen != sizeof(int)) | 2978 | if (newlen != sizeof(int)) |
2979 | return -EINVAL; | 2979 | return -EINVAL; |
2980 | if (get_user(new, (int __user *)newval)) | 2980 | if (get_user(new, (int __user *)newval)) |
2981 | return -EFAULT; | 2981 | return -EFAULT; |
2982 | *(int *)(table->data) = msecs_to_jiffies(new); | 2982 | *(int *)(table->data) = msecs_to_jiffies(new); |
2983 | } | 2983 | } |
2984 | return 1; | 2984 | return 1; |
2985 | } | 2985 | } |
2986 | 2986 | ||
2987 | 2987 | ||
2988 | 2988 | ||
2989 | #else /* CONFIG_SYSCTL_SYSCALL */ | 2989 | #else /* CONFIG_SYSCTL_SYSCALL */ |
2990 | 2990 | ||
2991 | 2991 | ||
2992 | asmlinkage long sys_sysctl(struct __sysctl_args __user *args) | 2992 | asmlinkage long sys_sysctl(struct __sysctl_args __user *args) |
2993 | { | 2993 | { |
2994 | struct __sysctl_args tmp; | 2994 | struct __sysctl_args tmp; |
2995 | int error; | 2995 | int error; |
2996 | 2996 | ||
2997 | if (copy_from_user(&tmp, args, sizeof(tmp))) | 2997 | if (copy_from_user(&tmp, args, sizeof(tmp))) |
2998 | return -EFAULT; | 2998 | return -EFAULT; |
2999 | 2999 | ||
3000 | error = deprecated_sysctl_warning(&tmp); | 3000 | error = deprecated_sysctl_warning(&tmp); |
3001 | 3001 | ||
3002 | /* If no error reading the parameters then just -ENOSYS ... */ | 3002 | /* If no error reading the parameters then just -ENOSYS ... */ |
3003 | if (!error) | 3003 | if (!error) |
3004 | error = -ENOSYS; | 3004 | error = -ENOSYS; |
3005 | 3005 | ||
3006 | return error; | 3006 | return error; |
3007 | } | 3007 | } |
3008 | 3008 | ||
3009 | int sysctl_data(struct ctl_table *table, | 3009 | int sysctl_data(struct ctl_table *table, |
3010 | void __user *oldval, size_t __user *oldlenp, | 3010 | void __user *oldval, size_t __user *oldlenp, |
3011 | void __user *newval, size_t newlen) | 3011 | void __user *newval, size_t newlen) |
3012 | { | 3012 | { |
3013 | return -ENOSYS; | 3013 | return -ENOSYS; |
3014 | } | 3014 | } |
3015 | 3015 | ||
3016 | int sysctl_string(struct ctl_table *table, | 3016 | int sysctl_string(struct ctl_table *table, |
3017 | void __user *oldval, size_t __user *oldlenp, | 3017 | void __user *oldval, size_t __user *oldlenp, |
3018 | void __user *newval, size_t newlen) | 3018 | void __user *newval, size_t newlen) |
3019 | { | 3019 | { |
3020 | return -ENOSYS; | 3020 | return -ENOSYS; |
3021 | } | 3021 | } |
3022 | 3022 | ||
3023 | int sysctl_intvec(struct ctl_table *table, | 3023 | int sysctl_intvec(struct ctl_table *table, |
3024 | void __user *oldval, size_t __user *oldlenp, | 3024 | void __user *oldval, size_t __user *oldlenp, |
3025 | void __user *newval, size_t newlen) | 3025 | void __user *newval, size_t newlen) |
3026 | { | 3026 | { |
3027 | return -ENOSYS; | 3027 | return -ENOSYS; |
3028 | } | 3028 | } |
3029 | 3029 | ||
3030 | int sysctl_jiffies(struct ctl_table *table, | 3030 | int sysctl_jiffies(struct ctl_table *table, |
3031 | void __user *oldval, size_t __user *oldlenp, | 3031 | void __user *oldval, size_t __user *oldlenp, |
3032 | void __user *newval, size_t newlen) | 3032 | void __user *newval, size_t newlen) |
3033 | { | 3033 | { |
3034 | return -ENOSYS; | 3034 | return -ENOSYS; |
3035 | } | 3035 | } |
3036 | 3036 | ||
3037 | int sysctl_ms_jiffies(struct ctl_table *table, | 3037 | int sysctl_ms_jiffies(struct ctl_table *table, |
3038 | void __user *oldval, size_t __user *oldlenp, | 3038 | void __user *oldval, size_t __user *oldlenp, |
3039 | void __user *newval, size_t newlen) | 3039 | void __user *newval, size_t newlen) |
3040 | { | 3040 | { |
3041 | return -ENOSYS; | 3041 | return -ENOSYS; |
3042 | } | 3042 | } |
3043 | 3043 | ||
3044 | #endif /* CONFIG_SYSCTL_SYSCALL */ | 3044 | #endif /* CONFIG_SYSCTL_SYSCALL */ |
3045 | 3045 | ||
3046 | static int deprecated_sysctl_warning(struct __sysctl_args *args) | 3046 | static int deprecated_sysctl_warning(struct __sysctl_args *args) |
3047 | { | 3047 | { |
3048 | static int msg_count; | 3048 | static int msg_count; |
3049 | int name[CTL_MAXNAME]; | 3049 | int name[CTL_MAXNAME]; |
3050 | int i; | 3050 | int i; |
3051 | 3051 | ||
3052 | /* Check args->nlen. */ | 3052 | /* Check args->nlen. */ |
3053 | if (args->nlen < 0 || args->nlen > CTL_MAXNAME) | 3053 | if (args->nlen < 0 || args->nlen > CTL_MAXNAME) |
3054 | return -ENOTDIR; | 3054 | return -ENOTDIR; |
3055 | 3055 | ||
3056 | /* Read in the sysctl name for better debug message logging */ | 3056 | /* Read in the sysctl name for better debug message logging */ |
3057 | for (i = 0; i < args->nlen; i++) | 3057 | for (i = 0; i < args->nlen; i++) |
3058 | if (get_user(name[i], args->name + i)) | 3058 | if (get_user(name[i], args->name + i)) |
3059 | return -EFAULT; | 3059 | return -EFAULT; |
3060 | 3060 | ||
3061 | /* Ignore accesses to kernel.version */ | 3061 | /* Ignore accesses to kernel.version */ |
3062 | if ((args->nlen == 2) && (name[0] == CTL_KERN) && (name[1] == KERN_VERSION)) | 3062 | if ((args->nlen == 2) && (name[0] == CTL_KERN) && (name[1] == KERN_VERSION)) |
3063 | return 0; | 3063 | return 0; |
3064 | 3064 | ||
3065 | if (msg_count < 5) { | 3065 | if (msg_count < 5) { |
3066 | msg_count++; | 3066 | msg_count++; |
3067 | printk(KERN_INFO | 3067 | printk(KERN_INFO |
3068 | "warning: process `%s' used the deprecated sysctl " | 3068 | "warning: process `%s' used the deprecated sysctl " |
3069 | "system call with ", current->comm); | 3069 | "system call with ", current->comm); |
3070 | for (i = 0; i < args->nlen; i++) | 3070 | for (i = 0; i < args->nlen; i++) |
3071 | printk("%d.", name[i]); | 3071 | printk("%d.", name[i]); |
3072 | printk("\n"); | 3072 | printk("\n"); |
3073 | } | 3073 | } |
3074 | return 0; | 3074 | return 0; |
3075 | } | 3075 | } |
3076 | 3076 | ||
3077 | /* | 3077 | /* |
3078 | * No sense putting this after each symbol definition, twice, | 3078 | * No sense putting this after each symbol definition, twice, |
3079 | * exception granted :-) | 3079 | * exception granted :-) |
3080 | */ | 3080 | */ |
3081 | EXPORT_SYMBOL(proc_dointvec); | 3081 | EXPORT_SYMBOL(proc_dointvec); |
3082 | EXPORT_SYMBOL(proc_dointvec_jiffies); | 3082 | EXPORT_SYMBOL(proc_dointvec_jiffies); |
3083 | EXPORT_SYMBOL(proc_dointvec_minmax); | 3083 | EXPORT_SYMBOL(proc_dointvec_minmax); |
3084 | EXPORT_SYMBOL(proc_dointvec_userhz_jiffies); | 3084 | EXPORT_SYMBOL(proc_dointvec_userhz_jiffies); |
3085 | EXPORT_SYMBOL(proc_dointvec_ms_jiffies); | 3085 | EXPORT_SYMBOL(proc_dointvec_ms_jiffies); |
3086 | EXPORT_SYMBOL(proc_dostring); | 3086 | EXPORT_SYMBOL(proc_dostring); |
3087 | EXPORT_SYMBOL(proc_doulongvec_minmax); | 3087 | EXPORT_SYMBOL(proc_doulongvec_minmax); |
3088 | EXPORT_SYMBOL(proc_doulongvec_ms_jiffies_minmax); | 3088 | EXPORT_SYMBOL(proc_doulongvec_ms_jiffies_minmax); |
3089 | EXPORT_SYMBOL(register_sysctl_table); | 3089 | EXPORT_SYMBOL(register_sysctl_table); |
3090 | EXPORT_SYMBOL(register_sysctl_paths); | 3090 | EXPORT_SYMBOL(register_sysctl_paths); |
3091 | EXPORT_SYMBOL(sysctl_intvec); | 3091 | EXPORT_SYMBOL(sysctl_intvec); |
3092 | EXPORT_SYMBOL(sysctl_jiffies); | 3092 | EXPORT_SYMBOL(sysctl_jiffies); |
3093 | EXPORT_SYMBOL(sysctl_ms_jiffies); | 3093 | EXPORT_SYMBOL(sysctl_ms_jiffies); |
3094 | EXPORT_SYMBOL(sysctl_string); | 3094 | EXPORT_SYMBOL(sysctl_string); |
3095 | EXPORT_SYMBOL(sysctl_data); | 3095 | EXPORT_SYMBOL(sysctl_data); |
3096 | EXPORT_SYMBOL(unregister_sysctl_table); | 3096 | EXPORT_SYMBOL(unregister_sysctl_table); |
3097 | 3097 |