Commit 90739081ef8d5495d50abba9c5d333be9acd872a
1 parent
9745512ce7
Exists in
master
and in
4 other branches
softlockup: fix signedness
fix softlockup tunables signedness. mark tunables read-mostly. Signed-off-by: Ingo Molnar <mingo@elte.hu>
Showing 3 changed files with 15 additions and 15 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 | 30 | ||
31 | /* | 31 | /* |
32 | * Scheduling policies | 32 | * Scheduling policies |
33 | */ | 33 | */ |
34 | #define SCHED_NORMAL 0 | 34 | #define SCHED_NORMAL 0 |
35 | #define SCHED_FIFO 1 | 35 | #define SCHED_FIFO 1 |
36 | #define SCHED_RR 2 | 36 | #define SCHED_RR 2 |
37 | #define SCHED_BATCH 3 | 37 | #define SCHED_BATCH 3 |
38 | /* SCHED_ISO: reserved but not implemented yet */ | 38 | /* SCHED_ISO: reserved but not implemented yet */ |
39 | #define SCHED_IDLE 5 | 39 | #define SCHED_IDLE 5 |
40 | 40 | ||
41 | #ifdef __KERNEL__ | 41 | #ifdef __KERNEL__ |
42 | 42 | ||
43 | struct sched_param { | 43 | struct sched_param { |
44 | int sched_priority; | 44 | int sched_priority; |
45 | }; | 45 | }; |
46 | 46 | ||
47 | #include <asm/param.h> /* for HZ */ | 47 | #include <asm/param.h> /* for HZ */ |
48 | 48 | ||
49 | #include <linux/capability.h> | 49 | #include <linux/capability.h> |
50 | #include <linux/threads.h> | 50 | #include <linux/threads.h> |
51 | #include <linux/kernel.h> | 51 | #include <linux/kernel.h> |
52 | #include <linux/types.h> | 52 | #include <linux/types.h> |
53 | #include <linux/timex.h> | 53 | #include <linux/timex.h> |
54 | #include <linux/jiffies.h> | 54 | #include <linux/jiffies.h> |
55 | #include <linux/rbtree.h> | 55 | #include <linux/rbtree.h> |
56 | #include <linux/thread_info.h> | 56 | #include <linux/thread_info.h> |
57 | #include <linux/cpumask.h> | 57 | #include <linux/cpumask.h> |
58 | #include <linux/errno.h> | 58 | #include <linux/errno.h> |
59 | #include <linux/nodemask.h> | 59 | #include <linux/nodemask.h> |
60 | #include <linux/mm_types.h> | 60 | #include <linux/mm_types.h> |
61 | 61 | ||
62 | #include <asm/system.h> | 62 | #include <asm/system.h> |
63 | #include <asm/semaphore.h> | 63 | #include <asm/semaphore.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/securebits.h> | 71 | #include <linux/securebits.h> |
72 | #include <linux/fs_struct.h> | 72 | #include <linux/fs_struct.h> |
73 | #include <linux/compiler.h> | 73 | #include <linux/compiler.h> |
74 | #include <linux/completion.h> | 74 | #include <linux/completion.h> |
75 | #include <linux/pid.h> | 75 | #include <linux/pid.h> |
76 | #include <linux/percpu.h> | 76 | #include <linux/percpu.h> |
77 | #include <linux/topology.h> | 77 | #include <linux/topology.h> |
78 | #include <linux/proportions.h> | 78 | #include <linux/proportions.h> |
79 | #include <linux/seccomp.h> | 79 | #include <linux/seccomp.h> |
80 | #include <linux/rcupdate.h> | 80 | #include <linux/rcupdate.h> |
81 | #include <linux/futex.h> | 81 | #include <linux/futex.h> |
82 | #include <linux/rtmutex.h> | 82 | #include <linux/rtmutex.h> |
83 | 83 | ||
84 | #include <linux/time.h> | 84 | #include <linux/time.h> |
85 | #include <linux/param.h> | 85 | #include <linux/param.h> |
86 | #include <linux/resource.h> | 86 | #include <linux/resource.h> |
87 | #include <linux/timer.h> | 87 | #include <linux/timer.h> |
88 | #include <linux/hrtimer.h> | 88 | #include <linux/hrtimer.h> |
89 | #include <linux/task_io_accounting.h> | 89 | #include <linux/task_io_accounting.h> |
90 | #include <linux/kobject.h> | 90 | #include <linux/kobject.h> |
91 | #include <linux/latencytop.h> | 91 | #include <linux/latencytop.h> |
92 | 92 | ||
93 | #include <asm/processor.h> | 93 | #include <asm/processor.h> |
94 | 94 | ||
95 | struct exec_domain; | 95 | struct exec_domain; |
96 | struct futex_pi_state; | 96 | struct futex_pi_state; |
97 | struct bio; | 97 | struct bio; |
98 | 98 | ||
99 | /* | 99 | /* |
100 | * List of flags we want to share for kernel threads, | 100 | * List of flags we want to share for kernel threads, |
101 | * if only because they are not used by them anyway. | 101 | * if only because they are not used by them anyway. |
102 | */ | 102 | */ |
103 | #define CLONE_KERNEL (CLONE_FS | CLONE_FILES | CLONE_SIGHAND) | 103 | #define CLONE_KERNEL (CLONE_FS | CLONE_FILES | CLONE_SIGHAND) |
104 | 104 | ||
105 | /* | 105 | /* |
106 | * These are the constant used to fake the fixed-point load-average | 106 | * These are the constant used to fake the fixed-point load-average |
107 | * counting. Some notes: | 107 | * counting. Some notes: |
108 | * - 11 bit fractions expand to 22 bits by the multiplies: this gives | 108 | * - 11 bit fractions expand to 22 bits by the multiplies: this gives |
109 | * a load-average precision of 10 bits integer + 11 bits fractional | 109 | * a load-average precision of 10 bits integer + 11 bits fractional |
110 | * - if you want to count load-averages more often, you need more | 110 | * - if you want to count load-averages more often, you need more |
111 | * precision, or rounding will get you. With 2-second counting freq, | 111 | * precision, or rounding will get you. With 2-second counting freq, |
112 | * the EXP_n values would be 1981, 2034 and 2043 if still using only | 112 | * the EXP_n values would be 1981, 2034 and 2043 if still using only |
113 | * 11 bit fractions. | 113 | * 11 bit fractions. |
114 | */ | 114 | */ |
115 | extern unsigned long avenrun[]; /* Load averages */ | 115 | extern unsigned long avenrun[]; /* Load averages */ |
116 | 116 | ||
117 | #define FSHIFT 11 /* nr of bits of precision */ | 117 | #define FSHIFT 11 /* nr of bits of precision */ |
118 | #define FIXED_1 (1<<FSHIFT) /* 1.0 as fixed-point */ | 118 | #define FIXED_1 (1<<FSHIFT) /* 1.0 as fixed-point */ |
119 | #define LOAD_FREQ (5*HZ+1) /* 5 sec intervals */ | 119 | #define LOAD_FREQ (5*HZ+1) /* 5 sec intervals */ |
120 | #define EXP_1 1884 /* 1/exp(5sec/1min) as fixed-point */ | 120 | #define EXP_1 1884 /* 1/exp(5sec/1min) as fixed-point */ |
121 | #define EXP_5 2014 /* 1/exp(5sec/5min) */ | 121 | #define EXP_5 2014 /* 1/exp(5sec/5min) */ |
122 | #define EXP_15 2037 /* 1/exp(5sec/15min) */ | 122 | #define EXP_15 2037 /* 1/exp(5sec/15min) */ |
123 | 123 | ||
124 | #define CALC_LOAD(load,exp,n) \ | 124 | #define CALC_LOAD(load,exp,n) \ |
125 | load *= exp; \ | 125 | load *= exp; \ |
126 | load += n*(FIXED_1-exp); \ | 126 | load += n*(FIXED_1-exp); \ |
127 | load >>= FSHIFT; | 127 | load >>= FSHIFT; |
128 | 128 | ||
129 | extern unsigned long total_forks; | 129 | extern unsigned long total_forks; |
130 | extern int nr_threads; | 130 | extern int nr_threads; |
131 | DECLARE_PER_CPU(unsigned long, process_counts); | 131 | DECLARE_PER_CPU(unsigned long, process_counts); |
132 | extern int nr_processes(void); | 132 | extern int nr_processes(void); |
133 | extern unsigned long nr_running(void); | 133 | extern unsigned long nr_running(void); |
134 | extern unsigned long nr_uninterruptible(void); | 134 | extern unsigned long nr_uninterruptible(void); |
135 | extern unsigned long nr_active(void); | 135 | extern unsigned long nr_active(void); |
136 | extern unsigned long nr_iowait(void); | 136 | extern unsigned long nr_iowait(void); |
137 | extern unsigned long weighted_cpuload(const int cpu); | 137 | extern unsigned long weighted_cpuload(const int cpu); |
138 | 138 | ||
139 | struct seq_file; | 139 | struct seq_file; |
140 | struct cfs_rq; | 140 | struct cfs_rq; |
141 | struct task_group; | 141 | struct task_group; |
142 | #ifdef CONFIG_SCHED_DEBUG | 142 | #ifdef CONFIG_SCHED_DEBUG |
143 | extern void proc_sched_show_task(struct task_struct *p, struct seq_file *m); | 143 | extern void proc_sched_show_task(struct task_struct *p, struct seq_file *m); |
144 | extern void proc_sched_set_task(struct task_struct *p); | 144 | extern void proc_sched_set_task(struct task_struct *p); |
145 | extern void | 145 | extern void |
146 | print_cfs_rq(struct seq_file *m, int cpu, struct cfs_rq *cfs_rq); | 146 | print_cfs_rq(struct seq_file *m, int cpu, struct cfs_rq *cfs_rq); |
147 | #else | 147 | #else |
148 | static inline void | 148 | static inline void |
149 | proc_sched_show_task(struct task_struct *p, struct seq_file *m) | 149 | proc_sched_show_task(struct task_struct *p, struct seq_file *m) |
150 | { | 150 | { |
151 | } | 151 | } |
152 | static inline void proc_sched_set_task(struct task_struct *p) | 152 | static inline void proc_sched_set_task(struct task_struct *p) |
153 | { | 153 | { |
154 | } | 154 | } |
155 | static inline void | 155 | static inline void |
156 | print_cfs_rq(struct seq_file *m, int cpu, struct cfs_rq *cfs_rq) | 156 | print_cfs_rq(struct seq_file *m, int cpu, struct cfs_rq *cfs_rq) |
157 | { | 157 | { |
158 | } | 158 | } |
159 | #endif | 159 | #endif |
160 | 160 | ||
161 | /* | 161 | /* |
162 | * Task state bitmask. NOTE! These bits are also | 162 | * Task state bitmask. NOTE! These bits are also |
163 | * encoded in fs/proc/array.c: get_task_state(). | 163 | * encoded in fs/proc/array.c: get_task_state(). |
164 | * | 164 | * |
165 | * We have two separate sets of flags: task->state | 165 | * We have two separate sets of flags: task->state |
166 | * is about runnability, while task->exit_state are | 166 | * is about runnability, while task->exit_state are |
167 | * about the task exiting. Confusing, but this way | 167 | * about the task exiting. Confusing, but this way |
168 | * modifying one set can't modify the other one by | 168 | * modifying one set can't modify the other one by |
169 | * mistake. | 169 | * mistake. |
170 | */ | 170 | */ |
171 | #define TASK_RUNNING 0 | 171 | #define TASK_RUNNING 0 |
172 | #define TASK_INTERRUPTIBLE 1 | 172 | #define TASK_INTERRUPTIBLE 1 |
173 | #define TASK_UNINTERRUPTIBLE 2 | 173 | #define TASK_UNINTERRUPTIBLE 2 |
174 | #define TASK_STOPPED 4 | 174 | #define TASK_STOPPED 4 |
175 | #define TASK_TRACED 8 | 175 | #define TASK_TRACED 8 |
176 | /* in tsk->exit_state */ | 176 | /* in tsk->exit_state */ |
177 | #define EXIT_ZOMBIE 16 | 177 | #define EXIT_ZOMBIE 16 |
178 | #define EXIT_DEAD 32 | 178 | #define EXIT_DEAD 32 |
179 | /* in tsk->state again */ | 179 | /* in tsk->state again */ |
180 | #define TASK_DEAD 64 | 180 | #define TASK_DEAD 64 |
181 | 181 | ||
182 | #define __set_task_state(tsk, state_value) \ | 182 | #define __set_task_state(tsk, state_value) \ |
183 | do { (tsk)->state = (state_value); } while (0) | 183 | do { (tsk)->state = (state_value); } while (0) |
184 | #define set_task_state(tsk, state_value) \ | 184 | #define set_task_state(tsk, state_value) \ |
185 | set_mb((tsk)->state, (state_value)) | 185 | set_mb((tsk)->state, (state_value)) |
186 | 186 | ||
187 | /* | 187 | /* |
188 | * set_current_state() includes a barrier so that the write of current->state | 188 | * set_current_state() includes a barrier so that the write of current->state |
189 | * is correctly serialised wrt the caller's subsequent test of whether to | 189 | * is correctly serialised wrt the caller's subsequent test of whether to |
190 | * actually sleep: | 190 | * actually sleep: |
191 | * | 191 | * |
192 | * set_current_state(TASK_UNINTERRUPTIBLE); | 192 | * set_current_state(TASK_UNINTERRUPTIBLE); |
193 | * if (do_i_need_to_sleep()) | 193 | * if (do_i_need_to_sleep()) |
194 | * schedule(); | 194 | * schedule(); |
195 | * | 195 | * |
196 | * If the caller does not need such serialisation then use __set_current_state() | 196 | * If the caller does not need such serialisation then use __set_current_state() |
197 | */ | 197 | */ |
198 | #define __set_current_state(state_value) \ | 198 | #define __set_current_state(state_value) \ |
199 | do { current->state = (state_value); } while (0) | 199 | do { current->state = (state_value); } while (0) |
200 | #define set_current_state(state_value) \ | 200 | #define set_current_state(state_value) \ |
201 | set_mb(current->state, (state_value)) | 201 | set_mb(current->state, (state_value)) |
202 | 202 | ||
203 | /* Task command name length */ | 203 | /* Task command name length */ |
204 | #define TASK_COMM_LEN 16 | 204 | #define TASK_COMM_LEN 16 |
205 | 205 | ||
206 | #include <linux/spinlock.h> | 206 | #include <linux/spinlock.h> |
207 | 207 | ||
208 | /* | 208 | /* |
209 | * This serializes "schedule()" and also protects | 209 | * This serializes "schedule()" and also protects |
210 | * the run-queue from deletions/modifications (but | 210 | * the run-queue from deletions/modifications (but |
211 | * _adding_ to the beginning of the run-queue has | 211 | * _adding_ to the beginning of the run-queue has |
212 | * a separate lock). | 212 | * a separate lock). |
213 | */ | 213 | */ |
214 | extern rwlock_t tasklist_lock; | 214 | extern rwlock_t tasklist_lock; |
215 | extern spinlock_t mmlist_lock; | 215 | extern spinlock_t mmlist_lock; |
216 | 216 | ||
217 | struct task_struct; | 217 | struct task_struct; |
218 | 218 | ||
219 | extern void sched_init(void); | 219 | extern void sched_init(void); |
220 | extern void sched_init_smp(void); | 220 | extern void sched_init_smp(void); |
221 | extern void init_idle(struct task_struct *idle, int cpu); | 221 | extern void init_idle(struct task_struct *idle, int cpu); |
222 | extern void init_idle_bootup_task(struct task_struct *idle); | 222 | extern void init_idle_bootup_task(struct task_struct *idle); |
223 | 223 | ||
224 | extern cpumask_t nohz_cpu_mask; | 224 | extern cpumask_t nohz_cpu_mask; |
225 | #if defined(CONFIG_SMP) && defined(CONFIG_NO_HZ) | 225 | #if defined(CONFIG_SMP) && defined(CONFIG_NO_HZ) |
226 | extern int select_nohz_load_balancer(int cpu); | 226 | extern int select_nohz_load_balancer(int cpu); |
227 | #else | 227 | #else |
228 | static inline int select_nohz_load_balancer(int cpu) | 228 | static inline int select_nohz_load_balancer(int cpu) |
229 | { | 229 | { |
230 | return 0; | 230 | return 0; |
231 | } | 231 | } |
232 | #endif | 232 | #endif |
233 | 233 | ||
234 | extern unsigned long rt_needs_cpu(int cpu); | 234 | extern unsigned long rt_needs_cpu(int cpu); |
235 | 235 | ||
236 | /* | 236 | /* |
237 | * Only dump TASK_* tasks. (0 for all tasks) | 237 | * Only dump TASK_* tasks. (0 for all tasks) |
238 | */ | 238 | */ |
239 | extern void show_state_filter(unsigned long state_filter); | 239 | extern void show_state_filter(unsigned long state_filter); |
240 | 240 | ||
241 | static inline void show_state(void) | 241 | static inline void show_state(void) |
242 | { | 242 | { |
243 | show_state_filter(0); | 243 | show_state_filter(0); |
244 | } | 244 | } |
245 | 245 | ||
246 | extern void show_regs(struct pt_regs *); | 246 | extern void show_regs(struct pt_regs *); |
247 | 247 | ||
248 | /* | 248 | /* |
249 | * TASK is a pointer to the task whose backtrace we want to see (or NULL for current | 249 | * TASK is a pointer to the task whose backtrace we want to see (or NULL for current |
250 | * task), SP is the stack pointer of the first frame that should be shown in the back | 250 | * task), SP is the stack pointer of the first frame that should be shown in the back |
251 | * trace (or NULL if the entire call-chain of the task should be shown). | 251 | * trace (or NULL if the entire call-chain of the task should be shown). |
252 | */ | 252 | */ |
253 | extern void show_stack(struct task_struct *task, unsigned long *sp); | 253 | extern void show_stack(struct task_struct *task, unsigned long *sp); |
254 | 254 | ||
255 | void io_schedule(void); | 255 | void io_schedule(void); |
256 | long io_schedule_timeout(long timeout); | 256 | long io_schedule_timeout(long timeout); |
257 | 257 | ||
258 | extern void cpu_init (void); | 258 | extern void cpu_init (void); |
259 | extern void trap_init(void); | 259 | extern void trap_init(void); |
260 | extern void account_process_tick(struct task_struct *task, int user); | 260 | extern void account_process_tick(struct task_struct *task, int user); |
261 | extern void update_process_times(int user); | 261 | extern void update_process_times(int user); |
262 | extern void scheduler_tick(void); | 262 | extern void scheduler_tick(void); |
263 | extern void hrtick_resched(void); | 263 | extern void hrtick_resched(void); |
264 | 264 | ||
265 | extern void sched_show_task(struct task_struct *p); | 265 | extern void sched_show_task(struct task_struct *p); |
266 | 266 | ||
267 | #ifdef CONFIG_DETECT_SOFTLOCKUP | 267 | #ifdef CONFIG_DETECT_SOFTLOCKUP |
268 | extern void softlockup_tick(void); | 268 | extern void softlockup_tick(void); |
269 | extern void spawn_softlockup_task(void); | 269 | extern void spawn_softlockup_task(void); |
270 | extern void touch_softlockup_watchdog(void); | 270 | extern void touch_softlockup_watchdog(void); |
271 | extern void touch_all_softlockup_watchdogs(void); | 271 | extern void touch_all_softlockup_watchdogs(void); |
272 | extern int softlockup_thresh; | 272 | extern unsigned long softlockup_thresh; |
273 | extern unsigned long sysctl_hung_task_check_count; | 273 | extern unsigned long sysctl_hung_task_check_count; |
274 | extern unsigned long sysctl_hung_task_timeout_secs; | 274 | extern unsigned long sysctl_hung_task_timeout_secs; |
275 | extern long sysctl_hung_task_warnings; | 275 | extern unsigned long sysctl_hung_task_warnings; |
276 | #else | 276 | #else |
277 | static inline void softlockup_tick(void) | 277 | static inline void softlockup_tick(void) |
278 | { | 278 | { |
279 | } | 279 | } |
280 | static inline void spawn_softlockup_task(void) | 280 | static inline void spawn_softlockup_task(void) |
281 | { | 281 | { |
282 | } | 282 | } |
283 | static inline void touch_softlockup_watchdog(void) | 283 | static inline void touch_softlockup_watchdog(void) |
284 | { | 284 | { |
285 | } | 285 | } |
286 | static inline void touch_all_softlockup_watchdogs(void) | 286 | static inline void touch_all_softlockup_watchdogs(void) |
287 | { | 287 | { |
288 | } | 288 | } |
289 | #endif | 289 | #endif |
290 | 290 | ||
291 | 291 | ||
292 | /* Attach to any functions which should be ignored in wchan output. */ | 292 | /* Attach to any functions which should be ignored in wchan output. */ |
293 | #define __sched __attribute__((__section__(".sched.text"))) | 293 | #define __sched __attribute__((__section__(".sched.text"))) |
294 | 294 | ||
295 | /* Linker adds these: start and end of __sched functions */ | 295 | /* Linker adds these: start and end of __sched functions */ |
296 | extern char __sched_text_start[], __sched_text_end[]; | 296 | extern char __sched_text_start[], __sched_text_end[]; |
297 | 297 | ||
298 | /* Is this address in the __sched functions? */ | 298 | /* Is this address in the __sched functions? */ |
299 | extern int in_sched_functions(unsigned long addr); | 299 | extern int in_sched_functions(unsigned long addr); |
300 | 300 | ||
301 | #define MAX_SCHEDULE_TIMEOUT LONG_MAX | 301 | #define MAX_SCHEDULE_TIMEOUT LONG_MAX |
302 | extern signed long FASTCALL(schedule_timeout(signed long timeout)); | 302 | extern signed long FASTCALL(schedule_timeout(signed long timeout)); |
303 | extern signed long schedule_timeout_interruptible(signed long timeout); | 303 | extern signed long schedule_timeout_interruptible(signed long timeout); |
304 | extern signed long schedule_timeout_uninterruptible(signed long timeout); | 304 | extern signed long schedule_timeout_uninterruptible(signed long timeout); |
305 | asmlinkage void schedule(void); | 305 | asmlinkage void schedule(void); |
306 | 306 | ||
307 | struct nsproxy; | 307 | struct nsproxy; |
308 | struct user_namespace; | 308 | struct user_namespace; |
309 | 309 | ||
310 | /* Maximum number of active map areas.. This is a random (large) number */ | 310 | /* Maximum number of active map areas.. This is a random (large) number */ |
311 | #define DEFAULT_MAX_MAP_COUNT 65536 | 311 | #define DEFAULT_MAX_MAP_COUNT 65536 |
312 | 312 | ||
313 | extern int sysctl_max_map_count; | 313 | extern int sysctl_max_map_count; |
314 | 314 | ||
315 | #include <linux/aio.h> | 315 | #include <linux/aio.h> |
316 | 316 | ||
317 | extern unsigned long | 317 | extern unsigned long |
318 | arch_get_unmapped_area(struct file *, unsigned long, unsigned long, | 318 | arch_get_unmapped_area(struct file *, unsigned long, unsigned long, |
319 | unsigned long, unsigned long); | 319 | unsigned long, unsigned long); |
320 | extern unsigned long | 320 | extern unsigned long |
321 | arch_get_unmapped_area_topdown(struct file *filp, unsigned long addr, | 321 | arch_get_unmapped_area_topdown(struct file *filp, unsigned long addr, |
322 | unsigned long len, unsigned long pgoff, | 322 | unsigned long len, unsigned long pgoff, |
323 | unsigned long flags); | 323 | unsigned long flags); |
324 | extern void arch_unmap_area(struct mm_struct *, unsigned long); | 324 | extern void arch_unmap_area(struct mm_struct *, unsigned long); |
325 | extern void arch_unmap_area_topdown(struct mm_struct *, unsigned long); | 325 | extern void arch_unmap_area_topdown(struct mm_struct *, unsigned long); |
326 | 326 | ||
327 | #if NR_CPUS >= CONFIG_SPLIT_PTLOCK_CPUS | 327 | #if NR_CPUS >= CONFIG_SPLIT_PTLOCK_CPUS |
328 | /* | 328 | /* |
329 | * The mm counters are not protected by its page_table_lock, | 329 | * The mm counters are not protected by its page_table_lock, |
330 | * so must be incremented atomically. | 330 | * so must be incremented atomically. |
331 | */ | 331 | */ |
332 | #define set_mm_counter(mm, member, value) atomic_long_set(&(mm)->_##member, value) | 332 | #define set_mm_counter(mm, member, value) atomic_long_set(&(mm)->_##member, value) |
333 | #define get_mm_counter(mm, member) ((unsigned long)atomic_long_read(&(mm)->_##member)) | 333 | #define get_mm_counter(mm, member) ((unsigned long)atomic_long_read(&(mm)->_##member)) |
334 | #define add_mm_counter(mm, member, value) atomic_long_add(value, &(mm)->_##member) | 334 | #define add_mm_counter(mm, member, value) atomic_long_add(value, &(mm)->_##member) |
335 | #define inc_mm_counter(mm, member) atomic_long_inc(&(mm)->_##member) | 335 | #define inc_mm_counter(mm, member) atomic_long_inc(&(mm)->_##member) |
336 | #define dec_mm_counter(mm, member) atomic_long_dec(&(mm)->_##member) | 336 | #define dec_mm_counter(mm, member) atomic_long_dec(&(mm)->_##member) |
337 | 337 | ||
338 | #else /* NR_CPUS < CONFIG_SPLIT_PTLOCK_CPUS */ | 338 | #else /* NR_CPUS < CONFIG_SPLIT_PTLOCK_CPUS */ |
339 | /* | 339 | /* |
340 | * The mm counters are protected by its page_table_lock, | 340 | * The mm counters are protected by its page_table_lock, |
341 | * so can be incremented directly. | 341 | * so can be incremented directly. |
342 | */ | 342 | */ |
343 | #define set_mm_counter(mm, member, value) (mm)->_##member = (value) | 343 | #define set_mm_counter(mm, member, value) (mm)->_##member = (value) |
344 | #define get_mm_counter(mm, member) ((mm)->_##member) | 344 | #define get_mm_counter(mm, member) ((mm)->_##member) |
345 | #define add_mm_counter(mm, member, value) (mm)->_##member += (value) | 345 | #define add_mm_counter(mm, member, value) (mm)->_##member += (value) |
346 | #define inc_mm_counter(mm, member) (mm)->_##member++ | 346 | #define inc_mm_counter(mm, member) (mm)->_##member++ |
347 | #define dec_mm_counter(mm, member) (mm)->_##member-- | 347 | #define dec_mm_counter(mm, member) (mm)->_##member-- |
348 | 348 | ||
349 | #endif /* NR_CPUS < CONFIG_SPLIT_PTLOCK_CPUS */ | 349 | #endif /* NR_CPUS < CONFIG_SPLIT_PTLOCK_CPUS */ |
350 | 350 | ||
351 | #define get_mm_rss(mm) \ | 351 | #define get_mm_rss(mm) \ |
352 | (get_mm_counter(mm, file_rss) + get_mm_counter(mm, anon_rss)) | 352 | (get_mm_counter(mm, file_rss) + get_mm_counter(mm, anon_rss)) |
353 | #define update_hiwater_rss(mm) do { \ | 353 | #define update_hiwater_rss(mm) do { \ |
354 | unsigned long _rss = get_mm_rss(mm); \ | 354 | unsigned long _rss = get_mm_rss(mm); \ |
355 | if ((mm)->hiwater_rss < _rss) \ | 355 | if ((mm)->hiwater_rss < _rss) \ |
356 | (mm)->hiwater_rss = _rss; \ | 356 | (mm)->hiwater_rss = _rss; \ |
357 | } while (0) | 357 | } while (0) |
358 | #define update_hiwater_vm(mm) do { \ | 358 | #define update_hiwater_vm(mm) do { \ |
359 | if ((mm)->hiwater_vm < (mm)->total_vm) \ | 359 | if ((mm)->hiwater_vm < (mm)->total_vm) \ |
360 | (mm)->hiwater_vm = (mm)->total_vm; \ | 360 | (mm)->hiwater_vm = (mm)->total_vm; \ |
361 | } while (0) | 361 | } while (0) |
362 | 362 | ||
363 | extern void set_dumpable(struct mm_struct *mm, int value); | 363 | extern void set_dumpable(struct mm_struct *mm, int value); |
364 | extern int get_dumpable(struct mm_struct *mm); | 364 | extern int get_dumpable(struct mm_struct *mm); |
365 | 365 | ||
366 | /* mm flags */ | 366 | /* mm flags */ |
367 | /* dumpable bits */ | 367 | /* dumpable bits */ |
368 | #define MMF_DUMPABLE 0 /* core dump is permitted */ | 368 | #define MMF_DUMPABLE 0 /* core dump is permitted */ |
369 | #define MMF_DUMP_SECURELY 1 /* core file is readable only by root */ | 369 | #define MMF_DUMP_SECURELY 1 /* core file is readable only by root */ |
370 | #define MMF_DUMPABLE_BITS 2 | 370 | #define MMF_DUMPABLE_BITS 2 |
371 | 371 | ||
372 | /* coredump filter bits */ | 372 | /* coredump filter bits */ |
373 | #define MMF_DUMP_ANON_PRIVATE 2 | 373 | #define MMF_DUMP_ANON_PRIVATE 2 |
374 | #define MMF_DUMP_ANON_SHARED 3 | 374 | #define MMF_DUMP_ANON_SHARED 3 |
375 | #define MMF_DUMP_MAPPED_PRIVATE 4 | 375 | #define MMF_DUMP_MAPPED_PRIVATE 4 |
376 | #define MMF_DUMP_MAPPED_SHARED 5 | 376 | #define MMF_DUMP_MAPPED_SHARED 5 |
377 | #define MMF_DUMP_ELF_HEADERS 6 | 377 | #define MMF_DUMP_ELF_HEADERS 6 |
378 | #define MMF_DUMP_FILTER_SHIFT MMF_DUMPABLE_BITS | 378 | #define MMF_DUMP_FILTER_SHIFT MMF_DUMPABLE_BITS |
379 | #define MMF_DUMP_FILTER_BITS 5 | 379 | #define MMF_DUMP_FILTER_BITS 5 |
380 | #define MMF_DUMP_FILTER_MASK \ | 380 | #define MMF_DUMP_FILTER_MASK \ |
381 | (((1 << MMF_DUMP_FILTER_BITS) - 1) << MMF_DUMP_FILTER_SHIFT) | 381 | (((1 << MMF_DUMP_FILTER_BITS) - 1) << MMF_DUMP_FILTER_SHIFT) |
382 | #define MMF_DUMP_FILTER_DEFAULT \ | 382 | #define MMF_DUMP_FILTER_DEFAULT \ |
383 | ((1 << MMF_DUMP_ANON_PRIVATE) | (1 << MMF_DUMP_ANON_SHARED)) | 383 | ((1 << MMF_DUMP_ANON_PRIVATE) | (1 << MMF_DUMP_ANON_SHARED)) |
384 | 384 | ||
385 | struct sighand_struct { | 385 | struct sighand_struct { |
386 | atomic_t count; | 386 | atomic_t count; |
387 | struct k_sigaction action[_NSIG]; | 387 | struct k_sigaction action[_NSIG]; |
388 | spinlock_t siglock; | 388 | spinlock_t siglock; |
389 | wait_queue_head_t signalfd_wqh; | 389 | wait_queue_head_t signalfd_wqh; |
390 | }; | 390 | }; |
391 | 391 | ||
392 | struct pacct_struct { | 392 | struct pacct_struct { |
393 | int ac_flag; | 393 | int ac_flag; |
394 | long ac_exitcode; | 394 | long ac_exitcode; |
395 | unsigned long ac_mem; | 395 | unsigned long ac_mem; |
396 | cputime_t ac_utime, ac_stime; | 396 | cputime_t ac_utime, ac_stime; |
397 | unsigned long ac_minflt, ac_majflt; | 397 | unsigned long ac_minflt, ac_majflt; |
398 | }; | 398 | }; |
399 | 399 | ||
400 | /* | 400 | /* |
401 | * NOTE! "signal_struct" does not have it's own | 401 | * NOTE! "signal_struct" does not have it's own |
402 | * locking, because a shared signal_struct always | 402 | * locking, because a shared signal_struct always |
403 | * implies a shared sighand_struct, so locking | 403 | * implies a shared sighand_struct, so locking |
404 | * sighand_struct is always a proper superset of | 404 | * sighand_struct is always a proper superset of |
405 | * the locking of signal_struct. | 405 | * the locking of signal_struct. |
406 | */ | 406 | */ |
407 | struct signal_struct { | 407 | struct signal_struct { |
408 | atomic_t count; | 408 | atomic_t count; |
409 | atomic_t live; | 409 | atomic_t live; |
410 | 410 | ||
411 | wait_queue_head_t wait_chldexit; /* for wait4() */ | 411 | wait_queue_head_t wait_chldexit; /* for wait4() */ |
412 | 412 | ||
413 | /* current thread group signal load-balancing target: */ | 413 | /* current thread group signal load-balancing target: */ |
414 | struct task_struct *curr_target; | 414 | struct task_struct *curr_target; |
415 | 415 | ||
416 | /* shared signal handling: */ | 416 | /* shared signal handling: */ |
417 | struct sigpending shared_pending; | 417 | struct sigpending shared_pending; |
418 | 418 | ||
419 | /* thread group exit support */ | 419 | /* thread group exit support */ |
420 | int group_exit_code; | 420 | int group_exit_code; |
421 | /* overloaded: | 421 | /* overloaded: |
422 | * - notify group_exit_task when ->count is equal to notify_count | 422 | * - notify group_exit_task when ->count is equal to notify_count |
423 | * - everyone except group_exit_task is stopped during signal delivery | 423 | * - everyone except group_exit_task is stopped during signal delivery |
424 | * of fatal signals, group_exit_task processes the signal. | 424 | * of fatal signals, group_exit_task processes the signal. |
425 | */ | 425 | */ |
426 | struct task_struct *group_exit_task; | 426 | struct task_struct *group_exit_task; |
427 | int notify_count; | 427 | int notify_count; |
428 | 428 | ||
429 | /* thread group stop support, overloads group_exit_code too */ | 429 | /* thread group stop support, overloads group_exit_code too */ |
430 | int group_stop_count; | 430 | int group_stop_count; |
431 | unsigned int flags; /* see SIGNAL_* flags below */ | 431 | unsigned int flags; /* see SIGNAL_* flags below */ |
432 | 432 | ||
433 | /* POSIX.1b Interval Timers */ | 433 | /* POSIX.1b Interval Timers */ |
434 | struct list_head posix_timers; | 434 | struct list_head posix_timers; |
435 | 435 | ||
436 | /* ITIMER_REAL timer for the process */ | 436 | /* ITIMER_REAL timer for the process */ |
437 | struct hrtimer real_timer; | 437 | struct hrtimer real_timer; |
438 | struct task_struct *tsk; | 438 | struct task_struct *tsk; |
439 | ktime_t it_real_incr; | 439 | ktime_t it_real_incr; |
440 | 440 | ||
441 | /* ITIMER_PROF and ITIMER_VIRTUAL timers for the process */ | 441 | /* ITIMER_PROF and ITIMER_VIRTUAL timers for the process */ |
442 | cputime_t it_prof_expires, it_virt_expires; | 442 | cputime_t it_prof_expires, it_virt_expires; |
443 | cputime_t it_prof_incr, it_virt_incr; | 443 | cputime_t it_prof_incr, it_virt_incr; |
444 | 444 | ||
445 | /* job control IDs */ | 445 | /* job control IDs */ |
446 | 446 | ||
447 | /* | 447 | /* |
448 | * pgrp and session fields are deprecated. | 448 | * pgrp and session fields are deprecated. |
449 | * use the task_session_Xnr and task_pgrp_Xnr routines below | 449 | * use the task_session_Xnr and task_pgrp_Xnr routines below |
450 | */ | 450 | */ |
451 | 451 | ||
452 | union { | 452 | union { |
453 | pid_t pgrp __deprecated; | 453 | pid_t pgrp __deprecated; |
454 | pid_t __pgrp; | 454 | pid_t __pgrp; |
455 | }; | 455 | }; |
456 | 456 | ||
457 | struct pid *tty_old_pgrp; | 457 | struct pid *tty_old_pgrp; |
458 | 458 | ||
459 | union { | 459 | union { |
460 | pid_t session __deprecated; | 460 | pid_t session __deprecated; |
461 | pid_t __session; | 461 | pid_t __session; |
462 | }; | 462 | }; |
463 | 463 | ||
464 | /* boolean value for session group leader */ | 464 | /* boolean value for session group leader */ |
465 | int leader; | 465 | int leader; |
466 | 466 | ||
467 | struct tty_struct *tty; /* NULL if no tty */ | 467 | struct tty_struct *tty; /* NULL if no tty */ |
468 | 468 | ||
469 | /* | 469 | /* |
470 | * Cumulative resource counters for dead threads in the group, | 470 | * Cumulative resource counters for dead threads in the group, |
471 | * and for reaped dead child processes forked by this group. | 471 | * and for reaped dead child processes forked by this group. |
472 | * Live threads maintain their own counters and add to these | 472 | * Live threads maintain their own counters and add to these |
473 | * in __exit_signal, except for the group leader. | 473 | * in __exit_signal, except for the group leader. |
474 | */ | 474 | */ |
475 | cputime_t utime, stime, cutime, cstime; | 475 | cputime_t utime, stime, cutime, cstime; |
476 | cputime_t gtime; | 476 | cputime_t gtime; |
477 | cputime_t cgtime; | 477 | cputime_t cgtime; |
478 | unsigned long nvcsw, nivcsw, cnvcsw, cnivcsw; | 478 | unsigned long nvcsw, nivcsw, cnvcsw, cnivcsw; |
479 | unsigned long min_flt, maj_flt, cmin_flt, cmaj_flt; | 479 | unsigned long min_flt, maj_flt, cmin_flt, cmaj_flt; |
480 | unsigned long inblock, oublock, cinblock, coublock; | 480 | unsigned long inblock, oublock, cinblock, coublock; |
481 | 481 | ||
482 | /* | 482 | /* |
483 | * Cumulative ns of scheduled CPU time for dead threads in the | 483 | * Cumulative ns of scheduled CPU time for dead threads in the |
484 | * group, not including a zombie group leader. (This only differs | 484 | * group, not including a zombie group leader. (This only differs |
485 | * from jiffies_to_ns(utime + stime) if sched_clock uses something | 485 | * from jiffies_to_ns(utime + stime) if sched_clock uses something |
486 | * other than jiffies.) | 486 | * other than jiffies.) |
487 | */ | 487 | */ |
488 | unsigned long long sum_sched_runtime; | 488 | unsigned long long sum_sched_runtime; |
489 | 489 | ||
490 | /* | 490 | /* |
491 | * We don't bother to synchronize most readers of this at all, | 491 | * We don't bother to synchronize most readers of this at all, |
492 | * because there is no reader checking a limit that actually needs | 492 | * because there is no reader checking a limit that actually needs |
493 | * to get both rlim_cur and rlim_max atomically, and either one | 493 | * to get both rlim_cur and rlim_max atomically, and either one |
494 | * alone is a single word that can safely be read normally. | 494 | * alone is a single word that can safely be read normally. |
495 | * getrlimit/setrlimit use task_lock(current->group_leader) to | 495 | * getrlimit/setrlimit use task_lock(current->group_leader) to |
496 | * protect this instead of the siglock, because they really | 496 | * protect this instead of the siglock, because they really |
497 | * have no need to disable irqs. | 497 | * have no need to disable irqs. |
498 | */ | 498 | */ |
499 | struct rlimit rlim[RLIM_NLIMITS]; | 499 | struct rlimit rlim[RLIM_NLIMITS]; |
500 | 500 | ||
501 | struct list_head cpu_timers[3]; | 501 | struct list_head cpu_timers[3]; |
502 | 502 | ||
503 | /* keep the process-shared keyrings here so that they do the right | 503 | /* keep the process-shared keyrings here so that they do the right |
504 | * thing in threads created with CLONE_THREAD */ | 504 | * thing in threads created with CLONE_THREAD */ |
505 | #ifdef CONFIG_KEYS | 505 | #ifdef CONFIG_KEYS |
506 | struct key *session_keyring; /* keyring inherited over fork */ | 506 | struct key *session_keyring; /* keyring inherited over fork */ |
507 | struct key *process_keyring; /* keyring private to this process */ | 507 | struct key *process_keyring; /* keyring private to this process */ |
508 | #endif | 508 | #endif |
509 | #ifdef CONFIG_BSD_PROCESS_ACCT | 509 | #ifdef CONFIG_BSD_PROCESS_ACCT |
510 | struct pacct_struct pacct; /* per-process accounting information */ | 510 | struct pacct_struct pacct; /* per-process accounting information */ |
511 | #endif | 511 | #endif |
512 | #ifdef CONFIG_TASKSTATS | 512 | #ifdef CONFIG_TASKSTATS |
513 | struct taskstats *stats; | 513 | struct taskstats *stats; |
514 | #endif | 514 | #endif |
515 | #ifdef CONFIG_AUDIT | 515 | #ifdef CONFIG_AUDIT |
516 | unsigned audit_tty; | 516 | unsigned audit_tty; |
517 | struct tty_audit_buf *tty_audit_buf; | 517 | struct tty_audit_buf *tty_audit_buf; |
518 | #endif | 518 | #endif |
519 | }; | 519 | }; |
520 | 520 | ||
521 | /* Context switch must be unlocked if interrupts are to be enabled */ | 521 | /* Context switch must be unlocked if interrupts are to be enabled */ |
522 | #ifdef __ARCH_WANT_INTERRUPTS_ON_CTXSW | 522 | #ifdef __ARCH_WANT_INTERRUPTS_ON_CTXSW |
523 | # define __ARCH_WANT_UNLOCKED_CTXSW | 523 | # define __ARCH_WANT_UNLOCKED_CTXSW |
524 | #endif | 524 | #endif |
525 | 525 | ||
526 | /* | 526 | /* |
527 | * Bits in flags field of signal_struct. | 527 | * Bits in flags field of signal_struct. |
528 | */ | 528 | */ |
529 | #define SIGNAL_STOP_STOPPED 0x00000001 /* job control stop in effect */ | 529 | #define SIGNAL_STOP_STOPPED 0x00000001 /* job control stop in effect */ |
530 | #define SIGNAL_STOP_DEQUEUED 0x00000002 /* stop signal dequeued */ | 530 | #define SIGNAL_STOP_DEQUEUED 0x00000002 /* stop signal dequeued */ |
531 | #define SIGNAL_STOP_CONTINUED 0x00000004 /* SIGCONT since WCONTINUED reap */ | 531 | #define SIGNAL_STOP_CONTINUED 0x00000004 /* SIGCONT since WCONTINUED reap */ |
532 | #define SIGNAL_GROUP_EXIT 0x00000008 /* group exit in progress */ | 532 | #define SIGNAL_GROUP_EXIT 0x00000008 /* group exit in progress */ |
533 | 533 | ||
534 | /* | 534 | /* |
535 | * Some day this will be a full-fledged user tracking system.. | 535 | * Some day this will be a full-fledged user tracking system.. |
536 | */ | 536 | */ |
537 | struct user_struct { | 537 | struct user_struct { |
538 | atomic_t __count; /* reference count */ | 538 | atomic_t __count; /* reference count */ |
539 | atomic_t processes; /* How many processes does this user have? */ | 539 | atomic_t processes; /* How many processes does this user have? */ |
540 | atomic_t files; /* How many open files does this user have? */ | 540 | atomic_t files; /* How many open files does this user have? */ |
541 | atomic_t sigpending; /* How many pending signals does this user have? */ | 541 | atomic_t sigpending; /* How many pending signals does this user have? */ |
542 | #ifdef CONFIG_INOTIFY_USER | 542 | #ifdef CONFIG_INOTIFY_USER |
543 | atomic_t inotify_watches; /* How many inotify watches does this user have? */ | 543 | atomic_t inotify_watches; /* How many inotify watches does this user have? */ |
544 | atomic_t inotify_devs; /* How many inotify devs does this user have opened? */ | 544 | atomic_t inotify_devs; /* How many inotify devs does this user have opened? */ |
545 | #endif | 545 | #endif |
546 | #ifdef CONFIG_POSIX_MQUEUE | 546 | #ifdef CONFIG_POSIX_MQUEUE |
547 | /* protected by mq_lock */ | 547 | /* protected by mq_lock */ |
548 | unsigned long mq_bytes; /* How many bytes can be allocated to mqueue? */ | 548 | unsigned long mq_bytes; /* How many bytes can be allocated to mqueue? */ |
549 | #endif | 549 | #endif |
550 | unsigned long locked_shm; /* How many pages of mlocked shm ? */ | 550 | unsigned long locked_shm; /* How many pages of mlocked shm ? */ |
551 | 551 | ||
552 | #ifdef CONFIG_KEYS | 552 | #ifdef CONFIG_KEYS |
553 | struct key *uid_keyring; /* UID specific keyring */ | 553 | struct key *uid_keyring; /* UID specific keyring */ |
554 | struct key *session_keyring; /* UID's default session keyring */ | 554 | struct key *session_keyring; /* UID's default session keyring */ |
555 | #endif | 555 | #endif |
556 | 556 | ||
557 | /* Hash table maintenance information */ | 557 | /* Hash table maintenance information */ |
558 | struct hlist_node uidhash_node; | 558 | struct hlist_node uidhash_node; |
559 | uid_t uid; | 559 | uid_t uid; |
560 | 560 | ||
561 | #ifdef CONFIG_FAIR_USER_SCHED | 561 | #ifdef CONFIG_FAIR_USER_SCHED |
562 | struct task_group *tg; | 562 | struct task_group *tg; |
563 | #ifdef CONFIG_SYSFS | 563 | #ifdef CONFIG_SYSFS |
564 | struct kobject kobj; | 564 | struct kobject kobj; |
565 | struct work_struct work; | 565 | struct work_struct work; |
566 | #endif | 566 | #endif |
567 | #endif | 567 | #endif |
568 | }; | 568 | }; |
569 | 569 | ||
570 | extern int uids_sysfs_init(void); | 570 | extern int uids_sysfs_init(void); |
571 | 571 | ||
572 | extern struct user_struct *find_user(uid_t); | 572 | extern struct user_struct *find_user(uid_t); |
573 | 573 | ||
574 | extern struct user_struct root_user; | 574 | extern struct user_struct root_user; |
575 | #define INIT_USER (&root_user) | 575 | #define INIT_USER (&root_user) |
576 | 576 | ||
577 | struct backing_dev_info; | 577 | struct backing_dev_info; |
578 | struct reclaim_state; | 578 | struct reclaim_state; |
579 | 579 | ||
580 | #if defined(CONFIG_SCHEDSTATS) || defined(CONFIG_TASK_DELAY_ACCT) | 580 | #if defined(CONFIG_SCHEDSTATS) || defined(CONFIG_TASK_DELAY_ACCT) |
581 | struct sched_info { | 581 | struct sched_info { |
582 | /* cumulative counters */ | 582 | /* cumulative counters */ |
583 | unsigned long pcount; /* # of times run on this cpu */ | 583 | unsigned long pcount; /* # of times run on this cpu */ |
584 | unsigned long long cpu_time, /* time spent on the cpu */ | 584 | unsigned long long cpu_time, /* time spent on the cpu */ |
585 | run_delay; /* time spent waiting on a runqueue */ | 585 | run_delay; /* time spent waiting on a runqueue */ |
586 | 586 | ||
587 | /* timestamps */ | 587 | /* timestamps */ |
588 | unsigned long long last_arrival,/* when we last ran on a cpu */ | 588 | unsigned long long last_arrival,/* when we last ran on a cpu */ |
589 | last_queued; /* when we were last queued to run */ | 589 | last_queued; /* when we were last queued to run */ |
590 | #ifdef CONFIG_SCHEDSTATS | 590 | #ifdef CONFIG_SCHEDSTATS |
591 | /* BKL stats */ | 591 | /* BKL stats */ |
592 | unsigned int bkl_count; | 592 | unsigned int bkl_count; |
593 | #endif | 593 | #endif |
594 | }; | 594 | }; |
595 | #endif /* defined(CONFIG_SCHEDSTATS) || defined(CONFIG_TASK_DELAY_ACCT) */ | 595 | #endif /* defined(CONFIG_SCHEDSTATS) || defined(CONFIG_TASK_DELAY_ACCT) */ |
596 | 596 | ||
597 | #ifdef CONFIG_SCHEDSTATS | 597 | #ifdef CONFIG_SCHEDSTATS |
598 | extern const struct file_operations proc_schedstat_operations; | 598 | extern const struct file_operations proc_schedstat_operations; |
599 | #endif /* CONFIG_SCHEDSTATS */ | 599 | #endif /* CONFIG_SCHEDSTATS */ |
600 | 600 | ||
601 | #ifdef CONFIG_TASK_DELAY_ACCT | 601 | #ifdef CONFIG_TASK_DELAY_ACCT |
602 | struct task_delay_info { | 602 | struct task_delay_info { |
603 | spinlock_t lock; | 603 | spinlock_t lock; |
604 | unsigned int flags; /* Private per-task flags */ | 604 | unsigned int flags; /* Private per-task flags */ |
605 | 605 | ||
606 | /* For each stat XXX, add following, aligned appropriately | 606 | /* For each stat XXX, add following, aligned appropriately |
607 | * | 607 | * |
608 | * struct timespec XXX_start, XXX_end; | 608 | * struct timespec XXX_start, XXX_end; |
609 | * u64 XXX_delay; | 609 | * u64 XXX_delay; |
610 | * u32 XXX_count; | 610 | * u32 XXX_count; |
611 | * | 611 | * |
612 | * Atomicity of updates to XXX_delay, XXX_count protected by | 612 | * Atomicity of updates to XXX_delay, XXX_count protected by |
613 | * single lock above (split into XXX_lock if contention is an issue). | 613 | * single lock above (split into XXX_lock if contention is an issue). |
614 | */ | 614 | */ |
615 | 615 | ||
616 | /* | 616 | /* |
617 | * XXX_count is incremented on every XXX operation, the delay | 617 | * XXX_count is incremented on every XXX operation, the delay |
618 | * associated with the operation is added to XXX_delay. | 618 | * associated with the operation is added to XXX_delay. |
619 | * XXX_delay contains the accumulated delay time in nanoseconds. | 619 | * XXX_delay contains the accumulated delay time in nanoseconds. |
620 | */ | 620 | */ |
621 | struct timespec blkio_start, blkio_end; /* Shared by blkio, swapin */ | 621 | struct timespec blkio_start, blkio_end; /* Shared by blkio, swapin */ |
622 | u64 blkio_delay; /* wait for sync block io completion */ | 622 | u64 blkio_delay; /* wait for sync block io completion */ |
623 | u64 swapin_delay; /* wait for swapin block io completion */ | 623 | u64 swapin_delay; /* wait for swapin block io completion */ |
624 | u32 blkio_count; /* total count of the number of sync block */ | 624 | u32 blkio_count; /* total count of the number of sync block */ |
625 | /* io operations performed */ | 625 | /* io operations performed */ |
626 | u32 swapin_count; /* total count of the number of swapin block */ | 626 | u32 swapin_count; /* total count of the number of swapin block */ |
627 | /* io operations performed */ | 627 | /* io operations performed */ |
628 | }; | 628 | }; |
629 | #endif /* CONFIG_TASK_DELAY_ACCT */ | 629 | #endif /* CONFIG_TASK_DELAY_ACCT */ |
630 | 630 | ||
631 | static inline int sched_info_on(void) | 631 | static inline int sched_info_on(void) |
632 | { | 632 | { |
633 | #ifdef CONFIG_SCHEDSTATS | 633 | #ifdef CONFIG_SCHEDSTATS |
634 | return 1; | 634 | return 1; |
635 | #elif defined(CONFIG_TASK_DELAY_ACCT) | 635 | #elif defined(CONFIG_TASK_DELAY_ACCT) |
636 | extern int delayacct_on; | 636 | extern int delayacct_on; |
637 | return delayacct_on; | 637 | return delayacct_on; |
638 | #else | 638 | #else |
639 | return 0; | 639 | return 0; |
640 | #endif | 640 | #endif |
641 | } | 641 | } |
642 | 642 | ||
643 | enum cpu_idle_type { | 643 | enum cpu_idle_type { |
644 | CPU_IDLE, | 644 | CPU_IDLE, |
645 | CPU_NOT_IDLE, | 645 | CPU_NOT_IDLE, |
646 | CPU_NEWLY_IDLE, | 646 | CPU_NEWLY_IDLE, |
647 | CPU_MAX_IDLE_TYPES | 647 | CPU_MAX_IDLE_TYPES |
648 | }; | 648 | }; |
649 | 649 | ||
650 | /* | 650 | /* |
651 | * sched-domains (multiprocessor balancing) declarations: | 651 | * sched-domains (multiprocessor balancing) declarations: |
652 | */ | 652 | */ |
653 | 653 | ||
654 | /* | 654 | /* |
655 | * Increase resolution of nice-level calculations: | 655 | * Increase resolution of nice-level calculations: |
656 | */ | 656 | */ |
657 | #define SCHED_LOAD_SHIFT 10 | 657 | #define SCHED_LOAD_SHIFT 10 |
658 | #define SCHED_LOAD_SCALE (1L << SCHED_LOAD_SHIFT) | 658 | #define SCHED_LOAD_SCALE (1L << SCHED_LOAD_SHIFT) |
659 | 659 | ||
660 | #define SCHED_LOAD_SCALE_FUZZ SCHED_LOAD_SCALE | 660 | #define SCHED_LOAD_SCALE_FUZZ SCHED_LOAD_SCALE |
661 | 661 | ||
662 | #ifdef CONFIG_SMP | 662 | #ifdef CONFIG_SMP |
663 | #define SD_LOAD_BALANCE 1 /* Do load balancing on this domain. */ | 663 | #define SD_LOAD_BALANCE 1 /* Do load balancing on this domain. */ |
664 | #define SD_BALANCE_NEWIDLE 2 /* Balance when about to become idle */ | 664 | #define SD_BALANCE_NEWIDLE 2 /* Balance when about to become idle */ |
665 | #define SD_BALANCE_EXEC 4 /* Balance on exec */ | 665 | #define SD_BALANCE_EXEC 4 /* Balance on exec */ |
666 | #define SD_BALANCE_FORK 8 /* Balance on fork, clone */ | 666 | #define SD_BALANCE_FORK 8 /* Balance on fork, clone */ |
667 | #define SD_WAKE_IDLE 16 /* Wake to idle CPU on task wakeup */ | 667 | #define SD_WAKE_IDLE 16 /* Wake to idle CPU on task wakeup */ |
668 | #define SD_WAKE_AFFINE 32 /* Wake task to waking CPU */ | 668 | #define SD_WAKE_AFFINE 32 /* Wake task to waking CPU */ |
669 | #define SD_WAKE_BALANCE 64 /* Perform balancing at task wakeup */ | 669 | #define SD_WAKE_BALANCE 64 /* Perform balancing at task wakeup */ |
670 | #define SD_SHARE_CPUPOWER 128 /* Domain members share cpu power */ | 670 | #define SD_SHARE_CPUPOWER 128 /* Domain members share cpu power */ |
671 | #define SD_POWERSAVINGS_BALANCE 256 /* Balance for power savings */ | 671 | #define SD_POWERSAVINGS_BALANCE 256 /* Balance for power savings */ |
672 | #define SD_SHARE_PKG_RESOURCES 512 /* Domain members share cpu pkg resources */ | 672 | #define SD_SHARE_PKG_RESOURCES 512 /* Domain members share cpu pkg resources */ |
673 | #define SD_SERIALIZE 1024 /* Only a single load balancing instance */ | 673 | #define SD_SERIALIZE 1024 /* Only a single load balancing instance */ |
674 | 674 | ||
675 | #define BALANCE_FOR_MC_POWER \ | 675 | #define BALANCE_FOR_MC_POWER \ |
676 | (sched_smt_power_savings ? SD_POWERSAVINGS_BALANCE : 0) | 676 | (sched_smt_power_savings ? SD_POWERSAVINGS_BALANCE : 0) |
677 | 677 | ||
678 | #define BALANCE_FOR_PKG_POWER \ | 678 | #define BALANCE_FOR_PKG_POWER \ |
679 | ((sched_mc_power_savings || sched_smt_power_savings) ? \ | 679 | ((sched_mc_power_savings || sched_smt_power_savings) ? \ |
680 | SD_POWERSAVINGS_BALANCE : 0) | 680 | SD_POWERSAVINGS_BALANCE : 0) |
681 | 681 | ||
682 | #define test_sd_parent(sd, flag) ((sd->parent && \ | 682 | #define test_sd_parent(sd, flag) ((sd->parent && \ |
683 | (sd->parent->flags & flag)) ? 1 : 0) | 683 | (sd->parent->flags & flag)) ? 1 : 0) |
684 | 684 | ||
685 | 685 | ||
686 | struct sched_group { | 686 | struct sched_group { |
687 | struct sched_group *next; /* Must be a circular list */ | 687 | struct sched_group *next; /* Must be a circular list */ |
688 | cpumask_t cpumask; | 688 | cpumask_t cpumask; |
689 | 689 | ||
690 | /* | 690 | /* |
691 | * CPU power of this group, SCHED_LOAD_SCALE being max power for a | 691 | * CPU power of this group, SCHED_LOAD_SCALE being max power for a |
692 | * single CPU. This is read only (except for setup, hotplug CPU). | 692 | * single CPU. This is read only (except for setup, hotplug CPU). |
693 | * Note : Never change cpu_power without recompute its reciprocal | 693 | * Note : Never change cpu_power without recompute its reciprocal |
694 | */ | 694 | */ |
695 | unsigned int __cpu_power; | 695 | unsigned int __cpu_power; |
696 | /* | 696 | /* |
697 | * reciprocal value of cpu_power to avoid expensive divides | 697 | * reciprocal value of cpu_power to avoid expensive divides |
698 | * (see include/linux/reciprocal_div.h) | 698 | * (see include/linux/reciprocal_div.h) |
699 | */ | 699 | */ |
700 | u32 reciprocal_cpu_power; | 700 | u32 reciprocal_cpu_power; |
701 | }; | 701 | }; |
702 | 702 | ||
703 | struct sched_domain { | 703 | struct sched_domain { |
704 | /* These fields must be setup */ | 704 | /* These fields must be setup */ |
705 | struct sched_domain *parent; /* top domain must be null terminated */ | 705 | struct sched_domain *parent; /* top domain must be null terminated */ |
706 | struct sched_domain *child; /* bottom domain must be null terminated */ | 706 | struct sched_domain *child; /* bottom domain must be null terminated */ |
707 | struct sched_group *groups; /* the balancing groups of the domain */ | 707 | struct sched_group *groups; /* the balancing groups of the domain */ |
708 | cpumask_t span; /* span of all CPUs in this domain */ | 708 | cpumask_t span; /* span of all CPUs in this domain */ |
709 | unsigned long min_interval; /* Minimum balance interval ms */ | 709 | unsigned long min_interval; /* Minimum balance interval ms */ |
710 | unsigned long max_interval; /* Maximum balance interval ms */ | 710 | unsigned long max_interval; /* Maximum balance interval ms */ |
711 | unsigned int busy_factor; /* less balancing by factor if busy */ | 711 | unsigned int busy_factor; /* less balancing by factor if busy */ |
712 | unsigned int imbalance_pct; /* No balance until over watermark */ | 712 | unsigned int imbalance_pct; /* No balance until over watermark */ |
713 | unsigned int cache_nice_tries; /* Leave cache hot tasks for # tries */ | 713 | unsigned int cache_nice_tries; /* Leave cache hot tasks for # tries */ |
714 | unsigned int busy_idx; | 714 | unsigned int busy_idx; |
715 | unsigned int idle_idx; | 715 | unsigned int idle_idx; |
716 | unsigned int newidle_idx; | 716 | unsigned int newidle_idx; |
717 | unsigned int wake_idx; | 717 | unsigned int wake_idx; |
718 | unsigned int forkexec_idx; | 718 | unsigned int forkexec_idx; |
719 | int flags; /* See SD_* */ | 719 | int flags; /* See SD_* */ |
720 | 720 | ||
721 | /* Runtime fields. */ | 721 | /* Runtime fields. */ |
722 | unsigned long last_balance; /* init to jiffies. units in jiffies */ | 722 | unsigned long last_balance; /* init to jiffies. units in jiffies */ |
723 | unsigned int balance_interval; /* initialise to 1. units in ms. */ | 723 | unsigned int balance_interval; /* initialise to 1. units in ms. */ |
724 | unsigned int nr_balance_failed; /* initialise to 0 */ | 724 | unsigned int nr_balance_failed; /* initialise to 0 */ |
725 | 725 | ||
726 | #ifdef CONFIG_SCHEDSTATS | 726 | #ifdef CONFIG_SCHEDSTATS |
727 | /* load_balance() stats */ | 727 | /* load_balance() stats */ |
728 | unsigned int lb_count[CPU_MAX_IDLE_TYPES]; | 728 | unsigned int lb_count[CPU_MAX_IDLE_TYPES]; |
729 | unsigned int lb_failed[CPU_MAX_IDLE_TYPES]; | 729 | unsigned int lb_failed[CPU_MAX_IDLE_TYPES]; |
730 | unsigned int lb_balanced[CPU_MAX_IDLE_TYPES]; | 730 | unsigned int lb_balanced[CPU_MAX_IDLE_TYPES]; |
731 | unsigned int lb_imbalance[CPU_MAX_IDLE_TYPES]; | 731 | unsigned int lb_imbalance[CPU_MAX_IDLE_TYPES]; |
732 | unsigned int lb_gained[CPU_MAX_IDLE_TYPES]; | 732 | unsigned int lb_gained[CPU_MAX_IDLE_TYPES]; |
733 | unsigned int lb_hot_gained[CPU_MAX_IDLE_TYPES]; | 733 | unsigned int lb_hot_gained[CPU_MAX_IDLE_TYPES]; |
734 | unsigned int lb_nobusyg[CPU_MAX_IDLE_TYPES]; | 734 | unsigned int lb_nobusyg[CPU_MAX_IDLE_TYPES]; |
735 | unsigned int lb_nobusyq[CPU_MAX_IDLE_TYPES]; | 735 | unsigned int lb_nobusyq[CPU_MAX_IDLE_TYPES]; |
736 | 736 | ||
737 | /* Active load balancing */ | 737 | /* Active load balancing */ |
738 | unsigned int alb_count; | 738 | unsigned int alb_count; |
739 | unsigned int alb_failed; | 739 | unsigned int alb_failed; |
740 | unsigned int alb_pushed; | 740 | unsigned int alb_pushed; |
741 | 741 | ||
742 | /* SD_BALANCE_EXEC stats */ | 742 | /* SD_BALANCE_EXEC stats */ |
743 | unsigned int sbe_count; | 743 | unsigned int sbe_count; |
744 | unsigned int sbe_balanced; | 744 | unsigned int sbe_balanced; |
745 | unsigned int sbe_pushed; | 745 | unsigned int sbe_pushed; |
746 | 746 | ||
747 | /* SD_BALANCE_FORK stats */ | 747 | /* SD_BALANCE_FORK stats */ |
748 | unsigned int sbf_count; | 748 | unsigned int sbf_count; |
749 | unsigned int sbf_balanced; | 749 | unsigned int sbf_balanced; |
750 | unsigned int sbf_pushed; | 750 | unsigned int sbf_pushed; |
751 | 751 | ||
752 | /* try_to_wake_up() stats */ | 752 | /* try_to_wake_up() stats */ |
753 | unsigned int ttwu_wake_remote; | 753 | unsigned int ttwu_wake_remote; |
754 | unsigned int ttwu_move_affine; | 754 | unsigned int ttwu_move_affine; |
755 | unsigned int ttwu_move_balance; | 755 | unsigned int ttwu_move_balance; |
756 | #endif | 756 | #endif |
757 | }; | 757 | }; |
758 | 758 | ||
759 | extern void partition_sched_domains(int ndoms_new, cpumask_t *doms_new); | 759 | extern void partition_sched_domains(int ndoms_new, cpumask_t *doms_new); |
760 | 760 | ||
761 | #endif /* CONFIG_SMP */ | 761 | #endif /* CONFIG_SMP */ |
762 | 762 | ||
763 | /* | 763 | /* |
764 | * A runqueue laden with a single nice 0 task scores a weighted_cpuload of | 764 | * A runqueue laden with a single nice 0 task scores a weighted_cpuload of |
765 | * SCHED_LOAD_SCALE. This function returns 1 if any cpu is laden with a | 765 | * SCHED_LOAD_SCALE. This function returns 1 if any cpu is laden with a |
766 | * task of nice 0 or enough lower priority tasks to bring up the | 766 | * task of nice 0 or enough lower priority tasks to bring up the |
767 | * weighted_cpuload | 767 | * weighted_cpuload |
768 | */ | 768 | */ |
769 | static inline int above_background_load(void) | 769 | static inline int above_background_load(void) |
770 | { | 770 | { |
771 | unsigned long cpu; | 771 | unsigned long cpu; |
772 | 772 | ||
773 | for_each_online_cpu(cpu) { | 773 | for_each_online_cpu(cpu) { |
774 | if (weighted_cpuload(cpu) >= SCHED_LOAD_SCALE) | 774 | if (weighted_cpuload(cpu) >= SCHED_LOAD_SCALE) |
775 | return 1; | 775 | return 1; |
776 | } | 776 | } |
777 | return 0; | 777 | return 0; |
778 | } | 778 | } |
779 | 779 | ||
780 | struct io_context; /* See blkdev.h */ | 780 | struct io_context; /* See blkdev.h */ |
781 | #define NGROUPS_SMALL 32 | 781 | #define NGROUPS_SMALL 32 |
782 | #define NGROUPS_PER_BLOCK ((int)(PAGE_SIZE / sizeof(gid_t))) | 782 | #define NGROUPS_PER_BLOCK ((int)(PAGE_SIZE / sizeof(gid_t))) |
783 | struct group_info { | 783 | struct group_info { |
784 | int ngroups; | 784 | int ngroups; |
785 | atomic_t usage; | 785 | atomic_t usage; |
786 | gid_t small_block[NGROUPS_SMALL]; | 786 | gid_t small_block[NGROUPS_SMALL]; |
787 | int nblocks; | 787 | int nblocks; |
788 | gid_t *blocks[0]; | 788 | gid_t *blocks[0]; |
789 | }; | 789 | }; |
790 | 790 | ||
791 | /* | 791 | /* |
792 | * get_group_info() must be called with the owning task locked (via task_lock()) | 792 | * get_group_info() must be called with the owning task locked (via task_lock()) |
793 | * when task != current. The reason being that the vast majority of callers are | 793 | * when task != current. The reason being that the vast majority of callers are |
794 | * looking at current->group_info, which can not be changed except by the | 794 | * looking at current->group_info, which can not be changed except by the |
795 | * current task. Changing current->group_info requires the task lock, too. | 795 | * current task. Changing current->group_info requires the task lock, too. |
796 | */ | 796 | */ |
797 | #define get_group_info(group_info) do { \ | 797 | #define get_group_info(group_info) do { \ |
798 | atomic_inc(&(group_info)->usage); \ | 798 | atomic_inc(&(group_info)->usage); \ |
799 | } while (0) | 799 | } while (0) |
800 | 800 | ||
801 | #define put_group_info(group_info) do { \ | 801 | #define put_group_info(group_info) do { \ |
802 | if (atomic_dec_and_test(&(group_info)->usage)) \ | 802 | if (atomic_dec_and_test(&(group_info)->usage)) \ |
803 | groups_free(group_info); \ | 803 | groups_free(group_info); \ |
804 | } while (0) | 804 | } while (0) |
805 | 805 | ||
806 | extern struct group_info *groups_alloc(int gidsetsize); | 806 | extern struct group_info *groups_alloc(int gidsetsize); |
807 | extern void groups_free(struct group_info *group_info); | 807 | extern void groups_free(struct group_info *group_info); |
808 | extern int set_current_groups(struct group_info *group_info); | 808 | extern int set_current_groups(struct group_info *group_info); |
809 | extern int groups_search(struct group_info *group_info, gid_t grp); | 809 | extern int groups_search(struct group_info *group_info, gid_t grp); |
810 | /* access the groups "array" with this macro */ | 810 | /* access the groups "array" with this macro */ |
811 | #define GROUP_AT(gi, i) \ | 811 | #define GROUP_AT(gi, i) \ |
812 | ((gi)->blocks[(i)/NGROUPS_PER_BLOCK][(i)%NGROUPS_PER_BLOCK]) | 812 | ((gi)->blocks[(i)/NGROUPS_PER_BLOCK][(i)%NGROUPS_PER_BLOCK]) |
813 | 813 | ||
814 | #ifdef ARCH_HAS_PREFETCH_SWITCH_STACK | 814 | #ifdef ARCH_HAS_PREFETCH_SWITCH_STACK |
815 | extern void prefetch_stack(struct task_struct *t); | 815 | extern void prefetch_stack(struct task_struct *t); |
816 | #else | 816 | #else |
817 | static inline void prefetch_stack(struct task_struct *t) { } | 817 | static inline void prefetch_stack(struct task_struct *t) { } |
818 | #endif | 818 | #endif |
819 | 819 | ||
820 | struct audit_context; /* See audit.c */ | 820 | struct audit_context; /* See audit.c */ |
821 | struct mempolicy; | 821 | struct mempolicy; |
822 | struct pipe_inode_info; | 822 | struct pipe_inode_info; |
823 | struct uts_namespace; | 823 | struct uts_namespace; |
824 | 824 | ||
825 | struct rq; | 825 | struct rq; |
826 | struct sched_domain; | 826 | struct sched_domain; |
827 | 827 | ||
828 | struct sched_class { | 828 | struct sched_class { |
829 | const struct sched_class *next; | 829 | const struct sched_class *next; |
830 | 830 | ||
831 | void (*enqueue_task) (struct rq *rq, struct task_struct *p, int wakeup); | 831 | void (*enqueue_task) (struct rq *rq, struct task_struct *p, int wakeup); |
832 | void (*dequeue_task) (struct rq *rq, struct task_struct *p, int sleep); | 832 | void (*dequeue_task) (struct rq *rq, struct task_struct *p, int sleep); |
833 | void (*yield_task) (struct rq *rq); | 833 | void (*yield_task) (struct rq *rq); |
834 | int (*select_task_rq)(struct task_struct *p, int sync); | 834 | int (*select_task_rq)(struct task_struct *p, int sync); |
835 | 835 | ||
836 | void (*check_preempt_curr) (struct rq *rq, struct task_struct *p); | 836 | void (*check_preempt_curr) (struct rq *rq, struct task_struct *p); |
837 | 837 | ||
838 | struct task_struct * (*pick_next_task) (struct rq *rq); | 838 | struct task_struct * (*pick_next_task) (struct rq *rq); |
839 | void (*put_prev_task) (struct rq *rq, struct task_struct *p); | 839 | void (*put_prev_task) (struct rq *rq, struct task_struct *p); |
840 | 840 | ||
841 | #ifdef CONFIG_SMP | 841 | #ifdef CONFIG_SMP |
842 | unsigned long (*load_balance) (struct rq *this_rq, int this_cpu, | 842 | unsigned long (*load_balance) (struct rq *this_rq, int this_cpu, |
843 | struct rq *busiest, unsigned long max_load_move, | 843 | struct rq *busiest, unsigned long max_load_move, |
844 | struct sched_domain *sd, enum cpu_idle_type idle, | 844 | struct sched_domain *sd, enum cpu_idle_type idle, |
845 | int *all_pinned, int *this_best_prio); | 845 | int *all_pinned, int *this_best_prio); |
846 | 846 | ||
847 | int (*move_one_task) (struct rq *this_rq, int this_cpu, | 847 | int (*move_one_task) (struct rq *this_rq, int this_cpu, |
848 | struct rq *busiest, struct sched_domain *sd, | 848 | struct rq *busiest, struct sched_domain *sd, |
849 | enum cpu_idle_type idle); | 849 | enum cpu_idle_type idle); |
850 | void (*pre_schedule) (struct rq *this_rq, struct task_struct *task); | 850 | void (*pre_schedule) (struct rq *this_rq, struct task_struct *task); |
851 | void (*post_schedule) (struct rq *this_rq); | 851 | void (*post_schedule) (struct rq *this_rq); |
852 | void (*task_wake_up) (struct rq *this_rq, struct task_struct *task); | 852 | void (*task_wake_up) (struct rq *this_rq, struct task_struct *task); |
853 | #endif | 853 | #endif |
854 | 854 | ||
855 | void (*set_curr_task) (struct rq *rq); | 855 | void (*set_curr_task) (struct rq *rq); |
856 | void (*task_tick) (struct rq *rq, struct task_struct *p, int queued); | 856 | void (*task_tick) (struct rq *rq, struct task_struct *p, int queued); |
857 | void (*task_new) (struct rq *rq, struct task_struct *p); | 857 | void (*task_new) (struct rq *rq, struct task_struct *p); |
858 | void (*set_cpus_allowed)(struct task_struct *p, cpumask_t *newmask); | 858 | void (*set_cpus_allowed)(struct task_struct *p, cpumask_t *newmask); |
859 | 859 | ||
860 | void (*join_domain)(struct rq *rq); | 860 | void (*join_domain)(struct rq *rq); |
861 | void (*leave_domain)(struct rq *rq); | 861 | void (*leave_domain)(struct rq *rq); |
862 | 862 | ||
863 | void (*switched_from) (struct rq *this_rq, struct task_struct *task, | 863 | void (*switched_from) (struct rq *this_rq, struct task_struct *task, |
864 | int running); | 864 | int running); |
865 | void (*switched_to) (struct rq *this_rq, struct task_struct *task, | 865 | void (*switched_to) (struct rq *this_rq, struct task_struct *task, |
866 | int running); | 866 | int running); |
867 | void (*prio_changed) (struct rq *this_rq, struct task_struct *task, | 867 | void (*prio_changed) (struct rq *this_rq, struct task_struct *task, |
868 | int oldprio, int running); | 868 | int oldprio, int running); |
869 | }; | 869 | }; |
870 | 870 | ||
871 | struct load_weight { | 871 | struct load_weight { |
872 | unsigned long weight, inv_weight; | 872 | unsigned long weight, inv_weight; |
873 | }; | 873 | }; |
874 | 874 | ||
875 | /* | 875 | /* |
876 | * CFS stats for a schedulable entity (task, task-group etc) | 876 | * CFS stats for a schedulable entity (task, task-group etc) |
877 | * | 877 | * |
878 | * Current field usage histogram: | 878 | * Current field usage histogram: |
879 | * | 879 | * |
880 | * 4 se->block_start | 880 | * 4 se->block_start |
881 | * 4 se->run_node | 881 | * 4 se->run_node |
882 | * 4 se->sleep_start | 882 | * 4 se->sleep_start |
883 | * 6 se->load.weight | 883 | * 6 se->load.weight |
884 | */ | 884 | */ |
885 | struct sched_entity { | 885 | struct sched_entity { |
886 | struct load_weight load; /* for load-balancing */ | 886 | struct load_weight load; /* for load-balancing */ |
887 | struct rb_node run_node; | 887 | struct rb_node run_node; |
888 | unsigned int on_rq; | 888 | unsigned int on_rq; |
889 | 889 | ||
890 | u64 exec_start; | 890 | u64 exec_start; |
891 | u64 sum_exec_runtime; | 891 | u64 sum_exec_runtime; |
892 | u64 vruntime; | 892 | u64 vruntime; |
893 | u64 prev_sum_exec_runtime; | 893 | u64 prev_sum_exec_runtime; |
894 | 894 | ||
895 | #ifdef CONFIG_SCHEDSTATS | 895 | #ifdef CONFIG_SCHEDSTATS |
896 | u64 wait_start; | 896 | u64 wait_start; |
897 | u64 wait_max; | 897 | u64 wait_max; |
898 | 898 | ||
899 | u64 sleep_start; | 899 | u64 sleep_start; |
900 | u64 sleep_max; | 900 | u64 sleep_max; |
901 | s64 sum_sleep_runtime; | 901 | s64 sum_sleep_runtime; |
902 | 902 | ||
903 | u64 block_start; | 903 | u64 block_start; |
904 | u64 block_max; | 904 | u64 block_max; |
905 | u64 exec_max; | 905 | u64 exec_max; |
906 | u64 slice_max; | 906 | u64 slice_max; |
907 | 907 | ||
908 | u64 nr_migrations; | 908 | u64 nr_migrations; |
909 | u64 nr_migrations_cold; | 909 | u64 nr_migrations_cold; |
910 | u64 nr_failed_migrations_affine; | 910 | u64 nr_failed_migrations_affine; |
911 | u64 nr_failed_migrations_running; | 911 | u64 nr_failed_migrations_running; |
912 | u64 nr_failed_migrations_hot; | 912 | u64 nr_failed_migrations_hot; |
913 | u64 nr_forced_migrations; | 913 | u64 nr_forced_migrations; |
914 | u64 nr_forced2_migrations; | 914 | u64 nr_forced2_migrations; |
915 | 915 | ||
916 | u64 nr_wakeups; | 916 | u64 nr_wakeups; |
917 | u64 nr_wakeups_sync; | 917 | u64 nr_wakeups_sync; |
918 | u64 nr_wakeups_migrate; | 918 | u64 nr_wakeups_migrate; |
919 | u64 nr_wakeups_local; | 919 | u64 nr_wakeups_local; |
920 | u64 nr_wakeups_remote; | 920 | u64 nr_wakeups_remote; |
921 | u64 nr_wakeups_affine; | 921 | u64 nr_wakeups_affine; |
922 | u64 nr_wakeups_affine_attempts; | 922 | u64 nr_wakeups_affine_attempts; |
923 | u64 nr_wakeups_passive; | 923 | u64 nr_wakeups_passive; |
924 | u64 nr_wakeups_idle; | 924 | u64 nr_wakeups_idle; |
925 | #endif | 925 | #endif |
926 | 926 | ||
927 | #ifdef CONFIG_FAIR_GROUP_SCHED | 927 | #ifdef CONFIG_FAIR_GROUP_SCHED |
928 | struct sched_entity *parent; | 928 | struct sched_entity *parent; |
929 | /* rq on which this entity is (to be) queued: */ | 929 | /* rq on which this entity is (to be) queued: */ |
930 | struct cfs_rq *cfs_rq; | 930 | struct cfs_rq *cfs_rq; |
931 | /* rq "owned" by this entity/group: */ | 931 | /* rq "owned" by this entity/group: */ |
932 | struct cfs_rq *my_q; | 932 | struct cfs_rq *my_q; |
933 | #endif | 933 | #endif |
934 | }; | 934 | }; |
935 | 935 | ||
936 | struct sched_rt_entity { | 936 | struct sched_rt_entity { |
937 | struct list_head run_list; | 937 | struct list_head run_list; |
938 | unsigned int time_slice; | 938 | unsigned int time_slice; |
939 | unsigned long timeout; | 939 | unsigned long timeout; |
940 | int nr_cpus_allowed; | 940 | int nr_cpus_allowed; |
941 | 941 | ||
942 | #ifdef CONFIG_FAIR_GROUP_SCHED | 942 | #ifdef CONFIG_FAIR_GROUP_SCHED |
943 | struct sched_rt_entity *parent; | 943 | struct sched_rt_entity *parent; |
944 | /* rq on which this entity is (to be) queued: */ | 944 | /* rq on which this entity is (to be) queued: */ |
945 | struct rt_rq *rt_rq; | 945 | struct rt_rq *rt_rq; |
946 | /* rq "owned" by this entity/group: */ | 946 | /* rq "owned" by this entity/group: */ |
947 | struct rt_rq *my_q; | 947 | struct rt_rq *my_q; |
948 | #endif | 948 | #endif |
949 | }; | 949 | }; |
950 | 950 | ||
951 | struct task_struct { | 951 | struct task_struct { |
952 | volatile long state; /* -1 unrunnable, 0 runnable, >0 stopped */ | 952 | volatile long state; /* -1 unrunnable, 0 runnable, >0 stopped */ |
953 | void *stack; | 953 | void *stack; |
954 | atomic_t usage; | 954 | atomic_t usage; |
955 | unsigned int flags; /* per process flags, defined below */ | 955 | unsigned int flags; /* per process flags, defined below */ |
956 | unsigned int ptrace; | 956 | unsigned int ptrace; |
957 | 957 | ||
958 | int lock_depth; /* BKL lock depth */ | 958 | int lock_depth; /* BKL lock depth */ |
959 | 959 | ||
960 | #ifdef CONFIG_SMP | 960 | #ifdef CONFIG_SMP |
961 | #ifdef __ARCH_WANT_UNLOCKED_CTXSW | 961 | #ifdef __ARCH_WANT_UNLOCKED_CTXSW |
962 | int oncpu; | 962 | int oncpu; |
963 | #endif | 963 | #endif |
964 | #endif | 964 | #endif |
965 | 965 | ||
966 | int prio, static_prio, normal_prio; | 966 | int prio, static_prio, normal_prio; |
967 | const struct sched_class *sched_class; | 967 | const struct sched_class *sched_class; |
968 | struct sched_entity se; | 968 | struct sched_entity se; |
969 | struct sched_rt_entity rt; | 969 | struct sched_rt_entity rt; |
970 | 970 | ||
971 | #ifdef CONFIG_PREEMPT_NOTIFIERS | 971 | #ifdef CONFIG_PREEMPT_NOTIFIERS |
972 | /* list of struct preempt_notifier: */ | 972 | /* list of struct preempt_notifier: */ |
973 | struct hlist_head preempt_notifiers; | 973 | struct hlist_head preempt_notifiers; |
974 | #endif | 974 | #endif |
975 | 975 | ||
976 | unsigned short ioprio; | 976 | unsigned short ioprio; |
977 | /* | 977 | /* |
978 | * fpu_counter contains the number of consecutive context switches | 978 | * fpu_counter contains the number of consecutive context switches |
979 | * that the FPU is used. If this is over a threshold, the lazy fpu | 979 | * that the FPU is used. If this is over a threshold, the lazy fpu |
980 | * saving becomes unlazy to save the trap. This is an unsigned char | 980 | * saving becomes unlazy to save the trap. This is an unsigned char |
981 | * so that after 256 times the counter wraps and the behavior turns | 981 | * so that after 256 times the counter wraps and the behavior turns |
982 | * lazy again; this to deal with bursty apps that only use FPU for | 982 | * lazy again; this to deal with bursty apps that only use FPU for |
983 | * a short time | 983 | * a short time |
984 | */ | 984 | */ |
985 | unsigned char fpu_counter; | 985 | unsigned char fpu_counter; |
986 | s8 oomkilladj; /* OOM kill score adjustment (bit shift). */ | 986 | s8 oomkilladj; /* OOM kill score adjustment (bit shift). */ |
987 | #ifdef CONFIG_BLK_DEV_IO_TRACE | 987 | #ifdef CONFIG_BLK_DEV_IO_TRACE |
988 | unsigned int btrace_seq; | 988 | unsigned int btrace_seq; |
989 | #endif | 989 | #endif |
990 | 990 | ||
991 | unsigned int policy; | 991 | unsigned int policy; |
992 | cpumask_t cpus_allowed; | 992 | cpumask_t cpus_allowed; |
993 | 993 | ||
994 | #ifdef CONFIG_PREEMPT_RCU | 994 | #ifdef CONFIG_PREEMPT_RCU |
995 | int rcu_read_lock_nesting; | 995 | int rcu_read_lock_nesting; |
996 | int rcu_flipctr_idx; | 996 | int rcu_flipctr_idx; |
997 | #endif /* #ifdef CONFIG_PREEMPT_RCU */ | 997 | #endif /* #ifdef CONFIG_PREEMPT_RCU */ |
998 | 998 | ||
999 | #if defined(CONFIG_SCHEDSTATS) || defined(CONFIG_TASK_DELAY_ACCT) | 999 | #if defined(CONFIG_SCHEDSTATS) || defined(CONFIG_TASK_DELAY_ACCT) |
1000 | struct sched_info sched_info; | 1000 | struct sched_info sched_info; |
1001 | #endif | 1001 | #endif |
1002 | 1002 | ||
1003 | struct list_head tasks; | 1003 | struct list_head tasks; |
1004 | /* | 1004 | /* |
1005 | * ptrace_list/ptrace_children forms the list of my children | 1005 | * ptrace_list/ptrace_children forms the list of my children |
1006 | * that were stolen by a ptracer. | 1006 | * that were stolen by a ptracer. |
1007 | */ | 1007 | */ |
1008 | struct list_head ptrace_children; | 1008 | struct list_head ptrace_children; |
1009 | struct list_head ptrace_list; | 1009 | struct list_head ptrace_list; |
1010 | 1010 | ||
1011 | struct mm_struct *mm, *active_mm; | 1011 | struct mm_struct *mm, *active_mm; |
1012 | 1012 | ||
1013 | /* task state */ | 1013 | /* task state */ |
1014 | struct linux_binfmt *binfmt; | 1014 | struct linux_binfmt *binfmt; |
1015 | int exit_state; | 1015 | int exit_state; |
1016 | int exit_code, exit_signal; | 1016 | int exit_code, exit_signal; |
1017 | int pdeath_signal; /* The signal sent when the parent dies */ | 1017 | int pdeath_signal; /* The signal sent when the parent dies */ |
1018 | /* ??? */ | 1018 | /* ??? */ |
1019 | unsigned int personality; | 1019 | unsigned int personality; |
1020 | unsigned did_exec:1; | 1020 | unsigned did_exec:1; |
1021 | pid_t pid; | 1021 | pid_t pid; |
1022 | pid_t tgid; | 1022 | pid_t tgid; |
1023 | 1023 | ||
1024 | #ifdef CONFIG_CC_STACKPROTECTOR | 1024 | #ifdef CONFIG_CC_STACKPROTECTOR |
1025 | /* Canary value for the -fstack-protector gcc feature */ | 1025 | /* Canary value for the -fstack-protector gcc feature */ |
1026 | unsigned long stack_canary; | 1026 | unsigned long stack_canary; |
1027 | #endif | 1027 | #endif |
1028 | /* | 1028 | /* |
1029 | * pointers to (original) parent process, youngest child, younger sibling, | 1029 | * pointers to (original) parent process, youngest child, younger sibling, |
1030 | * older sibling, respectively. (p->father can be replaced with | 1030 | * older sibling, respectively. (p->father can be replaced with |
1031 | * p->parent->pid) | 1031 | * p->parent->pid) |
1032 | */ | 1032 | */ |
1033 | struct task_struct *real_parent; /* real parent process (when being debugged) */ | 1033 | struct task_struct *real_parent; /* real parent process (when being debugged) */ |
1034 | struct task_struct *parent; /* parent process */ | 1034 | struct task_struct *parent; /* parent process */ |
1035 | /* | 1035 | /* |
1036 | * children/sibling forms the list of my children plus the | 1036 | * children/sibling forms the list of my children plus the |
1037 | * tasks I'm ptracing. | 1037 | * tasks I'm ptracing. |
1038 | */ | 1038 | */ |
1039 | struct list_head children; /* list of my children */ | 1039 | struct list_head children; /* list of my children */ |
1040 | struct list_head sibling; /* linkage in my parent's children list */ | 1040 | struct list_head sibling; /* linkage in my parent's children list */ |
1041 | struct task_struct *group_leader; /* threadgroup leader */ | 1041 | struct task_struct *group_leader; /* threadgroup leader */ |
1042 | 1042 | ||
1043 | /* PID/PID hash table linkage. */ | 1043 | /* PID/PID hash table linkage. */ |
1044 | struct pid_link pids[PIDTYPE_MAX]; | 1044 | struct pid_link pids[PIDTYPE_MAX]; |
1045 | struct list_head thread_group; | 1045 | struct list_head thread_group; |
1046 | 1046 | ||
1047 | struct completion *vfork_done; /* for vfork() */ | 1047 | struct completion *vfork_done; /* for vfork() */ |
1048 | int __user *set_child_tid; /* CLONE_CHILD_SETTID */ | 1048 | int __user *set_child_tid; /* CLONE_CHILD_SETTID */ |
1049 | int __user *clear_child_tid; /* CLONE_CHILD_CLEARTID */ | 1049 | int __user *clear_child_tid; /* CLONE_CHILD_CLEARTID */ |
1050 | 1050 | ||
1051 | unsigned int rt_priority; | 1051 | unsigned int rt_priority; |
1052 | cputime_t utime, stime, utimescaled, stimescaled; | 1052 | cputime_t utime, stime, utimescaled, stimescaled; |
1053 | cputime_t gtime; | 1053 | cputime_t gtime; |
1054 | cputime_t prev_utime, prev_stime; | 1054 | cputime_t prev_utime, prev_stime; |
1055 | unsigned long nvcsw, nivcsw; /* context switch counts */ | 1055 | unsigned long nvcsw, nivcsw; /* context switch counts */ |
1056 | struct timespec start_time; /* monotonic time */ | 1056 | struct timespec start_time; /* monotonic time */ |
1057 | struct timespec real_start_time; /* boot based time */ | 1057 | struct timespec real_start_time; /* boot based time */ |
1058 | /* mm fault and swap info: this can arguably be seen as either mm-specific or thread-specific */ | 1058 | /* mm fault and swap info: this can arguably be seen as either mm-specific or thread-specific */ |
1059 | unsigned long min_flt, maj_flt; | 1059 | unsigned long min_flt, maj_flt; |
1060 | 1060 | ||
1061 | cputime_t it_prof_expires, it_virt_expires; | 1061 | cputime_t it_prof_expires, it_virt_expires; |
1062 | unsigned long long it_sched_expires; | 1062 | unsigned long long it_sched_expires; |
1063 | struct list_head cpu_timers[3]; | 1063 | struct list_head cpu_timers[3]; |
1064 | 1064 | ||
1065 | /* process credentials */ | 1065 | /* process credentials */ |
1066 | uid_t uid,euid,suid,fsuid; | 1066 | uid_t uid,euid,suid,fsuid; |
1067 | gid_t gid,egid,sgid,fsgid; | 1067 | gid_t gid,egid,sgid,fsgid; |
1068 | struct group_info *group_info; | 1068 | struct group_info *group_info; |
1069 | kernel_cap_t cap_effective, cap_inheritable, cap_permitted; | 1069 | kernel_cap_t cap_effective, cap_inheritable, cap_permitted; |
1070 | unsigned keep_capabilities:1; | 1070 | unsigned keep_capabilities:1; |
1071 | struct user_struct *user; | 1071 | struct user_struct *user; |
1072 | #ifdef CONFIG_KEYS | 1072 | #ifdef CONFIG_KEYS |
1073 | struct key *request_key_auth; /* assumed request_key authority */ | 1073 | struct key *request_key_auth; /* assumed request_key authority */ |
1074 | struct key *thread_keyring; /* keyring private to this thread */ | 1074 | struct key *thread_keyring; /* keyring private to this thread */ |
1075 | unsigned char jit_keyring; /* default keyring to attach requested keys to */ | 1075 | unsigned char jit_keyring; /* default keyring to attach requested keys to */ |
1076 | #endif | 1076 | #endif |
1077 | char comm[TASK_COMM_LEN]; /* executable name excluding path | 1077 | char comm[TASK_COMM_LEN]; /* executable name excluding path |
1078 | - access with [gs]et_task_comm (which lock | 1078 | - access with [gs]et_task_comm (which lock |
1079 | it with task_lock()) | 1079 | it with task_lock()) |
1080 | - initialized normally by flush_old_exec */ | 1080 | - initialized normally by flush_old_exec */ |
1081 | /* file system info */ | 1081 | /* file system info */ |
1082 | int link_count, total_link_count; | 1082 | int link_count, total_link_count; |
1083 | #ifdef CONFIG_SYSVIPC | 1083 | #ifdef CONFIG_SYSVIPC |
1084 | /* ipc stuff */ | 1084 | /* ipc stuff */ |
1085 | struct sysv_sem sysvsem; | 1085 | struct sysv_sem sysvsem; |
1086 | #endif | 1086 | #endif |
1087 | #ifdef CONFIG_DETECT_SOFTLOCKUP | 1087 | #ifdef CONFIG_DETECT_SOFTLOCKUP |
1088 | /* hung task detection */ | 1088 | /* hung task detection */ |
1089 | unsigned long last_switch_timestamp; | 1089 | unsigned long last_switch_timestamp; |
1090 | unsigned long last_switch_count; | 1090 | unsigned long last_switch_count; |
1091 | #endif | 1091 | #endif |
1092 | /* CPU-specific state of this task */ | 1092 | /* CPU-specific state of this task */ |
1093 | struct thread_struct thread; | 1093 | struct thread_struct thread; |
1094 | /* filesystem information */ | 1094 | /* filesystem information */ |
1095 | struct fs_struct *fs; | 1095 | struct fs_struct *fs; |
1096 | /* open file information */ | 1096 | /* open file information */ |
1097 | struct files_struct *files; | 1097 | struct files_struct *files; |
1098 | /* namespaces */ | 1098 | /* namespaces */ |
1099 | struct nsproxy *nsproxy; | 1099 | struct nsproxy *nsproxy; |
1100 | /* signal handlers */ | 1100 | /* signal handlers */ |
1101 | struct signal_struct *signal; | 1101 | struct signal_struct *signal; |
1102 | struct sighand_struct *sighand; | 1102 | struct sighand_struct *sighand; |
1103 | 1103 | ||
1104 | sigset_t blocked, real_blocked; | 1104 | sigset_t blocked, real_blocked; |
1105 | sigset_t saved_sigmask; /* To be restored with TIF_RESTORE_SIGMASK */ | 1105 | sigset_t saved_sigmask; /* To be restored with TIF_RESTORE_SIGMASK */ |
1106 | struct sigpending pending; | 1106 | struct sigpending pending; |
1107 | 1107 | ||
1108 | unsigned long sas_ss_sp; | 1108 | unsigned long sas_ss_sp; |
1109 | size_t sas_ss_size; | 1109 | size_t sas_ss_size; |
1110 | int (*notifier)(void *priv); | 1110 | int (*notifier)(void *priv); |
1111 | void *notifier_data; | 1111 | void *notifier_data; |
1112 | sigset_t *notifier_mask; | 1112 | sigset_t *notifier_mask; |
1113 | #ifdef CONFIG_SECURITY | 1113 | #ifdef CONFIG_SECURITY |
1114 | void *security; | 1114 | void *security; |
1115 | #endif | 1115 | #endif |
1116 | struct audit_context *audit_context; | 1116 | struct audit_context *audit_context; |
1117 | seccomp_t seccomp; | 1117 | seccomp_t seccomp; |
1118 | 1118 | ||
1119 | /* Thread group tracking */ | 1119 | /* Thread group tracking */ |
1120 | u32 parent_exec_id; | 1120 | u32 parent_exec_id; |
1121 | u32 self_exec_id; | 1121 | u32 self_exec_id; |
1122 | /* Protection of (de-)allocation: mm, files, fs, tty, keyrings */ | 1122 | /* Protection of (de-)allocation: mm, files, fs, tty, keyrings */ |
1123 | spinlock_t alloc_lock; | 1123 | spinlock_t alloc_lock; |
1124 | 1124 | ||
1125 | /* Protection of the PI data structures: */ | 1125 | /* Protection of the PI data structures: */ |
1126 | spinlock_t pi_lock; | 1126 | spinlock_t pi_lock; |
1127 | 1127 | ||
1128 | #ifdef CONFIG_RT_MUTEXES | 1128 | #ifdef CONFIG_RT_MUTEXES |
1129 | /* PI waiters blocked on a rt_mutex held by this task */ | 1129 | /* PI waiters blocked on a rt_mutex held by this task */ |
1130 | struct plist_head pi_waiters; | 1130 | struct plist_head pi_waiters; |
1131 | /* Deadlock detection and priority inheritance handling */ | 1131 | /* Deadlock detection and priority inheritance handling */ |
1132 | struct rt_mutex_waiter *pi_blocked_on; | 1132 | struct rt_mutex_waiter *pi_blocked_on; |
1133 | #endif | 1133 | #endif |
1134 | 1134 | ||
1135 | #ifdef CONFIG_DEBUG_MUTEXES | 1135 | #ifdef CONFIG_DEBUG_MUTEXES |
1136 | /* mutex deadlock detection */ | 1136 | /* mutex deadlock detection */ |
1137 | struct mutex_waiter *blocked_on; | 1137 | struct mutex_waiter *blocked_on; |
1138 | #endif | 1138 | #endif |
1139 | #ifdef CONFIG_TRACE_IRQFLAGS | 1139 | #ifdef CONFIG_TRACE_IRQFLAGS |
1140 | unsigned int irq_events; | 1140 | unsigned int irq_events; |
1141 | int hardirqs_enabled; | 1141 | int hardirqs_enabled; |
1142 | unsigned long hardirq_enable_ip; | 1142 | unsigned long hardirq_enable_ip; |
1143 | unsigned int hardirq_enable_event; | 1143 | unsigned int hardirq_enable_event; |
1144 | unsigned long hardirq_disable_ip; | 1144 | unsigned long hardirq_disable_ip; |
1145 | unsigned int hardirq_disable_event; | 1145 | unsigned int hardirq_disable_event; |
1146 | int softirqs_enabled; | 1146 | int softirqs_enabled; |
1147 | unsigned long softirq_disable_ip; | 1147 | unsigned long softirq_disable_ip; |
1148 | unsigned int softirq_disable_event; | 1148 | unsigned int softirq_disable_event; |
1149 | unsigned long softirq_enable_ip; | 1149 | unsigned long softirq_enable_ip; |
1150 | unsigned int softirq_enable_event; | 1150 | unsigned int softirq_enable_event; |
1151 | int hardirq_context; | 1151 | int hardirq_context; |
1152 | int softirq_context; | 1152 | int softirq_context; |
1153 | #endif | 1153 | #endif |
1154 | #ifdef CONFIG_LOCKDEP | 1154 | #ifdef CONFIG_LOCKDEP |
1155 | # define MAX_LOCK_DEPTH 30UL | 1155 | # define MAX_LOCK_DEPTH 30UL |
1156 | u64 curr_chain_key; | 1156 | u64 curr_chain_key; |
1157 | int lockdep_depth; | 1157 | int lockdep_depth; |
1158 | struct held_lock held_locks[MAX_LOCK_DEPTH]; | 1158 | struct held_lock held_locks[MAX_LOCK_DEPTH]; |
1159 | unsigned int lockdep_recursion; | 1159 | unsigned int lockdep_recursion; |
1160 | #endif | 1160 | #endif |
1161 | 1161 | ||
1162 | /* journalling filesystem info */ | 1162 | /* journalling filesystem info */ |
1163 | void *journal_info; | 1163 | void *journal_info; |
1164 | 1164 | ||
1165 | /* stacked block device info */ | 1165 | /* stacked block device info */ |
1166 | struct bio *bio_list, **bio_tail; | 1166 | struct bio *bio_list, **bio_tail; |
1167 | 1167 | ||
1168 | /* VM state */ | 1168 | /* VM state */ |
1169 | struct reclaim_state *reclaim_state; | 1169 | struct reclaim_state *reclaim_state; |
1170 | 1170 | ||
1171 | struct backing_dev_info *backing_dev_info; | 1171 | struct backing_dev_info *backing_dev_info; |
1172 | 1172 | ||
1173 | struct io_context *io_context; | 1173 | struct io_context *io_context; |
1174 | 1174 | ||
1175 | unsigned long ptrace_message; | 1175 | unsigned long ptrace_message; |
1176 | siginfo_t *last_siginfo; /* For ptrace use. */ | 1176 | siginfo_t *last_siginfo; /* For ptrace use. */ |
1177 | #ifdef CONFIG_TASK_XACCT | 1177 | #ifdef CONFIG_TASK_XACCT |
1178 | /* i/o counters(bytes read/written, #syscalls */ | 1178 | /* i/o counters(bytes read/written, #syscalls */ |
1179 | u64 rchar, wchar, syscr, syscw; | 1179 | u64 rchar, wchar, syscr, syscw; |
1180 | #endif | 1180 | #endif |
1181 | struct task_io_accounting ioac; | 1181 | struct task_io_accounting ioac; |
1182 | #if defined(CONFIG_TASK_XACCT) | 1182 | #if defined(CONFIG_TASK_XACCT) |
1183 | u64 acct_rss_mem1; /* accumulated rss usage */ | 1183 | u64 acct_rss_mem1; /* accumulated rss usage */ |
1184 | u64 acct_vm_mem1; /* accumulated virtual memory usage */ | 1184 | u64 acct_vm_mem1; /* accumulated virtual memory usage */ |
1185 | cputime_t acct_stimexpd;/* stime since last update */ | 1185 | cputime_t acct_stimexpd;/* stime since last update */ |
1186 | #endif | 1186 | #endif |
1187 | #ifdef CONFIG_NUMA | 1187 | #ifdef CONFIG_NUMA |
1188 | struct mempolicy *mempolicy; | 1188 | struct mempolicy *mempolicy; |
1189 | short il_next; | 1189 | short il_next; |
1190 | #endif | 1190 | #endif |
1191 | #ifdef CONFIG_CPUSETS | 1191 | #ifdef CONFIG_CPUSETS |
1192 | nodemask_t mems_allowed; | 1192 | nodemask_t mems_allowed; |
1193 | int cpuset_mems_generation; | 1193 | int cpuset_mems_generation; |
1194 | int cpuset_mem_spread_rotor; | 1194 | int cpuset_mem_spread_rotor; |
1195 | #endif | 1195 | #endif |
1196 | #ifdef CONFIG_CGROUPS | 1196 | #ifdef CONFIG_CGROUPS |
1197 | /* Control Group info protected by css_set_lock */ | 1197 | /* Control Group info protected by css_set_lock */ |
1198 | struct css_set *cgroups; | 1198 | struct css_set *cgroups; |
1199 | /* cg_list protected by css_set_lock and tsk->alloc_lock */ | 1199 | /* cg_list protected by css_set_lock and tsk->alloc_lock */ |
1200 | struct list_head cg_list; | 1200 | struct list_head cg_list; |
1201 | #endif | 1201 | #endif |
1202 | #ifdef CONFIG_FUTEX | 1202 | #ifdef CONFIG_FUTEX |
1203 | struct robust_list_head __user *robust_list; | 1203 | struct robust_list_head __user *robust_list; |
1204 | #ifdef CONFIG_COMPAT | 1204 | #ifdef CONFIG_COMPAT |
1205 | struct compat_robust_list_head __user *compat_robust_list; | 1205 | struct compat_robust_list_head __user *compat_robust_list; |
1206 | #endif | 1206 | #endif |
1207 | struct list_head pi_state_list; | 1207 | struct list_head pi_state_list; |
1208 | struct futex_pi_state *pi_state_cache; | 1208 | struct futex_pi_state *pi_state_cache; |
1209 | #endif | 1209 | #endif |
1210 | atomic_t fs_excl; /* holding fs exclusive resources */ | 1210 | atomic_t fs_excl; /* holding fs exclusive resources */ |
1211 | struct rcu_head rcu; | 1211 | struct rcu_head rcu; |
1212 | 1212 | ||
1213 | /* | 1213 | /* |
1214 | * cache last used pipe for splice | 1214 | * cache last used pipe for splice |
1215 | */ | 1215 | */ |
1216 | struct pipe_inode_info *splice_pipe; | 1216 | struct pipe_inode_info *splice_pipe; |
1217 | #ifdef CONFIG_TASK_DELAY_ACCT | 1217 | #ifdef CONFIG_TASK_DELAY_ACCT |
1218 | struct task_delay_info *delays; | 1218 | struct task_delay_info *delays; |
1219 | #endif | 1219 | #endif |
1220 | #ifdef CONFIG_FAULT_INJECTION | 1220 | #ifdef CONFIG_FAULT_INJECTION |
1221 | int make_it_fail; | 1221 | int make_it_fail; |
1222 | #endif | 1222 | #endif |
1223 | struct prop_local_single dirties; | 1223 | struct prop_local_single dirties; |
1224 | #ifdef CONFIG_LATENCYTOP | 1224 | #ifdef CONFIG_LATENCYTOP |
1225 | int latency_record_count; | 1225 | int latency_record_count; |
1226 | struct latency_record latency_record[LT_SAVECOUNT]; | 1226 | struct latency_record latency_record[LT_SAVECOUNT]; |
1227 | #endif | 1227 | #endif |
1228 | }; | 1228 | }; |
1229 | 1229 | ||
1230 | /* | 1230 | /* |
1231 | * Priority of a process goes from 0..MAX_PRIO-1, valid RT | 1231 | * Priority of a process goes from 0..MAX_PRIO-1, valid RT |
1232 | * priority is 0..MAX_RT_PRIO-1, and SCHED_NORMAL/SCHED_BATCH | 1232 | * priority is 0..MAX_RT_PRIO-1, and SCHED_NORMAL/SCHED_BATCH |
1233 | * tasks are in the range MAX_RT_PRIO..MAX_PRIO-1. Priority | 1233 | * tasks are in the range MAX_RT_PRIO..MAX_PRIO-1. Priority |
1234 | * values are inverted: lower p->prio value means higher priority. | 1234 | * values are inverted: lower p->prio value means higher priority. |
1235 | * | 1235 | * |
1236 | * The MAX_USER_RT_PRIO value allows the actual maximum | 1236 | * The MAX_USER_RT_PRIO value allows the actual maximum |
1237 | * RT priority to be separate from the value exported to | 1237 | * RT priority to be separate from the value exported to |
1238 | * user-space. This allows kernel threads to set their | 1238 | * user-space. This allows kernel threads to set their |
1239 | * priority to a value higher than any user task. Note: | 1239 | * priority to a value higher than any user task. Note: |
1240 | * MAX_RT_PRIO must not be smaller than MAX_USER_RT_PRIO. | 1240 | * MAX_RT_PRIO must not be smaller than MAX_USER_RT_PRIO. |
1241 | */ | 1241 | */ |
1242 | 1242 | ||
1243 | #define MAX_USER_RT_PRIO 100 | 1243 | #define MAX_USER_RT_PRIO 100 |
1244 | #define MAX_RT_PRIO MAX_USER_RT_PRIO | 1244 | #define MAX_RT_PRIO MAX_USER_RT_PRIO |
1245 | 1245 | ||
1246 | #define MAX_PRIO (MAX_RT_PRIO + 40) | 1246 | #define MAX_PRIO (MAX_RT_PRIO + 40) |
1247 | #define DEFAULT_PRIO (MAX_RT_PRIO + 20) | 1247 | #define DEFAULT_PRIO (MAX_RT_PRIO + 20) |
1248 | 1248 | ||
1249 | static inline int rt_prio(int prio) | 1249 | static inline int rt_prio(int prio) |
1250 | { | 1250 | { |
1251 | if (unlikely(prio < MAX_RT_PRIO)) | 1251 | if (unlikely(prio < MAX_RT_PRIO)) |
1252 | return 1; | 1252 | return 1; |
1253 | return 0; | 1253 | return 0; |
1254 | } | 1254 | } |
1255 | 1255 | ||
1256 | static inline int rt_task(struct task_struct *p) | 1256 | static inline int rt_task(struct task_struct *p) |
1257 | { | 1257 | { |
1258 | return rt_prio(p->prio); | 1258 | return rt_prio(p->prio); |
1259 | } | 1259 | } |
1260 | 1260 | ||
1261 | static inline void set_task_session(struct task_struct *tsk, pid_t session) | 1261 | static inline void set_task_session(struct task_struct *tsk, pid_t session) |
1262 | { | 1262 | { |
1263 | tsk->signal->__session = session; | 1263 | tsk->signal->__session = session; |
1264 | } | 1264 | } |
1265 | 1265 | ||
1266 | static inline void set_task_pgrp(struct task_struct *tsk, pid_t pgrp) | 1266 | static inline void set_task_pgrp(struct task_struct *tsk, pid_t pgrp) |
1267 | { | 1267 | { |
1268 | tsk->signal->__pgrp = pgrp; | 1268 | tsk->signal->__pgrp = pgrp; |
1269 | } | 1269 | } |
1270 | 1270 | ||
1271 | static inline struct pid *task_pid(struct task_struct *task) | 1271 | static inline struct pid *task_pid(struct task_struct *task) |
1272 | { | 1272 | { |
1273 | return task->pids[PIDTYPE_PID].pid; | 1273 | return task->pids[PIDTYPE_PID].pid; |
1274 | } | 1274 | } |
1275 | 1275 | ||
1276 | static inline struct pid *task_tgid(struct task_struct *task) | 1276 | static inline struct pid *task_tgid(struct task_struct *task) |
1277 | { | 1277 | { |
1278 | return task->group_leader->pids[PIDTYPE_PID].pid; | 1278 | return task->group_leader->pids[PIDTYPE_PID].pid; |
1279 | } | 1279 | } |
1280 | 1280 | ||
1281 | static inline struct pid *task_pgrp(struct task_struct *task) | 1281 | static inline struct pid *task_pgrp(struct task_struct *task) |
1282 | { | 1282 | { |
1283 | return task->group_leader->pids[PIDTYPE_PGID].pid; | 1283 | return task->group_leader->pids[PIDTYPE_PGID].pid; |
1284 | } | 1284 | } |
1285 | 1285 | ||
1286 | static inline struct pid *task_session(struct task_struct *task) | 1286 | static inline struct pid *task_session(struct task_struct *task) |
1287 | { | 1287 | { |
1288 | return task->group_leader->pids[PIDTYPE_SID].pid; | 1288 | return task->group_leader->pids[PIDTYPE_SID].pid; |
1289 | } | 1289 | } |
1290 | 1290 | ||
1291 | struct pid_namespace; | 1291 | struct pid_namespace; |
1292 | 1292 | ||
1293 | /* | 1293 | /* |
1294 | * the helpers to get the task's different pids as they are seen | 1294 | * the helpers to get the task's different pids as they are seen |
1295 | * from various namespaces | 1295 | * from various namespaces |
1296 | * | 1296 | * |
1297 | * task_xid_nr() : global id, i.e. the id seen from the init namespace; | 1297 | * task_xid_nr() : global id, i.e. the id seen from the init namespace; |
1298 | * task_xid_vnr() : virtual id, i.e. the id seen from the namespace the task | 1298 | * task_xid_vnr() : virtual id, i.e. the id seen from the namespace the task |
1299 | * belongs to. this only makes sence when called in the | 1299 | * belongs to. this only makes sence when called in the |
1300 | * context of the task that belongs to the same namespace; | 1300 | * context of the task that belongs to the same namespace; |
1301 | * task_xid_nr_ns() : id seen from the ns specified; | 1301 | * task_xid_nr_ns() : id seen from the ns specified; |
1302 | * | 1302 | * |
1303 | * set_task_vxid() : assigns a virtual id to a task; | 1303 | * set_task_vxid() : assigns a virtual id to a task; |
1304 | * | 1304 | * |
1305 | * see also pid_nr() etc in include/linux/pid.h | 1305 | * see also pid_nr() etc in include/linux/pid.h |
1306 | */ | 1306 | */ |
1307 | 1307 | ||
1308 | static inline pid_t task_pid_nr(struct task_struct *tsk) | 1308 | static inline pid_t task_pid_nr(struct task_struct *tsk) |
1309 | { | 1309 | { |
1310 | return tsk->pid; | 1310 | return tsk->pid; |
1311 | } | 1311 | } |
1312 | 1312 | ||
1313 | pid_t task_pid_nr_ns(struct task_struct *tsk, struct pid_namespace *ns); | 1313 | pid_t task_pid_nr_ns(struct task_struct *tsk, struct pid_namespace *ns); |
1314 | 1314 | ||
1315 | static inline pid_t task_pid_vnr(struct task_struct *tsk) | 1315 | static inline pid_t task_pid_vnr(struct task_struct *tsk) |
1316 | { | 1316 | { |
1317 | return pid_vnr(task_pid(tsk)); | 1317 | return pid_vnr(task_pid(tsk)); |
1318 | } | 1318 | } |
1319 | 1319 | ||
1320 | 1320 | ||
1321 | static inline pid_t task_tgid_nr(struct task_struct *tsk) | 1321 | static inline pid_t task_tgid_nr(struct task_struct *tsk) |
1322 | { | 1322 | { |
1323 | return tsk->tgid; | 1323 | return tsk->tgid; |
1324 | } | 1324 | } |
1325 | 1325 | ||
1326 | pid_t task_tgid_nr_ns(struct task_struct *tsk, struct pid_namespace *ns); | 1326 | pid_t task_tgid_nr_ns(struct task_struct *tsk, struct pid_namespace *ns); |
1327 | 1327 | ||
1328 | static inline pid_t task_tgid_vnr(struct task_struct *tsk) | 1328 | static inline pid_t task_tgid_vnr(struct task_struct *tsk) |
1329 | { | 1329 | { |
1330 | return pid_vnr(task_tgid(tsk)); | 1330 | return pid_vnr(task_tgid(tsk)); |
1331 | } | 1331 | } |
1332 | 1332 | ||
1333 | 1333 | ||
1334 | static inline pid_t task_pgrp_nr(struct task_struct *tsk) | 1334 | static inline pid_t task_pgrp_nr(struct task_struct *tsk) |
1335 | { | 1335 | { |
1336 | return tsk->signal->__pgrp; | 1336 | return tsk->signal->__pgrp; |
1337 | } | 1337 | } |
1338 | 1338 | ||
1339 | pid_t task_pgrp_nr_ns(struct task_struct *tsk, struct pid_namespace *ns); | 1339 | pid_t task_pgrp_nr_ns(struct task_struct *tsk, struct pid_namespace *ns); |
1340 | 1340 | ||
1341 | static inline pid_t task_pgrp_vnr(struct task_struct *tsk) | 1341 | static inline pid_t task_pgrp_vnr(struct task_struct *tsk) |
1342 | { | 1342 | { |
1343 | return pid_vnr(task_pgrp(tsk)); | 1343 | return pid_vnr(task_pgrp(tsk)); |
1344 | } | 1344 | } |
1345 | 1345 | ||
1346 | 1346 | ||
1347 | static inline pid_t task_session_nr(struct task_struct *tsk) | 1347 | static inline pid_t task_session_nr(struct task_struct *tsk) |
1348 | { | 1348 | { |
1349 | return tsk->signal->__session; | 1349 | return tsk->signal->__session; |
1350 | } | 1350 | } |
1351 | 1351 | ||
1352 | pid_t task_session_nr_ns(struct task_struct *tsk, struct pid_namespace *ns); | 1352 | pid_t task_session_nr_ns(struct task_struct *tsk, struct pid_namespace *ns); |
1353 | 1353 | ||
1354 | static inline pid_t task_session_vnr(struct task_struct *tsk) | 1354 | static inline pid_t task_session_vnr(struct task_struct *tsk) |
1355 | { | 1355 | { |
1356 | return pid_vnr(task_session(tsk)); | 1356 | return pid_vnr(task_session(tsk)); |
1357 | } | 1357 | } |
1358 | 1358 | ||
1359 | 1359 | ||
1360 | /** | 1360 | /** |
1361 | * pid_alive - check that a task structure is not stale | 1361 | * pid_alive - check that a task structure is not stale |
1362 | * @p: Task structure to be checked. | 1362 | * @p: Task structure to be checked. |
1363 | * | 1363 | * |
1364 | * Test if a process is not yet dead (at most zombie state) | 1364 | * Test if a process is not yet dead (at most zombie state) |
1365 | * If pid_alive fails, then pointers within the task structure | 1365 | * If pid_alive fails, then pointers within the task structure |
1366 | * can be stale and must not be dereferenced. | 1366 | * can be stale and must not be dereferenced. |
1367 | */ | 1367 | */ |
1368 | static inline int pid_alive(struct task_struct *p) | 1368 | static inline int pid_alive(struct task_struct *p) |
1369 | { | 1369 | { |
1370 | return p->pids[PIDTYPE_PID].pid != NULL; | 1370 | return p->pids[PIDTYPE_PID].pid != NULL; |
1371 | } | 1371 | } |
1372 | 1372 | ||
1373 | /** | 1373 | /** |
1374 | * is_global_init - check if a task structure is init | 1374 | * is_global_init - check if a task structure is init |
1375 | * @tsk: Task structure to be checked. | 1375 | * @tsk: Task structure to be checked. |
1376 | * | 1376 | * |
1377 | * Check if a task structure is the first user space task the kernel created. | 1377 | * Check if a task structure is the first user space task the kernel created. |
1378 | */ | 1378 | */ |
1379 | static inline int is_global_init(struct task_struct *tsk) | 1379 | static inline int is_global_init(struct task_struct *tsk) |
1380 | { | 1380 | { |
1381 | return tsk->pid == 1; | 1381 | return tsk->pid == 1; |
1382 | } | 1382 | } |
1383 | 1383 | ||
1384 | /* | 1384 | /* |
1385 | * is_container_init: | 1385 | * is_container_init: |
1386 | * check whether in the task is init in its own pid namespace. | 1386 | * check whether in the task is init in its own pid namespace. |
1387 | */ | 1387 | */ |
1388 | extern int is_container_init(struct task_struct *tsk); | 1388 | extern int is_container_init(struct task_struct *tsk); |
1389 | 1389 | ||
1390 | extern struct pid *cad_pid; | 1390 | extern struct pid *cad_pid; |
1391 | 1391 | ||
1392 | extern void free_task(struct task_struct *tsk); | 1392 | extern void free_task(struct task_struct *tsk); |
1393 | #define get_task_struct(tsk) do { atomic_inc(&(tsk)->usage); } while(0) | 1393 | #define get_task_struct(tsk) do { atomic_inc(&(tsk)->usage); } while(0) |
1394 | 1394 | ||
1395 | extern void __put_task_struct(struct task_struct *t); | 1395 | extern void __put_task_struct(struct task_struct *t); |
1396 | 1396 | ||
1397 | static inline void put_task_struct(struct task_struct *t) | 1397 | static inline void put_task_struct(struct task_struct *t) |
1398 | { | 1398 | { |
1399 | if (atomic_dec_and_test(&t->usage)) | 1399 | if (atomic_dec_and_test(&t->usage)) |
1400 | __put_task_struct(t); | 1400 | __put_task_struct(t); |
1401 | } | 1401 | } |
1402 | 1402 | ||
1403 | /* | 1403 | /* |
1404 | * Per process flags | 1404 | * Per process flags |
1405 | */ | 1405 | */ |
1406 | #define PF_ALIGNWARN 0x00000001 /* Print alignment warning msgs */ | 1406 | #define PF_ALIGNWARN 0x00000001 /* Print alignment warning msgs */ |
1407 | /* Not implemented yet, only for 486*/ | 1407 | /* Not implemented yet, only for 486*/ |
1408 | #define PF_STARTING 0x00000002 /* being created */ | 1408 | #define PF_STARTING 0x00000002 /* being created */ |
1409 | #define PF_EXITING 0x00000004 /* getting shut down */ | 1409 | #define PF_EXITING 0x00000004 /* getting shut down */ |
1410 | #define PF_EXITPIDONE 0x00000008 /* pi exit done on shut down */ | 1410 | #define PF_EXITPIDONE 0x00000008 /* pi exit done on shut down */ |
1411 | #define PF_VCPU 0x00000010 /* I'm a virtual CPU */ | 1411 | #define PF_VCPU 0x00000010 /* I'm a virtual CPU */ |
1412 | #define PF_FORKNOEXEC 0x00000040 /* forked but didn't exec */ | 1412 | #define PF_FORKNOEXEC 0x00000040 /* forked but didn't exec */ |
1413 | #define PF_SUPERPRIV 0x00000100 /* used super-user privileges */ | 1413 | #define PF_SUPERPRIV 0x00000100 /* used super-user privileges */ |
1414 | #define PF_DUMPCORE 0x00000200 /* dumped core */ | 1414 | #define PF_DUMPCORE 0x00000200 /* dumped core */ |
1415 | #define PF_SIGNALED 0x00000400 /* killed by a signal */ | 1415 | #define PF_SIGNALED 0x00000400 /* killed by a signal */ |
1416 | #define PF_MEMALLOC 0x00000800 /* Allocating memory */ | 1416 | #define PF_MEMALLOC 0x00000800 /* Allocating memory */ |
1417 | #define PF_FLUSHER 0x00001000 /* responsible for disk writeback */ | 1417 | #define PF_FLUSHER 0x00001000 /* responsible for disk writeback */ |
1418 | #define PF_USED_MATH 0x00002000 /* if unset the fpu must be initialized before use */ | 1418 | #define PF_USED_MATH 0x00002000 /* if unset the fpu must be initialized before use */ |
1419 | #define PF_NOFREEZE 0x00008000 /* this thread should not be frozen */ | 1419 | #define PF_NOFREEZE 0x00008000 /* this thread should not be frozen */ |
1420 | #define PF_FROZEN 0x00010000 /* frozen for system suspend */ | 1420 | #define PF_FROZEN 0x00010000 /* frozen for system suspend */ |
1421 | #define PF_FSTRANS 0x00020000 /* inside a filesystem transaction */ | 1421 | #define PF_FSTRANS 0x00020000 /* inside a filesystem transaction */ |
1422 | #define PF_KSWAPD 0x00040000 /* I am kswapd */ | 1422 | #define PF_KSWAPD 0x00040000 /* I am kswapd */ |
1423 | #define PF_SWAPOFF 0x00080000 /* I am in swapoff */ | 1423 | #define PF_SWAPOFF 0x00080000 /* I am in swapoff */ |
1424 | #define PF_LESS_THROTTLE 0x00100000 /* Throttle me less: I clean memory */ | 1424 | #define PF_LESS_THROTTLE 0x00100000 /* Throttle me less: I clean memory */ |
1425 | #define PF_BORROWED_MM 0x00200000 /* I am a kthread doing use_mm */ | 1425 | #define PF_BORROWED_MM 0x00200000 /* I am a kthread doing use_mm */ |
1426 | #define PF_RANDOMIZE 0x00400000 /* randomize virtual address space */ | 1426 | #define PF_RANDOMIZE 0x00400000 /* randomize virtual address space */ |
1427 | #define PF_SWAPWRITE 0x00800000 /* Allowed to write to swap */ | 1427 | #define PF_SWAPWRITE 0x00800000 /* Allowed to write to swap */ |
1428 | #define PF_SPREAD_PAGE 0x01000000 /* Spread page cache over cpuset */ | 1428 | #define PF_SPREAD_PAGE 0x01000000 /* Spread page cache over cpuset */ |
1429 | #define PF_SPREAD_SLAB 0x02000000 /* Spread some slab caches over cpuset */ | 1429 | #define PF_SPREAD_SLAB 0x02000000 /* Spread some slab caches over cpuset */ |
1430 | #define PF_MEMPOLICY 0x10000000 /* Non-default NUMA mempolicy */ | 1430 | #define PF_MEMPOLICY 0x10000000 /* Non-default NUMA mempolicy */ |
1431 | #define PF_MUTEX_TESTER 0x20000000 /* Thread belongs to the rt mutex tester */ | 1431 | #define PF_MUTEX_TESTER 0x20000000 /* Thread belongs to the rt mutex tester */ |
1432 | #define PF_FREEZER_SKIP 0x40000000 /* Freezer should not count it as freezeable */ | 1432 | #define PF_FREEZER_SKIP 0x40000000 /* Freezer should not count it as freezeable */ |
1433 | 1433 | ||
1434 | /* | 1434 | /* |
1435 | * Only the _current_ task can read/write to tsk->flags, but other | 1435 | * Only the _current_ task can read/write to tsk->flags, but other |
1436 | * tasks can access tsk->flags in readonly mode for example | 1436 | * tasks can access tsk->flags in readonly mode for example |
1437 | * with tsk_used_math (like during threaded core dumping). | 1437 | * with tsk_used_math (like during threaded core dumping). |
1438 | * There is however an exception to this rule during ptrace | 1438 | * There is however an exception to this rule during ptrace |
1439 | * or during fork: the ptracer task is allowed to write to the | 1439 | * or during fork: the ptracer task is allowed to write to the |
1440 | * child->flags of its traced child (same goes for fork, the parent | 1440 | * child->flags of its traced child (same goes for fork, the parent |
1441 | * can write to the child->flags), because we're guaranteed the | 1441 | * can write to the child->flags), because we're guaranteed the |
1442 | * child is not running and in turn not changing child->flags | 1442 | * child is not running and in turn not changing child->flags |
1443 | * at the same time the parent does it. | 1443 | * at the same time the parent does it. |
1444 | */ | 1444 | */ |
1445 | #define clear_stopped_child_used_math(child) do { (child)->flags &= ~PF_USED_MATH; } while (0) | 1445 | #define clear_stopped_child_used_math(child) do { (child)->flags &= ~PF_USED_MATH; } while (0) |
1446 | #define set_stopped_child_used_math(child) do { (child)->flags |= PF_USED_MATH; } while (0) | 1446 | #define set_stopped_child_used_math(child) do { (child)->flags |= PF_USED_MATH; } while (0) |
1447 | #define clear_used_math() clear_stopped_child_used_math(current) | 1447 | #define clear_used_math() clear_stopped_child_used_math(current) |
1448 | #define set_used_math() set_stopped_child_used_math(current) | 1448 | #define set_used_math() set_stopped_child_used_math(current) |
1449 | #define conditional_stopped_child_used_math(condition, child) \ | 1449 | #define conditional_stopped_child_used_math(condition, child) \ |
1450 | do { (child)->flags &= ~PF_USED_MATH, (child)->flags |= (condition) ? PF_USED_MATH : 0; } while (0) | 1450 | do { (child)->flags &= ~PF_USED_MATH, (child)->flags |= (condition) ? PF_USED_MATH : 0; } while (0) |
1451 | #define conditional_used_math(condition) \ | 1451 | #define conditional_used_math(condition) \ |
1452 | conditional_stopped_child_used_math(condition, current) | 1452 | conditional_stopped_child_used_math(condition, current) |
1453 | #define copy_to_stopped_child_used_math(child) \ | 1453 | #define copy_to_stopped_child_used_math(child) \ |
1454 | do { (child)->flags &= ~PF_USED_MATH, (child)->flags |= current->flags & PF_USED_MATH; } while (0) | 1454 | do { (child)->flags &= ~PF_USED_MATH, (child)->flags |= current->flags & PF_USED_MATH; } while (0) |
1455 | /* NOTE: this will return 0 or PF_USED_MATH, it will never return 1 */ | 1455 | /* NOTE: this will return 0 or PF_USED_MATH, it will never return 1 */ |
1456 | #define tsk_used_math(p) ((p)->flags & PF_USED_MATH) | 1456 | #define tsk_used_math(p) ((p)->flags & PF_USED_MATH) |
1457 | #define used_math() tsk_used_math(current) | 1457 | #define used_math() tsk_used_math(current) |
1458 | 1458 | ||
1459 | #ifdef CONFIG_SMP | 1459 | #ifdef CONFIG_SMP |
1460 | extern int set_cpus_allowed(struct task_struct *p, cpumask_t new_mask); | 1460 | extern int set_cpus_allowed(struct task_struct *p, cpumask_t new_mask); |
1461 | #else | 1461 | #else |
1462 | static inline int set_cpus_allowed(struct task_struct *p, cpumask_t new_mask) | 1462 | static inline int set_cpus_allowed(struct task_struct *p, cpumask_t new_mask) |
1463 | { | 1463 | { |
1464 | if (!cpu_isset(0, new_mask)) | 1464 | if (!cpu_isset(0, new_mask)) |
1465 | return -EINVAL; | 1465 | return -EINVAL; |
1466 | return 0; | 1466 | return 0; |
1467 | } | 1467 | } |
1468 | #endif | 1468 | #endif |
1469 | 1469 | ||
1470 | extern unsigned long long sched_clock(void); | 1470 | extern unsigned long long sched_clock(void); |
1471 | 1471 | ||
1472 | /* | 1472 | /* |
1473 | * For kernel-internal use: high-speed (but slightly incorrect) per-cpu | 1473 | * For kernel-internal use: high-speed (but slightly incorrect) per-cpu |
1474 | * clock constructed from sched_clock(): | 1474 | * clock constructed from sched_clock(): |
1475 | */ | 1475 | */ |
1476 | extern unsigned long long cpu_clock(int cpu); | 1476 | extern unsigned long long cpu_clock(int cpu); |
1477 | 1477 | ||
1478 | extern unsigned long long | 1478 | extern unsigned long long |
1479 | task_sched_runtime(struct task_struct *task); | 1479 | task_sched_runtime(struct task_struct *task); |
1480 | 1480 | ||
1481 | /* sched_exec is called by processes performing an exec */ | 1481 | /* sched_exec is called by processes performing an exec */ |
1482 | #ifdef CONFIG_SMP | 1482 | #ifdef CONFIG_SMP |
1483 | extern void sched_exec(void); | 1483 | extern void sched_exec(void); |
1484 | #else | 1484 | #else |
1485 | #define sched_exec() {} | 1485 | #define sched_exec() {} |
1486 | #endif | 1486 | #endif |
1487 | 1487 | ||
1488 | extern void sched_clock_idle_sleep_event(void); | 1488 | extern void sched_clock_idle_sleep_event(void); |
1489 | extern void sched_clock_idle_wakeup_event(u64 delta_ns); | 1489 | extern void sched_clock_idle_wakeup_event(u64 delta_ns); |
1490 | 1490 | ||
1491 | #ifdef CONFIG_HOTPLUG_CPU | 1491 | #ifdef CONFIG_HOTPLUG_CPU |
1492 | extern void idle_task_exit(void); | 1492 | extern void idle_task_exit(void); |
1493 | #else | 1493 | #else |
1494 | static inline void idle_task_exit(void) {} | 1494 | static inline void idle_task_exit(void) {} |
1495 | #endif | 1495 | #endif |
1496 | 1496 | ||
1497 | extern void sched_idle_next(void); | 1497 | extern void sched_idle_next(void); |
1498 | 1498 | ||
1499 | #ifdef CONFIG_SCHED_DEBUG | 1499 | #ifdef CONFIG_SCHED_DEBUG |
1500 | extern unsigned int sysctl_sched_latency; | 1500 | extern unsigned int sysctl_sched_latency; |
1501 | extern unsigned int sysctl_sched_min_granularity; | 1501 | extern unsigned int sysctl_sched_min_granularity; |
1502 | extern unsigned int sysctl_sched_wakeup_granularity; | 1502 | extern unsigned int sysctl_sched_wakeup_granularity; |
1503 | extern unsigned int sysctl_sched_batch_wakeup_granularity; | 1503 | extern unsigned int sysctl_sched_batch_wakeup_granularity; |
1504 | extern unsigned int sysctl_sched_child_runs_first; | 1504 | extern unsigned int sysctl_sched_child_runs_first; |
1505 | extern unsigned int sysctl_sched_features; | 1505 | extern unsigned int sysctl_sched_features; |
1506 | extern unsigned int sysctl_sched_migration_cost; | 1506 | extern unsigned int sysctl_sched_migration_cost; |
1507 | extern unsigned int sysctl_sched_nr_migrate; | 1507 | extern unsigned int sysctl_sched_nr_migrate; |
1508 | extern unsigned int sysctl_sched_rt_period; | 1508 | extern unsigned int sysctl_sched_rt_period; |
1509 | extern unsigned int sysctl_sched_rt_ratio; | 1509 | extern unsigned int sysctl_sched_rt_ratio; |
1510 | #if defined(CONFIG_FAIR_GROUP_SCHED) && defined(CONFIG_SMP) | 1510 | #if defined(CONFIG_FAIR_GROUP_SCHED) && defined(CONFIG_SMP) |
1511 | extern unsigned int sysctl_sched_min_bal_int_shares; | 1511 | extern unsigned int sysctl_sched_min_bal_int_shares; |
1512 | extern unsigned int sysctl_sched_max_bal_int_shares; | 1512 | extern unsigned int sysctl_sched_max_bal_int_shares; |
1513 | #endif | 1513 | #endif |
1514 | 1514 | ||
1515 | int sched_nr_latency_handler(struct ctl_table *table, int write, | 1515 | int sched_nr_latency_handler(struct ctl_table *table, int write, |
1516 | struct file *file, void __user *buffer, size_t *length, | 1516 | struct file *file, void __user *buffer, size_t *length, |
1517 | loff_t *ppos); | 1517 | loff_t *ppos); |
1518 | #endif | 1518 | #endif |
1519 | 1519 | ||
1520 | extern unsigned int sysctl_sched_compat_yield; | 1520 | extern unsigned int sysctl_sched_compat_yield; |
1521 | 1521 | ||
1522 | #ifdef CONFIG_RT_MUTEXES | 1522 | #ifdef CONFIG_RT_MUTEXES |
1523 | extern int rt_mutex_getprio(struct task_struct *p); | 1523 | extern int rt_mutex_getprio(struct task_struct *p); |
1524 | extern void rt_mutex_setprio(struct task_struct *p, int prio); | 1524 | extern void rt_mutex_setprio(struct task_struct *p, int prio); |
1525 | extern void rt_mutex_adjust_pi(struct task_struct *p); | 1525 | extern void rt_mutex_adjust_pi(struct task_struct *p); |
1526 | #else | 1526 | #else |
1527 | static inline int rt_mutex_getprio(struct task_struct *p) | 1527 | static inline int rt_mutex_getprio(struct task_struct *p) |
1528 | { | 1528 | { |
1529 | return p->normal_prio; | 1529 | return p->normal_prio; |
1530 | } | 1530 | } |
1531 | # define rt_mutex_adjust_pi(p) do { } while (0) | 1531 | # define rt_mutex_adjust_pi(p) do { } while (0) |
1532 | #endif | 1532 | #endif |
1533 | 1533 | ||
1534 | extern void set_user_nice(struct task_struct *p, long nice); | 1534 | extern void set_user_nice(struct task_struct *p, long nice); |
1535 | extern int task_prio(const struct task_struct *p); | 1535 | extern int task_prio(const struct task_struct *p); |
1536 | extern int task_nice(const struct task_struct *p); | 1536 | extern int task_nice(const struct task_struct *p); |
1537 | extern int can_nice(const struct task_struct *p, const int nice); | 1537 | extern int can_nice(const struct task_struct *p, const int nice); |
1538 | extern int task_curr(const struct task_struct *p); | 1538 | extern int task_curr(const struct task_struct *p); |
1539 | extern int idle_cpu(int cpu); | 1539 | extern int idle_cpu(int cpu); |
1540 | extern int sched_setscheduler(struct task_struct *, int, struct sched_param *); | 1540 | extern int sched_setscheduler(struct task_struct *, int, struct sched_param *); |
1541 | extern struct task_struct *idle_task(int cpu); | 1541 | extern struct task_struct *idle_task(int cpu); |
1542 | extern struct task_struct *curr_task(int cpu); | 1542 | extern struct task_struct *curr_task(int cpu); |
1543 | extern void set_curr_task(int cpu, struct task_struct *p); | 1543 | extern void set_curr_task(int cpu, struct task_struct *p); |
1544 | 1544 | ||
1545 | void yield(void); | 1545 | void yield(void); |
1546 | 1546 | ||
1547 | /* | 1547 | /* |
1548 | * The default (Linux) execution domain. | 1548 | * The default (Linux) execution domain. |
1549 | */ | 1549 | */ |
1550 | extern struct exec_domain default_exec_domain; | 1550 | extern struct exec_domain default_exec_domain; |
1551 | 1551 | ||
1552 | union thread_union { | 1552 | union thread_union { |
1553 | struct thread_info thread_info; | 1553 | struct thread_info thread_info; |
1554 | unsigned long stack[THREAD_SIZE/sizeof(long)]; | 1554 | unsigned long stack[THREAD_SIZE/sizeof(long)]; |
1555 | }; | 1555 | }; |
1556 | 1556 | ||
1557 | #ifndef __HAVE_ARCH_KSTACK_END | 1557 | #ifndef __HAVE_ARCH_KSTACK_END |
1558 | static inline int kstack_end(void *addr) | 1558 | static inline int kstack_end(void *addr) |
1559 | { | 1559 | { |
1560 | /* Reliable end of stack detection: | 1560 | /* Reliable end of stack detection: |
1561 | * Some APM bios versions misalign the stack | 1561 | * Some APM bios versions misalign the stack |
1562 | */ | 1562 | */ |
1563 | return !(((unsigned long)addr+sizeof(void*)-1) & (THREAD_SIZE-sizeof(void*))); | 1563 | return !(((unsigned long)addr+sizeof(void*)-1) & (THREAD_SIZE-sizeof(void*))); |
1564 | } | 1564 | } |
1565 | #endif | 1565 | #endif |
1566 | 1566 | ||
1567 | extern union thread_union init_thread_union; | 1567 | extern union thread_union init_thread_union; |
1568 | extern struct task_struct init_task; | 1568 | extern struct task_struct init_task; |
1569 | 1569 | ||
1570 | extern struct mm_struct init_mm; | 1570 | extern struct mm_struct init_mm; |
1571 | 1571 | ||
1572 | extern struct pid_namespace init_pid_ns; | 1572 | extern struct pid_namespace init_pid_ns; |
1573 | 1573 | ||
1574 | /* | 1574 | /* |
1575 | * find a task by one of its numerical ids | 1575 | * find a task by one of its numerical ids |
1576 | * | 1576 | * |
1577 | * find_task_by_pid_type_ns(): | 1577 | * find_task_by_pid_type_ns(): |
1578 | * it is the most generic call - it finds a task by all id, | 1578 | * it is the most generic call - it finds a task by all id, |
1579 | * type and namespace specified | 1579 | * type and namespace specified |
1580 | * find_task_by_pid_ns(): | 1580 | * find_task_by_pid_ns(): |
1581 | * finds a task by its pid in the specified namespace | 1581 | * finds a task by its pid in the specified namespace |
1582 | * find_task_by_vpid(): | 1582 | * find_task_by_vpid(): |
1583 | * finds a task by its virtual pid | 1583 | * finds a task by its virtual pid |
1584 | * find_task_by_pid(): | 1584 | * find_task_by_pid(): |
1585 | * finds a task by its global pid | 1585 | * finds a task by its global pid |
1586 | * | 1586 | * |
1587 | * see also find_pid() etc in include/linux/pid.h | 1587 | * see also find_pid() etc in include/linux/pid.h |
1588 | */ | 1588 | */ |
1589 | 1589 | ||
1590 | extern struct task_struct *find_task_by_pid_type_ns(int type, int pid, | 1590 | extern struct task_struct *find_task_by_pid_type_ns(int type, int pid, |
1591 | struct pid_namespace *ns); | 1591 | struct pid_namespace *ns); |
1592 | 1592 | ||
1593 | extern struct task_struct *find_task_by_pid(pid_t nr); | 1593 | extern struct task_struct *find_task_by_pid(pid_t nr); |
1594 | extern struct task_struct *find_task_by_vpid(pid_t nr); | 1594 | extern struct task_struct *find_task_by_vpid(pid_t nr); |
1595 | extern struct task_struct *find_task_by_pid_ns(pid_t nr, | 1595 | extern struct task_struct *find_task_by_pid_ns(pid_t nr, |
1596 | struct pid_namespace *ns); | 1596 | struct pid_namespace *ns); |
1597 | 1597 | ||
1598 | extern void __set_special_pids(pid_t session, pid_t pgrp); | 1598 | extern void __set_special_pids(pid_t session, pid_t pgrp); |
1599 | 1599 | ||
1600 | /* per-UID process charging. */ | 1600 | /* per-UID process charging. */ |
1601 | extern struct user_struct * alloc_uid(struct user_namespace *, uid_t); | 1601 | extern struct user_struct * alloc_uid(struct user_namespace *, uid_t); |
1602 | static inline struct user_struct *get_uid(struct user_struct *u) | 1602 | static inline struct user_struct *get_uid(struct user_struct *u) |
1603 | { | 1603 | { |
1604 | atomic_inc(&u->__count); | 1604 | atomic_inc(&u->__count); |
1605 | return u; | 1605 | return u; |
1606 | } | 1606 | } |
1607 | extern void free_uid(struct user_struct *); | 1607 | extern void free_uid(struct user_struct *); |
1608 | extern void switch_uid(struct user_struct *); | 1608 | extern void switch_uid(struct user_struct *); |
1609 | extern void release_uids(struct user_namespace *ns); | 1609 | extern void release_uids(struct user_namespace *ns); |
1610 | 1610 | ||
1611 | #include <asm/current.h> | 1611 | #include <asm/current.h> |
1612 | 1612 | ||
1613 | extern void do_timer(unsigned long ticks); | 1613 | extern void do_timer(unsigned long ticks); |
1614 | 1614 | ||
1615 | extern int FASTCALL(wake_up_state(struct task_struct * tsk, unsigned int state)); | 1615 | extern int FASTCALL(wake_up_state(struct task_struct * tsk, unsigned int state)); |
1616 | extern int FASTCALL(wake_up_process(struct task_struct * tsk)); | 1616 | extern int FASTCALL(wake_up_process(struct task_struct * tsk)); |
1617 | extern void FASTCALL(wake_up_new_task(struct task_struct * tsk, | 1617 | extern void FASTCALL(wake_up_new_task(struct task_struct * tsk, |
1618 | unsigned long clone_flags)); | 1618 | unsigned long clone_flags)); |
1619 | #ifdef CONFIG_SMP | 1619 | #ifdef CONFIG_SMP |
1620 | extern void kick_process(struct task_struct *tsk); | 1620 | extern void kick_process(struct task_struct *tsk); |
1621 | #else | 1621 | #else |
1622 | static inline void kick_process(struct task_struct *tsk) { } | 1622 | static inline void kick_process(struct task_struct *tsk) { } |
1623 | #endif | 1623 | #endif |
1624 | extern void sched_fork(struct task_struct *p, int clone_flags); | 1624 | extern void sched_fork(struct task_struct *p, int clone_flags); |
1625 | extern void sched_dead(struct task_struct *p); | 1625 | extern void sched_dead(struct task_struct *p); |
1626 | 1626 | ||
1627 | extern int in_group_p(gid_t); | 1627 | extern int in_group_p(gid_t); |
1628 | extern int in_egroup_p(gid_t); | 1628 | extern int in_egroup_p(gid_t); |
1629 | 1629 | ||
1630 | extern void proc_caches_init(void); | 1630 | extern void proc_caches_init(void); |
1631 | extern void flush_signals(struct task_struct *); | 1631 | extern void flush_signals(struct task_struct *); |
1632 | extern void ignore_signals(struct task_struct *); | 1632 | extern void ignore_signals(struct task_struct *); |
1633 | extern void flush_signal_handlers(struct task_struct *, int force_default); | 1633 | extern void flush_signal_handlers(struct task_struct *, int force_default); |
1634 | extern int dequeue_signal(struct task_struct *tsk, sigset_t *mask, siginfo_t *info); | 1634 | extern int dequeue_signal(struct task_struct *tsk, sigset_t *mask, siginfo_t *info); |
1635 | 1635 | ||
1636 | static inline int dequeue_signal_lock(struct task_struct *tsk, sigset_t *mask, siginfo_t *info) | 1636 | static inline int dequeue_signal_lock(struct task_struct *tsk, sigset_t *mask, siginfo_t *info) |
1637 | { | 1637 | { |
1638 | unsigned long flags; | 1638 | unsigned long flags; |
1639 | int ret; | 1639 | int ret; |
1640 | 1640 | ||
1641 | spin_lock_irqsave(&tsk->sighand->siglock, flags); | 1641 | spin_lock_irqsave(&tsk->sighand->siglock, flags); |
1642 | ret = dequeue_signal(tsk, mask, info); | 1642 | ret = dequeue_signal(tsk, mask, info); |
1643 | spin_unlock_irqrestore(&tsk->sighand->siglock, flags); | 1643 | spin_unlock_irqrestore(&tsk->sighand->siglock, flags); |
1644 | 1644 | ||
1645 | return ret; | 1645 | return ret; |
1646 | } | 1646 | } |
1647 | 1647 | ||
1648 | extern void block_all_signals(int (*notifier)(void *priv), void *priv, | 1648 | extern void block_all_signals(int (*notifier)(void *priv), void *priv, |
1649 | sigset_t *mask); | 1649 | sigset_t *mask); |
1650 | extern void unblock_all_signals(void); | 1650 | extern void unblock_all_signals(void); |
1651 | extern void release_task(struct task_struct * p); | 1651 | extern void release_task(struct task_struct * p); |
1652 | extern int send_sig_info(int, struct siginfo *, struct task_struct *); | 1652 | extern int send_sig_info(int, struct siginfo *, struct task_struct *); |
1653 | extern int send_group_sig_info(int, struct siginfo *, struct task_struct *); | 1653 | extern int send_group_sig_info(int, struct siginfo *, struct task_struct *); |
1654 | extern int force_sigsegv(int, struct task_struct *); | 1654 | extern int force_sigsegv(int, struct task_struct *); |
1655 | extern int force_sig_info(int, struct siginfo *, struct task_struct *); | 1655 | extern int force_sig_info(int, struct siginfo *, struct task_struct *); |
1656 | extern int __kill_pgrp_info(int sig, struct siginfo *info, struct pid *pgrp); | 1656 | extern int __kill_pgrp_info(int sig, struct siginfo *info, struct pid *pgrp); |
1657 | extern int kill_pgrp_info(int sig, struct siginfo *info, struct pid *pgrp); | 1657 | extern int kill_pgrp_info(int sig, struct siginfo *info, struct pid *pgrp); |
1658 | extern int kill_pid_info(int sig, struct siginfo *info, struct pid *pid); | 1658 | extern int kill_pid_info(int sig, struct siginfo *info, struct pid *pid); |
1659 | extern int kill_pid_info_as_uid(int, struct siginfo *, struct pid *, uid_t, uid_t, u32); | 1659 | extern int kill_pid_info_as_uid(int, struct siginfo *, struct pid *, uid_t, uid_t, u32); |
1660 | extern int kill_pgrp(struct pid *pid, int sig, int priv); | 1660 | extern int kill_pgrp(struct pid *pid, int sig, int priv); |
1661 | extern int kill_pid(struct pid *pid, int sig, int priv); | 1661 | extern int kill_pid(struct pid *pid, int sig, int priv); |
1662 | extern int kill_proc_info(int, struct siginfo *, pid_t); | 1662 | extern int kill_proc_info(int, struct siginfo *, pid_t); |
1663 | extern void do_notify_parent(struct task_struct *, int); | 1663 | extern void do_notify_parent(struct task_struct *, int); |
1664 | extern void force_sig(int, struct task_struct *); | 1664 | extern void force_sig(int, struct task_struct *); |
1665 | extern void force_sig_specific(int, struct task_struct *); | 1665 | extern void force_sig_specific(int, struct task_struct *); |
1666 | extern int send_sig(int, struct task_struct *, int); | 1666 | extern int send_sig(int, struct task_struct *, int); |
1667 | extern void zap_other_threads(struct task_struct *p); | 1667 | extern void zap_other_threads(struct task_struct *p); |
1668 | extern int kill_proc(pid_t, int, int); | 1668 | extern int kill_proc(pid_t, int, int); |
1669 | extern struct sigqueue *sigqueue_alloc(void); | 1669 | extern struct sigqueue *sigqueue_alloc(void); |
1670 | extern void sigqueue_free(struct sigqueue *); | 1670 | extern void sigqueue_free(struct sigqueue *); |
1671 | extern int send_sigqueue(int, struct sigqueue *, struct task_struct *); | 1671 | extern int send_sigqueue(int, struct sigqueue *, struct task_struct *); |
1672 | extern int send_group_sigqueue(int, struct sigqueue *, struct task_struct *); | 1672 | extern int send_group_sigqueue(int, struct sigqueue *, struct task_struct *); |
1673 | extern int do_sigaction(int, struct k_sigaction *, struct k_sigaction *); | 1673 | extern int do_sigaction(int, struct k_sigaction *, struct k_sigaction *); |
1674 | extern int do_sigaltstack(const stack_t __user *, stack_t __user *, unsigned long); | 1674 | extern int do_sigaltstack(const stack_t __user *, stack_t __user *, unsigned long); |
1675 | 1675 | ||
1676 | static inline int kill_cad_pid(int sig, int priv) | 1676 | static inline int kill_cad_pid(int sig, int priv) |
1677 | { | 1677 | { |
1678 | return kill_pid(cad_pid, sig, priv); | 1678 | return kill_pid(cad_pid, sig, priv); |
1679 | } | 1679 | } |
1680 | 1680 | ||
1681 | /* These can be the second arg to send_sig_info/send_group_sig_info. */ | 1681 | /* These can be the second arg to send_sig_info/send_group_sig_info. */ |
1682 | #define SEND_SIG_NOINFO ((struct siginfo *) 0) | 1682 | #define SEND_SIG_NOINFO ((struct siginfo *) 0) |
1683 | #define SEND_SIG_PRIV ((struct siginfo *) 1) | 1683 | #define SEND_SIG_PRIV ((struct siginfo *) 1) |
1684 | #define SEND_SIG_FORCED ((struct siginfo *) 2) | 1684 | #define SEND_SIG_FORCED ((struct siginfo *) 2) |
1685 | 1685 | ||
1686 | static inline int is_si_special(const struct siginfo *info) | 1686 | static inline int is_si_special(const struct siginfo *info) |
1687 | { | 1687 | { |
1688 | return info <= SEND_SIG_FORCED; | 1688 | return info <= SEND_SIG_FORCED; |
1689 | } | 1689 | } |
1690 | 1690 | ||
1691 | /* True if we are on the alternate signal stack. */ | 1691 | /* True if we are on the alternate signal stack. */ |
1692 | 1692 | ||
1693 | static inline int on_sig_stack(unsigned long sp) | 1693 | static inline int on_sig_stack(unsigned long sp) |
1694 | { | 1694 | { |
1695 | return (sp - current->sas_ss_sp < current->sas_ss_size); | 1695 | return (sp - current->sas_ss_sp < current->sas_ss_size); |
1696 | } | 1696 | } |
1697 | 1697 | ||
1698 | static inline int sas_ss_flags(unsigned long sp) | 1698 | static inline int sas_ss_flags(unsigned long sp) |
1699 | { | 1699 | { |
1700 | return (current->sas_ss_size == 0 ? SS_DISABLE | 1700 | return (current->sas_ss_size == 0 ? SS_DISABLE |
1701 | : on_sig_stack(sp) ? SS_ONSTACK : 0); | 1701 | : on_sig_stack(sp) ? SS_ONSTACK : 0); |
1702 | } | 1702 | } |
1703 | 1703 | ||
1704 | /* | 1704 | /* |
1705 | * Routines for handling mm_structs | 1705 | * Routines for handling mm_structs |
1706 | */ | 1706 | */ |
1707 | extern struct mm_struct * mm_alloc(void); | 1707 | extern struct mm_struct * mm_alloc(void); |
1708 | 1708 | ||
1709 | /* mmdrop drops the mm and the page tables */ | 1709 | /* mmdrop drops the mm and the page tables */ |
1710 | extern void FASTCALL(__mmdrop(struct mm_struct *)); | 1710 | extern void FASTCALL(__mmdrop(struct mm_struct *)); |
1711 | static inline void mmdrop(struct mm_struct * mm) | 1711 | static inline void mmdrop(struct mm_struct * mm) |
1712 | { | 1712 | { |
1713 | if (unlikely(atomic_dec_and_test(&mm->mm_count))) | 1713 | if (unlikely(atomic_dec_and_test(&mm->mm_count))) |
1714 | __mmdrop(mm); | 1714 | __mmdrop(mm); |
1715 | } | 1715 | } |
1716 | 1716 | ||
1717 | /* mmput gets rid of the mappings and all user-space */ | 1717 | /* mmput gets rid of the mappings and all user-space */ |
1718 | extern void mmput(struct mm_struct *); | 1718 | extern void mmput(struct mm_struct *); |
1719 | /* Grab a reference to a task's mm, if it is not already going away */ | 1719 | /* Grab a reference to a task's mm, if it is not already going away */ |
1720 | extern struct mm_struct *get_task_mm(struct task_struct *task); | 1720 | extern struct mm_struct *get_task_mm(struct task_struct *task); |
1721 | /* Remove the current tasks stale references to the old mm_struct */ | 1721 | /* Remove the current tasks stale references to the old mm_struct */ |
1722 | extern void mm_release(struct task_struct *, struct mm_struct *); | 1722 | extern void mm_release(struct task_struct *, struct mm_struct *); |
1723 | 1723 | ||
1724 | extern int copy_thread(int, unsigned long, unsigned long, unsigned long, struct task_struct *, struct pt_regs *); | 1724 | extern int copy_thread(int, unsigned long, unsigned long, unsigned long, struct task_struct *, struct pt_regs *); |
1725 | extern void flush_thread(void); | 1725 | extern void flush_thread(void); |
1726 | extern void exit_thread(void); | 1726 | extern void exit_thread(void); |
1727 | 1727 | ||
1728 | extern void exit_files(struct task_struct *); | 1728 | extern void exit_files(struct task_struct *); |
1729 | extern void __cleanup_signal(struct signal_struct *); | 1729 | extern void __cleanup_signal(struct signal_struct *); |
1730 | extern void __cleanup_sighand(struct sighand_struct *); | 1730 | extern void __cleanup_sighand(struct sighand_struct *); |
1731 | extern void exit_itimers(struct signal_struct *); | 1731 | extern void exit_itimers(struct signal_struct *); |
1732 | 1732 | ||
1733 | extern NORET_TYPE void do_group_exit(int); | 1733 | extern NORET_TYPE void do_group_exit(int); |
1734 | 1734 | ||
1735 | extern void daemonize(const char *, ...); | 1735 | extern void daemonize(const char *, ...); |
1736 | extern int allow_signal(int); | 1736 | extern int allow_signal(int); |
1737 | extern int disallow_signal(int); | 1737 | extern int disallow_signal(int); |
1738 | 1738 | ||
1739 | extern int do_execve(char *, char __user * __user *, char __user * __user *, struct pt_regs *); | 1739 | extern int do_execve(char *, char __user * __user *, char __user * __user *, struct pt_regs *); |
1740 | extern long do_fork(unsigned long, unsigned long, struct pt_regs *, unsigned long, int __user *, int __user *); | 1740 | extern long do_fork(unsigned long, unsigned long, struct pt_regs *, unsigned long, int __user *, int __user *); |
1741 | struct task_struct *fork_idle(int); | 1741 | struct task_struct *fork_idle(int); |
1742 | 1742 | ||
1743 | extern void set_task_comm(struct task_struct *tsk, char *from); | 1743 | extern void set_task_comm(struct task_struct *tsk, char *from); |
1744 | extern void get_task_comm(char *to, struct task_struct *tsk); | 1744 | extern void get_task_comm(char *to, struct task_struct *tsk); |
1745 | 1745 | ||
1746 | #ifdef CONFIG_SMP | 1746 | #ifdef CONFIG_SMP |
1747 | extern void wait_task_inactive(struct task_struct * p); | 1747 | extern void wait_task_inactive(struct task_struct * p); |
1748 | #else | 1748 | #else |
1749 | #define wait_task_inactive(p) do { } while (0) | 1749 | #define wait_task_inactive(p) do { } while (0) |
1750 | #endif | 1750 | #endif |
1751 | 1751 | ||
1752 | #define remove_parent(p) list_del_init(&(p)->sibling) | 1752 | #define remove_parent(p) list_del_init(&(p)->sibling) |
1753 | #define add_parent(p) list_add_tail(&(p)->sibling,&(p)->parent->children) | 1753 | #define add_parent(p) list_add_tail(&(p)->sibling,&(p)->parent->children) |
1754 | 1754 | ||
1755 | #define next_task(p) list_entry(rcu_dereference((p)->tasks.next), struct task_struct, tasks) | 1755 | #define next_task(p) list_entry(rcu_dereference((p)->tasks.next), struct task_struct, tasks) |
1756 | 1756 | ||
1757 | #define for_each_process(p) \ | 1757 | #define for_each_process(p) \ |
1758 | for (p = &init_task ; (p = next_task(p)) != &init_task ; ) | 1758 | for (p = &init_task ; (p = next_task(p)) != &init_task ; ) |
1759 | 1759 | ||
1760 | /* | 1760 | /* |
1761 | * Careful: do_each_thread/while_each_thread is a double loop so | 1761 | * Careful: do_each_thread/while_each_thread is a double loop so |
1762 | * 'break' will not work as expected - use goto instead. | 1762 | * 'break' will not work as expected - use goto instead. |
1763 | */ | 1763 | */ |
1764 | #define do_each_thread(g, t) \ | 1764 | #define do_each_thread(g, t) \ |
1765 | for (g = t = &init_task ; (g = t = next_task(g)) != &init_task ; ) do | 1765 | for (g = t = &init_task ; (g = t = next_task(g)) != &init_task ; ) do |
1766 | 1766 | ||
1767 | #define while_each_thread(g, t) \ | 1767 | #define while_each_thread(g, t) \ |
1768 | while ((t = next_thread(t)) != g) | 1768 | while ((t = next_thread(t)) != g) |
1769 | 1769 | ||
1770 | /* de_thread depends on thread_group_leader not being a pid based check */ | 1770 | /* de_thread depends on thread_group_leader not being a pid based check */ |
1771 | #define thread_group_leader(p) (p == p->group_leader) | 1771 | #define thread_group_leader(p) (p == p->group_leader) |
1772 | 1772 | ||
1773 | /* Do to the insanities of de_thread it is possible for a process | 1773 | /* Do to the insanities of de_thread it is possible for a process |
1774 | * to have the pid of the thread group leader without actually being | 1774 | * to have the pid of the thread group leader without actually being |
1775 | * the thread group leader. For iteration through the pids in proc | 1775 | * the thread group leader. For iteration through the pids in proc |
1776 | * all we care about is that we have a task with the appropriate | 1776 | * all we care about is that we have a task with the appropriate |
1777 | * pid, we don't actually care if we have the right task. | 1777 | * pid, we don't actually care if we have the right task. |
1778 | */ | 1778 | */ |
1779 | static inline int has_group_leader_pid(struct task_struct *p) | 1779 | static inline int has_group_leader_pid(struct task_struct *p) |
1780 | { | 1780 | { |
1781 | return p->pid == p->tgid; | 1781 | return p->pid == p->tgid; |
1782 | } | 1782 | } |
1783 | 1783 | ||
1784 | static inline | 1784 | static inline |
1785 | int same_thread_group(struct task_struct *p1, struct task_struct *p2) | 1785 | int same_thread_group(struct task_struct *p1, struct task_struct *p2) |
1786 | { | 1786 | { |
1787 | return p1->tgid == p2->tgid; | 1787 | return p1->tgid == p2->tgid; |
1788 | } | 1788 | } |
1789 | 1789 | ||
1790 | static inline struct task_struct *next_thread(const struct task_struct *p) | 1790 | static inline struct task_struct *next_thread(const struct task_struct *p) |
1791 | { | 1791 | { |
1792 | return list_entry(rcu_dereference(p->thread_group.next), | 1792 | return list_entry(rcu_dereference(p->thread_group.next), |
1793 | struct task_struct, thread_group); | 1793 | struct task_struct, thread_group); |
1794 | } | 1794 | } |
1795 | 1795 | ||
1796 | static inline int thread_group_empty(struct task_struct *p) | 1796 | static inline int thread_group_empty(struct task_struct *p) |
1797 | { | 1797 | { |
1798 | return list_empty(&p->thread_group); | 1798 | return list_empty(&p->thread_group); |
1799 | } | 1799 | } |
1800 | 1800 | ||
1801 | #define delay_group_leader(p) \ | 1801 | #define delay_group_leader(p) \ |
1802 | (thread_group_leader(p) && !thread_group_empty(p)) | 1802 | (thread_group_leader(p) && !thread_group_empty(p)) |
1803 | 1803 | ||
1804 | /* | 1804 | /* |
1805 | * Protects ->fs, ->files, ->mm, ->group_info, ->comm, keyring | 1805 | * Protects ->fs, ->files, ->mm, ->group_info, ->comm, keyring |
1806 | * subscriptions and synchronises with wait4(). Also used in procfs. Also | 1806 | * subscriptions and synchronises with wait4(). Also used in procfs. Also |
1807 | * pins the final release of task.io_context. Also protects ->cpuset and | 1807 | * pins the final release of task.io_context. Also protects ->cpuset and |
1808 | * ->cgroup.subsys[]. | 1808 | * ->cgroup.subsys[]. |
1809 | * | 1809 | * |
1810 | * Nests both inside and outside of read_lock(&tasklist_lock). | 1810 | * Nests both inside and outside of read_lock(&tasklist_lock). |
1811 | * It must not be nested with write_lock_irq(&tasklist_lock), | 1811 | * It must not be nested with write_lock_irq(&tasklist_lock), |
1812 | * neither inside nor outside. | 1812 | * neither inside nor outside. |
1813 | */ | 1813 | */ |
1814 | static inline void task_lock(struct task_struct *p) | 1814 | static inline void task_lock(struct task_struct *p) |
1815 | { | 1815 | { |
1816 | spin_lock(&p->alloc_lock); | 1816 | spin_lock(&p->alloc_lock); |
1817 | } | 1817 | } |
1818 | 1818 | ||
1819 | static inline void task_unlock(struct task_struct *p) | 1819 | static inline void task_unlock(struct task_struct *p) |
1820 | { | 1820 | { |
1821 | spin_unlock(&p->alloc_lock); | 1821 | spin_unlock(&p->alloc_lock); |
1822 | } | 1822 | } |
1823 | 1823 | ||
1824 | extern struct sighand_struct *lock_task_sighand(struct task_struct *tsk, | 1824 | extern struct sighand_struct *lock_task_sighand(struct task_struct *tsk, |
1825 | unsigned long *flags); | 1825 | unsigned long *flags); |
1826 | 1826 | ||
1827 | static inline void unlock_task_sighand(struct task_struct *tsk, | 1827 | static inline void unlock_task_sighand(struct task_struct *tsk, |
1828 | unsigned long *flags) | 1828 | unsigned long *flags) |
1829 | { | 1829 | { |
1830 | spin_unlock_irqrestore(&tsk->sighand->siglock, *flags); | 1830 | spin_unlock_irqrestore(&tsk->sighand->siglock, *flags); |
1831 | } | 1831 | } |
1832 | 1832 | ||
1833 | #ifndef __HAVE_THREAD_FUNCTIONS | 1833 | #ifndef __HAVE_THREAD_FUNCTIONS |
1834 | 1834 | ||
1835 | #define task_thread_info(task) ((struct thread_info *)(task)->stack) | 1835 | #define task_thread_info(task) ((struct thread_info *)(task)->stack) |
1836 | #define task_stack_page(task) ((task)->stack) | 1836 | #define task_stack_page(task) ((task)->stack) |
1837 | 1837 | ||
1838 | static inline void setup_thread_stack(struct task_struct *p, struct task_struct *org) | 1838 | static inline void setup_thread_stack(struct task_struct *p, struct task_struct *org) |
1839 | { | 1839 | { |
1840 | *task_thread_info(p) = *task_thread_info(org); | 1840 | *task_thread_info(p) = *task_thread_info(org); |
1841 | task_thread_info(p)->task = p; | 1841 | task_thread_info(p)->task = p; |
1842 | } | 1842 | } |
1843 | 1843 | ||
1844 | static inline unsigned long *end_of_stack(struct task_struct *p) | 1844 | static inline unsigned long *end_of_stack(struct task_struct *p) |
1845 | { | 1845 | { |
1846 | return (unsigned long *)(task_thread_info(p) + 1); | 1846 | return (unsigned long *)(task_thread_info(p) + 1); |
1847 | } | 1847 | } |
1848 | 1848 | ||
1849 | #endif | 1849 | #endif |
1850 | 1850 | ||
1851 | /* set thread flags in other task's structures | 1851 | /* set thread flags in other task's structures |
1852 | * - see asm/thread_info.h for TIF_xxxx flags available | 1852 | * - see asm/thread_info.h for TIF_xxxx flags available |
1853 | */ | 1853 | */ |
1854 | static inline void set_tsk_thread_flag(struct task_struct *tsk, int flag) | 1854 | static inline void set_tsk_thread_flag(struct task_struct *tsk, int flag) |
1855 | { | 1855 | { |
1856 | set_ti_thread_flag(task_thread_info(tsk), flag); | 1856 | set_ti_thread_flag(task_thread_info(tsk), flag); |
1857 | } | 1857 | } |
1858 | 1858 | ||
1859 | static inline void clear_tsk_thread_flag(struct task_struct *tsk, int flag) | 1859 | static inline void clear_tsk_thread_flag(struct task_struct *tsk, int flag) |
1860 | { | 1860 | { |
1861 | clear_ti_thread_flag(task_thread_info(tsk), flag); | 1861 | clear_ti_thread_flag(task_thread_info(tsk), flag); |
1862 | } | 1862 | } |
1863 | 1863 | ||
1864 | static inline int test_and_set_tsk_thread_flag(struct task_struct *tsk, int flag) | 1864 | static inline int test_and_set_tsk_thread_flag(struct task_struct *tsk, int flag) |
1865 | { | 1865 | { |
1866 | return test_and_set_ti_thread_flag(task_thread_info(tsk), flag); | 1866 | return test_and_set_ti_thread_flag(task_thread_info(tsk), flag); |
1867 | } | 1867 | } |
1868 | 1868 | ||
1869 | static inline int test_and_clear_tsk_thread_flag(struct task_struct *tsk, int flag) | 1869 | static inline int test_and_clear_tsk_thread_flag(struct task_struct *tsk, int flag) |
1870 | { | 1870 | { |
1871 | return test_and_clear_ti_thread_flag(task_thread_info(tsk), flag); | 1871 | return test_and_clear_ti_thread_flag(task_thread_info(tsk), flag); |
1872 | } | 1872 | } |
1873 | 1873 | ||
1874 | static inline int test_tsk_thread_flag(struct task_struct *tsk, int flag) | 1874 | static inline int test_tsk_thread_flag(struct task_struct *tsk, int flag) |
1875 | { | 1875 | { |
1876 | return test_ti_thread_flag(task_thread_info(tsk), flag); | 1876 | return test_ti_thread_flag(task_thread_info(tsk), flag); |
1877 | } | 1877 | } |
1878 | 1878 | ||
1879 | static inline void set_tsk_need_resched(struct task_struct *tsk) | 1879 | static inline void set_tsk_need_resched(struct task_struct *tsk) |
1880 | { | 1880 | { |
1881 | set_tsk_thread_flag(tsk,TIF_NEED_RESCHED); | 1881 | set_tsk_thread_flag(tsk,TIF_NEED_RESCHED); |
1882 | } | 1882 | } |
1883 | 1883 | ||
1884 | static inline void clear_tsk_need_resched(struct task_struct *tsk) | 1884 | static inline void clear_tsk_need_resched(struct task_struct *tsk) |
1885 | { | 1885 | { |
1886 | clear_tsk_thread_flag(tsk,TIF_NEED_RESCHED); | 1886 | clear_tsk_thread_flag(tsk,TIF_NEED_RESCHED); |
1887 | } | 1887 | } |
1888 | 1888 | ||
1889 | static inline int signal_pending(struct task_struct *p) | 1889 | static inline int signal_pending(struct task_struct *p) |
1890 | { | 1890 | { |
1891 | return unlikely(test_tsk_thread_flag(p,TIF_SIGPENDING)); | 1891 | return unlikely(test_tsk_thread_flag(p,TIF_SIGPENDING)); |
1892 | } | 1892 | } |
1893 | 1893 | ||
1894 | static inline int need_resched(void) | 1894 | static inline int need_resched(void) |
1895 | { | 1895 | { |
1896 | return unlikely(test_thread_flag(TIF_NEED_RESCHED)); | 1896 | return unlikely(test_thread_flag(TIF_NEED_RESCHED)); |
1897 | } | 1897 | } |
1898 | 1898 | ||
1899 | /* | 1899 | /* |
1900 | * cond_resched() and cond_resched_lock(): latency reduction via | 1900 | * cond_resched() and cond_resched_lock(): latency reduction via |
1901 | * explicit rescheduling in places that are safe. The return | 1901 | * explicit rescheduling in places that are safe. The return |
1902 | * value indicates whether a reschedule was done in fact. | 1902 | * value indicates whether a reschedule was done in fact. |
1903 | * cond_resched_lock() will drop the spinlock before scheduling, | 1903 | * cond_resched_lock() will drop the spinlock before scheduling, |
1904 | * cond_resched_softirq() will enable bhs before scheduling. | 1904 | * cond_resched_softirq() will enable bhs before scheduling. |
1905 | */ | 1905 | */ |
1906 | #ifdef CONFIG_PREEMPT | 1906 | #ifdef CONFIG_PREEMPT |
1907 | static inline int cond_resched(void) | 1907 | static inline int cond_resched(void) |
1908 | { | 1908 | { |
1909 | return 0; | 1909 | return 0; |
1910 | } | 1910 | } |
1911 | #else | 1911 | #else |
1912 | extern int _cond_resched(void); | 1912 | extern int _cond_resched(void); |
1913 | static inline int cond_resched(void) | 1913 | static inline int cond_resched(void) |
1914 | { | 1914 | { |
1915 | return _cond_resched(); | 1915 | return _cond_resched(); |
1916 | } | 1916 | } |
1917 | #endif | 1917 | #endif |
1918 | extern int cond_resched_lock(spinlock_t * lock); | 1918 | extern int cond_resched_lock(spinlock_t * lock); |
1919 | extern int cond_resched_softirq(void); | 1919 | extern int cond_resched_softirq(void); |
1920 | 1920 | ||
1921 | /* | 1921 | /* |
1922 | * Does a critical section need to be broken due to another | 1922 | * Does a critical section need to be broken due to another |
1923 | * task waiting?: | 1923 | * task waiting?: |
1924 | */ | 1924 | */ |
1925 | #if defined(CONFIG_PREEMPT) && defined(CONFIG_SMP) | 1925 | #if defined(CONFIG_PREEMPT) && defined(CONFIG_SMP) |
1926 | # define need_lockbreak(lock) ((lock)->break_lock) | 1926 | # define need_lockbreak(lock) ((lock)->break_lock) |
1927 | #else | 1927 | #else |
1928 | # define need_lockbreak(lock) 0 | 1928 | # define need_lockbreak(lock) 0 |
1929 | #endif | 1929 | #endif |
1930 | 1930 | ||
1931 | /* | 1931 | /* |
1932 | * Does a critical section need to be broken due to another | 1932 | * Does a critical section need to be broken due to another |
1933 | * task waiting or preemption being signalled: | 1933 | * task waiting or preemption being signalled: |
1934 | */ | 1934 | */ |
1935 | static inline int lock_need_resched(spinlock_t *lock) | 1935 | static inline int lock_need_resched(spinlock_t *lock) |
1936 | { | 1936 | { |
1937 | if (need_lockbreak(lock) || need_resched()) | 1937 | if (need_lockbreak(lock) || need_resched()) |
1938 | return 1; | 1938 | return 1; |
1939 | return 0; | 1939 | return 0; |
1940 | } | 1940 | } |
1941 | 1941 | ||
1942 | /* | 1942 | /* |
1943 | * Reevaluate whether the task has signals pending delivery. | 1943 | * Reevaluate whether the task has signals pending delivery. |
1944 | * Wake the task if so. | 1944 | * Wake the task if so. |
1945 | * This is required every time the blocked sigset_t changes. | 1945 | * This is required every time the blocked sigset_t changes. |
1946 | * callers must hold sighand->siglock. | 1946 | * callers must hold sighand->siglock. |
1947 | */ | 1947 | */ |
1948 | extern void recalc_sigpending_and_wake(struct task_struct *t); | 1948 | extern void recalc_sigpending_and_wake(struct task_struct *t); |
1949 | extern void recalc_sigpending(void); | 1949 | extern void recalc_sigpending(void); |
1950 | 1950 | ||
1951 | extern void signal_wake_up(struct task_struct *t, int resume_stopped); | 1951 | extern void signal_wake_up(struct task_struct *t, int resume_stopped); |
1952 | 1952 | ||
1953 | /* | 1953 | /* |
1954 | * Wrappers for p->thread_info->cpu access. No-op on UP. | 1954 | * Wrappers for p->thread_info->cpu access. No-op on UP. |
1955 | */ | 1955 | */ |
1956 | #ifdef CONFIG_SMP | 1956 | #ifdef CONFIG_SMP |
1957 | 1957 | ||
1958 | static inline unsigned int task_cpu(const struct task_struct *p) | 1958 | static inline unsigned int task_cpu(const struct task_struct *p) |
1959 | { | 1959 | { |
1960 | return task_thread_info(p)->cpu; | 1960 | return task_thread_info(p)->cpu; |
1961 | } | 1961 | } |
1962 | 1962 | ||
1963 | extern void set_task_cpu(struct task_struct *p, unsigned int cpu); | 1963 | extern void set_task_cpu(struct task_struct *p, unsigned int cpu); |
1964 | 1964 | ||
1965 | #else | 1965 | #else |
1966 | 1966 | ||
1967 | static inline unsigned int task_cpu(const struct task_struct *p) | 1967 | static inline unsigned int task_cpu(const struct task_struct *p) |
1968 | { | 1968 | { |
1969 | return 0; | 1969 | return 0; |
1970 | } | 1970 | } |
1971 | 1971 | ||
1972 | static inline void set_task_cpu(struct task_struct *p, unsigned int cpu) | 1972 | static inline void set_task_cpu(struct task_struct *p, unsigned int cpu) |
1973 | { | 1973 | { |
1974 | } | 1974 | } |
1975 | 1975 | ||
1976 | #endif /* CONFIG_SMP */ | 1976 | #endif /* CONFIG_SMP */ |
1977 | 1977 | ||
1978 | #ifdef HAVE_ARCH_PICK_MMAP_LAYOUT | 1978 | #ifdef HAVE_ARCH_PICK_MMAP_LAYOUT |
1979 | extern void arch_pick_mmap_layout(struct mm_struct *mm); | 1979 | extern void arch_pick_mmap_layout(struct mm_struct *mm); |
1980 | #else | 1980 | #else |
1981 | static inline void arch_pick_mmap_layout(struct mm_struct *mm) | 1981 | static inline void arch_pick_mmap_layout(struct mm_struct *mm) |
1982 | { | 1982 | { |
1983 | mm->mmap_base = TASK_UNMAPPED_BASE; | 1983 | mm->mmap_base = TASK_UNMAPPED_BASE; |
1984 | mm->get_unmapped_area = arch_get_unmapped_area; | 1984 | mm->get_unmapped_area = arch_get_unmapped_area; |
1985 | mm->unmap_area = arch_unmap_area; | 1985 | mm->unmap_area = arch_unmap_area; |
1986 | } | 1986 | } |
1987 | #endif | 1987 | #endif |
1988 | 1988 | ||
1989 | extern long sched_setaffinity(pid_t pid, cpumask_t new_mask); | 1989 | extern long sched_setaffinity(pid_t pid, cpumask_t new_mask); |
1990 | extern long sched_getaffinity(pid_t pid, cpumask_t *mask); | 1990 | extern long sched_getaffinity(pid_t pid, cpumask_t *mask); |
1991 | 1991 | ||
1992 | extern int sched_mc_power_savings, sched_smt_power_savings; | 1992 | extern int sched_mc_power_savings, sched_smt_power_savings; |
1993 | 1993 | ||
1994 | extern void normalize_rt_tasks(void); | 1994 | extern void normalize_rt_tasks(void); |
1995 | 1995 | ||
1996 | #ifdef CONFIG_FAIR_GROUP_SCHED | 1996 | #ifdef CONFIG_FAIR_GROUP_SCHED |
1997 | 1997 | ||
1998 | extern struct task_group init_task_group; | 1998 | extern struct task_group init_task_group; |
1999 | 1999 | ||
2000 | extern struct task_group *sched_create_group(void); | 2000 | extern struct task_group *sched_create_group(void); |
2001 | extern void sched_destroy_group(struct task_group *tg); | 2001 | extern void sched_destroy_group(struct task_group *tg); |
2002 | extern void sched_move_task(struct task_struct *tsk); | 2002 | extern void sched_move_task(struct task_struct *tsk); |
2003 | extern int sched_group_set_shares(struct task_group *tg, unsigned long shares); | 2003 | extern int sched_group_set_shares(struct task_group *tg, unsigned long shares); |
2004 | extern unsigned long sched_group_shares(struct task_group *tg); | 2004 | extern unsigned long sched_group_shares(struct task_group *tg); |
2005 | 2005 | ||
2006 | #endif | 2006 | #endif |
2007 | 2007 | ||
2008 | #ifdef CONFIG_TASK_XACCT | 2008 | #ifdef CONFIG_TASK_XACCT |
2009 | static inline void add_rchar(struct task_struct *tsk, ssize_t amt) | 2009 | static inline void add_rchar(struct task_struct *tsk, ssize_t amt) |
2010 | { | 2010 | { |
2011 | tsk->rchar += amt; | 2011 | tsk->rchar += amt; |
2012 | } | 2012 | } |
2013 | 2013 | ||
2014 | static inline void add_wchar(struct task_struct *tsk, ssize_t amt) | 2014 | static inline void add_wchar(struct task_struct *tsk, ssize_t amt) |
2015 | { | 2015 | { |
2016 | tsk->wchar += amt; | 2016 | tsk->wchar += amt; |
2017 | } | 2017 | } |
2018 | 2018 | ||
2019 | static inline void inc_syscr(struct task_struct *tsk) | 2019 | static inline void inc_syscr(struct task_struct *tsk) |
2020 | { | 2020 | { |
2021 | tsk->syscr++; | 2021 | tsk->syscr++; |
2022 | } | 2022 | } |
2023 | 2023 | ||
2024 | static inline void inc_syscw(struct task_struct *tsk) | 2024 | static inline void inc_syscw(struct task_struct *tsk) |
2025 | { | 2025 | { |
2026 | tsk->syscw++; | 2026 | tsk->syscw++; |
2027 | } | 2027 | } |
2028 | #else | 2028 | #else |
2029 | static inline void add_rchar(struct task_struct *tsk, ssize_t amt) | 2029 | static inline void add_rchar(struct task_struct *tsk, ssize_t amt) |
2030 | { | 2030 | { |
2031 | } | 2031 | } |
2032 | 2032 | ||
2033 | static inline void add_wchar(struct task_struct *tsk, ssize_t amt) | 2033 | static inline void add_wchar(struct task_struct *tsk, ssize_t amt) |
2034 | { | 2034 | { |
2035 | } | 2035 | } |
2036 | 2036 | ||
2037 | static inline void inc_syscr(struct task_struct *tsk) | 2037 | static inline void inc_syscr(struct task_struct *tsk) |
2038 | { | 2038 | { |
2039 | } | 2039 | } |
2040 | 2040 | ||
2041 | static inline void inc_syscw(struct task_struct *tsk) | 2041 | static inline void inc_syscw(struct task_struct *tsk) |
2042 | { | 2042 | { |
2043 | } | 2043 | } |
2044 | #endif | 2044 | #endif |
2045 | 2045 | ||
2046 | #ifdef CONFIG_SMP | 2046 | #ifdef CONFIG_SMP |
2047 | void migration_init(void); | 2047 | void migration_init(void); |
2048 | #else | 2048 | #else |
2049 | static inline void migration_init(void) | 2049 | static inline void migration_init(void) |
2050 | { | 2050 | { |
2051 | } | 2051 | } |
2052 | #endif | 2052 | #endif |
2053 | 2053 | ||
2054 | #endif /* __KERNEL__ */ | 2054 | #endif /* __KERNEL__ */ |
2055 | 2055 | ||
2056 | #endif | 2056 | #endif |
2057 | 2057 |
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/notifier.h> | 16 | #include <linux/notifier.h> |
17 | #include <linux/module.h> | 17 | #include <linux/module.h> |
18 | 18 | ||
19 | #include <asm/irq_regs.h> | 19 | #include <asm/irq_regs.h> |
20 | 20 | ||
21 | static DEFINE_SPINLOCK(print_lock); | 21 | static DEFINE_SPINLOCK(print_lock); |
22 | 22 | ||
23 | static DEFINE_PER_CPU(unsigned long, touch_timestamp); | 23 | static DEFINE_PER_CPU(unsigned long, touch_timestamp); |
24 | static DEFINE_PER_CPU(unsigned long, print_timestamp); | 24 | static DEFINE_PER_CPU(unsigned long, print_timestamp); |
25 | static DEFINE_PER_CPU(struct task_struct *, watchdog_task); | 25 | static DEFINE_PER_CPU(struct task_struct *, watchdog_task); |
26 | 26 | ||
27 | static int did_panic; | 27 | static int __read_mostly did_panic; |
28 | int softlockup_thresh = 60; | 28 | unsigned long __read_mostly softlockup_thresh = 60; |
29 | 29 | ||
30 | static int | 30 | static int |
31 | softlock_panic(struct notifier_block *this, unsigned long event, void *ptr) | 31 | softlock_panic(struct notifier_block *this, unsigned long event, void *ptr) |
32 | { | 32 | { |
33 | did_panic = 1; | 33 | did_panic = 1; |
34 | 34 | ||
35 | return NOTIFY_DONE; | 35 | return NOTIFY_DONE; |
36 | } | 36 | } |
37 | 37 | ||
38 | static struct notifier_block panic_block = { | 38 | static struct notifier_block panic_block = { |
39 | .notifier_call = softlock_panic, | 39 | .notifier_call = softlock_panic, |
40 | }; | 40 | }; |
41 | 41 | ||
42 | /* | 42 | /* |
43 | * Returns seconds, approximately. We don't need nanosecond | 43 | * Returns seconds, approximately. We don't need nanosecond |
44 | * resolution, and we don't need to waste time with a big divide when | 44 | * resolution, and we don't need to waste time with a big divide when |
45 | * 2^30ns == 1.074s. | 45 | * 2^30ns == 1.074s. |
46 | */ | 46 | */ |
47 | static unsigned long get_timestamp(int this_cpu) | 47 | static unsigned long get_timestamp(int this_cpu) |
48 | { | 48 | { |
49 | return cpu_clock(this_cpu) >> 30LL; /* 2^30 ~= 10^9 */ | 49 | return cpu_clock(this_cpu) >> 30LL; /* 2^30 ~= 10^9 */ |
50 | } | 50 | } |
51 | 51 | ||
52 | void touch_softlockup_watchdog(void) | 52 | void touch_softlockup_watchdog(void) |
53 | { | 53 | { |
54 | int this_cpu = raw_smp_processor_id(); | 54 | int this_cpu = raw_smp_processor_id(); |
55 | 55 | ||
56 | __raw_get_cpu_var(touch_timestamp) = get_timestamp(this_cpu); | 56 | __raw_get_cpu_var(touch_timestamp) = get_timestamp(this_cpu); |
57 | } | 57 | } |
58 | EXPORT_SYMBOL(touch_softlockup_watchdog); | 58 | EXPORT_SYMBOL(touch_softlockup_watchdog); |
59 | 59 | ||
60 | void touch_all_softlockup_watchdogs(void) | 60 | void touch_all_softlockup_watchdogs(void) |
61 | { | 61 | { |
62 | int cpu; | 62 | int cpu; |
63 | 63 | ||
64 | /* Cause each CPU to re-update its timestamp rather than complain */ | 64 | /* Cause each CPU to re-update its timestamp rather than complain */ |
65 | for_each_online_cpu(cpu) | 65 | for_each_online_cpu(cpu) |
66 | per_cpu(touch_timestamp, cpu) = 0; | 66 | per_cpu(touch_timestamp, cpu) = 0; |
67 | } | 67 | } |
68 | EXPORT_SYMBOL(touch_all_softlockup_watchdogs); | 68 | EXPORT_SYMBOL(touch_all_softlockup_watchdogs); |
69 | 69 | ||
70 | /* | 70 | /* |
71 | * This callback runs from the timer interrupt, and checks | 71 | * This callback runs from the timer interrupt, and checks |
72 | * whether the watchdog thread has hung or not: | 72 | * whether the watchdog thread has hung or not: |
73 | */ | 73 | */ |
74 | void softlockup_tick(void) | 74 | void softlockup_tick(void) |
75 | { | 75 | { |
76 | int this_cpu = smp_processor_id(); | 76 | int this_cpu = smp_processor_id(); |
77 | unsigned long touch_timestamp = per_cpu(touch_timestamp, this_cpu); | 77 | unsigned long touch_timestamp = per_cpu(touch_timestamp, this_cpu); |
78 | unsigned long print_timestamp; | 78 | unsigned long print_timestamp; |
79 | struct pt_regs *regs = get_irq_regs(); | 79 | struct pt_regs *regs = get_irq_regs(); |
80 | unsigned long now; | 80 | unsigned long now; |
81 | 81 | ||
82 | if (touch_timestamp == 0) { | 82 | if (touch_timestamp == 0) { |
83 | touch_softlockup_watchdog(); | 83 | touch_softlockup_watchdog(); |
84 | return; | 84 | return; |
85 | } | 85 | } |
86 | 86 | ||
87 | print_timestamp = per_cpu(print_timestamp, this_cpu); | 87 | print_timestamp = per_cpu(print_timestamp, this_cpu); |
88 | 88 | ||
89 | /* report at most once a second */ | 89 | /* report at most once a second */ |
90 | if ((print_timestamp >= touch_timestamp && | 90 | if ((print_timestamp >= touch_timestamp && |
91 | print_timestamp < (touch_timestamp + 1)) || | 91 | print_timestamp < (touch_timestamp + 1)) || |
92 | did_panic || !per_cpu(watchdog_task, this_cpu)) { | 92 | did_panic || !per_cpu(watchdog_task, this_cpu)) { |
93 | return; | 93 | return; |
94 | } | 94 | } |
95 | 95 | ||
96 | /* do not print during early bootup: */ | 96 | /* do not print during early bootup: */ |
97 | if (unlikely(system_state != SYSTEM_RUNNING)) { | 97 | if (unlikely(system_state != SYSTEM_RUNNING)) { |
98 | touch_softlockup_watchdog(); | 98 | touch_softlockup_watchdog(); |
99 | return; | 99 | return; |
100 | } | 100 | } |
101 | 101 | ||
102 | now = get_timestamp(this_cpu); | 102 | now = get_timestamp(this_cpu); |
103 | 103 | ||
104 | /* Warn about unreasonable delays: */ | 104 | /* Warn about unreasonable delays: */ |
105 | if (now <= (touch_timestamp + softlockup_thresh)) | 105 | if (now <= (touch_timestamp + softlockup_thresh)) |
106 | return; | 106 | return; |
107 | 107 | ||
108 | per_cpu(print_timestamp, this_cpu) = touch_timestamp; | 108 | per_cpu(print_timestamp, this_cpu) = touch_timestamp; |
109 | 109 | ||
110 | spin_lock(&print_lock); | 110 | spin_lock(&print_lock); |
111 | printk(KERN_ERR "BUG: soft lockup - CPU#%d stuck for %lus! [%s:%d]\n", | 111 | printk(KERN_ERR "BUG: soft lockup - CPU#%d stuck for %lus! [%s:%d]\n", |
112 | this_cpu, now - touch_timestamp, | 112 | this_cpu, now - touch_timestamp, |
113 | current->comm, task_pid_nr(current)); | 113 | current->comm, task_pid_nr(current)); |
114 | if (regs) | 114 | if (regs) |
115 | show_regs(regs); | 115 | show_regs(regs); |
116 | else | 116 | else |
117 | dump_stack(); | 117 | dump_stack(); |
118 | spin_unlock(&print_lock); | 118 | spin_unlock(&print_lock); |
119 | } | 119 | } |
120 | 120 | ||
121 | /* | 121 | /* |
122 | * Have a reasonable limit on the number of tasks checked: | 122 | * Have a reasonable limit on the number of tasks checked: |
123 | */ | 123 | */ |
124 | unsigned long sysctl_hung_task_check_count = 1024; | 124 | unsigned long __read_mostly sysctl_hung_task_check_count = 1024; |
125 | 125 | ||
126 | /* | 126 | /* |
127 | * Zero means infinite timeout - no checking done: | 127 | * Zero means infinite timeout - no checking done: |
128 | */ | 128 | */ |
129 | unsigned long sysctl_hung_task_timeout_secs = 120; | 129 | unsigned long __read_mostly sysctl_hung_task_timeout_secs = 120; |
130 | 130 | ||
131 | long sysctl_hung_task_warnings = 10; | 131 | unsigned long __read_mostly sysctl_hung_task_warnings = 10; |
132 | 132 | ||
133 | /* | 133 | /* |
134 | * Only do the hung-tasks check on one CPU: | 134 | * Only do the hung-tasks check on one CPU: |
135 | */ | 135 | */ |
136 | static int check_cpu __read_mostly = -1; | 136 | static int check_cpu __read_mostly = -1; |
137 | 137 | ||
138 | static void check_hung_task(struct task_struct *t, unsigned long now) | 138 | static void check_hung_task(struct task_struct *t, unsigned long now) |
139 | { | 139 | { |
140 | unsigned long switch_count = t->nvcsw + t->nivcsw; | 140 | unsigned long switch_count = t->nvcsw + t->nivcsw; |
141 | 141 | ||
142 | if (t->flags & PF_FROZEN) | 142 | if (t->flags & PF_FROZEN) |
143 | return; | 143 | return; |
144 | 144 | ||
145 | if (switch_count != t->last_switch_count || !t->last_switch_timestamp) { | 145 | if (switch_count != t->last_switch_count || !t->last_switch_timestamp) { |
146 | t->last_switch_count = switch_count; | 146 | t->last_switch_count = switch_count; |
147 | t->last_switch_timestamp = now; | 147 | t->last_switch_timestamp = now; |
148 | return; | 148 | return; |
149 | } | 149 | } |
150 | if ((long)(now - t->last_switch_timestamp) < | 150 | if ((long)(now - t->last_switch_timestamp) < |
151 | sysctl_hung_task_timeout_secs) | 151 | sysctl_hung_task_timeout_secs) |
152 | return; | 152 | return; |
153 | if (sysctl_hung_task_warnings < 0) | 153 | if (sysctl_hung_task_warnings < 0) |
154 | return; | 154 | return; |
155 | sysctl_hung_task_warnings--; | 155 | sysctl_hung_task_warnings--; |
156 | 156 | ||
157 | /* | 157 | /* |
158 | * Ok, the task did not get scheduled for more than 2 minutes, | 158 | * Ok, the task did not get scheduled for more than 2 minutes, |
159 | * complain: | 159 | * complain: |
160 | */ | 160 | */ |
161 | printk(KERN_ERR "INFO: task %s:%d blocked for more than " | 161 | printk(KERN_ERR "INFO: task %s:%d blocked for more than " |
162 | "%ld seconds.\n", t->comm, t->pid, | 162 | "%ld seconds.\n", t->comm, t->pid, |
163 | sysctl_hung_task_timeout_secs); | 163 | sysctl_hung_task_timeout_secs); |
164 | printk(KERN_ERR "\"echo 0 > /proc/sys/kernel/hung_task_timeout_secs\"" | 164 | printk(KERN_ERR "\"echo 0 > /proc/sys/kernel/hung_task_timeout_secs\"" |
165 | " disables this message.\n"); | 165 | " disables this message.\n"); |
166 | sched_show_task(t); | 166 | sched_show_task(t); |
167 | __debug_show_held_locks(t); | 167 | __debug_show_held_locks(t); |
168 | 168 | ||
169 | t->last_switch_timestamp = now; | 169 | t->last_switch_timestamp = now; |
170 | touch_nmi_watchdog(); | 170 | touch_nmi_watchdog(); |
171 | } | 171 | } |
172 | 172 | ||
173 | /* | 173 | /* |
174 | * Check whether a TASK_UNINTERRUPTIBLE does not get woken up for | 174 | * Check whether a TASK_UNINTERRUPTIBLE does not get woken up for |
175 | * a really long time (120 seconds). If that happens, print out | 175 | * a really long time (120 seconds). If that happens, print out |
176 | * a warning. | 176 | * a warning. |
177 | */ | 177 | */ |
178 | static void check_hung_uninterruptible_tasks(int this_cpu) | 178 | static void check_hung_uninterruptible_tasks(int this_cpu) |
179 | { | 179 | { |
180 | int max_count = sysctl_hung_task_check_count; | 180 | int max_count = sysctl_hung_task_check_count; |
181 | unsigned long now = get_timestamp(this_cpu); | 181 | unsigned long now = get_timestamp(this_cpu); |
182 | struct task_struct *g, *t; | 182 | struct task_struct *g, *t; |
183 | 183 | ||
184 | /* | 184 | /* |
185 | * If the system crashed already then all bets are off, | 185 | * If the system crashed already then all bets are off, |
186 | * do not report extra hung tasks: | 186 | * do not report extra hung tasks: |
187 | */ | 187 | */ |
188 | if ((tainted & TAINT_DIE) || did_panic) | 188 | if ((tainted & TAINT_DIE) || did_panic) |
189 | return; | 189 | return; |
190 | 190 | ||
191 | read_lock(&tasklist_lock); | 191 | read_lock(&tasklist_lock); |
192 | do_each_thread(g, t) { | 192 | do_each_thread(g, t) { |
193 | if (!--max_count) | 193 | if (!--max_count) |
194 | break; | 194 | break; |
195 | if (t->state & TASK_UNINTERRUPTIBLE) | 195 | if (t->state & TASK_UNINTERRUPTIBLE) |
196 | check_hung_task(t, now); | 196 | check_hung_task(t, now); |
197 | } while_each_thread(g, t); | 197 | } while_each_thread(g, t); |
198 | 198 | ||
199 | read_unlock(&tasklist_lock); | 199 | read_unlock(&tasklist_lock); |
200 | } | 200 | } |
201 | 201 | ||
202 | /* | 202 | /* |
203 | * The watchdog thread - runs every second and touches the timestamp. | 203 | * The watchdog thread - runs every second and touches the timestamp. |
204 | */ | 204 | */ |
205 | static int watchdog(void *__bind_cpu) | 205 | static int watchdog(void *__bind_cpu) |
206 | { | 206 | { |
207 | struct sched_param param = { .sched_priority = MAX_RT_PRIO-1 }; | 207 | struct sched_param param = { .sched_priority = MAX_RT_PRIO-1 }; |
208 | int this_cpu = (long)__bind_cpu; | 208 | int this_cpu = (long)__bind_cpu; |
209 | 209 | ||
210 | sched_setscheduler(current, SCHED_FIFO, ¶m); | 210 | sched_setscheduler(current, SCHED_FIFO, ¶m); |
211 | 211 | ||
212 | /* initialize timestamp */ | 212 | /* initialize timestamp */ |
213 | touch_softlockup_watchdog(); | 213 | touch_softlockup_watchdog(); |
214 | 214 | ||
215 | /* | 215 | /* |
216 | * Run briefly once per second to reset the softlockup timestamp. | 216 | * Run briefly once per second to reset the softlockup timestamp. |
217 | * If this gets delayed for more than 60 seconds then the | 217 | * If this gets delayed for more than 60 seconds then the |
218 | * debug-printout triggers in softlockup_tick(). | 218 | * debug-printout triggers in softlockup_tick(). |
219 | */ | 219 | */ |
220 | while (!kthread_should_stop()) { | 220 | while (!kthread_should_stop()) { |
221 | touch_softlockup_watchdog(); | 221 | touch_softlockup_watchdog(); |
222 | msleep_interruptible(10000); | 222 | msleep_interruptible(10000); |
223 | 223 | ||
224 | if (this_cpu != check_cpu) | 224 | if (this_cpu != check_cpu) |
225 | continue; | 225 | continue; |
226 | 226 | ||
227 | if (sysctl_hung_task_timeout_secs) | 227 | if (sysctl_hung_task_timeout_secs) |
228 | check_hung_uninterruptible_tasks(this_cpu); | 228 | check_hung_uninterruptible_tasks(this_cpu); |
229 | } | 229 | } |
230 | 230 | ||
231 | return 0; | 231 | return 0; |
232 | } | 232 | } |
233 | 233 | ||
234 | /* | 234 | /* |
235 | * Create/destroy watchdog threads as CPUs come and go: | 235 | * Create/destroy watchdog threads as CPUs come and go: |
236 | */ | 236 | */ |
237 | static int __cpuinit | 237 | static int __cpuinit |
238 | cpu_callback(struct notifier_block *nfb, unsigned long action, void *hcpu) | 238 | cpu_callback(struct notifier_block *nfb, unsigned long action, void *hcpu) |
239 | { | 239 | { |
240 | int hotcpu = (unsigned long)hcpu; | 240 | int hotcpu = (unsigned long)hcpu; |
241 | struct task_struct *p; | 241 | struct task_struct *p; |
242 | 242 | ||
243 | switch (action) { | 243 | switch (action) { |
244 | case CPU_UP_PREPARE: | 244 | case CPU_UP_PREPARE: |
245 | case CPU_UP_PREPARE_FROZEN: | 245 | case CPU_UP_PREPARE_FROZEN: |
246 | BUG_ON(per_cpu(watchdog_task, hotcpu)); | 246 | BUG_ON(per_cpu(watchdog_task, hotcpu)); |
247 | p = kthread_create(watchdog, hcpu, "watchdog/%d", hotcpu); | 247 | p = kthread_create(watchdog, hcpu, "watchdog/%d", hotcpu); |
248 | if (IS_ERR(p)) { | 248 | if (IS_ERR(p)) { |
249 | printk(KERN_ERR "watchdog for %i failed\n", hotcpu); | 249 | printk(KERN_ERR "watchdog for %i failed\n", hotcpu); |
250 | return NOTIFY_BAD; | 250 | return NOTIFY_BAD; |
251 | } | 251 | } |
252 | per_cpu(touch_timestamp, hotcpu) = 0; | 252 | per_cpu(touch_timestamp, hotcpu) = 0; |
253 | per_cpu(watchdog_task, hotcpu) = p; | 253 | per_cpu(watchdog_task, hotcpu) = p; |
254 | kthread_bind(p, hotcpu); | 254 | kthread_bind(p, hotcpu); |
255 | break; | 255 | break; |
256 | case CPU_ONLINE: | 256 | case CPU_ONLINE: |
257 | case CPU_ONLINE_FROZEN: | 257 | case CPU_ONLINE_FROZEN: |
258 | check_cpu = any_online_cpu(cpu_online_map); | 258 | check_cpu = any_online_cpu(cpu_online_map); |
259 | wake_up_process(per_cpu(watchdog_task, hotcpu)); | 259 | wake_up_process(per_cpu(watchdog_task, hotcpu)); |
260 | break; | 260 | break; |
261 | #ifdef CONFIG_HOTPLUG_CPU | 261 | #ifdef CONFIG_HOTPLUG_CPU |
262 | case CPU_UP_CANCELED: | 262 | case CPU_UP_CANCELED: |
263 | case CPU_UP_CANCELED_FROZEN: | 263 | case CPU_UP_CANCELED_FROZEN: |
264 | if (!per_cpu(watchdog_task, hotcpu)) | 264 | if (!per_cpu(watchdog_task, hotcpu)) |
265 | break; | 265 | break; |
266 | /* Unbind so it can run. Fall thru. */ | 266 | /* Unbind so it can run. Fall thru. */ |
267 | kthread_bind(per_cpu(watchdog_task, hotcpu), | 267 | kthread_bind(per_cpu(watchdog_task, hotcpu), |
268 | any_online_cpu(cpu_online_map)); | 268 | any_online_cpu(cpu_online_map)); |
269 | case CPU_DOWN_PREPARE: | 269 | case CPU_DOWN_PREPARE: |
270 | case CPU_DOWN_PREPARE_FROZEN: | 270 | case CPU_DOWN_PREPARE_FROZEN: |
271 | if (hotcpu == check_cpu) { | 271 | if (hotcpu == check_cpu) { |
272 | cpumask_t temp_cpu_online_map = cpu_online_map; | 272 | cpumask_t temp_cpu_online_map = cpu_online_map; |
273 | 273 | ||
274 | cpu_clear(hotcpu, temp_cpu_online_map); | 274 | cpu_clear(hotcpu, temp_cpu_online_map); |
275 | check_cpu = any_online_cpu(temp_cpu_online_map); | 275 | check_cpu = any_online_cpu(temp_cpu_online_map); |
276 | } | 276 | } |
277 | break; | 277 | break; |
278 | case CPU_DEAD: | 278 | case CPU_DEAD: |
279 | case CPU_DEAD_FROZEN: | 279 | case CPU_DEAD_FROZEN: |
280 | p = per_cpu(watchdog_task, hotcpu); | 280 | p = per_cpu(watchdog_task, hotcpu); |
281 | per_cpu(watchdog_task, hotcpu) = NULL; | 281 | per_cpu(watchdog_task, hotcpu) = NULL; |
282 | kthread_stop(p); | 282 | kthread_stop(p); |
283 | break; | 283 | break; |
284 | #endif /* CONFIG_HOTPLUG_CPU */ | 284 | #endif /* CONFIG_HOTPLUG_CPU */ |
285 | } | 285 | } |
286 | return NOTIFY_OK; | 286 | return NOTIFY_OK; |
287 | } | 287 | } |
288 | 288 | ||
289 | static struct notifier_block __cpuinitdata cpu_nfb = { | 289 | static struct notifier_block __cpuinitdata cpu_nfb = { |
290 | .notifier_call = cpu_callback | 290 | .notifier_call = cpu_callback |
291 | }; | 291 | }; |
292 | 292 | ||
293 | __init void spawn_softlockup_task(void) | 293 | __init void spawn_softlockup_task(void) |
294 | { | 294 | { |
295 | void *cpu = (void *)(long)smp_processor_id(); | 295 | void *cpu = (void *)(long)smp_processor_id(); |
296 | int err = cpu_callback(&cpu_nfb, CPU_UP_PREPARE, cpu); | 296 | int err = cpu_callback(&cpu_nfb, CPU_UP_PREPARE, cpu); |
297 | 297 | ||
298 | BUG_ON(err == NOTIFY_BAD); | 298 | BUG_ON(err == NOTIFY_BAD); |
299 | cpu_callback(&cpu_nfb, CPU_ONLINE, cpu); | 299 | cpu_callback(&cpu_nfb, CPU_ONLINE, cpu); |
300 | register_cpu_notifier(&cpu_nfb); | 300 | register_cpu_notifier(&cpu_nfb); |
301 | 301 | ||
302 | atomic_notifier_chain_register(&panic_notifier_list, &panic_block); | 302 | atomic_notifier_chain_register(&panic_notifier_list, &panic_block); |
303 | } | 303 | } |
304 | 304 |
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/security.h> | 40 | #include <linux/security.h> |
41 | #include <linux/initrd.h> | 41 | #include <linux/initrd.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/nfs_fs.h> | 46 | #include <linux/nfs_fs.h> |
47 | #include <linux/acpi.h> | 47 | #include <linux/acpi.h> |
48 | #include <linux/reboot.h> | 48 | #include <linux/reboot.h> |
49 | 49 | ||
50 | #include <asm/uaccess.h> | 50 | #include <asm/uaccess.h> |
51 | #include <asm/processor.h> | 51 | #include <asm/processor.h> |
52 | 52 | ||
53 | #ifdef CONFIG_X86 | 53 | #ifdef CONFIG_X86 |
54 | #include <asm/nmi.h> | 54 | #include <asm/nmi.h> |
55 | #include <asm/stacktrace.h> | 55 | #include <asm/stacktrace.h> |
56 | #endif | 56 | #endif |
57 | 57 | ||
58 | static int deprecated_sysctl_warning(struct __sysctl_args *args); | 58 | static int deprecated_sysctl_warning(struct __sysctl_args *args); |
59 | 59 | ||
60 | #if defined(CONFIG_SYSCTL) | 60 | #if defined(CONFIG_SYSCTL) |
61 | 61 | ||
62 | /* External variables not in a header file. */ | 62 | /* External variables not in a header file. */ |
63 | extern int C_A_D; | 63 | extern int C_A_D; |
64 | extern int print_fatal_signals; | 64 | extern int print_fatal_signals; |
65 | extern int sysctl_overcommit_memory; | 65 | extern int sysctl_overcommit_memory; |
66 | extern int sysctl_overcommit_ratio; | 66 | extern int sysctl_overcommit_ratio; |
67 | extern int sysctl_panic_on_oom; | 67 | extern int sysctl_panic_on_oom; |
68 | extern int sysctl_oom_kill_allocating_task; | 68 | extern int sysctl_oom_kill_allocating_task; |
69 | extern int max_threads; | 69 | extern int max_threads; |
70 | extern int core_uses_pid; | 70 | extern int core_uses_pid; |
71 | extern int suid_dumpable; | 71 | extern int suid_dumpable; |
72 | extern char core_pattern[]; | 72 | extern char core_pattern[]; |
73 | extern int pid_max; | 73 | extern int pid_max; |
74 | extern int min_free_kbytes; | 74 | extern int min_free_kbytes; |
75 | extern int printk_ratelimit_jiffies; | 75 | extern int printk_ratelimit_jiffies; |
76 | extern int printk_ratelimit_burst; | 76 | extern int printk_ratelimit_burst; |
77 | extern int pid_max_min, pid_max_max; | 77 | extern int pid_max_min, pid_max_max; |
78 | extern int sysctl_drop_caches; | 78 | extern int sysctl_drop_caches; |
79 | extern int percpu_pagelist_fraction; | 79 | extern int percpu_pagelist_fraction; |
80 | extern int compat_log; | 80 | extern int compat_log; |
81 | extern int maps_protect; | 81 | extern int maps_protect; |
82 | extern int sysctl_stat_interval; | 82 | extern int sysctl_stat_interval; |
83 | extern int audit_argv_kb; | 83 | extern int audit_argv_kb; |
84 | extern int latencytop_enabled; | 84 | extern int latencytop_enabled; |
85 | 85 | ||
86 | /* Constants used for minimum and maximum */ | 86 | /* Constants used for minimum and maximum */ |
87 | #ifdef CONFIG_DETECT_SOFTLOCKUP | 87 | #ifdef CONFIG_DETECT_SOFTLOCKUP |
88 | static int one = 1; | 88 | static int one = 1; |
89 | static int sixty = 60; | 89 | static int sixty = 60; |
90 | #endif | 90 | #endif |
91 | 91 | ||
92 | #ifdef CONFIG_MMU | 92 | #ifdef CONFIG_MMU |
93 | static int two = 2; | 93 | static int two = 2; |
94 | #endif | 94 | #endif |
95 | 95 | ||
96 | static int zero; | 96 | static int zero; |
97 | static int one_hundred = 100; | 97 | static int one_hundred = 100; |
98 | 98 | ||
99 | /* this is needed for the proc_dointvec_minmax for [fs_]overflow UID and GID */ | 99 | /* this is needed for the proc_dointvec_minmax for [fs_]overflow UID and GID */ |
100 | static int maxolduid = 65535; | 100 | static int maxolduid = 65535; |
101 | static int minolduid; | 101 | static int minolduid; |
102 | static int min_percpu_pagelist_fract = 8; | 102 | static int min_percpu_pagelist_fract = 8; |
103 | 103 | ||
104 | static int ngroups_max = NGROUPS_MAX; | 104 | static int ngroups_max = NGROUPS_MAX; |
105 | 105 | ||
106 | #ifdef CONFIG_KMOD | 106 | #ifdef CONFIG_KMOD |
107 | extern char modprobe_path[]; | 107 | extern char modprobe_path[]; |
108 | #endif | 108 | #endif |
109 | #ifdef CONFIG_CHR_DEV_SG | 109 | #ifdef CONFIG_CHR_DEV_SG |
110 | extern int sg_big_buff; | 110 | extern int sg_big_buff; |
111 | #endif | 111 | #endif |
112 | 112 | ||
113 | #ifdef __sparc__ | 113 | #ifdef __sparc__ |
114 | extern char reboot_command []; | 114 | extern char reboot_command []; |
115 | extern int stop_a_enabled; | 115 | extern int stop_a_enabled; |
116 | extern int scons_pwroff; | 116 | extern int scons_pwroff; |
117 | #endif | 117 | #endif |
118 | 118 | ||
119 | #ifdef __hppa__ | 119 | #ifdef __hppa__ |
120 | extern int pwrsw_enabled; | 120 | extern int pwrsw_enabled; |
121 | extern int unaligned_enabled; | 121 | extern int unaligned_enabled; |
122 | #endif | 122 | #endif |
123 | 123 | ||
124 | #ifdef CONFIG_S390 | 124 | #ifdef CONFIG_S390 |
125 | #ifdef CONFIG_MATHEMU | 125 | #ifdef CONFIG_MATHEMU |
126 | extern int sysctl_ieee_emulation_warnings; | 126 | extern int sysctl_ieee_emulation_warnings; |
127 | #endif | 127 | #endif |
128 | extern int sysctl_userprocess_debug; | 128 | extern int sysctl_userprocess_debug; |
129 | extern int spin_retry; | 129 | extern int spin_retry; |
130 | #endif | 130 | #endif |
131 | 131 | ||
132 | extern int sysctl_hz_timer; | 132 | extern int sysctl_hz_timer; |
133 | 133 | ||
134 | #ifdef CONFIG_BSD_PROCESS_ACCT | 134 | #ifdef CONFIG_BSD_PROCESS_ACCT |
135 | extern int acct_parm[]; | 135 | extern int acct_parm[]; |
136 | #endif | 136 | #endif |
137 | 137 | ||
138 | #ifdef CONFIG_IA64 | 138 | #ifdef CONFIG_IA64 |
139 | extern int no_unaligned_warning; | 139 | extern int no_unaligned_warning; |
140 | #endif | 140 | #endif |
141 | 141 | ||
142 | #ifdef CONFIG_RT_MUTEXES | 142 | #ifdef CONFIG_RT_MUTEXES |
143 | extern int max_lock_depth; | 143 | extern int max_lock_depth; |
144 | #endif | 144 | #endif |
145 | 145 | ||
146 | #ifdef CONFIG_SYSCTL_SYSCALL | 146 | #ifdef CONFIG_SYSCTL_SYSCALL |
147 | static int parse_table(int __user *, int, void __user *, size_t __user *, | 147 | static int parse_table(int __user *, int, void __user *, size_t __user *, |
148 | void __user *, size_t, struct ctl_table *); | 148 | void __user *, size_t, struct ctl_table *); |
149 | #endif | 149 | #endif |
150 | 150 | ||
151 | 151 | ||
152 | #ifdef CONFIG_PROC_SYSCTL | 152 | #ifdef CONFIG_PROC_SYSCTL |
153 | static int proc_do_cad_pid(struct ctl_table *table, int write, struct file *filp, | 153 | static int proc_do_cad_pid(struct ctl_table *table, int write, struct file *filp, |
154 | void __user *buffer, size_t *lenp, loff_t *ppos); | 154 | void __user *buffer, size_t *lenp, loff_t *ppos); |
155 | static int proc_dointvec_taint(struct ctl_table *table, int write, struct file *filp, | 155 | static int proc_dointvec_taint(struct ctl_table *table, int write, struct file *filp, |
156 | void __user *buffer, size_t *lenp, loff_t *ppos); | 156 | void __user *buffer, size_t *lenp, loff_t *ppos); |
157 | #endif | 157 | #endif |
158 | 158 | ||
159 | static struct ctl_table root_table[]; | 159 | static struct ctl_table root_table[]; |
160 | static struct ctl_table_header root_table_header = | 160 | static struct ctl_table_header root_table_header = |
161 | { root_table, LIST_HEAD_INIT(root_table_header.ctl_entry) }; | 161 | { root_table, LIST_HEAD_INIT(root_table_header.ctl_entry) }; |
162 | 162 | ||
163 | static struct ctl_table kern_table[]; | 163 | static struct ctl_table kern_table[]; |
164 | static struct ctl_table vm_table[]; | 164 | static struct ctl_table vm_table[]; |
165 | static struct ctl_table fs_table[]; | 165 | static struct ctl_table fs_table[]; |
166 | static struct ctl_table debug_table[]; | 166 | static struct ctl_table debug_table[]; |
167 | static struct ctl_table dev_table[]; | 167 | static struct ctl_table dev_table[]; |
168 | extern struct ctl_table random_table[]; | 168 | extern struct ctl_table random_table[]; |
169 | #ifdef CONFIG_INOTIFY_USER | 169 | #ifdef CONFIG_INOTIFY_USER |
170 | extern struct ctl_table inotify_table[]; | 170 | extern struct ctl_table inotify_table[]; |
171 | #endif | 171 | #endif |
172 | 172 | ||
173 | #ifdef HAVE_ARCH_PICK_MMAP_LAYOUT | 173 | #ifdef HAVE_ARCH_PICK_MMAP_LAYOUT |
174 | int sysctl_legacy_va_layout; | 174 | int sysctl_legacy_va_layout; |
175 | #endif | 175 | #endif |
176 | 176 | ||
177 | extern int prove_locking; | 177 | extern int prove_locking; |
178 | extern int lock_stat; | 178 | extern int lock_stat; |
179 | 179 | ||
180 | /* The default sysctl tables: */ | 180 | /* The default sysctl tables: */ |
181 | 181 | ||
182 | static struct ctl_table root_table[] = { | 182 | static struct ctl_table root_table[] = { |
183 | { | 183 | { |
184 | .ctl_name = CTL_KERN, | 184 | .ctl_name = CTL_KERN, |
185 | .procname = "kernel", | 185 | .procname = "kernel", |
186 | .mode = 0555, | 186 | .mode = 0555, |
187 | .child = kern_table, | 187 | .child = kern_table, |
188 | }, | 188 | }, |
189 | { | 189 | { |
190 | .ctl_name = CTL_VM, | 190 | .ctl_name = CTL_VM, |
191 | .procname = "vm", | 191 | .procname = "vm", |
192 | .mode = 0555, | 192 | .mode = 0555, |
193 | .child = vm_table, | 193 | .child = vm_table, |
194 | }, | 194 | }, |
195 | #ifdef CONFIG_NET | 195 | #ifdef CONFIG_NET |
196 | { | 196 | { |
197 | .ctl_name = CTL_NET, | 197 | .ctl_name = CTL_NET, |
198 | .procname = "net", | 198 | .procname = "net", |
199 | .mode = 0555, | 199 | .mode = 0555, |
200 | .child = net_table, | 200 | .child = net_table, |
201 | }, | 201 | }, |
202 | #endif | 202 | #endif |
203 | { | 203 | { |
204 | .ctl_name = CTL_FS, | 204 | .ctl_name = CTL_FS, |
205 | .procname = "fs", | 205 | .procname = "fs", |
206 | .mode = 0555, | 206 | .mode = 0555, |
207 | .child = fs_table, | 207 | .child = fs_table, |
208 | }, | 208 | }, |
209 | { | 209 | { |
210 | .ctl_name = CTL_DEBUG, | 210 | .ctl_name = CTL_DEBUG, |
211 | .procname = "debug", | 211 | .procname = "debug", |
212 | .mode = 0555, | 212 | .mode = 0555, |
213 | .child = debug_table, | 213 | .child = debug_table, |
214 | }, | 214 | }, |
215 | { | 215 | { |
216 | .ctl_name = CTL_DEV, | 216 | .ctl_name = CTL_DEV, |
217 | .procname = "dev", | 217 | .procname = "dev", |
218 | .mode = 0555, | 218 | .mode = 0555, |
219 | .child = dev_table, | 219 | .child = dev_table, |
220 | }, | 220 | }, |
221 | /* | 221 | /* |
222 | * NOTE: do not add new entries to this table unless you have read | 222 | * NOTE: do not add new entries to this table unless you have read |
223 | * Documentation/sysctl/ctl_unnumbered.txt | 223 | * Documentation/sysctl/ctl_unnumbered.txt |
224 | */ | 224 | */ |
225 | { .ctl_name = 0 } | 225 | { .ctl_name = 0 } |
226 | }; | 226 | }; |
227 | 227 | ||
228 | #ifdef CONFIG_SCHED_DEBUG | 228 | #ifdef CONFIG_SCHED_DEBUG |
229 | static int min_sched_granularity_ns = 100000; /* 100 usecs */ | 229 | static int min_sched_granularity_ns = 100000; /* 100 usecs */ |
230 | static int max_sched_granularity_ns = NSEC_PER_SEC; /* 1 second */ | 230 | static int max_sched_granularity_ns = NSEC_PER_SEC; /* 1 second */ |
231 | static int min_wakeup_granularity_ns; /* 0 usecs */ | 231 | static int min_wakeup_granularity_ns; /* 0 usecs */ |
232 | static int max_wakeup_granularity_ns = NSEC_PER_SEC; /* 1 second */ | 232 | static int max_wakeup_granularity_ns = NSEC_PER_SEC; /* 1 second */ |
233 | #endif | 233 | #endif |
234 | 234 | ||
235 | static struct ctl_table kern_table[] = { | 235 | static struct ctl_table kern_table[] = { |
236 | #ifdef CONFIG_SCHED_DEBUG | 236 | #ifdef CONFIG_SCHED_DEBUG |
237 | { | 237 | { |
238 | .ctl_name = CTL_UNNUMBERED, | 238 | .ctl_name = CTL_UNNUMBERED, |
239 | .procname = "sched_min_granularity_ns", | 239 | .procname = "sched_min_granularity_ns", |
240 | .data = &sysctl_sched_min_granularity, | 240 | .data = &sysctl_sched_min_granularity, |
241 | .maxlen = sizeof(unsigned int), | 241 | .maxlen = sizeof(unsigned int), |
242 | .mode = 0644, | 242 | .mode = 0644, |
243 | .proc_handler = &sched_nr_latency_handler, | 243 | .proc_handler = &sched_nr_latency_handler, |
244 | .strategy = &sysctl_intvec, | 244 | .strategy = &sysctl_intvec, |
245 | .extra1 = &min_sched_granularity_ns, | 245 | .extra1 = &min_sched_granularity_ns, |
246 | .extra2 = &max_sched_granularity_ns, | 246 | .extra2 = &max_sched_granularity_ns, |
247 | }, | 247 | }, |
248 | { | 248 | { |
249 | .ctl_name = CTL_UNNUMBERED, | 249 | .ctl_name = CTL_UNNUMBERED, |
250 | .procname = "sched_latency_ns", | 250 | .procname = "sched_latency_ns", |
251 | .data = &sysctl_sched_latency, | 251 | .data = &sysctl_sched_latency, |
252 | .maxlen = sizeof(unsigned int), | 252 | .maxlen = sizeof(unsigned int), |
253 | .mode = 0644, | 253 | .mode = 0644, |
254 | .proc_handler = &sched_nr_latency_handler, | 254 | .proc_handler = &sched_nr_latency_handler, |
255 | .strategy = &sysctl_intvec, | 255 | .strategy = &sysctl_intvec, |
256 | .extra1 = &min_sched_granularity_ns, | 256 | .extra1 = &min_sched_granularity_ns, |
257 | .extra2 = &max_sched_granularity_ns, | 257 | .extra2 = &max_sched_granularity_ns, |
258 | }, | 258 | }, |
259 | { | 259 | { |
260 | .ctl_name = CTL_UNNUMBERED, | 260 | .ctl_name = CTL_UNNUMBERED, |
261 | .procname = "sched_wakeup_granularity_ns", | 261 | .procname = "sched_wakeup_granularity_ns", |
262 | .data = &sysctl_sched_wakeup_granularity, | 262 | .data = &sysctl_sched_wakeup_granularity, |
263 | .maxlen = sizeof(unsigned int), | 263 | .maxlen = sizeof(unsigned int), |
264 | .mode = 0644, | 264 | .mode = 0644, |
265 | .proc_handler = &proc_dointvec_minmax, | 265 | .proc_handler = &proc_dointvec_minmax, |
266 | .strategy = &sysctl_intvec, | 266 | .strategy = &sysctl_intvec, |
267 | .extra1 = &min_wakeup_granularity_ns, | 267 | .extra1 = &min_wakeup_granularity_ns, |
268 | .extra2 = &max_wakeup_granularity_ns, | 268 | .extra2 = &max_wakeup_granularity_ns, |
269 | }, | 269 | }, |
270 | { | 270 | { |
271 | .ctl_name = CTL_UNNUMBERED, | 271 | .ctl_name = CTL_UNNUMBERED, |
272 | .procname = "sched_batch_wakeup_granularity_ns", | 272 | .procname = "sched_batch_wakeup_granularity_ns", |
273 | .data = &sysctl_sched_batch_wakeup_granularity, | 273 | .data = &sysctl_sched_batch_wakeup_granularity, |
274 | .maxlen = sizeof(unsigned int), | 274 | .maxlen = sizeof(unsigned int), |
275 | .mode = 0644, | 275 | .mode = 0644, |
276 | .proc_handler = &proc_dointvec_minmax, | 276 | .proc_handler = &proc_dointvec_minmax, |
277 | .strategy = &sysctl_intvec, | 277 | .strategy = &sysctl_intvec, |
278 | .extra1 = &min_wakeup_granularity_ns, | 278 | .extra1 = &min_wakeup_granularity_ns, |
279 | .extra2 = &max_wakeup_granularity_ns, | 279 | .extra2 = &max_wakeup_granularity_ns, |
280 | }, | 280 | }, |
281 | { | 281 | { |
282 | .ctl_name = CTL_UNNUMBERED, | 282 | .ctl_name = CTL_UNNUMBERED, |
283 | .procname = "sched_child_runs_first", | 283 | .procname = "sched_child_runs_first", |
284 | .data = &sysctl_sched_child_runs_first, | 284 | .data = &sysctl_sched_child_runs_first, |
285 | .maxlen = sizeof(unsigned int), | 285 | .maxlen = sizeof(unsigned int), |
286 | .mode = 0644, | 286 | .mode = 0644, |
287 | .proc_handler = &proc_dointvec, | 287 | .proc_handler = &proc_dointvec, |
288 | }, | 288 | }, |
289 | { | 289 | { |
290 | .ctl_name = CTL_UNNUMBERED, | 290 | .ctl_name = CTL_UNNUMBERED, |
291 | .procname = "sched_features", | 291 | .procname = "sched_features", |
292 | .data = &sysctl_sched_features, | 292 | .data = &sysctl_sched_features, |
293 | .maxlen = sizeof(unsigned int), | 293 | .maxlen = sizeof(unsigned int), |
294 | .mode = 0644, | 294 | .mode = 0644, |
295 | .proc_handler = &proc_dointvec, | 295 | .proc_handler = &proc_dointvec, |
296 | }, | 296 | }, |
297 | { | 297 | { |
298 | .ctl_name = CTL_UNNUMBERED, | 298 | .ctl_name = CTL_UNNUMBERED, |
299 | .procname = "sched_migration_cost", | 299 | .procname = "sched_migration_cost", |
300 | .data = &sysctl_sched_migration_cost, | 300 | .data = &sysctl_sched_migration_cost, |
301 | .maxlen = sizeof(unsigned int), | 301 | .maxlen = sizeof(unsigned int), |
302 | .mode = 0644, | 302 | .mode = 0644, |
303 | .proc_handler = &proc_dointvec, | 303 | .proc_handler = &proc_dointvec, |
304 | }, | 304 | }, |
305 | { | 305 | { |
306 | .ctl_name = CTL_UNNUMBERED, | 306 | .ctl_name = CTL_UNNUMBERED, |
307 | .procname = "sched_nr_migrate", | 307 | .procname = "sched_nr_migrate", |
308 | .data = &sysctl_sched_nr_migrate, | 308 | .data = &sysctl_sched_nr_migrate, |
309 | .maxlen = sizeof(unsigned int), | 309 | .maxlen = sizeof(unsigned int), |
310 | .mode = 0644, | 310 | .mode = 0644, |
311 | .proc_handler = &proc_dointvec, | 311 | .proc_handler = &proc_dointvec, |
312 | }, | 312 | }, |
313 | { | 313 | { |
314 | .ctl_name = CTL_UNNUMBERED, | 314 | .ctl_name = CTL_UNNUMBERED, |
315 | .procname = "sched_rt_period_ms", | 315 | .procname = "sched_rt_period_ms", |
316 | .data = &sysctl_sched_rt_period, | 316 | .data = &sysctl_sched_rt_period, |
317 | .maxlen = sizeof(unsigned int), | 317 | .maxlen = sizeof(unsigned int), |
318 | .mode = 0644, | 318 | .mode = 0644, |
319 | .proc_handler = &proc_dointvec, | 319 | .proc_handler = &proc_dointvec, |
320 | }, | 320 | }, |
321 | { | 321 | { |
322 | .ctl_name = CTL_UNNUMBERED, | 322 | .ctl_name = CTL_UNNUMBERED, |
323 | .procname = "sched_rt_ratio", | 323 | .procname = "sched_rt_ratio", |
324 | .data = &sysctl_sched_rt_ratio, | 324 | .data = &sysctl_sched_rt_ratio, |
325 | .maxlen = sizeof(unsigned int), | 325 | .maxlen = sizeof(unsigned int), |
326 | .mode = 0644, | 326 | .mode = 0644, |
327 | .proc_handler = &proc_dointvec, | 327 | .proc_handler = &proc_dointvec, |
328 | }, | 328 | }, |
329 | #if defined(CONFIG_FAIR_GROUP_SCHED) && defined(CONFIG_SMP) | 329 | #if defined(CONFIG_FAIR_GROUP_SCHED) && defined(CONFIG_SMP) |
330 | { | 330 | { |
331 | .ctl_name = CTL_UNNUMBERED, | 331 | .ctl_name = CTL_UNNUMBERED, |
332 | .procname = "sched_min_bal_int_shares", | 332 | .procname = "sched_min_bal_int_shares", |
333 | .data = &sysctl_sched_min_bal_int_shares, | 333 | .data = &sysctl_sched_min_bal_int_shares, |
334 | .maxlen = sizeof(unsigned int), | 334 | .maxlen = sizeof(unsigned int), |
335 | .mode = 0644, | 335 | .mode = 0644, |
336 | .proc_handler = &proc_dointvec, | 336 | .proc_handler = &proc_dointvec, |
337 | }, | 337 | }, |
338 | { | 338 | { |
339 | .ctl_name = CTL_UNNUMBERED, | 339 | .ctl_name = CTL_UNNUMBERED, |
340 | .procname = "sched_max_bal_int_shares", | 340 | .procname = "sched_max_bal_int_shares", |
341 | .data = &sysctl_sched_max_bal_int_shares, | 341 | .data = &sysctl_sched_max_bal_int_shares, |
342 | .maxlen = sizeof(unsigned int), | 342 | .maxlen = sizeof(unsigned int), |
343 | .mode = 0644, | 343 | .mode = 0644, |
344 | .proc_handler = &proc_dointvec, | 344 | .proc_handler = &proc_dointvec, |
345 | }, | 345 | }, |
346 | #endif | 346 | #endif |
347 | #endif | 347 | #endif |
348 | { | 348 | { |
349 | .ctl_name = CTL_UNNUMBERED, | 349 | .ctl_name = CTL_UNNUMBERED, |
350 | .procname = "sched_compat_yield", | 350 | .procname = "sched_compat_yield", |
351 | .data = &sysctl_sched_compat_yield, | 351 | .data = &sysctl_sched_compat_yield, |
352 | .maxlen = sizeof(unsigned int), | 352 | .maxlen = sizeof(unsigned int), |
353 | .mode = 0644, | 353 | .mode = 0644, |
354 | .proc_handler = &proc_dointvec, | 354 | .proc_handler = &proc_dointvec, |
355 | }, | 355 | }, |
356 | #ifdef CONFIG_PROVE_LOCKING | 356 | #ifdef CONFIG_PROVE_LOCKING |
357 | { | 357 | { |
358 | .ctl_name = CTL_UNNUMBERED, | 358 | .ctl_name = CTL_UNNUMBERED, |
359 | .procname = "prove_locking", | 359 | .procname = "prove_locking", |
360 | .data = &prove_locking, | 360 | .data = &prove_locking, |
361 | .maxlen = sizeof(int), | 361 | .maxlen = sizeof(int), |
362 | .mode = 0644, | 362 | .mode = 0644, |
363 | .proc_handler = &proc_dointvec, | 363 | .proc_handler = &proc_dointvec, |
364 | }, | 364 | }, |
365 | #endif | 365 | #endif |
366 | #ifdef CONFIG_LOCK_STAT | 366 | #ifdef CONFIG_LOCK_STAT |
367 | { | 367 | { |
368 | .ctl_name = CTL_UNNUMBERED, | 368 | .ctl_name = CTL_UNNUMBERED, |
369 | .procname = "lock_stat", | 369 | .procname = "lock_stat", |
370 | .data = &lock_stat, | 370 | .data = &lock_stat, |
371 | .maxlen = sizeof(int), | 371 | .maxlen = sizeof(int), |
372 | .mode = 0644, | 372 | .mode = 0644, |
373 | .proc_handler = &proc_dointvec, | 373 | .proc_handler = &proc_dointvec, |
374 | }, | 374 | }, |
375 | #endif | 375 | #endif |
376 | { | 376 | { |
377 | .ctl_name = KERN_PANIC, | 377 | .ctl_name = KERN_PANIC, |
378 | .procname = "panic", | 378 | .procname = "panic", |
379 | .data = &panic_timeout, | 379 | .data = &panic_timeout, |
380 | .maxlen = sizeof(int), | 380 | .maxlen = sizeof(int), |
381 | .mode = 0644, | 381 | .mode = 0644, |
382 | .proc_handler = &proc_dointvec, | 382 | .proc_handler = &proc_dointvec, |
383 | }, | 383 | }, |
384 | { | 384 | { |
385 | .ctl_name = KERN_CORE_USES_PID, | 385 | .ctl_name = KERN_CORE_USES_PID, |
386 | .procname = "core_uses_pid", | 386 | .procname = "core_uses_pid", |
387 | .data = &core_uses_pid, | 387 | .data = &core_uses_pid, |
388 | .maxlen = sizeof(int), | 388 | .maxlen = sizeof(int), |
389 | .mode = 0644, | 389 | .mode = 0644, |
390 | .proc_handler = &proc_dointvec, | 390 | .proc_handler = &proc_dointvec, |
391 | }, | 391 | }, |
392 | #ifdef CONFIG_AUDITSYSCALL | 392 | #ifdef CONFIG_AUDITSYSCALL |
393 | { | 393 | { |
394 | .ctl_name = CTL_UNNUMBERED, | 394 | .ctl_name = CTL_UNNUMBERED, |
395 | .procname = "audit_argv_kb", | 395 | .procname = "audit_argv_kb", |
396 | .data = &audit_argv_kb, | 396 | .data = &audit_argv_kb, |
397 | .maxlen = sizeof(int), | 397 | .maxlen = sizeof(int), |
398 | .mode = 0644, | 398 | .mode = 0644, |
399 | .proc_handler = &proc_dointvec, | 399 | .proc_handler = &proc_dointvec, |
400 | }, | 400 | }, |
401 | #endif | 401 | #endif |
402 | { | 402 | { |
403 | .ctl_name = KERN_CORE_PATTERN, | 403 | .ctl_name = KERN_CORE_PATTERN, |
404 | .procname = "core_pattern", | 404 | .procname = "core_pattern", |
405 | .data = core_pattern, | 405 | .data = core_pattern, |
406 | .maxlen = CORENAME_MAX_SIZE, | 406 | .maxlen = CORENAME_MAX_SIZE, |
407 | .mode = 0644, | 407 | .mode = 0644, |
408 | .proc_handler = &proc_dostring, | 408 | .proc_handler = &proc_dostring, |
409 | .strategy = &sysctl_string, | 409 | .strategy = &sysctl_string, |
410 | }, | 410 | }, |
411 | #ifdef CONFIG_PROC_SYSCTL | 411 | #ifdef CONFIG_PROC_SYSCTL |
412 | { | 412 | { |
413 | .procname = "tainted", | 413 | .procname = "tainted", |
414 | .data = &tainted, | 414 | .data = &tainted, |
415 | .maxlen = sizeof(int), | 415 | .maxlen = sizeof(int), |
416 | .mode = 0644, | 416 | .mode = 0644, |
417 | .proc_handler = &proc_dointvec_taint, | 417 | .proc_handler = &proc_dointvec_taint, |
418 | }, | 418 | }, |
419 | #endif | 419 | #endif |
420 | #ifdef CONFIG_LATENCYTOP | 420 | #ifdef CONFIG_LATENCYTOP |
421 | { | 421 | { |
422 | .procname = "latencytop", | 422 | .procname = "latencytop", |
423 | .data = &latencytop_enabled, | 423 | .data = &latencytop_enabled, |
424 | .maxlen = sizeof(int), | 424 | .maxlen = sizeof(int), |
425 | .mode = 0644, | 425 | .mode = 0644, |
426 | .proc_handler = &proc_dointvec, | 426 | .proc_handler = &proc_dointvec, |
427 | }, | 427 | }, |
428 | #endif | 428 | #endif |
429 | #ifdef CONFIG_SECURITY_CAPABILITIES | 429 | #ifdef CONFIG_SECURITY_CAPABILITIES |
430 | { | 430 | { |
431 | .procname = "cap-bound", | 431 | .procname = "cap-bound", |
432 | .data = &cap_bset, | 432 | .data = &cap_bset, |
433 | .maxlen = sizeof(kernel_cap_t), | 433 | .maxlen = sizeof(kernel_cap_t), |
434 | .mode = 0600, | 434 | .mode = 0600, |
435 | .proc_handler = &proc_dointvec_bset, | 435 | .proc_handler = &proc_dointvec_bset, |
436 | }, | 436 | }, |
437 | #endif /* def CONFIG_SECURITY_CAPABILITIES */ | 437 | #endif /* def CONFIG_SECURITY_CAPABILITIES */ |
438 | #ifdef CONFIG_BLK_DEV_INITRD | 438 | #ifdef CONFIG_BLK_DEV_INITRD |
439 | { | 439 | { |
440 | .ctl_name = KERN_REALROOTDEV, | 440 | .ctl_name = KERN_REALROOTDEV, |
441 | .procname = "real-root-dev", | 441 | .procname = "real-root-dev", |
442 | .data = &real_root_dev, | 442 | .data = &real_root_dev, |
443 | .maxlen = sizeof(int), | 443 | .maxlen = sizeof(int), |
444 | .mode = 0644, | 444 | .mode = 0644, |
445 | .proc_handler = &proc_dointvec, | 445 | .proc_handler = &proc_dointvec, |
446 | }, | 446 | }, |
447 | #endif | 447 | #endif |
448 | { | 448 | { |
449 | .ctl_name = CTL_UNNUMBERED, | 449 | .ctl_name = CTL_UNNUMBERED, |
450 | .procname = "print-fatal-signals", | 450 | .procname = "print-fatal-signals", |
451 | .data = &print_fatal_signals, | 451 | .data = &print_fatal_signals, |
452 | .maxlen = sizeof(int), | 452 | .maxlen = sizeof(int), |
453 | .mode = 0644, | 453 | .mode = 0644, |
454 | .proc_handler = &proc_dointvec, | 454 | .proc_handler = &proc_dointvec, |
455 | }, | 455 | }, |
456 | #ifdef __sparc__ | 456 | #ifdef __sparc__ |
457 | { | 457 | { |
458 | .ctl_name = KERN_SPARC_REBOOT, | 458 | .ctl_name = KERN_SPARC_REBOOT, |
459 | .procname = "reboot-cmd", | 459 | .procname = "reboot-cmd", |
460 | .data = reboot_command, | 460 | .data = reboot_command, |
461 | .maxlen = 256, | 461 | .maxlen = 256, |
462 | .mode = 0644, | 462 | .mode = 0644, |
463 | .proc_handler = &proc_dostring, | 463 | .proc_handler = &proc_dostring, |
464 | .strategy = &sysctl_string, | 464 | .strategy = &sysctl_string, |
465 | }, | 465 | }, |
466 | { | 466 | { |
467 | .ctl_name = KERN_SPARC_STOP_A, | 467 | .ctl_name = KERN_SPARC_STOP_A, |
468 | .procname = "stop-a", | 468 | .procname = "stop-a", |
469 | .data = &stop_a_enabled, | 469 | .data = &stop_a_enabled, |
470 | .maxlen = sizeof (int), | 470 | .maxlen = sizeof (int), |
471 | .mode = 0644, | 471 | .mode = 0644, |
472 | .proc_handler = &proc_dointvec, | 472 | .proc_handler = &proc_dointvec, |
473 | }, | 473 | }, |
474 | { | 474 | { |
475 | .ctl_name = KERN_SPARC_SCONS_PWROFF, | 475 | .ctl_name = KERN_SPARC_SCONS_PWROFF, |
476 | .procname = "scons-poweroff", | 476 | .procname = "scons-poweroff", |
477 | .data = &scons_pwroff, | 477 | .data = &scons_pwroff, |
478 | .maxlen = sizeof (int), | 478 | .maxlen = sizeof (int), |
479 | .mode = 0644, | 479 | .mode = 0644, |
480 | .proc_handler = &proc_dointvec, | 480 | .proc_handler = &proc_dointvec, |
481 | }, | 481 | }, |
482 | #endif | 482 | #endif |
483 | #ifdef __hppa__ | 483 | #ifdef __hppa__ |
484 | { | 484 | { |
485 | .ctl_name = KERN_HPPA_PWRSW, | 485 | .ctl_name = KERN_HPPA_PWRSW, |
486 | .procname = "soft-power", | 486 | .procname = "soft-power", |
487 | .data = &pwrsw_enabled, | 487 | .data = &pwrsw_enabled, |
488 | .maxlen = sizeof (int), | 488 | .maxlen = sizeof (int), |
489 | .mode = 0644, | 489 | .mode = 0644, |
490 | .proc_handler = &proc_dointvec, | 490 | .proc_handler = &proc_dointvec, |
491 | }, | 491 | }, |
492 | { | 492 | { |
493 | .ctl_name = KERN_HPPA_UNALIGNED, | 493 | .ctl_name = KERN_HPPA_UNALIGNED, |
494 | .procname = "unaligned-trap", | 494 | .procname = "unaligned-trap", |
495 | .data = &unaligned_enabled, | 495 | .data = &unaligned_enabled, |
496 | .maxlen = sizeof (int), | 496 | .maxlen = sizeof (int), |
497 | .mode = 0644, | 497 | .mode = 0644, |
498 | .proc_handler = &proc_dointvec, | 498 | .proc_handler = &proc_dointvec, |
499 | }, | 499 | }, |
500 | #endif | 500 | #endif |
501 | { | 501 | { |
502 | .ctl_name = KERN_CTLALTDEL, | 502 | .ctl_name = KERN_CTLALTDEL, |
503 | .procname = "ctrl-alt-del", | 503 | .procname = "ctrl-alt-del", |
504 | .data = &C_A_D, | 504 | .data = &C_A_D, |
505 | .maxlen = sizeof(int), | 505 | .maxlen = sizeof(int), |
506 | .mode = 0644, | 506 | .mode = 0644, |
507 | .proc_handler = &proc_dointvec, | 507 | .proc_handler = &proc_dointvec, |
508 | }, | 508 | }, |
509 | { | 509 | { |
510 | .ctl_name = KERN_PRINTK, | 510 | .ctl_name = KERN_PRINTK, |
511 | .procname = "printk", | 511 | .procname = "printk", |
512 | .data = &console_loglevel, | 512 | .data = &console_loglevel, |
513 | .maxlen = 4*sizeof(int), | 513 | .maxlen = 4*sizeof(int), |
514 | .mode = 0644, | 514 | .mode = 0644, |
515 | .proc_handler = &proc_dointvec, | 515 | .proc_handler = &proc_dointvec, |
516 | }, | 516 | }, |
517 | #ifdef CONFIG_KMOD | 517 | #ifdef CONFIG_KMOD |
518 | { | 518 | { |
519 | .ctl_name = KERN_MODPROBE, | 519 | .ctl_name = KERN_MODPROBE, |
520 | .procname = "modprobe", | 520 | .procname = "modprobe", |
521 | .data = &modprobe_path, | 521 | .data = &modprobe_path, |
522 | .maxlen = KMOD_PATH_LEN, | 522 | .maxlen = KMOD_PATH_LEN, |
523 | .mode = 0644, | 523 | .mode = 0644, |
524 | .proc_handler = &proc_dostring, | 524 | .proc_handler = &proc_dostring, |
525 | .strategy = &sysctl_string, | 525 | .strategy = &sysctl_string, |
526 | }, | 526 | }, |
527 | #endif | 527 | #endif |
528 | #if defined(CONFIG_HOTPLUG) && defined(CONFIG_NET) | 528 | #if defined(CONFIG_HOTPLUG) && defined(CONFIG_NET) |
529 | { | 529 | { |
530 | .ctl_name = KERN_HOTPLUG, | 530 | .ctl_name = KERN_HOTPLUG, |
531 | .procname = "hotplug", | 531 | .procname = "hotplug", |
532 | .data = &uevent_helper, | 532 | .data = &uevent_helper, |
533 | .maxlen = UEVENT_HELPER_PATH_LEN, | 533 | .maxlen = UEVENT_HELPER_PATH_LEN, |
534 | .mode = 0644, | 534 | .mode = 0644, |
535 | .proc_handler = &proc_dostring, | 535 | .proc_handler = &proc_dostring, |
536 | .strategy = &sysctl_string, | 536 | .strategy = &sysctl_string, |
537 | }, | 537 | }, |
538 | #endif | 538 | #endif |
539 | #ifdef CONFIG_CHR_DEV_SG | 539 | #ifdef CONFIG_CHR_DEV_SG |
540 | { | 540 | { |
541 | .ctl_name = KERN_SG_BIG_BUFF, | 541 | .ctl_name = KERN_SG_BIG_BUFF, |
542 | .procname = "sg-big-buff", | 542 | .procname = "sg-big-buff", |
543 | .data = &sg_big_buff, | 543 | .data = &sg_big_buff, |
544 | .maxlen = sizeof (int), | 544 | .maxlen = sizeof (int), |
545 | .mode = 0444, | 545 | .mode = 0444, |
546 | .proc_handler = &proc_dointvec, | 546 | .proc_handler = &proc_dointvec, |
547 | }, | 547 | }, |
548 | #endif | 548 | #endif |
549 | #ifdef CONFIG_BSD_PROCESS_ACCT | 549 | #ifdef CONFIG_BSD_PROCESS_ACCT |
550 | { | 550 | { |
551 | .ctl_name = KERN_ACCT, | 551 | .ctl_name = KERN_ACCT, |
552 | .procname = "acct", | 552 | .procname = "acct", |
553 | .data = &acct_parm, | 553 | .data = &acct_parm, |
554 | .maxlen = 3*sizeof(int), | 554 | .maxlen = 3*sizeof(int), |
555 | .mode = 0644, | 555 | .mode = 0644, |
556 | .proc_handler = &proc_dointvec, | 556 | .proc_handler = &proc_dointvec, |
557 | }, | 557 | }, |
558 | #endif | 558 | #endif |
559 | #ifdef CONFIG_MAGIC_SYSRQ | 559 | #ifdef CONFIG_MAGIC_SYSRQ |
560 | { | 560 | { |
561 | .ctl_name = KERN_SYSRQ, | 561 | .ctl_name = KERN_SYSRQ, |
562 | .procname = "sysrq", | 562 | .procname = "sysrq", |
563 | .data = &__sysrq_enabled, | 563 | .data = &__sysrq_enabled, |
564 | .maxlen = sizeof (int), | 564 | .maxlen = sizeof (int), |
565 | .mode = 0644, | 565 | .mode = 0644, |
566 | .proc_handler = &proc_dointvec, | 566 | .proc_handler = &proc_dointvec, |
567 | }, | 567 | }, |
568 | #endif | 568 | #endif |
569 | #ifdef CONFIG_PROC_SYSCTL | 569 | #ifdef CONFIG_PROC_SYSCTL |
570 | { | 570 | { |
571 | .procname = "cad_pid", | 571 | .procname = "cad_pid", |
572 | .data = NULL, | 572 | .data = NULL, |
573 | .maxlen = sizeof (int), | 573 | .maxlen = sizeof (int), |
574 | .mode = 0600, | 574 | .mode = 0600, |
575 | .proc_handler = &proc_do_cad_pid, | 575 | .proc_handler = &proc_do_cad_pid, |
576 | }, | 576 | }, |
577 | #endif | 577 | #endif |
578 | { | 578 | { |
579 | .ctl_name = KERN_MAX_THREADS, | 579 | .ctl_name = KERN_MAX_THREADS, |
580 | .procname = "threads-max", | 580 | .procname = "threads-max", |
581 | .data = &max_threads, | 581 | .data = &max_threads, |
582 | .maxlen = sizeof(int), | 582 | .maxlen = sizeof(int), |
583 | .mode = 0644, | 583 | .mode = 0644, |
584 | .proc_handler = &proc_dointvec, | 584 | .proc_handler = &proc_dointvec, |
585 | }, | 585 | }, |
586 | { | 586 | { |
587 | .ctl_name = KERN_RANDOM, | 587 | .ctl_name = KERN_RANDOM, |
588 | .procname = "random", | 588 | .procname = "random", |
589 | .mode = 0555, | 589 | .mode = 0555, |
590 | .child = random_table, | 590 | .child = random_table, |
591 | }, | 591 | }, |
592 | { | 592 | { |
593 | .ctl_name = KERN_OVERFLOWUID, | 593 | .ctl_name = KERN_OVERFLOWUID, |
594 | .procname = "overflowuid", | 594 | .procname = "overflowuid", |
595 | .data = &overflowuid, | 595 | .data = &overflowuid, |
596 | .maxlen = sizeof(int), | 596 | .maxlen = sizeof(int), |
597 | .mode = 0644, | 597 | .mode = 0644, |
598 | .proc_handler = &proc_dointvec_minmax, | 598 | .proc_handler = &proc_dointvec_minmax, |
599 | .strategy = &sysctl_intvec, | 599 | .strategy = &sysctl_intvec, |
600 | .extra1 = &minolduid, | 600 | .extra1 = &minolduid, |
601 | .extra2 = &maxolduid, | 601 | .extra2 = &maxolduid, |
602 | }, | 602 | }, |
603 | { | 603 | { |
604 | .ctl_name = KERN_OVERFLOWGID, | 604 | .ctl_name = KERN_OVERFLOWGID, |
605 | .procname = "overflowgid", | 605 | .procname = "overflowgid", |
606 | .data = &overflowgid, | 606 | .data = &overflowgid, |
607 | .maxlen = sizeof(int), | 607 | .maxlen = sizeof(int), |
608 | .mode = 0644, | 608 | .mode = 0644, |
609 | .proc_handler = &proc_dointvec_minmax, | 609 | .proc_handler = &proc_dointvec_minmax, |
610 | .strategy = &sysctl_intvec, | 610 | .strategy = &sysctl_intvec, |
611 | .extra1 = &minolduid, | 611 | .extra1 = &minolduid, |
612 | .extra2 = &maxolduid, | 612 | .extra2 = &maxolduid, |
613 | }, | 613 | }, |
614 | #ifdef CONFIG_S390 | 614 | #ifdef CONFIG_S390 |
615 | #ifdef CONFIG_MATHEMU | 615 | #ifdef CONFIG_MATHEMU |
616 | { | 616 | { |
617 | .ctl_name = KERN_IEEE_EMULATION_WARNINGS, | 617 | .ctl_name = KERN_IEEE_EMULATION_WARNINGS, |
618 | .procname = "ieee_emulation_warnings", | 618 | .procname = "ieee_emulation_warnings", |
619 | .data = &sysctl_ieee_emulation_warnings, | 619 | .data = &sysctl_ieee_emulation_warnings, |
620 | .maxlen = sizeof(int), | 620 | .maxlen = sizeof(int), |
621 | .mode = 0644, | 621 | .mode = 0644, |
622 | .proc_handler = &proc_dointvec, | 622 | .proc_handler = &proc_dointvec, |
623 | }, | 623 | }, |
624 | #endif | 624 | #endif |
625 | #ifdef CONFIG_NO_IDLE_HZ | 625 | #ifdef CONFIG_NO_IDLE_HZ |
626 | { | 626 | { |
627 | .ctl_name = KERN_HZ_TIMER, | 627 | .ctl_name = KERN_HZ_TIMER, |
628 | .procname = "hz_timer", | 628 | .procname = "hz_timer", |
629 | .data = &sysctl_hz_timer, | 629 | .data = &sysctl_hz_timer, |
630 | .maxlen = sizeof(int), | 630 | .maxlen = sizeof(int), |
631 | .mode = 0644, | 631 | .mode = 0644, |
632 | .proc_handler = &proc_dointvec, | 632 | .proc_handler = &proc_dointvec, |
633 | }, | 633 | }, |
634 | #endif | 634 | #endif |
635 | { | 635 | { |
636 | .ctl_name = KERN_S390_USER_DEBUG_LOGGING, | 636 | .ctl_name = KERN_S390_USER_DEBUG_LOGGING, |
637 | .procname = "userprocess_debug", | 637 | .procname = "userprocess_debug", |
638 | .data = &sysctl_userprocess_debug, | 638 | .data = &sysctl_userprocess_debug, |
639 | .maxlen = sizeof(int), | 639 | .maxlen = sizeof(int), |
640 | .mode = 0644, | 640 | .mode = 0644, |
641 | .proc_handler = &proc_dointvec, | 641 | .proc_handler = &proc_dointvec, |
642 | }, | 642 | }, |
643 | #endif | 643 | #endif |
644 | { | 644 | { |
645 | .ctl_name = KERN_PIDMAX, | 645 | .ctl_name = KERN_PIDMAX, |
646 | .procname = "pid_max", | 646 | .procname = "pid_max", |
647 | .data = &pid_max, | 647 | .data = &pid_max, |
648 | .maxlen = sizeof (int), | 648 | .maxlen = sizeof (int), |
649 | .mode = 0644, | 649 | .mode = 0644, |
650 | .proc_handler = &proc_dointvec_minmax, | 650 | .proc_handler = &proc_dointvec_minmax, |
651 | .strategy = sysctl_intvec, | 651 | .strategy = sysctl_intvec, |
652 | .extra1 = &pid_max_min, | 652 | .extra1 = &pid_max_min, |
653 | .extra2 = &pid_max_max, | 653 | .extra2 = &pid_max_max, |
654 | }, | 654 | }, |
655 | { | 655 | { |
656 | .ctl_name = KERN_PANIC_ON_OOPS, | 656 | .ctl_name = KERN_PANIC_ON_OOPS, |
657 | .procname = "panic_on_oops", | 657 | .procname = "panic_on_oops", |
658 | .data = &panic_on_oops, | 658 | .data = &panic_on_oops, |
659 | .maxlen = sizeof(int), | 659 | .maxlen = sizeof(int), |
660 | .mode = 0644, | 660 | .mode = 0644, |
661 | .proc_handler = &proc_dointvec, | 661 | .proc_handler = &proc_dointvec, |
662 | }, | 662 | }, |
663 | { | 663 | { |
664 | .ctl_name = KERN_PRINTK_RATELIMIT, | 664 | .ctl_name = KERN_PRINTK_RATELIMIT, |
665 | .procname = "printk_ratelimit", | 665 | .procname = "printk_ratelimit", |
666 | .data = &printk_ratelimit_jiffies, | 666 | .data = &printk_ratelimit_jiffies, |
667 | .maxlen = sizeof(int), | 667 | .maxlen = sizeof(int), |
668 | .mode = 0644, | 668 | .mode = 0644, |
669 | .proc_handler = &proc_dointvec_jiffies, | 669 | .proc_handler = &proc_dointvec_jiffies, |
670 | .strategy = &sysctl_jiffies, | 670 | .strategy = &sysctl_jiffies, |
671 | }, | 671 | }, |
672 | { | 672 | { |
673 | .ctl_name = KERN_PRINTK_RATELIMIT_BURST, | 673 | .ctl_name = KERN_PRINTK_RATELIMIT_BURST, |
674 | .procname = "printk_ratelimit_burst", | 674 | .procname = "printk_ratelimit_burst", |
675 | .data = &printk_ratelimit_burst, | 675 | .data = &printk_ratelimit_burst, |
676 | .maxlen = sizeof(int), | 676 | .maxlen = sizeof(int), |
677 | .mode = 0644, | 677 | .mode = 0644, |
678 | .proc_handler = &proc_dointvec, | 678 | .proc_handler = &proc_dointvec, |
679 | }, | 679 | }, |
680 | { | 680 | { |
681 | .ctl_name = KERN_NGROUPS_MAX, | 681 | .ctl_name = KERN_NGROUPS_MAX, |
682 | .procname = "ngroups_max", | 682 | .procname = "ngroups_max", |
683 | .data = &ngroups_max, | 683 | .data = &ngroups_max, |
684 | .maxlen = sizeof (int), | 684 | .maxlen = sizeof (int), |
685 | .mode = 0444, | 685 | .mode = 0444, |
686 | .proc_handler = &proc_dointvec, | 686 | .proc_handler = &proc_dointvec, |
687 | }, | 687 | }, |
688 | #if defined(CONFIG_X86_LOCAL_APIC) && defined(CONFIG_X86) | 688 | #if defined(CONFIG_X86_LOCAL_APIC) && defined(CONFIG_X86) |
689 | { | 689 | { |
690 | .ctl_name = KERN_UNKNOWN_NMI_PANIC, | 690 | .ctl_name = KERN_UNKNOWN_NMI_PANIC, |
691 | .procname = "unknown_nmi_panic", | 691 | .procname = "unknown_nmi_panic", |
692 | .data = &unknown_nmi_panic, | 692 | .data = &unknown_nmi_panic, |
693 | .maxlen = sizeof (int), | 693 | .maxlen = sizeof (int), |
694 | .mode = 0644, | 694 | .mode = 0644, |
695 | .proc_handler = &proc_dointvec, | 695 | .proc_handler = &proc_dointvec, |
696 | }, | 696 | }, |
697 | { | 697 | { |
698 | .procname = "nmi_watchdog", | 698 | .procname = "nmi_watchdog", |
699 | .data = &nmi_watchdog_enabled, | 699 | .data = &nmi_watchdog_enabled, |
700 | .maxlen = sizeof (int), | 700 | .maxlen = sizeof (int), |
701 | .mode = 0644, | 701 | .mode = 0644, |
702 | .proc_handler = &proc_nmi_enabled, | 702 | .proc_handler = &proc_nmi_enabled, |
703 | }, | 703 | }, |
704 | #endif | 704 | #endif |
705 | #if defined(CONFIG_X86) | 705 | #if defined(CONFIG_X86) |
706 | { | 706 | { |
707 | .ctl_name = KERN_PANIC_ON_NMI, | 707 | .ctl_name = KERN_PANIC_ON_NMI, |
708 | .procname = "panic_on_unrecovered_nmi", | 708 | .procname = "panic_on_unrecovered_nmi", |
709 | .data = &panic_on_unrecovered_nmi, | 709 | .data = &panic_on_unrecovered_nmi, |
710 | .maxlen = sizeof(int), | 710 | .maxlen = sizeof(int), |
711 | .mode = 0644, | 711 | .mode = 0644, |
712 | .proc_handler = &proc_dointvec, | 712 | .proc_handler = &proc_dointvec, |
713 | }, | 713 | }, |
714 | { | 714 | { |
715 | .ctl_name = KERN_BOOTLOADER_TYPE, | 715 | .ctl_name = KERN_BOOTLOADER_TYPE, |
716 | .procname = "bootloader_type", | 716 | .procname = "bootloader_type", |
717 | .data = &bootloader_type, | 717 | .data = &bootloader_type, |
718 | .maxlen = sizeof (int), | 718 | .maxlen = sizeof (int), |
719 | .mode = 0444, | 719 | .mode = 0444, |
720 | .proc_handler = &proc_dointvec, | 720 | .proc_handler = &proc_dointvec, |
721 | }, | 721 | }, |
722 | { | 722 | { |
723 | .ctl_name = CTL_UNNUMBERED, | 723 | .ctl_name = CTL_UNNUMBERED, |
724 | .procname = "kstack_depth_to_print", | 724 | .procname = "kstack_depth_to_print", |
725 | .data = &kstack_depth_to_print, | 725 | .data = &kstack_depth_to_print, |
726 | .maxlen = sizeof(int), | 726 | .maxlen = sizeof(int), |
727 | .mode = 0644, | 727 | .mode = 0644, |
728 | .proc_handler = &proc_dointvec, | 728 | .proc_handler = &proc_dointvec, |
729 | }, | 729 | }, |
730 | #endif | 730 | #endif |
731 | #if defined(CONFIG_MMU) | 731 | #if defined(CONFIG_MMU) |
732 | { | 732 | { |
733 | .ctl_name = KERN_RANDOMIZE, | 733 | .ctl_name = KERN_RANDOMIZE, |
734 | .procname = "randomize_va_space", | 734 | .procname = "randomize_va_space", |
735 | .data = &randomize_va_space, | 735 | .data = &randomize_va_space, |
736 | .maxlen = sizeof(int), | 736 | .maxlen = sizeof(int), |
737 | .mode = 0644, | 737 | .mode = 0644, |
738 | .proc_handler = &proc_dointvec, | 738 | .proc_handler = &proc_dointvec, |
739 | }, | 739 | }, |
740 | #endif | 740 | #endif |
741 | #if defined(CONFIG_S390) && defined(CONFIG_SMP) | 741 | #if defined(CONFIG_S390) && defined(CONFIG_SMP) |
742 | { | 742 | { |
743 | .ctl_name = KERN_SPIN_RETRY, | 743 | .ctl_name = KERN_SPIN_RETRY, |
744 | .procname = "spin_retry", | 744 | .procname = "spin_retry", |
745 | .data = &spin_retry, | 745 | .data = &spin_retry, |
746 | .maxlen = sizeof (int), | 746 | .maxlen = sizeof (int), |
747 | .mode = 0644, | 747 | .mode = 0644, |
748 | .proc_handler = &proc_dointvec, | 748 | .proc_handler = &proc_dointvec, |
749 | }, | 749 | }, |
750 | #endif | 750 | #endif |
751 | #if defined(CONFIG_ACPI_SLEEP) && defined(CONFIG_X86) | 751 | #if defined(CONFIG_ACPI_SLEEP) && defined(CONFIG_X86) |
752 | { | 752 | { |
753 | .procname = "acpi_video_flags", | 753 | .procname = "acpi_video_flags", |
754 | .data = &acpi_realmode_flags, | 754 | .data = &acpi_realmode_flags, |
755 | .maxlen = sizeof (unsigned long), | 755 | .maxlen = sizeof (unsigned long), |
756 | .mode = 0644, | 756 | .mode = 0644, |
757 | .proc_handler = &proc_doulongvec_minmax, | 757 | .proc_handler = &proc_doulongvec_minmax, |
758 | }, | 758 | }, |
759 | #endif | 759 | #endif |
760 | #ifdef CONFIG_IA64 | 760 | #ifdef CONFIG_IA64 |
761 | { | 761 | { |
762 | .ctl_name = KERN_IA64_UNALIGNED, | 762 | .ctl_name = KERN_IA64_UNALIGNED, |
763 | .procname = "ignore-unaligned-usertrap", | 763 | .procname = "ignore-unaligned-usertrap", |
764 | .data = &no_unaligned_warning, | 764 | .data = &no_unaligned_warning, |
765 | .maxlen = sizeof (int), | 765 | .maxlen = sizeof (int), |
766 | .mode = 0644, | 766 | .mode = 0644, |
767 | .proc_handler = &proc_dointvec, | 767 | .proc_handler = &proc_dointvec, |
768 | }, | 768 | }, |
769 | #endif | 769 | #endif |
770 | #ifdef CONFIG_DETECT_SOFTLOCKUP | 770 | #ifdef CONFIG_DETECT_SOFTLOCKUP |
771 | { | 771 | { |
772 | .ctl_name = CTL_UNNUMBERED, | 772 | .ctl_name = CTL_UNNUMBERED, |
773 | .procname = "softlockup_thresh", | 773 | .procname = "softlockup_thresh", |
774 | .data = &softlockup_thresh, | 774 | .data = &softlockup_thresh, |
775 | .maxlen = sizeof(int), | 775 | .maxlen = sizeof(unsigned long), |
776 | .mode = 0644, | 776 | .mode = 0644, |
777 | .proc_handler = &proc_dointvec_minmax, | 777 | .proc_handler = &proc_doulongvec_minmax, |
778 | .strategy = &sysctl_intvec, | 778 | .strategy = &sysctl_intvec, |
779 | .extra1 = &one, | 779 | .extra1 = &one, |
780 | .extra2 = &sixty, | 780 | .extra2 = &sixty, |
781 | }, | 781 | }, |
782 | { | 782 | { |
783 | .ctl_name = CTL_UNNUMBERED, | 783 | .ctl_name = CTL_UNNUMBERED, |
784 | .procname = "hung_task_check_count", | 784 | .procname = "hung_task_check_count", |
785 | .data = &sysctl_hung_task_check_count, | 785 | .data = &sysctl_hung_task_check_count, |
786 | .maxlen = sizeof(int), | 786 | .maxlen = sizeof(unsigned long), |
787 | .mode = 0644, | 787 | .mode = 0644, |
788 | .proc_handler = &proc_dointvec_minmax, | 788 | .proc_handler = &proc_doulongvec_minmax, |
789 | .strategy = &sysctl_intvec, | 789 | .strategy = &sysctl_intvec, |
790 | }, | 790 | }, |
791 | { | 791 | { |
792 | .ctl_name = CTL_UNNUMBERED, | 792 | .ctl_name = CTL_UNNUMBERED, |
793 | .procname = "hung_task_timeout_secs", | 793 | .procname = "hung_task_timeout_secs", |
794 | .data = &sysctl_hung_task_timeout_secs, | 794 | .data = &sysctl_hung_task_timeout_secs, |
795 | .maxlen = sizeof(int), | 795 | .maxlen = sizeof(unsigned long), |
796 | .mode = 0644, | 796 | .mode = 0644, |
797 | .proc_handler = &proc_dointvec_minmax, | 797 | .proc_handler = &proc_doulongvec_minmax, |
798 | .strategy = &sysctl_intvec, | 798 | .strategy = &sysctl_intvec, |
799 | }, | 799 | }, |
800 | { | 800 | { |
801 | .ctl_name = CTL_UNNUMBERED, | 801 | .ctl_name = CTL_UNNUMBERED, |
802 | .procname = "hung_task_warnings", | 802 | .procname = "hung_task_warnings", |
803 | .data = &sysctl_hung_task_warnings, | 803 | .data = &sysctl_hung_task_warnings, |
804 | .maxlen = sizeof(int), | 804 | .maxlen = sizeof(unsigned long), |
805 | .mode = 0644, | 805 | .mode = 0644, |
806 | .proc_handler = &proc_dointvec_minmax, | 806 | .proc_handler = &proc_doulongvec_minmax, |
807 | .strategy = &sysctl_intvec, | 807 | .strategy = &sysctl_intvec, |
808 | }, | 808 | }, |
809 | #endif | 809 | #endif |
810 | #ifdef CONFIG_COMPAT | 810 | #ifdef CONFIG_COMPAT |
811 | { | 811 | { |
812 | .ctl_name = KERN_COMPAT_LOG, | 812 | .ctl_name = KERN_COMPAT_LOG, |
813 | .procname = "compat-log", | 813 | .procname = "compat-log", |
814 | .data = &compat_log, | 814 | .data = &compat_log, |
815 | .maxlen = sizeof (int), | 815 | .maxlen = sizeof (int), |
816 | .mode = 0644, | 816 | .mode = 0644, |
817 | .proc_handler = &proc_dointvec, | 817 | .proc_handler = &proc_dointvec, |
818 | }, | 818 | }, |
819 | #endif | 819 | #endif |
820 | #ifdef CONFIG_RT_MUTEXES | 820 | #ifdef CONFIG_RT_MUTEXES |
821 | { | 821 | { |
822 | .ctl_name = KERN_MAX_LOCK_DEPTH, | 822 | .ctl_name = KERN_MAX_LOCK_DEPTH, |
823 | .procname = "max_lock_depth", | 823 | .procname = "max_lock_depth", |
824 | .data = &max_lock_depth, | 824 | .data = &max_lock_depth, |
825 | .maxlen = sizeof(int), | 825 | .maxlen = sizeof(int), |
826 | .mode = 0644, | 826 | .mode = 0644, |
827 | .proc_handler = &proc_dointvec, | 827 | .proc_handler = &proc_dointvec, |
828 | }, | 828 | }, |
829 | #endif | 829 | #endif |
830 | #ifdef CONFIG_PROC_FS | 830 | #ifdef CONFIG_PROC_FS |
831 | { | 831 | { |
832 | .ctl_name = CTL_UNNUMBERED, | 832 | .ctl_name = CTL_UNNUMBERED, |
833 | .procname = "maps_protect", | 833 | .procname = "maps_protect", |
834 | .data = &maps_protect, | 834 | .data = &maps_protect, |
835 | .maxlen = sizeof(int), | 835 | .maxlen = sizeof(int), |
836 | .mode = 0644, | 836 | .mode = 0644, |
837 | .proc_handler = &proc_dointvec, | 837 | .proc_handler = &proc_dointvec, |
838 | }, | 838 | }, |
839 | #endif | 839 | #endif |
840 | { | 840 | { |
841 | .ctl_name = CTL_UNNUMBERED, | 841 | .ctl_name = CTL_UNNUMBERED, |
842 | .procname = "poweroff_cmd", | 842 | .procname = "poweroff_cmd", |
843 | .data = &poweroff_cmd, | 843 | .data = &poweroff_cmd, |
844 | .maxlen = POWEROFF_CMD_PATH_LEN, | 844 | .maxlen = POWEROFF_CMD_PATH_LEN, |
845 | .mode = 0644, | 845 | .mode = 0644, |
846 | .proc_handler = &proc_dostring, | 846 | .proc_handler = &proc_dostring, |
847 | .strategy = &sysctl_string, | 847 | .strategy = &sysctl_string, |
848 | }, | 848 | }, |
849 | /* | 849 | /* |
850 | * NOTE: do not add new entries to this table unless you have read | 850 | * NOTE: do not add new entries to this table unless you have read |
851 | * Documentation/sysctl/ctl_unnumbered.txt | 851 | * Documentation/sysctl/ctl_unnumbered.txt |
852 | */ | 852 | */ |
853 | { .ctl_name = 0 } | 853 | { .ctl_name = 0 } |
854 | }; | 854 | }; |
855 | 855 | ||
856 | static struct ctl_table vm_table[] = { | 856 | static struct ctl_table vm_table[] = { |
857 | { | 857 | { |
858 | .ctl_name = VM_OVERCOMMIT_MEMORY, | 858 | .ctl_name = VM_OVERCOMMIT_MEMORY, |
859 | .procname = "overcommit_memory", | 859 | .procname = "overcommit_memory", |
860 | .data = &sysctl_overcommit_memory, | 860 | .data = &sysctl_overcommit_memory, |
861 | .maxlen = sizeof(sysctl_overcommit_memory), | 861 | .maxlen = sizeof(sysctl_overcommit_memory), |
862 | .mode = 0644, | 862 | .mode = 0644, |
863 | .proc_handler = &proc_dointvec, | 863 | .proc_handler = &proc_dointvec, |
864 | }, | 864 | }, |
865 | { | 865 | { |
866 | .ctl_name = VM_PANIC_ON_OOM, | 866 | .ctl_name = VM_PANIC_ON_OOM, |
867 | .procname = "panic_on_oom", | 867 | .procname = "panic_on_oom", |
868 | .data = &sysctl_panic_on_oom, | 868 | .data = &sysctl_panic_on_oom, |
869 | .maxlen = sizeof(sysctl_panic_on_oom), | 869 | .maxlen = sizeof(sysctl_panic_on_oom), |
870 | .mode = 0644, | 870 | .mode = 0644, |
871 | .proc_handler = &proc_dointvec, | 871 | .proc_handler = &proc_dointvec, |
872 | }, | 872 | }, |
873 | { | 873 | { |
874 | .ctl_name = CTL_UNNUMBERED, | 874 | .ctl_name = CTL_UNNUMBERED, |
875 | .procname = "oom_kill_allocating_task", | 875 | .procname = "oom_kill_allocating_task", |
876 | .data = &sysctl_oom_kill_allocating_task, | 876 | .data = &sysctl_oom_kill_allocating_task, |
877 | .maxlen = sizeof(sysctl_oom_kill_allocating_task), | 877 | .maxlen = sizeof(sysctl_oom_kill_allocating_task), |
878 | .mode = 0644, | 878 | .mode = 0644, |
879 | .proc_handler = &proc_dointvec, | 879 | .proc_handler = &proc_dointvec, |
880 | }, | 880 | }, |
881 | { | 881 | { |
882 | .ctl_name = VM_OVERCOMMIT_RATIO, | 882 | .ctl_name = VM_OVERCOMMIT_RATIO, |
883 | .procname = "overcommit_ratio", | 883 | .procname = "overcommit_ratio", |
884 | .data = &sysctl_overcommit_ratio, | 884 | .data = &sysctl_overcommit_ratio, |
885 | .maxlen = sizeof(sysctl_overcommit_ratio), | 885 | .maxlen = sizeof(sysctl_overcommit_ratio), |
886 | .mode = 0644, | 886 | .mode = 0644, |
887 | .proc_handler = &proc_dointvec, | 887 | .proc_handler = &proc_dointvec, |
888 | }, | 888 | }, |
889 | { | 889 | { |
890 | .ctl_name = VM_PAGE_CLUSTER, | 890 | .ctl_name = VM_PAGE_CLUSTER, |
891 | .procname = "page-cluster", | 891 | .procname = "page-cluster", |
892 | .data = &page_cluster, | 892 | .data = &page_cluster, |
893 | .maxlen = sizeof(int), | 893 | .maxlen = sizeof(int), |
894 | .mode = 0644, | 894 | .mode = 0644, |
895 | .proc_handler = &proc_dointvec, | 895 | .proc_handler = &proc_dointvec, |
896 | }, | 896 | }, |
897 | { | 897 | { |
898 | .ctl_name = VM_DIRTY_BACKGROUND, | 898 | .ctl_name = VM_DIRTY_BACKGROUND, |
899 | .procname = "dirty_background_ratio", | 899 | .procname = "dirty_background_ratio", |
900 | .data = &dirty_background_ratio, | 900 | .data = &dirty_background_ratio, |
901 | .maxlen = sizeof(dirty_background_ratio), | 901 | .maxlen = sizeof(dirty_background_ratio), |
902 | .mode = 0644, | 902 | .mode = 0644, |
903 | .proc_handler = &proc_dointvec_minmax, | 903 | .proc_handler = &proc_dointvec_minmax, |
904 | .strategy = &sysctl_intvec, | 904 | .strategy = &sysctl_intvec, |
905 | .extra1 = &zero, | 905 | .extra1 = &zero, |
906 | .extra2 = &one_hundred, | 906 | .extra2 = &one_hundred, |
907 | }, | 907 | }, |
908 | { | 908 | { |
909 | .ctl_name = VM_DIRTY_RATIO, | 909 | .ctl_name = VM_DIRTY_RATIO, |
910 | .procname = "dirty_ratio", | 910 | .procname = "dirty_ratio", |
911 | .data = &vm_dirty_ratio, | 911 | .data = &vm_dirty_ratio, |
912 | .maxlen = sizeof(vm_dirty_ratio), | 912 | .maxlen = sizeof(vm_dirty_ratio), |
913 | .mode = 0644, | 913 | .mode = 0644, |
914 | .proc_handler = &dirty_ratio_handler, | 914 | .proc_handler = &dirty_ratio_handler, |
915 | .strategy = &sysctl_intvec, | 915 | .strategy = &sysctl_intvec, |
916 | .extra1 = &zero, | 916 | .extra1 = &zero, |
917 | .extra2 = &one_hundred, | 917 | .extra2 = &one_hundred, |
918 | }, | 918 | }, |
919 | { | 919 | { |
920 | .procname = "dirty_writeback_centisecs", | 920 | .procname = "dirty_writeback_centisecs", |
921 | .data = &dirty_writeback_interval, | 921 | .data = &dirty_writeback_interval, |
922 | .maxlen = sizeof(dirty_writeback_interval), | 922 | .maxlen = sizeof(dirty_writeback_interval), |
923 | .mode = 0644, | 923 | .mode = 0644, |
924 | .proc_handler = &dirty_writeback_centisecs_handler, | 924 | .proc_handler = &dirty_writeback_centisecs_handler, |
925 | }, | 925 | }, |
926 | { | 926 | { |
927 | .procname = "dirty_expire_centisecs", | 927 | .procname = "dirty_expire_centisecs", |
928 | .data = &dirty_expire_interval, | 928 | .data = &dirty_expire_interval, |
929 | .maxlen = sizeof(dirty_expire_interval), | 929 | .maxlen = sizeof(dirty_expire_interval), |
930 | .mode = 0644, | 930 | .mode = 0644, |
931 | .proc_handler = &proc_dointvec_userhz_jiffies, | 931 | .proc_handler = &proc_dointvec_userhz_jiffies, |
932 | }, | 932 | }, |
933 | { | 933 | { |
934 | .ctl_name = VM_NR_PDFLUSH_THREADS, | 934 | .ctl_name = VM_NR_PDFLUSH_THREADS, |
935 | .procname = "nr_pdflush_threads", | 935 | .procname = "nr_pdflush_threads", |
936 | .data = &nr_pdflush_threads, | 936 | .data = &nr_pdflush_threads, |
937 | .maxlen = sizeof nr_pdflush_threads, | 937 | .maxlen = sizeof nr_pdflush_threads, |
938 | .mode = 0444 /* read-only*/, | 938 | .mode = 0444 /* read-only*/, |
939 | .proc_handler = &proc_dointvec, | 939 | .proc_handler = &proc_dointvec, |
940 | }, | 940 | }, |
941 | { | 941 | { |
942 | .ctl_name = VM_SWAPPINESS, | 942 | .ctl_name = VM_SWAPPINESS, |
943 | .procname = "swappiness", | 943 | .procname = "swappiness", |
944 | .data = &vm_swappiness, | 944 | .data = &vm_swappiness, |
945 | .maxlen = sizeof(vm_swappiness), | 945 | .maxlen = sizeof(vm_swappiness), |
946 | .mode = 0644, | 946 | .mode = 0644, |
947 | .proc_handler = &proc_dointvec_minmax, | 947 | .proc_handler = &proc_dointvec_minmax, |
948 | .strategy = &sysctl_intvec, | 948 | .strategy = &sysctl_intvec, |
949 | .extra1 = &zero, | 949 | .extra1 = &zero, |
950 | .extra2 = &one_hundred, | 950 | .extra2 = &one_hundred, |
951 | }, | 951 | }, |
952 | #ifdef CONFIG_HUGETLB_PAGE | 952 | #ifdef CONFIG_HUGETLB_PAGE |
953 | { | 953 | { |
954 | .procname = "nr_hugepages", | 954 | .procname = "nr_hugepages", |
955 | .data = &max_huge_pages, | 955 | .data = &max_huge_pages, |
956 | .maxlen = sizeof(unsigned long), | 956 | .maxlen = sizeof(unsigned long), |
957 | .mode = 0644, | 957 | .mode = 0644, |
958 | .proc_handler = &hugetlb_sysctl_handler, | 958 | .proc_handler = &hugetlb_sysctl_handler, |
959 | .extra1 = (void *)&hugetlb_zero, | 959 | .extra1 = (void *)&hugetlb_zero, |
960 | .extra2 = (void *)&hugetlb_infinity, | 960 | .extra2 = (void *)&hugetlb_infinity, |
961 | }, | 961 | }, |
962 | { | 962 | { |
963 | .ctl_name = VM_HUGETLB_GROUP, | 963 | .ctl_name = VM_HUGETLB_GROUP, |
964 | .procname = "hugetlb_shm_group", | 964 | .procname = "hugetlb_shm_group", |
965 | .data = &sysctl_hugetlb_shm_group, | 965 | .data = &sysctl_hugetlb_shm_group, |
966 | .maxlen = sizeof(gid_t), | 966 | .maxlen = sizeof(gid_t), |
967 | .mode = 0644, | 967 | .mode = 0644, |
968 | .proc_handler = &proc_dointvec, | 968 | .proc_handler = &proc_dointvec, |
969 | }, | 969 | }, |
970 | { | 970 | { |
971 | .ctl_name = CTL_UNNUMBERED, | 971 | .ctl_name = CTL_UNNUMBERED, |
972 | .procname = "hugepages_treat_as_movable", | 972 | .procname = "hugepages_treat_as_movable", |
973 | .data = &hugepages_treat_as_movable, | 973 | .data = &hugepages_treat_as_movable, |
974 | .maxlen = sizeof(int), | 974 | .maxlen = sizeof(int), |
975 | .mode = 0644, | 975 | .mode = 0644, |
976 | .proc_handler = &hugetlb_treat_movable_handler, | 976 | .proc_handler = &hugetlb_treat_movable_handler, |
977 | }, | 977 | }, |
978 | { | 978 | { |
979 | .ctl_name = CTL_UNNUMBERED, | 979 | .ctl_name = CTL_UNNUMBERED, |
980 | .procname = "nr_overcommit_hugepages", | 980 | .procname = "nr_overcommit_hugepages", |
981 | .data = &nr_overcommit_huge_pages, | 981 | .data = &nr_overcommit_huge_pages, |
982 | .maxlen = sizeof(nr_overcommit_huge_pages), | 982 | .maxlen = sizeof(nr_overcommit_huge_pages), |
983 | .mode = 0644, | 983 | .mode = 0644, |
984 | .proc_handler = &proc_doulongvec_minmax, | 984 | .proc_handler = &proc_doulongvec_minmax, |
985 | }, | 985 | }, |
986 | #endif | 986 | #endif |
987 | { | 987 | { |
988 | .ctl_name = VM_LOWMEM_RESERVE_RATIO, | 988 | .ctl_name = VM_LOWMEM_RESERVE_RATIO, |
989 | .procname = "lowmem_reserve_ratio", | 989 | .procname = "lowmem_reserve_ratio", |
990 | .data = &sysctl_lowmem_reserve_ratio, | 990 | .data = &sysctl_lowmem_reserve_ratio, |
991 | .maxlen = sizeof(sysctl_lowmem_reserve_ratio), | 991 | .maxlen = sizeof(sysctl_lowmem_reserve_ratio), |
992 | .mode = 0644, | 992 | .mode = 0644, |
993 | .proc_handler = &lowmem_reserve_ratio_sysctl_handler, | 993 | .proc_handler = &lowmem_reserve_ratio_sysctl_handler, |
994 | .strategy = &sysctl_intvec, | 994 | .strategy = &sysctl_intvec, |
995 | }, | 995 | }, |
996 | { | 996 | { |
997 | .ctl_name = VM_DROP_PAGECACHE, | 997 | .ctl_name = VM_DROP_PAGECACHE, |
998 | .procname = "drop_caches", | 998 | .procname = "drop_caches", |
999 | .data = &sysctl_drop_caches, | 999 | .data = &sysctl_drop_caches, |
1000 | .maxlen = sizeof(int), | 1000 | .maxlen = sizeof(int), |
1001 | .mode = 0644, | 1001 | .mode = 0644, |
1002 | .proc_handler = drop_caches_sysctl_handler, | 1002 | .proc_handler = drop_caches_sysctl_handler, |
1003 | .strategy = &sysctl_intvec, | 1003 | .strategy = &sysctl_intvec, |
1004 | }, | 1004 | }, |
1005 | { | 1005 | { |
1006 | .ctl_name = VM_MIN_FREE_KBYTES, | 1006 | .ctl_name = VM_MIN_FREE_KBYTES, |
1007 | .procname = "min_free_kbytes", | 1007 | .procname = "min_free_kbytes", |
1008 | .data = &min_free_kbytes, | 1008 | .data = &min_free_kbytes, |
1009 | .maxlen = sizeof(min_free_kbytes), | 1009 | .maxlen = sizeof(min_free_kbytes), |
1010 | .mode = 0644, | 1010 | .mode = 0644, |
1011 | .proc_handler = &min_free_kbytes_sysctl_handler, | 1011 | .proc_handler = &min_free_kbytes_sysctl_handler, |
1012 | .strategy = &sysctl_intvec, | 1012 | .strategy = &sysctl_intvec, |
1013 | .extra1 = &zero, | 1013 | .extra1 = &zero, |
1014 | }, | 1014 | }, |
1015 | { | 1015 | { |
1016 | .ctl_name = VM_PERCPU_PAGELIST_FRACTION, | 1016 | .ctl_name = VM_PERCPU_PAGELIST_FRACTION, |
1017 | .procname = "percpu_pagelist_fraction", | 1017 | .procname = "percpu_pagelist_fraction", |
1018 | .data = &percpu_pagelist_fraction, | 1018 | .data = &percpu_pagelist_fraction, |
1019 | .maxlen = sizeof(percpu_pagelist_fraction), | 1019 | .maxlen = sizeof(percpu_pagelist_fraction), |
1020 | .mode = 0644, | 1020 | .mode = 0644, |
1021 | .proc_handler = &percpu_pagelist_fraction_sysctl_handler, | 1021 | .proc_handler = &percpu_pagelist_fraction_sysctl_handler, |
1022 | .strategy = &sysctl_intvec, | 1022 | .strategy = &sysctl_intvec, |
1023 | .extra1 = &min_percpu_pagelist_fract, | 1023 | .extra1 = &min_percpu_pagelist_fract, |
1024 | }, | 1024 | }, |
1025 | #ifdef CONFIG_MMU | 1025 | #ifdef CONFIG_MMU |
1026 | { | 1026 | { |
1027 | .ctl_name = VM_MAX_MAP_COUNT, | 1027 | .ctl_name = VM_MAX_MAP_COUNT, |
1028 | .procname = "max_map_count", | 1028 | .procname = "max_map_count", |
1029 | .data = &sysctl_max_map_count, | 1029 | .data = &sysctl_max_map_count, |
1030 | .maxlen = sizeof(sysctl_max_map_count), | 1030 | .maxlen = sizeof(sysctl_max_map_count), |
1031 | .mode = 0644, | 1031 | .mode = 0644, |
1032 | .proc_handler = &proc_dointvec | 1032 | .proc_handler = &proc_dointvec |
1033 | }, | 1033 | }, |
1034 | #endif | 1034 | #endif |
1035 | { | 1035 | { |
1036 | .ctl_name = VM_LAPTOP_MODE, | 1036 | .ctl_name = VM_LAPTOP_MODE, |
1037 | .procname = "laptop_mode", | 1037 | .procname = "laptop_mode", |
1038 | .data = &laptop_mode, | 1038 | .data = &laptop_mode, |
1039 | .maxlen = sizeof(laptop_mode), | 1039 | .maxlen = sizeof(laptop_mode), |
1040 | .mode = 0644, | 1040 | .mode = 0644, |
1041 | .proc_handler = &proc_dointvec_jiffies, | 1041 | .proc_handler = &proc_dointvec_jiffies, |
1042 | .strategy = &sysctl_jiffies, | 1042 | .strategy = &sysctl_jiffies, |
1043 | }, | 1043 | }, |
1044 | { | 1044 | { |
1045 | .ctl_name = VM_BLOCK_DUMP, | 1045 | .ctl_name = VM_BLOCK_DUMP, |
1046 | .procname = "block_dump", | 1046 | .procname = "block_dump", |
1047 | .data = &block_dump, | 1047 | .data = &block_dump, |
1048 | .maxlen = sizeof(block_dump), | 1048 | .maxlen = sizeof(block_dump), |
1049 | .mode = 0644, | 1049 | .mode = 0644, |
1050 | .proc_handler = &proc_dointvec, | 1050 | .proc_handler = &proc_dointvec, |
1051 | .strategy = &sysctl_intvec, | 1051 | .strategy = &sysctl_intvec, |
1052 | .extra1 = &zero, | 1052 | .extra1 = &zero, |
1053 | }, | 1053 | }, |
1054 | { | 1054 | { |
1055 | .ctl_name = VM_VFS_CACHE_PRESSURE, | 1055 | .ctl_name = VM_VFS_CACHE_PRESSURE, |
1056 | .procname = "vfs_cache_pressure", | 1056 | .procname = "vfs_cache_pressure", |
1057 | .data = &sysctl_vfs_cache_pressure, | 1057 | .data = &sysctl_vfs_cache_pressure, |
1058 | .maxlen = sizeof(sysctl_vfs_cache_pressure), | 1058 | .maxlen = sizeof(sysctl_vfs_cache_pressure), |
1059 | .mode = 0644, | 1059 | .mode = 0644, |
1060 | .proc_handler = &proc_dointvec, | 1060 | .proc_handler = &proc_dointvec, |
1061 | .strategy = &sysctl_intvec, | 1061 | .strategy = &sysctl_intvec, |
1062 | .extra1 = &zero, | 1062 | .extra1 = &zero, |
1063 | }, | 1063 | }, |
1064 | #ifdef HAVE_ARCH_PICK_MMAP_LAYOUT | 1064 | #ifdef HAVE_ARCH_PICK_MMAP_LAYOUT |
1065 | { | 1065 | { |
1066 | .ctl_name = VM_LEGACY_VA_LAYOUT, | 1066 | .ctl_name = VM_LEGACY_VA_LAYOUT, |
1067 | .procname = "legacy_va_layout", | 1067 | .procname = "legacy_va_layout", |
1068 | .data = &sysctl_legacy_va_layout, | 1068 | .data = &sysctl_legacy_va_layout, |
1069 | .maxlen = sizeof(sysctl_legacy_va_layout), | 1069 | .maxlen = sizeof(sysctl_legacy_va_layout), |
1070 | .mode = 0644, | 1070 | .mode = 0644, |
1071 | .proc_handler = &proc_dointvec, | 1071 | .proc_handler = &proc_dointvec, |
1072 | .strategy = &sysctl_intvec, | 1072 | .strategy = &sysctl_intvec, |
1073 | .extra1 = &zero, | 1073 | .extra1 = &zero, |
1074 | }, | 1074 | }, |
1075 | #endif | 1075 | #endif |
1076 | #ifdef CONFIG_NUMA | 1076 | #ifdef CONFIG_NUMA |
1077 | { | 1077 | { |
1078 | .ctl_name = VM_ZONE_RECLAIM_MODE, | 1078 | .ctl_name = VM_ZONE_RECLAIM_MODE, |
1079 | .procname = "zone_reclaim_mode", | 1079 | .procname = "zone_reclaim_mode", |
1080 | .data = &zone_reclaim_mode, | 1080 | .data = &zone_reclaim_mode, |
1081 | .maxlen = sizeof(zone_reclaim_mode), | 1081 | .maxlen = sizeof(zone_reclaim_mode), |
1082 | .mode = 0644, | 1082 | .mode = 0644, |
1083 | .proc_handler = &proc_dointvec, | 1083 | .proc_handler = &proc_dointvec, |
1084 | .strategy = &sysctl_intvec, | 1084 | .strategy = &sysctl_intvec, |
1085 | .extra1 = &zero, | 1085 | .extra1 = &zero, |
1086 | }, | 1086 | }, |
1087 | { | 1087 | { |
1088 | .ctl_name = VM_MIN_UNMAPPED, | 1088 | .ctl_name = VM_MIN_UNMAPPED, |
1089 | .procname = "min_unmapped_ratio", | 1089 | .procname = "min_unmapped_ratio", |
1090 | .data = &sysctl_min_unmapped_ratio, | 1090 | .data = &sysctl_min_unmapped_ratio, |
1091 | .maxlen = sizeof(sysctl_min_unmapped_ratio), | 1091 | .maxlen = sizeof(sysctl_min_unmapped_ratio), |
1092 | .mode = 0644, | 1092 | .mode = 0644, |
1093 | .proc_handler = &sysctl_min_unmapped_ratio_sysctl_handler, | 1093 | .proc_handler = &sysctl_min_unmapped_ratio_sysctl_handler, |
1094 | .strategy = &sysctl_intvec, | 1094 | .strategy = &sysctl_intvec, |
1095 | .extra1 = &zero, | 1095 | .extra1 = &zero, |
1096 | .extra2 = &one_hundred, | 1096 | .extra2 = &one_hundred, |
1097 | }, | 1097 | }, |
1098 | { | 1098 | { |
1099 | .ctl_name = VM_MIN_SLAB, | 1099 | .ctl_name = VM_MIN_SLAB, |
1100 | .procname = "min_slab_ratio", | 1100 | .procname = "min_slab_ratio", |
1101 | .data = &sysctl_min_slab_ratio, | 1101 | .data = &sysctl_min_slab_ratio, |
1102 | .maxlen = sizeof(sysctl_min_slab_ratio), | 1102 | .maxlen = sizeof(sysctl_min_slab_ratio), |
1103 | .mode = 0644, | 1103 | .mode = 0644, |
1104 | .proc_handler = &sysctl_min_slab_ratio_sysctl_handler, | 1104 | .proc_handler = &sysctl_min_slab_ratio_sysctl_handler, |
1105 | .strategy = &sysctl_intvec, | 1105 | .strategy = &sysctl_intvec, |
1106 | .extra1 = &zero, | 1106 | .extra1 = &zero, |
1107 | .extra2 = &one_hundred, | 1107 | .extra2 = &one_hundred, |
1108 | }, | 1108 | }, |
1109 | #endif | 1109 | #endif |
1110 | #ifdef CONFIG_SMP | 1110 | #ifdef CONFIG_SMP |
1111 | { | 1111 | { |
1112 | .ctl_name = CTL_UNNUMBERED, | 1112 | .ctl_name = CTL_UNNUMBERED, |
1113 | .procname = "stat_interval", | 1113 | .procname = "stat_interval", |
1114 | .data = &sysctl_stat_interval, | 1114 | .data = &sysctl_stat_interval, |
1115 | .maxlen = sizeof(sysctl_stat_interval), | 1115 | .maxlen = sizeof(sysctl_stat_interval), |
1116 | .mode = 0644, | 1116 | .mode = 0644, |
1117 | .proc_handler = &proc_dointvec_jiffies, | 1117 | .proc_handler = &proc_dointvec_jiffies, |
1118 | .strategy = &sysctl_jiffies, | 1118 | .strategy = &sysctl_jiffies, |
1119 | }, | 1119 | }, |
1120 | #endif | 1120 | #endif |
1121 | #ifdef CONFIG_SECURITY | 1121 | #ifdef CONFIG_SECURITY |
1122 | { | 1122 | { |
1123 | .ctl_name = CTL_UNNUMBERED, | 1123 | .ctl_name = CTL_UNNUMBERED, |
1124 | .procname = "mmap_min_addr", | 1124 | .procname = "mmap_min_addr", |
1125 | .data = &mmap_min_addr, | 1125 | .data = &mmap_min_addr, |
1126 | .maxlen = sizeof(unsigned long), | 1126 | .maxlen = sizeof(unsigned long), |
1127 | .mode = 0644, | 1127 | .mode = 0644, |
1128 | .proc_handler = &proc_doulongvec_minmax, | 1128 | .proc_handler = &proc_doulongvec_minmax, |
1129 | }, | 1129 | }, |
1130 | #endif | 1130 | #endif |
1131 | #ifdef CONFIG_NUMA | 1131 | #ifdef CONFIG_NUMA |
1132 | { | 1132 | { |
1133 | .ctl_name = CTL_UNNUMBERED, | 1133 | .ctl_name = CTL_UNNUMBERED, |
1134 | .procname = "numa_zonelist_order", | 1134 | .procname = "numa_zonelist_order", |
1135 | .data = &numa_zonelist_order, | 1135 | .data = &numa_zonelist_order, |
1136 | .maxlen = NUMA_ZONELIST_ORDER_LEN, | 1136 | .maxlen = NUMA_ZONELIST_ORDER_LEN, |
1137 | .mode = 0644, | 1137 | .mode = 0644, |
1138 | .proc_handler = &numa_zonelist_order_handler, | 1138 | .proc_handler = &numa_zonelist_order_handler, |
1139 | .strategy = &sysctl_string, | 1139 | .strategy = &sysctl_string, |
1140 | }, | 1140 | }, |
1141 | #endif | 1141 | #endif |
1142 | #if (defined(CONFIG_X86_32) && !defined(CONFIG_UML))|| \ | 1142 | #if (defined(CONFIG_X86_32) && !defined(CONFIG_UML))|| \ |
1143 | (defined(CONFIG_SUPERH) && defined(CONFIG_VSYSCALL)) | 1143 | (defined(CONFIG_SUPERH) && defined(CONFIG_VSYSCALL)) |
1144 | { | 1144 | { |
1145 | .ctl_name = VM_VDSO_ENABLED, | 1145 | .ctl_name = VM_VDSO_ENABLED, |
1146 | .procname = "vdso_enabled", | 1146 | .procname = "vdso_enabled", |
1147 | .data = &vdso_enabled, | 1147 | .data = &vdso_enabled, |
1148 | .maxlen = sizeof(vdso_enabled), | 1148 | .maxlen = sizeof(vdso_enabled), |
1149 | .mode = 0644, | 1149 | .mode = 0644, |
1150 | .proc_handler = &proc_dointvec, | 1150 | .proc_handler = &proc_dointvec, |
1151 | .strategy = &sysctl_intvec, | 1151 | .strategy = &sysctl_intvec, |
1152 | .extra1 = &zero, | 1152 | .extra1 = &zero, |
1153 | }, | 1153 | }, |
1154 | #endif | 1154 | #endif |
1155 | /* | 1155 | /* |
1156 | * NOTE: do not add new entries to this table unless you have read | 1156 | * NOTE: do not add new entries to this table unless you have read |
1157 | * Documentation/sysctl/ctl_unnumbered.txt | 1157 | * Documentation/sysctl/ctl_unnumbered.txt |
1158 | */ | 1158 | */ |
1159 | { .ctl_name = 0 } | 1159 | { .ctl_name = 0 } |
1160 | }; | 1160 | }; |
1161 | 1161 | ||
1162 | #if defined(CONFIG_BINFMT_MISC) || defined(CONFIG_BINFMT_MISC_MODULE) | 1162 | #if defined(CONFIG_BINFMT_MISC) || defined(CONFIG_BINFMT_MISC_MODULE) |
1163 | static struct ctl_table binfmt_misc_table[] = { | 1163 | static struct ctl_table binfmt_misc_table[] = { |
1164 | { .ctl_name = 0 } | 1164 | { .ctl_name = 0 } |
1165 | }; | 1165 | }; |
1166 | #endif | 1166 | #endif |
1167 | 1167 | ||
1168 | static struct ctl_table fs_table[] = { | 1168 | static struct ctl_table fs_table[] = { |
1169 | { | 1169 | { |
1170 | .ctl_name = FS_NRINODE, | 1170 | .ctl_name = FS_NRINODE, |
1171 | .procname = "inode-nr", | 1171 | .procname = "inode-nr", |
1172 | .data = &inodes_stat, | 1172 | .data = &inodes_stat, |
1173 | .maxlen = 2*sizeof(int), | 1173 | .maxlen = 2*sizeof(int), |
1174 | .mode = 0444, | 1174 | .mode = 0444, |
1175 | .proc_handler = &proc_dointvec, | 1175 | .proc_handler = &proc_dointvec, |
1176 | }, | 1176 | }, |
1177 | { | 1177 | { |
1178 | .ctl_name = FS_STATINODE, | 1178 | .ctl_name = FS_STATINODE, |
1179 | .procname = "inode-state", | 1179 | .procname = "inode-state", |
1180 | .data = &inodes_stat, | 1180 | .data = &inodes_stat, |
1181 | .maxlen = 7*sizeof(int), | 1181 | .maxlen = 7*sizeof(int), |
1182 | .mode = 0444, | 1182 | .mode = 0444, |
1183 | .proc_handler = &proc_dointvec, | 1183 | .proc_handler = &proc_dointvec, |
1184 | }, | 1184 | }, |
1185 | { | 1185 | { |
1186 | .procname = "file-nr", | 1186 | .procname = "file-nr", |
1187 | .data = &files_stat, | 1187 | .data = &files_stat, |
1188 | .maxlen = 3*sizeof(int), | 1188 | .maxlen = 3*sizeof(int), |
1189 | .mode = 0444, | 1189 | .mode = 0444, |
1190 | .proc_handler = &proc_nr_files, | 1190 | .proc_handler = &proc_nr_files, |
1191 | }, | 1191 | }, |
1192 | { | 1192 | { |
1193 | .ctl_name = FS_MAXFILE, | 1193 | .ctl_name = FS_MAXFILE, |
1194 | .procname = "file-max", | 1194 | .procname = "file-max", |
1195 | .data = &files_stat.max_files, | 1195 | .data = &files_stat.max_files, |
1196 | .maxlen = sizeof(int), | 1196 | .maxlen = sizeof(int), |
1197 | .mode = 0644, | 1197 | .mode = 0644, |
1198 | .proc_handler = &proc_dointvec, | 1198 | .proc_handler = &proc_dointvec, |
1199 | }, | 1199 | }, |
1200 | { | 1200 | { |
1201 | .ctl_name = FS_DENTRY, | 1201 | .ctl_name = FS_DENTRY, |
1202 | .procname = "dentry-state", | 1202 | .procname = "dentry-state", |
1203 | .data = &dentry_stat, | 1203 | .data = &dentry_stat, |
1204 | .maxlen = 6*sizeof(int), | 1204 | .maxlen = 6*sizeof(int), |
1205 | .mode = 0444, | 1205 | .mode = 0444, |
1206 | .proc_handler = &proc_dointvec, | 1206 | .proc_handler = &proc_dointvec, |
1207 | }, | 1207 | }, |
1208 | { | 1208 | { |
1209 | .ctl_name = FS_OVERFLOWUID, | 1209 | .ctl_name = FS_OVERFLOWUID, |
1210 | .procname = "overflowuid", | 1210 | .procname = "overflowuid", |
1211 | .data = &fs_overflowuid, | 1211 | .data = &fs_overflowuid, |
1212 | .maxlen = sizeof(int), | 1212 | .maxlen = sizeof(int), |
1213 | .mode = 0644, | 1213 | .mode = 0644, |
1214 | .proc_handler = &proc_dointvec_minmax, | 1214 | .proc_handler = &proc_dointvec_minmax, |
1215 | .strategy = &sysctl_intvec, | 1215 | .strategy = &sysctl_intvec, |
1216 | .extra1 = &minolduid, | 1216 | .extra1 = &minolduid, |
1217 | .extra2 = &maxolduid, | 1217 | .extra2 = &maxolduid, |
1218 | }, | 1218 | }, |
1219 | { | 1219 | { |
1220 | .ctl_name = FS_OVERFLOWGID, | 1220 | .ctl_name = FS_OVERFLOWGID, |
1221 | .procname = "overflowgid", | 1221 | .procname = "overflowgid", |
1222 | .data = &fs_overflowgid, | 1222 | .data = &fs_overflowgid, |
1223 | .maxlen = sizeof(int), | 1223 | .maxlen = sizeof(int), |
1224 | .mode = 0644, | 1224 | .mode = 0644, |
1225 | .proc_handler = &proc_dointvec_minmax, | 1225 | .proc_handler = &proc_dointvec_minmax, |
1226 | .strategy = &sysctl_intvec, | 1226 | .strategy = &sysctl_intvec, |
1227 | .extra1 = &minolduid, | 1227 | .extra1 = &minolduid, |
1228 | .extra2 = &maxolduid, | 1228 | .extra2 = &maxolduid, |
1229 | }, | 1229 | }, |
1230 | { | 1230 | { |
1231 | .ctl_name = FS_LEASES, | 1231 | .ctl_name = FS_LEASES, |
1232 | .procname = "leases-enable", | 1232 | .procname = "leases-enable", |
1233 | .data = &leases_enable, | 1233 | .data = &leases_enable, |
1234 | .maxlen = sizeof(int), | 1234 | .maxlen = sizeof(int), |
1235 | .mode = 0644, | 1235 | .mode = 0644, |
1236 | .proc_handler = &proc_dointvec, | 1236 | .proc_handler = &proc_dointvec, |
1237 | }, | 1237 | }, |
1238 | #ifdef CONFIG_DNOTIFY | 1238 | #ifdef CONFIG_DNOTIFY |
1239 | { | 1239 | { |
1240 | .ctl_name = FS_DIR_NOTIFY, | 1240 | .ctl_name = FS_DIR_NOTIFY, |
1241 | .procname = "dir-notify-enable", | 1241 | .procname = "dir-notify-enable", |
1242 | .data = &dir_notify_enable, | 1242 | .data = &dir_notify_enable, |
1243 | .maxlen = sizeof(int), | 1243 | .maxlen = sizeof(int), |
1244 | .mode = 0644, | 1244 | .mode = 0644, |
1245 | .proc_handler = &proc_dointvec, | 1245 | .proc_handler = &proc_dointvec, |
1246 | }, | 1246 | }, |
1247 | #endif | 1247 | #endif |
1248 | #ifdef CONFIG_MMU | 1248 | #ifdef CONFIG_MMU |
1249 | { | 1249 | { |
1250 | .ctl_name = FS_LEASE_TIME, | 1250 | .ctl_name = FS_LEASE_TIME, |
1251 | .procname = "lease-break-time", | 1251 | .procname = "lease-break-time", |
1252 | .data = &lease_break_time, | 1252 | .data = &lease_break_time, |
1253 | .maxlen = sizeof(int), | 1253 | .maxlen = sizeof(int), |
1254 | .mode = 0644, | 1254 | .mode = 0644, |
1255 | .proc_handler = &proc_dointvec_minmax, | 1255 | .proc_handler = &proc_dointvec_minmax, |
1256 | .strategy = &sysctl_intvec, | 1256 | .strategy = &sysctl_intvec, |
1257 | .extra1 = &zero, | 1257 | .extra1 = &zero, |
1258 | .extra2 = &two, | 1258 | .extra2 = &two, |
1259 | }, | 1259 | }, |
1260 | { | 1260 | { |
1261 | .procname = "aio-nr", | 1261 | .procname = "aio-nr", |
1262 | .data = &aio_nr, | 1262 | .data = &aio_nr, |
1263 | .maxlen = sizeof(aio_nr), | 1263 | .maxlen = sizeof(aio_nr), |
1264 | .mode = 0444, | 1264 | .mode = 0444, |
1265 | .proc_handler = &proc_doulongvec_minmax, | 1265 | .proc_handler = &proc_doulongvec_minmax, |
1266 | }, | 1266 | }, |
1267 | { | 1267 | { |
1268 | .procname = "aio-max-nr", | 1268 | .procname = "aio-max-nr", |
1269 | .data = &aio_max_nr, | 1269 | .data = &aio_max_nr, |
1270 | .maxlen = sizeof(aio_max_nr), | 1270 | .maxlen = sizeof(aio_max_nr), |
1271 | .mode = 0644, | 1271 | .mode = 0644, |
1272 | .proc_handler = &proc_doulongvec_minmax, | 1272 | .proc_handler = &proc_doulongvec_minmax, |
1273 | }, | 1273 | }, |
1274 | #ifdef CONFIG_INOTIFY_USER | 1274 | #ifdef CONFIG_INOTIFY_USER |
1275 | { | 1275 | { |
1276 | .ctl_name = FS_INOTIFY, | 1276 | .ctl_name = FS_INOTIFY, |
1277 | .procname = "inotify", | 1277 | .procname = "inotify", |
1278 | .mode = 0555, | 1278 | .mode = 0555, |
1279 | .child = inotify_table, | 1279 | .child = inotify_table, |
1280 | }, | 1280 | }, |
1281 | #endif | 1281 | #endif |
1282 | #endif | 1282 | #endif |
1283 | { | 1283 | { |
1284 | .ctl_name = KERN_SETUID_DUMPABLE, | 1284 | .ctl_name = KERN_SETUID_DUMPABLE, |
1285 | .procname = "suid_dumpable", | 1285 | .procname = "suid_dumpable", |
1286 | .data = &suid_dumpable, | 1286 | .data = &suid_dumpable, |
1287 | .maxlen = sizeof(int), | 1287 | .maxlen = sizeof(int), |
1288 | .mode = 0644, | 1288 | .mode = 0644, |
1289 | .proc_handler = &proc_dointvec, | 1289 | .proc_handler = &proc_dointvec, |
1290 | }, | 1290 | }, |
1291 | #if defined(CONFIG_BINFMT_MISC) || defined(CONFIG_BINFMT_MISC_MODULE) | 1291 | #if defined(CONFIG_BINFMT_MISC) || defined(CONFIG_BINFMT_MISC_MODULE) |
1292 | { | 1292 | { |
1293 | .ctl_name = CTL_UNNUMBERED, | 1293 | .ctl_name = CTL_UNNUMBERED, |
1294 | .procname = "binfmt_misc", | 1294 | .procname = "binfmt_misc", |
1295 | .mode = 0555, | 1295 | .mode = 0555, |
1296 | .child = binfmt_misc_table, | 1296 | .child = binfmt_misc_table, |
1297 | }, | 1297 | }, |
1298 | #endif | 1298 | #endif |
1299 | /* | 1299 | /* |
1300 | * NOTE: do not add new entries to this table unless you have read | 1300 | * NOTE: do not add new entries to this table unless you have read |
1301 | * Documentation/sysctl/ctl_unnumbered.txt | 1301 | * Documentation/sysctl/ctl_unnumbered.txt |
1302 | */ | 1302 | */ |
1303 | { .ctl_name = 0 } | 1303 | { .ctl_name = 0 } |
1304 | }; | 1304 | }; |
1305 | 1305 | ||
1306 | static struct ctl_table debug_table[] = { | 1306 | static struct ctl_table debug_table[] = { |
1307 | #if defined(CONFIG_X86) || defined(CONFIG_PPC) | 1307 | #if defined(CONFIG_X86) || defined(CONFIG_PPC) |
1308 | { | 1308 | { |
1309 | .ctl_name = CTL_UNNUMBERED, | 1309 | .ctl_name = CTL_UNNUMBERED, |
1310 | .procname = "exception-trace", | 1310 | .procname = "exception-trace", |
1311 | .data = &show_unhandled_signals, | 1311 | .data = &show_unhandled_signals, |
1312 | .maxlen = sizeof(int), | 1312 | .maxlen = sizeof(int), |
1313 | .mode = 0644, | 1313 | .mode = 0644, |
1314 | .proc_handler = proc_dointvec | 1314 | .proc_handler = proc_dointvec |
1315 | }, | 1315 | }, |
1316 | #endif | 1316 | #endif |
1317 | { .ctl_name = 0 } | 1317 | { .ctl_name = 0 } |
1318 | }; | 1318 | }; |
1319 | 1319 | ||
1320 | static struct ctl_table dev_table[] = { | 1320 | static struct ctl_table dev_table[] = { |
1321 | { .ctl_name = 0 } | 1321 | { .ctl_name = 0 } |
1322 | }; | 1322 | }; |
1323 | 1323 | ||
1324 | static DEFINE_SPINLOCK(sysctl_lock); | 1324 | static DEFINE_SPINLOCK(sysctl_lock); |
1325 | 1325 | ||
1326 | /* called under sysctl_lock */ | 1326 | /* called under sysctl_lock */ |
1327 | static int use_table(struct ctl_table_header *p) | 1327 | static int use_table(struct ctl_table_header *p) |
1328 | { | 1328 | { |
1329 | if (unlikely(p->unregistering)) | 1329 | if (unlikely(p->unregistering)) |
1330 | return 0; | 1330 | return 0; |
1331 | p->used++; | 1331 | p->used++; |
1332 | return 1; | 1332 | return 1; |
1333 | } | 1333 | } |
1334 | 1334 | ||
1335 | /* called under sysctl_lock */ | 1335 | /* called under sysctl_lock */ |
1336 | static void unuse_table(struct ctl_table_header *p) | 1336 | static void unuse_table(struct ctl_table_header *p) |
1337 | { | 1337 | { |
1338 | if (!--p->used) | 1338 | if (!--p->used) |
1339 | if (unlikely(p->unregistering)) | 1339 | if (unlikely(p->unregistering)) |
1340 | complete(p->unregistering); | 1340 | complete(p->unregistering); |
1341 | } | 1341 | } |
1342 | 1342 | ||
1343 | /* called under sysctl_lock, will reacquire if has to wait */ | 1343 | /* called under sysctl_lock, will reacquire if has to wait */ |
1344 | static void start_unregistering(struct ctl_table_header *p) | 1344 | static void start_unregistering(struct ctl_table_header *p) |
1345 | { | 1345 | { |
1346 | /* | 1346 | /* |
1347 | * if p->used is 0, nobody will ever touch that entry again; | 1347 | * if p->used is 0, nobody will ever touch that entry again; |
1348 | * we'll eliminate all paths to it before dropping sysctl_lock | 1348 | * we'll eliminate all paths to it before dropping sysctl_lock |
1349 | */ | 1349 | */ |
1350 | if (unlikely(p->used)) { | 1350 | if (unlikely(p->used)) { |
1351 | struct completion wait; | 1351 | struct completion wait; |
1352 | init_completion(&wait); | 1352 | init_completion(&wait); |
1353 | p->unregistering = &wait; | 1353 | p->unregistering = &wait; |
1354 | spin_unlock(&sysctl_lock); | 1354 | spin_unlock(&sysctl_lock); |
1355 | wait_for_completion(&wait); | 1355 | wait_for_completion(&wait); |
1356 | spin_lock(&sysctl_lock); | 1356 | spin_lock(&sysctl_lock); |
1357 | } | 1357 | } |
1358 | /* | 1358 | /* |
1359 | * do not remove from the list until nobody holds it; walking the | 1359 | * do not remove from the list until nobody holds it; walking the |
1360 | * list in do_sysctl() relies on that. | 1360 | * list in do_sysctl() relies on that. |
1361 | */ | 1361 | */ |
1362 | list_del_init(&p->ctl_entry); | 1362 | list_del_init(&p->ctl_entry); |
1363 | } | 1363 | } |
1364 | 1364 | ||
1365 | void sysctl_head_finish(struct ctl_table_header *head) | 1365 | void sysctl_head_finish(struct ctl_table_header *head) |
1366 | { | 1366 | { |
1367 | if (!head) | 1367 | if (!head) |
1368 | return; | 1368 | return; |
1369 | spin_lock(&sysctl_lock); | 1369 | spin_lock(&sysctl_lock); |
1370 | unuse_table(head); | 1370 | unuse_table(head); |
1371 | spin_unlock(&sysctl_lock); | 1371 | spin_unlock(&sysctl_lock); |
1372 | } | 1372 | } |
1373 | 1373 | ||
1374 | struct ctl_table_header *sysctl_head_next(struct ctl_table_header *prev) | 1374 | struct ctl_table_header *sysctl_head_next(struct ctl_table_header *prev) |
1375 | { | 1375 | { |
1376 | struct ctl_table_header *head; | 1376 | struct ctl_table_header *head; |
1377 | struct list_head *tmp; | 1377 | struct list_head *tmp; |
1378 | spin_lock(&sysctl_lock); | 1378 | spin_lock(&sysctl_lock); |
1379 | if (prev) { | 1379 | if (prev) { |
1380 | tmp = &prev->ctl_entry; | 1380 | tmp = &prev->ctl_entry; |
1381 | unuse_table(prev); | 1381 | unuse_table(prev); |
1382 | goto next; | 1382 | goto next; |
1383 | } | 1383 | } |
1384 | tmp = &root_table_header.ctl_entry; | 1384 | tmp = &root_table_header.ctl_entry; |
1385 | for (;;) { | 1385 | for (;;) { |
1386 | head = list_entry(tmp, struct ctl_table_header, ctl_entry); | 1386 | head = list_entry(tmp, struct ctl_table_header, ctl_entry); |
1387 | 1387 | ||
1388 | if (!use_table(head)) | 1388 | if (!use_table(head)) |
1389 | goto next; | 1389 | goto next; |
1390 | spin_unlock(&sysctl_lock); | 1390 | spin_unlock(&sysctl_lock); |
1391 | return head; | 1391 | return head; |
1392 | next: | 1392 | next: |
1393 | tmp = tmp->next; | 1393 | tmp = tmp->next; |
1394 | if (tmp == &root_table_header.ctl_entry) | 1394 | if (tmp == &root_table_header.ctl_entry) |
1395 | break; | 1395 | break; |
1396 | } | 1396 | } |
1397 | spin_unlock(&sysctl_lock); | 1397 | spin_unlock(&sysctl_lock); |
1398 | return NULL; | 1398 | return NULL; |
1399 | } | 1399 | } |
1400 | 1400 | ||
1401 | #ifdef CONFIG_SYSCTL_SYSCALL | 1401 | #ifdef CONFIG_SYSCTL_SYSCALL |
1402 | int do_sysctl(int __user *name, int nlen, void __user *oldval, size_t __user *oldlenp, | 1402 | int do_sysctl(int __user *name, int nlen, void __user *oldval, size_t __user *oldlenp, |
1403 | void __user *newval, size_t newlen) | 1403 | void __user *newval, size_t newlen) |
1404 | { | 1404 | { |
1405 | struct ctl_table_header *head; | 1405 | struct ctl_table_header *head; |
1406 | int error = -ENOTDIR; | 1406 | int error = -ENOTDIR; |
1407 | 1407 | ||
1408 | if (nlen <= 0 || nlen >= CTL_MAXNAME) | 1408 | if (nlen <= 0 || nlen >= CTL_MAXNAME) |
1409 | return -ENOTDIR; | 1409 | return -ENOTDIR; |
1410 | if (oldval) { | 1410 | if (oldval) { |
1411 | int old_len; | 1411 | int old_len; |
1412 | if (!oldlenp || get_user(old_len, oldlenp)) | 1412 | if (!oldlenp || get_user(old_len, oldlenp)) |
1413 | return -EFAULT; | 1413 | return -EFAULT; |
1414 | } | 1414 | } |
1415 | 1415 | ||
1416 | for (head = sysctl_head_next(NULL); head; | 1416 | for (head = sysctl_head_next(NULL); head; |
1417 | head = sysctl_head_next(head)) { | 1417 | head = sysctl_head_next(head)) { |
1418 | error = parse_table(name, nlen, oldval, oldlenp, | 1418 | error = parse_table(name, nlen, oldval, oldlenp, |
1419 | newval, newlen, head->ctl_table); | 1419 | newval, newlen, head->ctl_table); |
1420 | if (error != -ENOTDIR) { | 1420 | if (error != -ENOTDIR) { |
1421 | sysctl_head_finish(head); | 1421 | sysctl_head_finish(head); |
1422 | break; | 1422 | break; |
1423 | } | 1423 | } |
1424 | } | 1424 | } |
1425 | return error; | 1425 | return error; |
1426 | } | 1426 | } |
1427 | 1427 | ||
1428 | asmlinkage long sys_sysctl(struct __sysctl_args __user *args) | 1428 | asmlinkage long sys_sysctl(struct __sysctl_args __user *args) |
1429 | { | 1429 | { |
1430 | struct __sysctl_args tmp; | 1430 | struct __sysctl_args tmp; |
1431 | int error; | 1431 | int error; |
1432 | 1432 | ||
1433 | if (copy_from_user(&tmp, args, sizeof(tmp))) | 1433 | if (copy_from_user(&tmp, args, sizeof(tmp))) |
1434 | return -EFAULT; | 1434 | return -EFAULT; |
1435 | 1435 | ||
1436 | error = deprecated_sysctl_warning(&tmp); | 1436 | error = deprecated_sysctl_warning(&tmp); |
1437 | if (error) | 1437 | if (error) |
1438 | goto out; | 1438 | goto out; |
1439 | 1439 | ||
1440 | lock_kernel(); | 1440 | lock_kernel(); |
1441 | error = do_sysctl(tmp.name, tmp.nlen, tmp.oldval, tmp.oldlenp, | 1441 | error = do_sysctl(tmp.name, tmp.nlen, tmp.oldval, tmp.oldlenp, |
1442 | tmp.newval, tmp.newlen); | 1442 | tmp.newval, tmp.newlen); |
1443 | unlock_kernel(); | 1443 | unlock_kernel(); |
1444 | out: | 1444 | out: |
1445 | return error; | 1445 | return error; |
1446 | } | 1446 | } |
1447 | #endif /* CONFIG_SYSCTL_SYSCALL */ | 1447 | #endif /* CONFIG_SYSCTL_SYSCALL */ |
1448 | 1448 | ||
1449 | /* | 1449 | /* |
1450 | * sysctl_perm does NOT grant the superuser all rights automatically, because | 1450 | * sysctl_perm does NOT grant the superuser all rights automatically, because |
1451 | * some sysctl variables are readonly even to root. | 1451 | * some sysctl variables are readonly even to root. |
1452 | */ | 1452 | */ |
1453 | 1453 | ||
1454 | static int test_perm(int mode, int op) | 1454 | static int test_perm(int mode, int op) |
1455 | { | 1455 | { |
1456 | if (!current->euid) | 1456 | if (!current->euid) |
1457 | mode >>= 6; | 1457 | mode >>= 6; |
1458 | else if (in_egroup_p(0)) | 1458 | else if (in_egroup_p(0)) |
1459 | mode >>= 3; | 1459 | mode >>= 3; |
1460 | if ((mode & op & 0007) == op) | 1460 | if ((mode & op & 0007) == op) |
1461 | return 0; | 1461 | return 0; |
1462 | return -EACCES; | 1462 | return -EACCES; |
1463 | } | 1463 | } |
1464 | 1464 | ||
1465 | int sysctl_perm(struct ctl_table *table, int op) | 1465 | int sysctl_perm(struct ctl_table *table, int op) |
1466 | { | 1466 | { |
1467 | int error; | 1467 | int error; |
1468 | error = security_sysctl(table, op); | 1468 | error = security_sysctl(table, op); |
1469 | if (error) | 1469 | if (error) |
1470 | return error; | 1470 | return error; |
1471 | return test_perm(table->mode, op); | 1471 | return test_perm(table->mode, op); |
1472 | } | 1472 | } |
1473 | 1473 | ||
1474 | #ifdef CONFIG_SYSCTL_SYSCALL | 1474 | #ifdef CONFIG_SYSCTL_SYSCALL |
1475 | static int parse_table(int __user *name, int nlen, | 1475 | static int parse_table(int __user *name, int nlen, |
1476 | void __user *oldval, size_t __user *oldlenp, | 1476 | void __user *oldval, size_t __user *oldlenp, |
1477 | void __user *newval, size_t newlen, | 1477 | void __user *newval, size_t newlen, |
1478 | struct ctl_table *table) | 1478 | struct ctl_table *table) |
1479 | { | 1479 | { |
1480 | int n; | 1480 | int n; |
1481 | repeat: | 1481 | repeat: |
1482 | if (!nlen) | 1482 | if (!nlen) |
1483 | return -ENOTDIR; | 1483 | return -ENOTDIR; |
1484 | if (get_user(n, name)) | 1484 | if (get_user(n, name)) |
1485 | return -EFAULT; | 1485 | return -EFAULT; |
1486 | for ( ; table->ctl_name || table->procname; table++) { | 1486 | for ( ; table->ctl_name || table->procname; table++) { |
1487 | if (!table->ctl_name) | 1487 | if (!table->ctl_name) |
1488 | continue; | 1488 | continue; |
1489 | if (n == table->ctl_name) { | 1489 | if (n == table->ctl_name) { |
1490 | int error; | 1490 | int error; |
1491 | if (table->child) { | 1491 | if (table->child) { |
1492 | if (sysctl_perm(table, 001)) | 1492 | if (sysctl_perm(table, 001)) |
1493 | return -EPERM; | 1493 | return -EPERM; |
1494 | name++; | 1494 | name++; |
1495 | nlen--; | 1495 | nlen--; |
1496 | table = table->child; | 1496 | table = table->child; |
1497 | goto repeat; | 1497 | goto repeat; |
1498 | } | 1498 | } |
1499 | error = do_sysctl_strategy(table, name, nlen, | 1499 | error = do_sysctl_strategy(table, name, nlen, |
1500 | oldval, oldlenp, | 1500 | oldval, oldlenp, |
1501 | newval, newlen); | 1501 | newval, newlen); |
1502 | return error; | 1502 | return error; |
1503 | } | 1503 | } |
1504 | } | 1504 | } |
1505 | return -ENOTDIR; | 1505 | return -ENOTDIR; |
1506 | } | 1506 | } |
1507 | 1507 | ||
1508 | /* Perform the actual read/write of a sysctl table entry. */ | 1508 | /* Perform the actual read/write of a sysctl table entry. */ |
1509 | int do_sysctl_strategy (struct ctl_table *table, | 1509 | int do_sysctl_strategy (struct ctl_table *table, |
1510 | int __user *name, int nlen, | 1510 | int __user *name, int nlen, |
1511 | void __user *oldval, size_t __user *oldlenp, | 1511 | void __user *oldval, size_t __user *oldlenp, |
1512 | void __user *newval, size_t newlen) | 1512 | void __user *newval, size_t newlen) |
1513 | { | 1513 | { |
1514 | int op = 0, rc; | 1514 | int op = 0, rc; |
1515 | 1515 | ||
1516 | if (oldval) | 1516 | if (oldval) |
1517 | op |= 004; | 1517 | op |= 004; |
1518 | if (newval) | 1518 | if (newval) |
1519 | op |= 002; | 1519 | op |= 002; |
1520 | if (sysctl_perm(table, op)) | 1520 | if (sysctl_perm(table, op)) |
1521 | return -EPERM; | 1521 | return -EPERM; |
1522 | 1522 | ||
1523 | if (table->strategy) { | 1523 | if (table->strategy) { |
1524 | rc = table->strategy(table, name, nlen, oldval, oldlenp, | 1524 | rc = table->strategy(table, name, nlen, oldval, oldlenp, |
1525 | newval, newlen); | 1525 | newval, newlen); |
1526 | if (rc < 0) | 1526 | if (rc < 0) |
1527 | return rc; | 1527 | return rc; |
1528 | if (rc > 0) | 1528 | if (rc > 0) |
1529 | return 0; | 1529 | return 0; |
1530 | } | 1530 | } |
1531 | 1531 | ||
1532 | /* If there is no strategy routine, or if the strategy returns | 1532 | /* If there is no strategy routine, or if the strategy returns |
1533 | * zero, proceed with automatic r/w */ | 1533 | * zero, proceed with automatic r/w */ |
1534 | if (table->data && table->maxlen) { | 1534 | if (table->data && table->maxlen) { |
1535 | rc = sysctl_data(table, name, nlen, oldval, oldlenp, | 1535 | rc = sysctl_data(table, name, nlen, oldval, oldlenp, |
1536 | newval, newlen); | 1536 | newval, newlen); |
1537 | if (rc < 0) | 1537 | if (rc < 0) |
1538 | return rc; | 1538 | return rc; |
1539 | } | 1539 | } |
1540 | return 0; | 1540 | return 0; |
1541 | } | 1541 | } |
1542 | #endif /* CONFIG_SYSCTL_SYSCALL */ | 1542 | #endif /* CONFIG_SYSCTL_SYSCALL */ |
1543 | 1543 | ||
1544 | static void sysctl_set_parent(struct ctl_table *parent, struct ctl_table *table) | 1544 | static void sysctl_set_parent(struct ctl_table *parent, struct ctl_table *table) |
1545 | { | 1545 | { |
1546 | for (; table->ctl_name || table->procname; table++) { | 1546 | for (; table->ctl_name || table->procname; table++) { |
1547 | table->parent = parent; | 1547 | table->parent = parent; |
1548 | if (table->child) | 1548 | if (table->child) |
1549 | sysctl_set_parent(table, table->child); | 1549 | sysctl_set_parent(table, table->child); |
1550 | } | 1550 | } |
1551 | } | 1551 | } |
1552 | 1552 | ||
1553 | static __init int sysctl_init(void) | 1553 | static __init int sysctl_init(void) |
1554 | { | 1554 | { |
1555 | int err; | 1555 | int err; |
1556 | sysctl_set_parent(NULL, root_table); | 1556 | sysctl_set_parent(NULL, root_table); |
1557 | err = sysctl_check_table(root_table); | 1557 | err = sysctl_check_table(root_table); |
1558 | return 0; | 1558 | return 0; |
1559 | } | 1559 | } |
1560 | 1560 | ||
1561 | core_initcall(sysctl_init); | 1561 | core_initcall(sysctl_init); |
1562 | 1562 | ||
1563 | /** | 1563 | /** |
1564 | * register_sysctl_table - register a sysctl hierarchy | 1564 | * register_sysctl_table - register a sysctl hierarchy |
1565 | * @table: the top-level table structure | 1565 | * @table: the top-level table structure |
1566 | * | 1566 | * |
1567 | * Register a sysctl table hierarchy. @table should be a filled in ctl_table | 1567 | * Register a sysctl table hierarchy. @table should be a filled in ctl_table |
1568 | * array. An entry with a ctl_name of 0 terminates the table. | 1568 | * array. An entry with a ctl_name of 0 terminates the table. |
1569 | * | 1569 | * |
1570 | * The members of the &struct ctl_table structure are used as follows: | 1570 | * The members of the &struct ctl_table structure are used as follows: |
1571 | * | 1571 | * |
1572 | * ctl_name - This is the numeric sysctl value used by sysctl(2). The number | 1572 | * ctl_name - This is the numeric sysctl value used by sysctl(2). The number |
1573 | * must be unique within that level of sysctl | 1573 | * must be unique within that level of sysctl |
1574 | * | 1574 | * |
1575 | * procname - the name of the sysctl file under /proc/sys. Set to %NULL to not | 1575 | * procname - the name of the sysctl file under /proc/sys. Set to %NULL to not |
1576 | * enter a sysctl file | 1576 | * enter a sysctl file |
1577 | * | 1577 | * |
1578 | * data - a pointer to data for use by proc_handler | 1578 | * data - a pointer to data for use by proc_handler |
1579 | * | 1579 | * |
1580 | * maxlen - the maximum size in bytes of the data | 1580 | * maxlen - the maximum size in bytes of the data |
1581 | * | 1581 | * |
1582 | * mode - the file permissions for the /proc/sys file, and for sysctl(2) | 1582 | * mode - the file permissions for the /proc/sys file, and for sysctl(2) |
1583 | * | 1583 | * |
1584 | * child - a pointer to the child sysctl table if this entry is a directory, or | 1584 | * child - a pointer to the child sysctl table if this entry is a directory, or |
1585 | * %NULL. | 1585 | * %NULL. |
1586 | * | 1586 | * |
1587 | * proc_handler - the text handler routine (described below) | 1587 | * proc_handler - the text handler routine (described below) |
1588 | * | 1588 | * |
1589 | * strategy - the strategy routine (described below) | 1589 | * strategy - the strategy routine (described below) |
1590 | * | 1590 | * |
1591 | * de - for internal use by the sysctl routines | 1591 | * de - for internal use by the sysctl routines |
1592 | * | 1592 | * |
1593 | * extra1, extra2 - extra pointers usable by the proc handler routines | 1593 | * extra1, extra2 - extra pointers usable by the proc handler routines |
1594 | * | 1594 | * |
1595 | * Leaf nodes in the sysctl tree will be represented by a single file | 1595 | * Leaf nodes in the sysctl tree will be represented by a single file |
1596 | * under /proc; non-leaf nodes will be represented by directories. | 1596 | * under /proc; non-leaf nodes will be represented by directories. |
1597 | * | 1597 | * |
1598 | * sysctl(2) can automatically manage read and write requests through | 1598 | * sysctl(2) can automatically manage read and write requests through |
1599 | * the sysctl table. The data and maxlen fields of the ctl_table | 1599 | * the sysctl table. The data and maxlen fields of the ctl_table |
1600 | * struct enable minimal validation of the values being written to be | 1600 | * struct enable minimal validation of the values being written to be |
1601 | * performed, and the mode field allows minimal authentication. | 1601 | * performed, and the mode field allows minimal authentication. |
1602 | * | 1602 | * |
1603 | * More sophisticated management can be enabled by the provision of a | 1603 | * More sophisticated management can be enabled by the provision of a |
1604 | * strategy routine with the table entry. This will be called before | 1604 | * strategy routine with the table entry. This will be called before |
1605 | * any automatic read or write of the data is performed. | 1605 | * any automatic read or write of the data is performed. |
1606 | * | 1606 | * |
1607 | * The strategy routine may return | 1607 | * The strategy routine may return |
1608 | * | 1608 | * |
1609 | * < 0 - Error occurred (error is passed to user process) | 1609 | * < 0 - Error occurred (error is passed to user process) |
1610 | * | 1610 | * |
1611 | * 0 - OK - proceed with automatic read or write. | 1611 | * 0 - OK - proceed with automatic read or write. |
1612 | * | 1612 | * |
1613 | * > 0 - OK - read or write has been done by the strategy routine, so | 1613 | * > 0 - OK - read or write has been done by the strategy routine, so |
1614 | * return immediately. | 1614 | * return immediately. |
1615 | * | 1615 | * |
1616 | * There must be a proc_handler routine for any terminal nodes | 1616 | * There must be a proc_handler routine for any terminal nodes |
1617 | * mirrored under /proc/sys (non-terminals are handled by a built-in | 1617 | * mirrored under /proc/sys (non-terminals are handled by a built-in |
1618 | * directory handler). Several default handlers are available to | 1618 | * directory handler). Several default handlers are available to |
1619 | * cover common cases - | 1619 | * cover common cases - |
1620 | * | 1620 | * |
1621 | * proc_dostring(), proc_dointvec(), proc_dointvec_jiffies(), | 1621 | * proc_dostring(), proc_dointvec(), proc_dointvec_jiffies(), |
1622 | * proc_dointvec_userhz_jiffies(), proc_dointvec_minmax(), | 1622 | * proc_dointvec_userhz_jiffies(), proc_dointvec_minmax(), |
1623 | * proc_doulongvec_ms_jiffies_minmax(), proc_doulongvec_minmax() | 1623 | * proc_doulongvec_ms_jiffies_minmax(), proc_doulongvec_minmax() |
1624 | * | 1624 | * |
1625 | * It is the handler's job to read the input buffer from user memory | 1625 | * It is the handler's job to read the input buffer from user memory |
1626 | * and process it. The handler should return 0 on success. | 1626 | * and process it. The handler should return 0 on success. |
1627 | * | 1627 | * |
1628 | * This routine returns %NULL on a failure to register, and a pointer | 1628 | * This routine returns %NULL on a failure to register, and a pointer |
1629 | * to the table header on success. | 1629 | * to the table header on success. |
1630 | */ | 1630 | */ |
1631 | struct ctl_table_header *register_sysctl_table(struct ctl_table * table) | 1631 | struct ctl_table_header *register_sysctl_table(struct ctl_table * table) |
1632 | { | 1632 | { |
1633 | struct ctl_table_header *tmp; | 1633 | struct ctl_table_header *tmp; |
1634 | tmp = kmalloc(sizeof(struct ctl_table_header), GFP_KERNEL); | 1634 | tmp = kmalloc(sizeof(struct ctl_table_header), GFP_KERNEL); |
1635 | if (!tmp) | 1635 | if (!tmp) |
1636 | return NULL; | 1636 | return NULL; |
1637 | tmp->ctl_table = table; | 1637 | tmp->ctl_table = table; |
1638 | INIT_LIST_HEAD(&tmp->ctl_entry); | 1638 | INIT_LIST_HEAD(&tmp->ctl_entry); |
1639 | tmp->used = 0; | 1639 | tmp->used = 0; |
1640 | tmp->unregistering = NULL; | 1640 | tmp->unregistering = NULL; |
1641 | sysctl_set_parent(NULL, table); | 1641 | sysctl_set_parent(NULL, table); |
1642 | if (sysctl_check_table(tmp->ctl_table)) { | 1642 | if (sysctl_check_table(tmp->ctl_table)) { |
1643 | kfree(tmp); | 1643 | kfree(tmp); |
1644 | return NULL; | 1644 | return NULL; |
1645 | } | 1645 | } |
1646 | spin_lock(&sysctl_lock); | 1646 | spin_lock(&sysctl_lock); |
1647 | list_add_tail(&tmp->ctl_entry, &root_table_header.ctl_entry); | 1647 | list_add_tail(&tmp->ctl_entry, &root_table_header.ctl_entry); |
1648 | spin_unlock(&sysctl_lock); | 1648 | spin_unlock(&sysctl_lock); |
1649 | return tmp; | 1649 | return tmp; |
1650 | } | 1650 | } |
1651 | 1651 | ||
1652 | /** | 1652 | /** |
1653 | * unregister_sysctl_table - unregister a sysctl table hierarchy | 1653 | * unregister_sysctl_table - unregister a sysctl table hierarchy |
1654 | * @header: the header returned from register_sysctl_table | 1654 | * @header: the header returned from register_sysctl_table |
1655 | * | 1655 | * |
1656 | * Unregisters the sysctl table and all children. proc entries may not | 1656 | * Unregisters the sysctl table and all children. proc entries may not |
1657 | * actually be removed until they are no longer used by anyone. | 1657 | * actually be removed until they are no longer used by anyone. |
1658 | */ | 1658 | */ |
1659 | void unregister_sysctl_table(struct ctl_table_header * header) | 1659 | void unregister_sysctl_table(struct ctl_table_header * header) |
1660 | { | 1660 | { |
1661 | might_sleep(); | 1661 | might_sleep(); |
1662 | 1662 | ||
1663 | if (header == NULL) | 1663 | if (header == NULL) |
1664 | return; | 1664 | return; |
1665 | 1665 | ||
1666 | spin_lock(&sysctl_lock); | 1666 | spin_lock(&sysctl_lock); |
1667 | start_unregistering(header); | 1667 | start_unregistering(header); |
1668 | spin_unlock(&sysctl_lock); | 1668 | spin_unlock(&sysctl_lock); |
1669 | kfree(header); | 1669 | kfree(header); |
1670 | } | 1670 | } |
1671 | 1671 | ||
1672 | #else /* !CONFIG_SYSCTL */ | 1672 | #else /* !CONFIG_SYSCTL */ |
1673 | struct ctl_table_header *register_sysctl_table(struct ctl_table * table) | 1673 | struct ctl_table_header *register_sysctl_table(struct ctl_table * table) |
1674 | { | 1674 | { |
1675 | return NULL; | 1675 | return NULL; |
1676 | } | 1676 | } |
1677 | 1677 | ||
1678 | void unregister_sysctl_table(struct ctl_table_header * table) | 1678 | void unregister_sysctl_table(struct ctl_table_header * table) |
1679 | { | 1679 | { |
1680 | } | 1680 | } |
1681 | 1681 | ||
1682 | #endif /* CONFIG_SYSCTL */ | 1682 | #endif /* CONFIG_SYSCTL */ |
1683 | 1683 | ||
1684 | /* | 1684 | /* |
1685 | * /proc/sys support | 1685 | * /proc/sys support |
1686 | */ | 1686 | */ |
1687 | 1687 | ||
1688 | #ifdef CONFIG_PROC_SYSCTL | 1688 | #ifdef CONFIG_PROC_SYSCTL |
1689 | 1689 | ||
1690 | static int _proc_do_string(void* data, int maxlen, int write, | 1690 | static int _proc_do_string(void* data, int maxlen, int write, |
1691 | struct file *filp, void __user *buffer, | 1691 | struct file *filp, void __user *buffer, |
1692 | size_t *lenp, loff_t *ppos) | 1692 | size_t *lenp, loff_t *ppos) |
1693 | { | 1693 | { |
1694 | size_t len; | 1694 | size_t len; |
1695 | char __user *p; | 1695 | char __user *p; |
1696 | char c; | 1696 | char c; |
1697 | 1697 | ||
1698 | if (!data || !maxlen || !*lenp) { | 1698 | if (!data || !maxlen || !*lenp) { |
1699 | *lenp = 0; | 1699 | *lenp = 0; |
1700 | return 0; | 1700 | return 0; |
1701 | } | 1701 | } |
1702 | 1702 | ||
1703 | if (write) { | 1703 | if (write) { |
1704 | len = 0; | 1704 | len = 0; |
1705 | p = buffer; | 1705 | p = buffer; |
1706 | while (len < *lenp) { | 1706 | while (len < *lenp) { |
1707 | if (get_user(c, p++)) | 1707 | if (get_user(c, p++)) |
1708 | return -EFAULT; | 1708 | return -EFAULT; |
1709 | if (c == 0 || c == '\n') | 1709 | if (c == 0 || c == '\n') |
1710 | break; | 1710 | break; |
1711 | len++; | 1711 | len++; |
1712 | } | 1712 | } |
1713 | if (len >= maxlen) | 1713 | if (len >= maxlen) |
1714 | len = maxlen-1; | 1714 | len = maxlen-1; |
1715 | if(copy_from_user(data, buffer, len)) | 1715 | if(copy_from_user(data, buffer, len)) |
1716 | return -EFAULT; | 1716 | return -EFAULT; |
1717 | ((char *) data)[len] = 0; | 1717 | ((char *) data)[len] = 0; |
1718 | *ppos += *lenp; | 1718 | *ppos += *lenp; |
1719 | } else { | 1719 | } else { |
1720 | len = strlen(data); | 1720 | len = strlen(data); |
1721 | if (len > maxlen) | 1721 | if (len > maxlen) |
1722 | len = maxlen; | 1722 | len = maxlen; |
1723 | 1723 | ||
1724 | if (*ppos > len) { | 1724 | if (*ppos > len) { |
1725 | *lenp = 0; | 1725 | *lenp = 0; |
1726 | return 0; | 1726 | return 0; |
1727 | } | 1727 | } |
1728 | 1728 | ||
1729 | data += *ppos; | 1729 | data += *ppos; |
1730 | len -= *ppos; | 1730 | len -= *ppos; |
1731 | 1731 | ||
1732 | if (len > *lenp) | 1732 | if (len > *lenp) |
1733 | len = *lenp; | 1733 | len = *lenp; |
1734 | if (len) | 1734 | if (len) |
1735 | if(copy_to_user(buffer, data, len)) | 1735 | if(copy_to_user(buffer, data, len)) |
1736 | return -EFAULT; | 1736 | return -EFAULT; |
1737 | if (len < *lenp) { | 1737 | if (len < *lenp) { |
1738 | if(put_user('\n', ((char __user *) buffer) + len)) | 1738 | if(put_user('\n', ((char __user *) buffer) + len)) |
1739 | return -EFAULT; | 1739 | return -EFAULT; |
1740 | len++; | 1740 | len++; |
1741 | } | 1741 | } |
1742 | *lenp = len; | 1742 | *lenp = len; |
1743 | *ppos += len; | 1743 | *ppos += len; |
1744 | } | 1744 | } |
1745 | return 0; | 1745 | return 0; |
1746 | } | 1746 | } |
1747 | 1747 | ||
1748 | /** | 1748 | /** |
1749 | * proc_dostring - read a string sysctl | 1749 | * proc_dostring - read a string sysctl |
1750 | * @table: the sysctl table | 1750 | * @table: the sysctl table |
1751 | * @write: %TRUE if this is a write to the sysctl file | 1751 | * @write: %TRUE if this is a write to the sysctl file |
1752 | * @filp: the file structure | 1752 | * @filp: the file structure |
1753 | * @buffer: the user buffer | 1753 | * @buffer: the user buffer |
1754 | * @lenp: the size of the user buffer | 1754 | * @lenp: the size of the user buffer |
1755 | * @ppos: file position | 1755 | * @ppos: file position |
1756 | * | 1756 | * |
1757 | * Reads/writes a string from/to the user buffer. If the kernel | 1757 | * Reads/writes a string from/to the user buffer. If the kernel |
1758 | * buffer provided is not large enough to hold the string, the | 1758 | * buffer provided is not large enough to hold the string, the |
1759 | * string is truncated. The copied string is %NULL-terminated. | 1759 | * string is truncated. The copied string is %NULL-terminated. |
1760 | * If the string is being read by the user process, it is copied | 1760 | * If the string is being read by the user process, it is copied |
1761 | * and a newline '\n' is added. It is truncated if the buffer is | 1761 | * and a newline '\n' is added. It is truncated if the buffer is |
1762 | * not large enough. | 1762 | * not large enough. |
1763 | * | 1763 | * |
1764 | * Returns 0 on success. | 1764 | * Returns 0 on success. |
1765 | */ | 1765 | */ |
1766 | int proc_dostring(struct ctl_table *table, int write, struct file *filp, | 1766 | int proc_dostring(struct ctl_table *table, int write, struct file *filp, |
1767 | void __user *buffer, size_t *lenp, loff_t *ppos) | 1767 | void __user *buffer, size_t *lenp, loff_t *ppos) |
1768 | { | 1768 | { |
1769 | return _proc_do_string(table->data, table->maxlen, write, filp, | 1769 | return _proc_do_string(table->data, table->maxlen, write, filp, |
1770 | buffer, lenp, ppos); | 1770 | buffer, lenp, ppos); |
1771 | } | 1771 | } |
1772 | 1772 | ||
1773 | 1773 | ||
1774 | static int do_proc_dointvec_conv(int *negp, unsigned long *lvalp, | 1774 | static int do_proc_dointvec_conv(int *negp, unsigned long *lvalp, |
1775 | int *valp, | 1775 | int *valp, |
1776 | int write, void *data) | 1776 | int write, void *data) |
1777 | { | 1777 | { |
1778 | if (write) { | 1778 | if (write) { |
1779 | *valp = *negp ? -*lvalp : *lvalp; | 1779 | *valp = *negp ? -*lvalp : *lvalp; |
1780 | } else { | 1780 | } else { |
1781 | int val = *valp; | 1781 | int val = *valp; |
1782 | if (val < 0) { | 1782 | if (val < 0) { |
1783 | *negp = -1; | 1783 | *negp = -1; |
1784 | *lvalp = (unsigned long)-val; | 1784 | *lvalp = (unsigned long)-val; |
1785 | } else { | 1785 | } else { |
1786 | *negp = 0; | 1786 | *negp = 0; |
1787 | *lvalp = (unsigned long)val; | 1787 | *lvalp = (unsigned long)val; |
1788 | } | 1788 | } |
1789 | } | 1789 | } |
1790 | return 0; | 1790 | return 0; |
1791 | } | 1791 | } |
1792 | 1792 | ||
1793 | static int __do_proc_dointvec(void *tbl_data, struct ctl_table *table, | 1793 | static int __do_proc_dointvec(void *tbl_data, struct ctl_table *table, |
1794 | int write, struct file *filp, void __user *buffer, | 1794 | int write, struct file *filp, void __user *buffer, |
1795 | size_t *lenp, loff_t *ppos, | 1795 | size_t *lenp, loff_t *ppos, |
1796 | int (*conv)(int *negp, unsigned long *lvalp, int *valp, | 1796 | int (*conv)(int *negp, unsigned long *lvalp, int *valp, |
1797 | int write, void *data), | 1797 | int write, void *data), |
1798 | void *data) | 1798 | void *data) |
1799 | { | 1799 | { |
1800 | #define TMPBUFLEN 21 | 1800 | #define TMPBUFLEN 21 |
1801 | int *i, vleft, first=1, neg, val; | 1801 | int *i, vleft, first=1, neg, val; |
1802 | unsigned long lval; | 1802 | unsigned long lval; |
1803 | size_t left, len; | 1803 | size_t left, len; |
1804 | 1804 | ||
1805 | char buf[TMPBUFLEN], *p; | 1805 | char buf[TMPBUFLEN], *p; |
1806 | char __user *s = buffer; | 1806 | char __user *s = buffer; |
1807 | 1807 | ||
1808 | if (!tbl_data || !table->maxlen || !*lenp || | 1808 | if (!tbl_data || !table->maxlen || !*lenp || |
1809 | (*ppos && !write)) { | 1809 | (*ppos && !write)) { |
1810 | *lenp = 0; | 1810 | *lenp = 0; |
1811 | return 0; | 1811 | return 0; |
1812 | } | 1812 | } |
1813 | 1813 | ||
1814 | i = (int *) tbl_data; | 1814 | i = (int *) tbl_data; |
1815 | vleft = table->maxlen / sizeof(*i); | 1815 | vleft = table->maxlen / sizeof(*i); |
1816 | left = *lenp; | 1816 | left = *lenp; |
1817 | 1817 | ||
1818 | if (!conv) | 1818 | if (!conv) |
1819 | conv = do_proc_dointvec_conv; | 1819 | conv = do_proc_dointvec_conv; |
1820 | 1820 | ||
1821 | for (; left && vleft--; i++, first=0) { | 1821 | for (; left && vleft--; i++, first=0) { |
1822 | if (write) { | 1822 | if (write) { |
1823 | while (left) { | 1823 | while (left) { |
1824 | char c; | 1824 | char c; |
1825 | if (get_user(c, s)) | 1825 | if (get_user(c, s)) |
1826 | return -EFAULT; | 1826 | return -EFAULT; |
1827 | if (!isspace(c)) | 1827 | if (!isspace(c)) |
1828 | break; | 1828 | break; |
1829 | left--; | 1829 | left--; |
1830 | s++; | 1830 | s++; |
1831 | } | 1831 | } |
1832 | if (!left) | 1832 | if (!left) |
1833 | break; | 1833 | break; |
1834 | neg = 0; | 1834 | neg = 0; |
1835 | len = left; | 1835 | len = left; |
1836 | if (len > sizeof(buf) - 1) | 1836 | if (len > sizeof(buf) - 1) |
1837 | len = sizeof(buf) - 1; | 1837 | len = sizeof(buf) - 1; |
1838 | if (copy_from_user(buf, s, len)) | 1838 | if (copy_from_user(buf, s, len)) |
1839 | return -EFAULT; | 1839 | return -EFAULT; |
1840 | buf[len] = 0; | 1840 | buf[len] = 0; |
1841 | p = buf; | 1841 | p = buf; |
1842 | if (*p == '-' && left > 1) { | 1842 | if (*p == '-' && left > 1) { |
1843 | neg = 1; | 1843 | neg = 1; |
1844 | p++; | 1844 | p++; |
1845 | } | 1845 | } |
1846 | if (*p < '0' || *p > '9') | 1846 | if (*p < '0' || *p > '9') |
1847 | break; | 1847 | break; |
1848 | 1848 | ||
1849 | lval = simple_strtoul(p, &p, 0); | 1849 | lval = simple_strtoul(p, &p, 0); |
1850 | 1850 | ||
1851 | len = p-buf; | 1851 | len = p-buf; |
1852 | if ((len < left) && *p && !isspace(*p)) | 1852 | if ((len < left) && *p && !isspace(*p)) |
1853 | break; | 1853 | break; |
1854 | if (neg) | 1854 | if (neg) |
1855 | val = -val; | 1855 | val = -val; |
1856 | s += len; | 1856 | s += len; |
1857 | left -= len; | 1857 | left -= len; |
1858 | 1858 | ||
1859 | if (conv(&neg, &lval, i, 1, data)) | 1859 | if (conv(&neg, &lval, i, 1, data)) |
1860 | break; | 1860 | break; |
1861 | } else { | 1861 | } else { |
1862 | p = buf; | 1862 | p = buf; |
1863 | if (!first) | 1863 | if (!first) |
1864 | *p++ = '\t'; | 1864 | *p++ = '\t'; |
1865 | 1865 | ||
1866 | if (conv(&neg, &lval, i, 0, data)) | 1866 | if (conv(&neg, &lval, i, 0, data)) |
1867 | break; | 1867 | break; |
1868 | 1868 | ||
1869 | sprintf(p, "%s%lu", neg ? "-" : "", lval); | 1869 | sprintf(p, "%s%lu", neg ? "-" : "", lval); |
1870 | len = strlen(buf); | 1870 | len = strlen(buf); |
1871 | if (len > left) | 1871 | if (len > left) |
1872 | len = left; | 1872 | len = left; |
1873 | if(copy_to_user(s, buf, len)) | 1873 | if(copy_to_user(s, buf, len)) |
1874 | return -EFAULT; | 1874 | return -EFAULT; |
1875 | left -= len; | 1875 | left -= len; |
1876 | s += len; | 1876 | s += len; |
1877 | } | 1877 | } |
1878 | } | 1878 | } |
1879 | 1879 | ||
1880 | if (!write && !first && left) { | 1880 | if (!write && !first && left) { |
1881 | if(put_user('\n', s)) | 1881 | if(put_user('\n', s)) |
1882 | return -EFAULT; | 1882 | return -EFAULT; |
1883 | left--, s++; | 1883 | left--, s++; |
1884 | } | 1884 | } |
1885 | if (write) { | 1885 | if (write) { |
1886 | while (left) { | 1886 | while (left) { |
1887 | char c; | 1887 | char c; |
1888 | if (get_user(c, s++)) | 1888 | if (get_user(c, s++)) |
1889 | return -EFAULT; | 1889 | return -EFAULT; |
1890 | if (!isspace(c)) | 1890 | if (!isspace(c)) |
1891 | break; | 1891 | break; |
1892 | left--; | 1892 | left--; |
1893 | } | 1893 | } |
1894 | } | 1894 | } |
1895 | if (write && first) | 1895 | if (write && first) |
1896 | return -EINVAL; | 1896 | return -EINVAL; |
1897 | *lenp -= left; | 1897 | *lenp -= left; |
1898 | *ppos += *lenp; | 1898 | *ppos += *lenp; |
1899 | return 0; | 1899 | return 0; |
1900 | #undef TMPBUFLEN | 1900 | #undef TMPBUFLEN |
1901 | } | 1901 | } |
1902 | 1902 | ||
1903 | static int do_proc_dointvec(struct ctl_table *table, int write, struct file *filp, | 1903 | static int do_proc_dointvec(struct ctl_table *table, int write, struct file *filp, |
1904 | void __user *buffer, size_t *lenp, loff_t *ppos, | 1904 | void __user *buffer, size_t *lenp, loff_t *ppos, |
1905 | int (*conv)(int *negp, unsigned long *lvalp, int *valp, | 1905 | int (*conv)(int *negp, unsigned long *lvalp, int *valp, |
1906 | int write, void *data), | 1906 | int write, void *data), |
1907 | void *data) | 1907 | void *data) |
1908 | { | 1908 | { |
1909 | return __do_proc_dointvec(table->data, table, write, filp, | 1909 | return __do_proc_dointvec(table->data, table, write, filp, |
1910 | buffer, lenp, ppos, conv, data); | 1910 | buffer, lenp, ppos, conv, data); |
1911 | } | 1911 | } |
1912 | 1912 | ||
1913 | /** | 1913 | /** |
1914 | * proc_dointvec - read a vector of integers | 1914 | * proc_dointvec - read a vector of integers |
1915 | * @table: the sysctl table | 1915 | * @table: the sysctl table |
1916 | * @write: %TRUE if this is a write to the sysctl file | 1916 | * @write: %TRUE if this is a write to the sysctl file |
1917 | * @filp: the file structure | 1917 | * @filp: the file structure |
1918 | * @buffer: the user buffer | 1918 | * @buffer: the user buffer |
1919 | * @lenp: the size of the user buffer | 1919 | * @lenp: the size of the user buffer |
1920 | * @ppos: file position | 1920 | * @ppos: file position |
1921 | * | 1921 | * |
1922 | * Reads/writes up to table->maxlen/sizeof(unsigned int) integer | 1922 | * Reads/writes up to table->maxlen/sizeof(unsigned int) integer |
1923 | * values from/to the user buffer, treated as an ASCII string. | 1923 | * values from/to the user buffer, treated as an ASCII string. |
1924 | * | 1924 | * |
1925 | * Returns 0 on success. | 1925 | * Returns 0 on success. |
1926 | */ | 1926 | */ |
1927 | int proc_dointvec(struct ctl_table *table, int write, struct file *filp, | 1927 | int proc_dointvec(struct ctl_table *table, int write, struct file *filp, |
1928 | void __user *buffer, size_t *lenp, loff_t *ppos) | 1928 | void __user *buffer, size_t *lenp, loff_t *ppos) |
1929 | { | 1929 | { |
1930 | return do_proc_dointvec(table,write,filp,buffer,lenp,ppos, | 1930 | return do_proc_dointvec(table,write,filp,buffer,lenp,ppos, |
1931 | NULL,NULL); | 1931 | NULL,NULL); |
1932 | } | 1932 | } |
1933 | 1933 | ||
1934 | #define OP_SET 0 | 1934 | #define OP_SET 0 |
1935 | #define OP_AND 1 | 1935 | #define OP_AND 1 |
1936 | #define OP_OR 2 | 1936 | #define OP_OR 2 |
1937 | 1937 | ||
1938 | static int do_proc_dointvec_bset_conv(int *negp, unsigned long *lvalp, | 1938 | static int do_proc_dointvec_bset_conv(int *negp, unsigned long *lvalp, |
1939 | int *valp, | 1939 | int *valp, |
1940 | int write, void *data) | 1940 | int write, void *data) |
1941 | { | 1941 | { |
1942 | int op = *(int *)data; | 1942 | int op = *(int *)data; |
1943 | if (write) { | 1943 | if (write) { |
1944 | int val = *negp ? -*lvalp : *lvalp; | 1944 | int val = *negp ? -*lvalp : *lvalp; |
1945 | switch(op) { | 1945 | switch(op) { |
1946 | case OP_SET: *valp = val; break; | 1946 | case OP_SET: *valp = val; break; |
1947 | case OP_AND: *valp &= val; break; | 1947 | case OP_AND: *valp &= val; break; |
1948 | case OP_OR: *valp |= val; break; | 1948 | case OP_OR: *valp |= val; break; |
1949 | } | 1949 | } |
1950 | } else { | 1950 | } else { |
1951 | int val = *valp; | 1951 | int val = *valp; |
1952 | if (val < 0) { | 1952 | if (val < 0) { |
1953 | *negp = -1; | 1953 | *negp = -1; |
1954 | *lvalp = (unsigned long)-val; | 1954 | *lvalp = (unsigned long)-val; |
1955 | } else { | 1955 | } else { |
1956 | *negp = 0; | 1956 | *negp = 0; |
1957 | *lvalp = (unsigned long)val; | 1957 | *lvalp = (unsigned long)val; |
1958 | } | 1958 | } |
1959 | } | 1959 | } |
1960 | return 0; | 1960 | return 0; |
1961 | } | 1961 | } |
1962 | 1962 | ||
1963 | #ifdef CONFIG_SECURITY_CAPABILITIES | 1963 | #ifdef CONFIG_SECURITY_CAPABILITIES |
1964 | /* | 1964 | /* |
1965 | * init may raise the set. | 1965 | * init may raise the set. |
1966 | */ | 1966 | */ |
1967 | 1967 | ||
1968 | int proc_dointvec_bset(struct ctl_table *table, int write, struct file *filp, | 1968 | int proc_dointvec_bset(struct ctl_table *table, int write, struct file *filp, |
1969 | void __user *buffer, size_t *lenp, loff_t *ppos) | 1969 | void __user *buffer, size_t *lenp, loff_t *ppos) |
1970 | { | 1970 | { |
1971 | int op; | 1971 | int op; |
1972 | 1972 | ||
1973 | if (write && !capable(CAP_SYS_MODULE)) { | 1973 | if (write && !capable(CAP_SYS_MODULE)) { |
1974 | return -EPERM; | 1974 | return -EPERM; |
1975 | } | 1975 | } |
1976 | 1976 | ||
1977 | op = is_global_init(current) ? OP_SET : OP_AND; | 1977 | op = is_global_init(current) ? OP_SET : OP_AND; |
1978 | return do_proc_dointvec(table,write,filp,buffer,lenp,ppos, | 1978 | return do_proc_dointvec(table,write,filp,buffer,lenp,ppos, |
1979 | do_proc_dointvec_bset_conv,&op); | 1979 | do_proc_dointvec_bset_conv,&op); |
1980 | } | 1980 | } |
1981 | #endif /* def CONFIG_SECURITY_CAPABILITIES */ | 1981 | #endif /* def CONFIG_SECURITY_CAPABILITIES */ |
1982 | 1982 | ||
1983 | /* | 1983 | /* |
1984 | * Taint values can only be increased | 1984 | * Taint values can only be increased |
1985 | */ | 1985 | */ |
1986 | static int proc_dointvec_taint(struct ctl_table *table, int write, struct file *filp, | 1986 | static int proc_dointvec_taint(struct ctl_table *table, int write, struct file *filp, |
1987 | void __user *buffer, size_t *lenp, loff_t *ppos) | 1987 | void __user *buffer, size_t *lenp, loff_t *ppos) |
1988 | { | 1988 | { |
1989 | int op; | 1989 | int op; |
1990 | 1990 | ||
1991 | if (write && !capable(CAP_SYS_ADMIN)) | 1991 | if (write && !capable(CAP_SYS_ADMIN)) |
1992 | return -EPERM; | 1992 | return -EPERM; |
1993 | 1993 | ||
1994 | op = OP_OR; | 1994 | op = OP_OR; |
1995 | return do_proc_dointvec(table,write,filp,buffer,lenp,ppos, | 1995 | return do_proc_dointvec(table,write,filp,buffer,lenp,ppos, |
1996 | do_proc_dointvec_bset_conv,&op); | 1996 | do_proc_dointvec_bset_conv,&op); |
1997 | } | 1997 | } |
1998 | 1998 | ||
1999 | struct do_proc_dointvec_minmax_conv_param { | 1999 | struct do_proc_dointvec_minmax_conv_param { |
2000 | int *min; | 2000 | int *min; |
2001 | int *max; | 2001 | int *max; |
2002 | }; | 2002 | }; |
2003 | 2003 | ||
2004 | static int do_proc_dointvec_minmax_conv(int *negp, unsigned long *lvalp, | 2004 | static int do_proc_dointvec_minmax_conv(int *negp, unsigned long *lvalp, |
2005 | int *valp, | 2005 | int *valp, |
2006 | int write, void *data) | 2006 | int write, void *data) |
2007 | { | 2007 | { |
2008 | struct do_proc_dointvec_minmax_conv_param *param = data; | 2008 | struct do_proc_dointvec_minmax_conv_param *param = data; |
2009 | if (write) { | 2009 | if (write) { |
2010 | int val = *negp ? -*lvalp : *lvalp; | 2010 | int val = *negp ? -*lvalp : *lvalp; |
2011 | if ((param->min && *param->min > val) || | 2011 | if ((param->min && *param->min > val) || |
2012 | (param->max && *param->max < val)) | 2012 | (param->max && *param->max < val)) |
2013 | return -EINVAL; | 2013 | return -EINVAL; |
2014 | *valp = val; | 2014 | *valp = val; |
2015 | } else { | 2015 | } else { |
2016 | int val = *valp; | 2016 | int val = *valp; |
2017 | if (val < 0) { | 2017 | if (val < 0) { |
2018 | *negp = -1; | 2018 | *negp = -1; |
2019 | *lvalp = (unsigned long)-val; | 2019 | *lvalp = (unsigned long)-val; |
2020 | } else { | 2020 | } else { |
2021 | *negp = 0; | 2021 | *negp = 0; |
2022 | *lvalp = (unsigned long)val; | 2022 | *lvalp = (unsigned long)val; |
2023 | } | 2023 | } |
2024 | } | 2024 | } |
2025 | return 0; | 2025 | return 0; |
2026 | } | 2026 | } |
2027 | 2027 | ||
2028 | /** | 2028 | /** |
2029 | * proc_dointvec_minmax - read a vector of integers with min/max values | 2029 | * proc_dointvec_minmax - read a vector of integers with min/max values |
2030 | * @table: the sysctl table | 2030 | * @table: the sysctl table |
2031 | * @write: %TRUE if this is a write to the sysctl file | 2031 | * @write: %TRUE if this is a write to the sysctl file |
2032 | * @filp: the file structure | 2032 | * @filp: the file structure |
2033 | * @buffer: the user buffer | 2033 | * @buffer: the user buffer |
2034 | * @lenp: the size of the user buffer | 2034 | * @lenp: the size of the user buffer |
2035 | * @ppos: file position | 2035 | * @ppos: file position |
2036 | * | 2036 | * |
2037 | * Reads/writes up to table->maxlen/sizeof(unsigned int) integer | 2037 | * Reads/writes up to table->maxlen/sizeof(unsigned int) integer |
2038 | * values from/to the user buffer, treated as an ASCII string. | 2038 | * values from/to the user buffer, treated as an ASCII string. |
2039 | * | 2039 | * |
2040 | * This routine will ensure the values are within the range specified by | 2040 | * This routine will ensure the values are within the range specified by |
2041 | * table->extra1 (min) and table->extra2 (max). | 2041 | * table->extra1 (min) and table->extra2 (max). |
2042 | * | 2042 | * |
2043 | * Returns 0 on success. | 2043 | * Returns 0 on success. |
2044 | */ | 2044 | */ |
2045 | int proc_dointvec_minmax(struct ctl_table *table, int write, struct file *filp, | 2045 | int proc_dointvec_minmax(struct ctl_table *table, int write, struct file *filp, |
2046 | void __user *buffer, size_t *lenp, loff_t *ppos) | 2046 | void __user *buffer, size_t *lenp, loff_t *ppos) |
2047 | { | 2047 | { |
2048 | struct do_proc_dointvec_minmax_conv_param param = { | 2048 | struct do_proc_dointvec_minmax_conv_param param = { |
2049 | .min = (int *) table->extra1, | 2049 | .min = (int *) table->extra1, |
2050 | .max = (int *) table->extra2, | 2050 | .max = (int *) table->extra2, |
2051 | }; | 2051 | }; |
2052 | return do_proc_dointvec(table, write, filp, buffer, lenp, ppos, | 2052 | return do_proc_dointvec(table, write, filp, buffer, lenp, ppos, |
2053 | do_proc_dointvec_minmax_conv, ¶m); | 2053 | do_proc_dointvec_minmax_conv, ¶m); |
2054 | } | 2054 | } |
2055 | 2055 | ||
2056 | static int __do_proc_doulongvec_minmax(void *data, struct ctl_table *table, int write, | 2056 | static int __do_proc_doulongvec_minmax(void *data, struct ctl_table *table, int write, |
2057 | struct file *filp, | 2057 | struct file *filp, |
2058 | void __user *buffer, | 2058 | void __user *buffer, |
2059 | size_t *lenp, loff_t *ppos, | 2059 | size_t *lenp, loff_t *ppos, |
2060 | unsigned long convmul, | 2060 | unsigned long convmul, |
2061 | unsigned long convdiv) | 2061 | unsigned long convdiv) |
2062 | { | 2062 | { |
2063 | #define TMPBUFLEN 21 | 2063 | #define TMPBUFLEN 21 |
2064 | unsigned long *i, *min, *max, val; | 2064 | unsigned long *i, *min, *max, val; |
2065 | int vleft, first=1, neg; | 2065 | int vleft, first=1, neg; |
2066 | size_t len, left; | 2066 | size_t len, left; |
2067 | char buf[TMPBUFLEN], *p; | 2067 | char buf[TMPBUFLEN], *p; |
2068 | char __user *s = buffer; | 2068 | char __user *s = buffer; |
2069 | 2069 | ||
2070 | if (!data || !table->maxlen || !*lenp || | 2070 | if (!data || !table->maxlen || !*lenp || |
2071 | (*ppos && !write)) { | 2071 | (*ppos && !write)) { |
2072 | *lenp = 0; | 2072 | *lenp = 0; |
2073 | return 0; | 2073 | return 0; |
2074 | } | 2074 | } |
2075 | 2075 | ||
2076 | i = (unsigned long *) data; | 2076 | i = (unsigned long *) data; |
2077 | min = (unsigned long *) table->extra1; | 2077 | min = (unsigned long *) table->extra1; |
2078 | max = (unsigned long *) table->extra2; | 2078 | max = (unsigned long *) table->extra2; |
2079 | vleft = table->maxlen / sizeof(unsigned long); | 2079 | vleft = table->maxlen / sizeof(unsigned long); |
2080 | left = *lenp; | 2080 | left = *lenp; |
2081 | 2081 | ||
2082 | for (; left && vleft--; i++, min++, max++, first=0) { | 2082 | for (; left && vleft--; i++, min++, max++, first=0) { |
2083 | if (write) { | 2083 | if (write) { |
2084 | while (left) { | 2084 | while (left) { |
2085 | char c; | 2085 | char c; |
2086 | if (get_user(c, s)) | 2086 | if (get_user(c, s)) |
2087 | return -EFAULT; | 2087 | return -EFAULT; |
2088 | if (!isspace(c)) | 2088 | if (!isspace(c)) |
2089 | break; | 2089 | break; |
2090 | left--; | 2090 | left--; |
2091 | s++; | 2091 | s++; |
2092 | } | 2092 | } |
2093 | if (!left) | 2093 | if (!left) |
2094 | break; | 2094 | break; |
2095 | neg = 0; | 2095 | neg = 0; |
2096 | len = left; | 2096 | len = left; |
2097 | if (len > TMPBUFLEN-1) | 2097 | if (len > TMPBUFLEN-1) |
2098 | len = TMPBUFLEN-1; | 2098 | len = TMPBUFLEN-1; |
2099 | if (copy_from_user(buf, s, len)) | 2099 | if (copy_from_user(buf, s, len)) |
2100 | return -EFAULT; | 2100 | return -EFAULT; |
2101 | buf[len] = 0; | 2101 | buf[len] = 0; |
2102 | p = buf; | 2102 | p = buf; |
2103 | if (*p == '-' && left > 1) { | 2103 | if (*p == '-' && left > 1) { |
2104 | neg = 1; | 2104 | neg = 1; |
2105 | p++; | 2105 | p++; |
2106 | } | 2106 | } |
2107 | if (*p < '0' || *p > '9') | 2107 | if (*p < '0' || *p > '9') |
2108 | break; | 2108 | break; |
2109 | val = simple_strtoul(p, &p, 0) * convmul / convdiv ; | 2109 | val = simple_strtoul(p, &p, 0) * convmul / convdiv ; |
2110 | len = p-buf; | 2110 | len = p-buf; |
2111 | if ((len < left) && *p && !isspace(*p)) | 2111 | if ((len < left) && *p && !isspace(*p)) |
2112 | break; | 2112 | break; |
2113 | if (neg) | 2113 | if (neg) |
2114 | val = -val; | 2114 | val = -val; |
2115 | s += len; | 2115 | s += len; |
2116 | left -= len; | 2116 | left -= len; |
2117 | 2117 | ||
2118 | if(neg) | 2118 | if(neg) |
2119 | continue; | 2119 | continue; |
2120 | if ((min && val < *min) || (max && val > *max)) | 2120 | if ((min && val < *min) || (max && val > *max)) |
2121 | continue; | 2121 | continue; |
2122 | *i = val; | 2122 | *i = val; |
2123 | } else { | 2123 | } else { |
2124 | p = buf; | 2124 | p = buf; |
2125 | if (!first) | 2125 | if (!first) |
2126 | *p++ = '\t'; | 2126 | *p++ = '\t'; |
2127 | sprintf(p, "%lu", convdiv * (*i) / convmul); | 2127 | sprintf(p, "%lu", convdiv * (*i) / convmul); |
2128 | len = strlen(buf); | 2128 | len = strlen(buf); |
2129 | if (len > left) | 2129 | if (len > left) |
2130 | len = left; | 2130 | len = left; |
2131 | if(copy_to_user(s, buf, len)) | 2131 | if(copy_to_user(s, buf, len)) |
2132 | return -EFAULT; | 2132 | return -EFAULT; |
2133 | left -= len; | 2133 | left -= len; |
2134 | s += len; | 2134 | s += len; |
2135 | } | 2135 | } |
2136 | } | 2136 | } |
2137 | 2137 | ||
2138 | if (!write && !first && left) { | 2138 | if (!write && !first && left) { |
2139 | if(put_user('\n', s)) | 2139 | if(put_user('\n', s)) |
2140 | return -EFAULT; | 2140 | return -EFAULT; |
2141 | left--, s++; | 2141 | left--, s++; |
2142 | } | 2142 | } |
2143 | if (write) { | 2143 | if (write) { |
2144 | while (left) { | 2144 | while (left) { |
2145 | char c; | 2145 | char c; |
2146 | if (get_user(c, s++)) | 2146 | if (get_user(c, s++)) |
2147 | return -EFAULT; | 2147 | return -EFAULT; |
2148 | if (!isspace(c)) | 2148 | if (!isspace(c)) |
2149 | break; | 2149 | break; |
2150 | left--; | 2150 | left--; |
2151 | } | 2151 | } |
2152 | } | 2152 | } |
2153 | if (write && first) | 2153 | if (write && first) |
2154 | return -EINVAL; | 2154 | return -EINVAL; |
2155 | *lenp -= left; | 2155 | *lenp -= left; |
2156 | *ppos += *lenp; | 2156 | *ppos += *lenp; |
2157 | return 0; | 2157 | return 0; |
2158 | #undef TMPBUFLEN | 2158 | #undef TMPBUFLEN |
2159 | } | 2159 | } |
2160 | 2160 | ||
2161 | static int do_proc_doulongvec_minmax(struct ctl_table *table, int write, | 2161 | static int do_proc_doulongvec_minmax(struct ctl_table *table, int write, |
2162 | struct file *filp, | 2162 | struct file *filp, |
2163 | void __user *buffer, | 2163 | void __user *buffer, |
2164 | size_t *lenp, loff_t *ppos, | 2164 | size_t *lenp, loff_t *ppos, |
2165 | unsigned long convmul, | 2165 | unsigned long convmul, |
2166 | unsigned long convdiv) | 2166 | unsigned long convdiv) |
2167 | { | 2167 | { |
2168 | return __do_proc_doulongvec_minmax(table->data, table, write, | 2168 | return __do_proc_doulongvec_minmax(table->data, table, write, |
2169 | filp, buffer, lenp, ppos, convmul, convdiv); | 2169 | filp, buffer, lenp, ppos, convmul, convdiv); |
2170 | } | 2170 | } |
2171 | 2171 | ||
2172 | /** | 2172 | /** |
2173 | * proc_doulongvec_minmax - read a vector of long integers with min/max values | 2173 | * proc_doulongvec_minmax - read a vector of long integers with min/max values |
2174 | * @table: the sysctl table | 2174 | * @table: the sysctl table |
2175 | * @write: %TRUE if this is a write to the sysctl file | 2175 | * @write: %TRUE if this is a write to the sysctl file |
2176 | * @filp: the file structure | 2176 | * @filp: the file structure |
2177 | * @buffer: the user buffer | 2177 | * @buffer: the user buffer |
2178 | * @lenp: the size of the user buffer | 2178 | * @lenp: the size of the user buffer |
2179 | * @ppos: file position | 2179 | * @ppos: file position |
2180 | * | 2180 | * |
2181 | * Reads/writes up to table->maxlen/sizeof(unsigned long) unsigned long | 2181 | * Reads/writes up to table->maxlen/sizeof(unsigned long) unsigned long |
2182 | * values from/to the user buffer, treated as an ASCII string. | 2182 | * values from/to the user buffer, treated as an ASCII string. |
2183 | * | 2183 | * |
2184 | * This routine will ensure the values are within the range specified by | 2184 | * This routine will ensure the values are within the range specified by |
2185 | * table->extra1 (min) and table->extra2 (max). | 2185 | * table->extra1 (min) and table->extra2 (max). |
2186 | * | 2186 | * |
2187 | * Returns 0 on success. | 2187 | * Returns 0 on success. |
2188 | */ | 2188 | */ |
2189 | int proc_doulongvec_minmax(struct ctl_table *table, int write, struct file *filp, | 2189 | int proc_doulongvec_minmax(struct ctl_table *table, int write, struct file *filp, |
2190 | void __user *buffer, size_t *lenp, loff_t *ppos) | 2190 | void __user *buffer, size_t *lenp, loff_t *ppos) |
2191 | { | 2191 | { |
2192 | return do_proc_doulongvec_minmax(table, write, filp, buffer, lenp, ppos, 1l, 1l); | 2192 | return do_proc_doulongvec_minmax(table, write, filp, buffer, lenp, ppos, 1l, 1l); |
2193 | } | 2193 | } |
2194 | 2194 | ||
2195 | /** | 2195 | /** |
2196 | * proc_doulongvec_ms_jiffies_minmax - read a vector of millisecond values with min/max values | 2196 | * proc_doulongvec_ms_jiffies_minmax - read a vector of millisecond values with min/max values |
2197 | * @table: the sysctl table | 2197 | * @table: the sysctl table |
2198 | * @write: %TRUE if this is a write to the sysctl file | 2198 | * @write: %TRUE if this is a write to the sysctl file |
2199 | * @filp: the file structure | 2199 | * @filp: the file structure |
2200 | * @buffer: the user buffer | 2200 | * @buffer: the user buffer |
2201 | * @lenp: the size of the user buffer | 2201 | * @lenp: the size of the user buffer |
2202 | * @ppos: file position | 2202 | * @ppos: file position |
2203 | * | 2203 | * |
2204 | * Reads/writes up to table->maxlen/sizeof(unsigned long) unsigned long | 2204 | * Reads/writes up to table->maxlen/sizeof(unsigned long) unsigned long |
2205 | * values from/to the user buffer, treated as an ASCII string. The values | 2205 | * values from/to the user buffer, treated as an ASCII string. The values |
2206 | * are treated as milliseconds, and converted to jiffies when they are stored. | 2206 | * are treated as milliseconds, and converted to jiffies when they are stored. |
2207 | * | 2207 | * |
2208 | * This routine will ensure the values are within the range specified by | 2208 | * This routine will ensure the values are within the range specified by |
2209 | * table->extra1 (min) and table->extra2 (max). | 2209 | * table->extra1 (min) and table->extra2 (max). |
2210 | * | 2210 | * |
2211 | * Returns 0 on success. | 2211 | * Returns 0 on success. |
2212 | */ | 2212 | */ |
2213 | int proc_doulongvec_ms_jiffies_minmax(struct ctl_table *table, int write, | 2213 | int proc_doulongvec_ms_jiffies_minmax(struct ctl_table *table, int write, |
2214 | struct file *filp, | 2214 | struct file *filp, |
2215 | void __user *buffer, | 2215 | void __user *buffer, |
2216 | size_t *lenp, loff_t *ppos) | 2216 | size_t *lenp, loff_t *ppos) |
2217 | { | 2217 | { |
2218 | return do_proc_doulongvec_minmax(table, write, filp, buffer, | 2218 | return do_proc_doulongvec_minmax(table, write, filp, buffer, |
2219 | lenp, ppos, HZ, 1000l); | 2219 | lenp, ppos, HZ, 1000l); |
2220 | } | 2220 | } |
2221 | 2221 | ||
2222 | 2222 | ||
2223 | static int do_proc_dointvec_jiffies_conv(int *negp, unsigned long *lvalp, | 2223 | static int do_proc_dointvec_jiffies_conv(int *negp, unsigned long *lvalp, |
2224 | int *valp, | 2224 | int *valp, |
2225 | int write, void *data) | 2225 | int write, void *data) |
2226 | { | 2226 | { |
2227 | if (write) { | 2227 | if (write) { |
2228 | if (*lvalp > LONG_MAX / HZ) | 2228 | if (*lvalp > LONG_MAX / HZ) |
2229 | return 1; | 2229 | return 1; |
2230 | *valp = *negp ? -(*lvalp*HZ) : (*lvalp*HZ); | 2230 | *valp = *negp ? -(*lvalp*HZ) : (*lvalp*HZ); |
2231 | } else { | 2231 | } else { |
2232 | int val = *valp; | 2232 | int val = *valp; |
2233 | unsigned long lval; | 2233 | unsigned long lval; |
2234 | if (val < 0) { | 2234 | if (val < 0) { |
2235 | *negp = -1; | 2235 | *negp = -1; |
2236 | lval = (unsigned long)-val; | 2236 | lval = (unsigned long)-val; |
2237 | } else { | 2237 | } else { |
2238 | *negp = 0; | 2238 | *negp = 0; |
2239 | lval = (unsigned long)val; | 2239 | lval = (unsigned long)val; |
2240 | } | 2240 | } |
2241 | *lvalp = lval / HZ; | 2241 | *lvalp = lval / HZ; |
2242 | } | 2242 | } |
2243 | return 0; | 2243 | return 0; |
2244 | } | 2244 | } |
2245 | 2245 | ||
2246 | static int do_proc_dointvec_userhz_jiffies_conv(int *negp, unsigned long *lvalp, | 2246 | static int do_proc_dointvec_userhz_jiffies_conv(int *negp, unsigned long *lvalp, |
2247 | int *valp, | 2247 | int *valp, |
2248 | int write, void *data) | 2248 | int write, void *data) |
2249 | { | 2249 | { |
2250 | if (write) { | 2250 | if (write) { |
2251 | if (USER_HZ < HZ && *lvalp > (LONG_MAX / HZ) * USER_HZ) | 2251 | if (USER_HZ < HZ && *lvalp > (LONG_MAX / HZ) * USER_HZ) |
2252 | return 1; | 2252 | return 1; |
2253 | *valp = clock_t_to_jiffies(*negp ? -*lvalp : *lvalp); | 2253 | *valp = clock_t_to_jiffies(*negp ? -*lvalp : *lvalp); |
2254 | } else { | 2254 | } else { |
2255 | int val = *valp; | 2255 | int val = *valp; |
2256 | unsigned long lval; | 2256 | unsigned long lval; |
2257 | if (val < 0) { | 2257 | if (val < 0) { |
2258 | *negp = -1; | 2258 | *negp = -1; |
2259 | lval = (unsigned long)-val; | 2259 | lval = (unsigned long)-val; |
2260 | } else { | 2260 | } else { |
2261 | *negp = 0; | 2261 | *negp = 0; |
2262 | lval = (unsigned long)val; | 2262 | lval = (unsigned long)val; |
2263 | } | 2263 | } |
2264 | *lvalp = jiffies_to_clock_t(lval); | 2264 | *lvalp = jiffies_to_clock_t(lval); |
2265 | } | 2265 | } |
2266 | return 0; | 2266 | return 0; |
2267 | } | 2267 | } |
2268 | 2268 | ||
2269 | static int do_proc_dointvec_ms_jiffies_conv(int *negp, unsigned long *lvalp, | 2269 | static int do_proc_dointvec_ms_jiffies_conv(int *negp, unsigned long *lvalp, |
2270 | int *valp, | 2270 | int *valp, |
2271 | int write, void *data) | 2271 | int write, void *data) |
2272 | { | 2272 | { |
2273 | if (write) { | 2273 | if (write) { |
2274 | *valp = msecs_to_jiffies(*negp ? -*lvalp : *lvalp); | 2274 | *valp = msecs_to_jiffies(*negp ? -*lvalp : *lvalp); |
2275 | } else { | 2275 | } else { |
2276 | int val = *valp; | 2276 | int val = *valp; |
2277 | unsigned long lval; | 2277 | unsigned long lval; |
2278 | if (val < 0) { | 2278 | if (val < 0) { |
2279 | *negp = -1; | 2279 | *negp = -1; |
2280 | lval = (unsigned long)-val; | 2280 | lval = (unsigned long)-val; |
2281 | } else { | 2281 | } else { |
2282 | *negp = 0; | 2282 | *negp = 0; |
2283 | lval = (unsigned long)val; | 2283 | lval = (unsigned long)val; |
2284 | } | 2284 | } |
2285 | *lvalp = jiffies_to_msecs(lval); | 2285 | *lvalp = jiffies_to_msecs(lval); |
2286 | } | 2286 | } |
2287 | return 0; | 2287 | return 0; |
2288 | } | 2288 | } |
2289 | 2289 | ||
2290 | /** | 2290 | /** |
2291 | * proc_dointvec_jiffies - read a vector of integers as seconds | 2291 | * proc_dointvec_jiffies - read a vector of integers as seconds |
2292 | * @table: the sysctl table | 2292 | * @table: the sysctl table |
2293 | * @write: %TRUE if this is a write to the sysctl file | 2293 | * @write: %TRUE if this is a write to the sysctl file |
2294 | * @filp: the file structure | 2294 | * @filp: the file structure |
2295 | * @buffer: the user buffer | 2295 | * @buffer: the user buffer |
2296 | * @lenp: the size of the user buffer | 2296 | * @lenp: the size of the user buffer |
2297 | * @ppos: file position | 2297 | * @ppos: file position |
2298 | * | 2298 | * |
2299 | * Reads/writes up to table->maxlen/sizeof(unsigned int) integer | 2299 | * Reads/writes up to table->maxlen/sizeof(unsigned int) integer |
2300 | * values from/to the user buffer, treated as an ASCII string. | 2300 | * values from/to the user buffer, treated as an ASCII string. |
2301 | * The values read are assumed to be in seconds, and are converted into | 2301 | * The values read are assumed to be in seconds, and are converted into |
2302 | * jiffies. | 2302 | * jiffies. |
2303 | * | 2303 | * |
2304 | * Returns 0 on success. | 2304 | * Returns 0 on success. |
2305 | */ | 2305 | */ |
2306 | int proc_dointvec_jiffies(struct ctl_table *table, int write, struct file *filp, | 2306 | int proc_dointvec_jiffies(struct ctl_table *table, int write, struct file *filp, |
2307 | void __user *buffer, size_t *lenp, loff_t *ppos) | 2307 | void __user *buffer, size_t *lenp, loff_t *ppos) |
2308 | { | 2308 | { |
2309 | return do_proc_dointvec(table,write,filp,buffer,lenp,ppos, | 2309 | return do_proc_dointvec(table,write,filp,buffer,lenp,ppos, |
2310 | do_proc_dointvec_jiffies_conv,NULL); | 2310 | do_proc_dointvec_jiffies_conv,NULL); |
2311 | } | 2311 | } |
2312 | 2312 | ||
2313 | /** | 2313 | /** |
2314 | * proc_dointvec_userhz_jiffies - read a vector of integers as 1/USER_HZ seconds | 2314 | * proc_dointvec_userhz_jiffies - read a vector of integers as 1/USER_HZ seconds |
2315 | * @table: the sysctl table | 2315 | * @table: the sysctl table |
2316 | * @write: %TRUE if this is a write to the sysctl file | 2316 | * @write: %TRUE if this is a write to the sysctl file |
2317 | * @filp: the file structure | 2317 | * @filp: the file structure |
2318 | * @buffer: the user buffer | 2318 | * @buffer: the user buffer |
2319 | * @lenp: the size of the user buffer | 2319 | * @lenp: the size of the user buffer |
2320 | * @ppos: pointer to the file position | 2320 | * @ppos: pointer to the file position |
2321 | * | 2321 | * |
2322 | * Reads/writes up to table->maxlen/sizeof(unsigned int) integer | 2322 | * Reads/writes up to table->maxlen/sizeof(unsigned int) integer |
2323 | * values from/to the user buffer, treated as an ASCII string. | 2323 | * values from/to the user buffer, treated as an ASCII string. |
2324 | * The values read are assumed to be in 1/USER_HZ seconds, and | 2324 | * The values read are assumed to be in 1/USER_HZ seconds, and |
2325 | * are converted into jiffies. | 2325 | * are converted into jiffies. |
2326 | * | 2326 | * |
2327 | * Returns 0 on success. | 2327 | * Returns 0 on success. |
2328 | */ | 2328 | */ |
2329 | int proc_dointvec_userhz_jiffies(struct ctl_table *table, int write, struct file *filp, | 2329 | int proc_dointvec_userhz_jiffies(struct ctl_table *table, int write, struct file *filp, |
2330 | void __user *buffer, size_t *lenp, loff_t *ppos) | 2330 | void __user *buffer, size_t *lenp, loff_t *ppos) |
2331 | { | 2331 | { |
2332 | return do_proc_dointvec(table,write,filp,buffer,lenp,ppos, | 2332 | return do_proc_dointvec(table,write,filp,buffer,lenp,ppos, |
2333 | do_proc_dointvec_userhz_jiffies_conv,NULL); | 2333 | do_proc_dointvec_userhz_jiffies_conv,NULL); |
2334 | } | 2334 | } |
2335 | 2335 | ||
2336 | /** | 2336 | /** |
2337 | * proc_dointvec_ms_jiffies - read a vector of integers as 1 milliseconds | 2337 | * proc_dointvec_ms_jiffies - read a vector of integers as 1 milliseconds |
2338 | * @table: the sysctl table | 2338 | * @table: the sysctl table |
2339 | * @write: %TRUE if this is a write to the sysctl file | 2339 | * @write: %TRUE if this is a write to the sysctl file |
2340 | * @filp: the file structure | 2340 | * @filp: the file structure |
2341 | * @buffer: the user buffer | 2341 | * @buffer: the user buffer |
2342 | * @lenp: the size of the user buffer | 2342 | * @lenp: the size of the user buffer |
2343 | * @ppos: file position | 2343 | * @ppos: file position |
2344 | * @ppos: the current position in the file | 2344 | * @ppos: the current position in the file |
2345 | * | 2345 | * |
2346 | * Reads/writes up to table->maxlen/sizeof(unsigned int) integer | 2346 | * Reads/writes up to table->maxlen/sizeof(unsigned int) integer |
2347 | * values from/to the user buffer, treated as an ASCII string. | 2347 | * values from/to the user buffer, treated as an ASCII string. |
2348 | * The values read are assumed to be in 1/1000 seconds, and | 2348 | * The values read are assumed to be in 1/1000 seconds, and |
2349 | * are converted into jiffies. | 2349 | * are converted into jiffies. |
2350 | * | 2350 | * |
2351 | * Returns 0 on success. | 2351 | * Returns 0 on success. |
2352 | */ | 2352 | */ |
2353 | int proc_dointvec_ms_jiffies(struct ctl_table *table, int write, struct file *filp, | 2353 | int proc_dointvec_ms_jiffies(struct ctl_table *table, int write, struct file *filp, |
2354 | void __user *buffer, size_t *lenp, loff_t *ppos) | 2354 | void __user *buffer, size_t *lenp, loff_t *ppos) |
2355 | { | 2355 | { |
2356 | return do_proc_dointvec(table, write, filp, buffer, lenp, ppos, | 2356 | return do_proc_dointvec(table, write, filp, buffer, lenp, ppos, |
2357 | do_proc_dointvec_ms_jiffies_conv, NULL); | 2357 | do_proc_dointvec_ms_jiffies_conv, NULL); |
2358 | } | 2358 | } |
2359 | 2359 | ||
2360 | static int proc_do_cad_pid(struct ctl_table *table, int write, struct file *filp, | 2360 | static int proc_do_cad_pid(struct ctl_table *table, int write, struct file *filp, |
2361 | void __user *buffer, size_t *lenp, loff_t *ppos) | 2361 | void __user *buffer, size_t *lenp, loff_t *ppos) |
2362 | { | 2362 | { |
2363 | struct pid *new_pid; | 2363 | struct pid *new_pid; |
2364 | pid_t tmp; | 2364 | pid_t tmp; |
2365 | int r; | 2365 | int r; |
2366 | 2366 | ||
2367 | tmp = pid_nr_ns(cad_pid, current->nsproxy->pid_ns); | 2367 | tmp = pid_nr_ns(cad_pid, current->nsproxy->pid_ns); |
2368 | 2368 | ||
2369 | r = __do_proc_dointvec(&tmp, table, write, filp, buffer, | 2369 | r = __do_proc_dointvec(&tmp, table, write, filp, buffer, |
2370 | lenp, ppos, NULL, NULL); | 2370 | lenp, ppos, NULL, NULL); |
2371 | if (r || !write) | 2371 | if (r || !write) |
2372 | return r; | 2372 | return r; |
2373 | 2373 | ||
2374 | new_pid = find_get_pid(tmp); | 2374 | new_pid = find_get_pid(tmp); |
2375 | if (!new_pid) | 2375 | if (!new_pid) |
2376 | return -ESRCH; | 2376 | return -ESRCH; |
2377 | 2377 | ||
2378 | put_pid(xchg(&cad_pid, new_pid)); | 2378 | put_pid(xchg(&cad_pid, new_pid)); |
2379 | return 0; | 2379 | return 0; |
2380 | } | 2380 | } |
2381 | 2381 | ||
2382 | #else /* CONFIG_PROC_FS */ | 2382 | #else /* CONFIG_PROC_FS */ |
2383 | 2383 | ||
2384 | int proc_dostring(struct ctl_table *table, int write, struct file *filp, | 2384 | int proc_dostring(struct ctl_table *table, int write, struct file *filp, |
2385 | void __user *buffer, size_t *lenp, loff_t *ppos) | 2385 | void __user *buffer, size_t *lenp, loff_t *ppos) |
2386 | { | 2386 | { |
2387 | return -ENOSYS; | 2387 | return -ENOSYS; |
2388 | } | 2388 | } |
2389 | 2389 | ||
2390 | int proc_dointvec(struct ctl_table *table, int write, struct file *filp, | 2390 | int proc_dointvec(struct ctl_table *table, int write, struct file *filp, |
2391 | void __user *buffer, size_t *lenp, loff_t *ppos) | 2391 | void __user *buffer, size_t *lenp, loff_t *ppos) |
2392 | { | 2392 | { |
2393 | return -ENOSYS; | 2393 | return -ENOSYS; |
2394 | } | 2394 | } |
2395 | 2395 | ||
2396 | int proc_dointvec_bset(struct ctl_table *table, int write, struct file *filp, | 2396 | int proc_dointvec_bset(struct ctl_table *table, int write, struct file *filp, |
2397 | void __user *buffer, size_t *lenp, loff_t *ppos) | 2397 | void __user *buffer, size_t *lenp, loff_t *ppos) |
2398 | { | 2398 | { |
2399 | return -ENOSYS; | 2399 | return -ENOSYS; |
2400 | } | 2400 | } |
2401 | 2401 | ||
2402 | int proc_dointvec_minmax(struct ctl_table *table, int write, struct file *filp, | 2402 | int proc_dointvec_minmax(struct ctl_table *table, int write, struct file *filp, |
2403 | void __user *buffer, size_t *lenp, loff_t *ppos) | 2403 | void __user *buffer, size_t *lenp, loff_t *ppos) |
2404 | { | 2404 | { |
2405 | return -ENOSYS; | 2405 | return -ENOSYS; |
2406 | } | 2406 | } |
2407 | 2407 | ||
2408 | int proc_dointvec_jiffies(struct ctl_table *table, int write, struct file *filp, | 2408 | int proc_dointvec_jiffies(struct ctl_table *table, int write, struct file *filp, |
2409 | void __user *buffer, size_t *lenp, loff_t *ppos) | 2409 | void __user *buffer, size_t *lenp, loff_t *ppos) |
2410 | { | 2410 | { |
2411 | return -ENOSYS; | 2411 | return -ENOSYS; |
2412 | } | 2412 | } |
2413 | 2413 | ||
2414 | int proc_dointvec_userhz_jiffies(struct ctl_table *table, int write, struct file *filp, | 2414 | int proc_dointvec_userhz_jiffies(struct ctl_table *table, int write, struct file *filp, |
2415 | void __user *buffer, size_t *lenp, loff_t *ppos) | 2415 | void __user *buffer, size_t *lenp, loff_t *ppos) |
2416 | { | 2416 | { |
2417 | return -ENOSYS; | 2417 | return -ENOSYS; |
2418 | } | 2418 | } |
2419 | 2419 | ||
2420 | int proc_dointvec_ms_jiffies(struct ctl_table *table, int write, struct file *filp, | 2420 | int proc_dointvec_ms_jiffies(struct ctl_table *table, int write, struct file *filp, |
2421 | void __user *buffer, size_t *lenp, loff_t *ppos) | 2421 | void __user *buffer, size_t *lenp, loff_t *ppos) |
2422 | { | 2422 | { |
2423 | return -ENOSYS; | 2423 | return -ENOSYS; |
2424 | } | 2424 | } |
2425 | 2425 | ||
2426 | int proc_doulongvec_minmax(struct ctl_table *table, int write, struct file *filp, | 2426 | int proc_doulongvec_minmax(struct ctl_table *table, int write, struct file *filp, |
2427 | void __user *buffer, size_t *lenp, loff_t *ppos) | 2427 | void __user *buffer, size_t *lenp, loff_t *ppos) |
2428 | { | 2428 | { |
2429 | return -ENOSYS; | 2429 | return -ENOSYS; |
2430 | } | 2430 | } |
2431 | 2431 | ||
2432 | int proc_doulongvec_ms_jiffies_minmax(struct ctl_table *table, int write, | 2432 | int proc_doulongvec_ms_jiffies_minmax(struct ctl_table *table, int write, |
2433 | struct file *filp, | 2433 | struct file *filp, |
2434 | void __user *buffer, | 2434 | void __user *buffer, |
2435 | size_t *lenp, loff_t *ppos) | 2435 | size_t *lenp, loff_t *ppos) |
2436 | { | 2436 | { |
2437 | return -ENOSYS; | 2437 | return -ENOSYS; |
2438 | } | 2438 | } |
2439 | 2439 | ||
2440 | 2440 | ||
2441 | #endif /* CONFIG_PROC_FS */ | 2441 | #endif /* CONFIG_PROC_FS */ |
2442 | 2442 | ||
2443 | 2443 | ||
2444 | #ifdef CONFIG_SYSCTL_SYSCALL | 2444 | #ifdef CONFIG_SYSCTL_SYSCALL |
2445 | /* | 2445 | /* |
2446 | * General sysctl support routines | 2446 | * General sysctl support routines |
2447 | */ | 2447 | */ |
2448 | 2448 | ||
2449 | /* The generic sysctl data routine (used if no strategy routine supplied) */ | 2449 | /* The generic sysctl data routine (used if no strategy routine supplied) */ |
2450 | int sysctl_data(struct ctl_table *table, int __user *name, int nlen, | 2450 | int sysctl_data(struct ctl_table *table, int __user *name, int nlen, |
2451 | void __user *oldval, size_t __user *oldlenp, | 2451 | void __user *oldval, size_t __user *oldlenp, |
2452 | void __user *newval, size_t newlen) | 2452 | void __user *newval, size_t newlen) |
2453 | { | 2453 | { |
2454 | size_t len; | 2454 | size_t len; |
2455 | 2455 | ||
2456 | /* Get out of I don't have a variable */ | 2456 | /* Get out of I don't have a variable */ |
2457 | if (!table->data || !table->maxlen) | 2457 | if (!table->data || !table->maxlen) |
2458 | return -ENOTDIR; | 2458 | return -ENOTDIR; |
2459 | 2459 | ||
2460 | if (oldval && oldlenp) { | 2460 | if (oldval && oldlenp) { |
2461 | if (get_user(len, oldlenp)) | 2461 | if (get_user(len, oldlenp)) |
2462 | return -EFAULT; | 2462 | return -EFAULT; |
2463 | if (len) { | 2463 | if (len) { |
2464 | if (len > table->maxlen) | 2464 | if (len > table->maxlen) |
2465 | len = table->maxlen; | 2465 | len = table->maxlen; |
2466 | if (copy_to_user(oldval, table->data, len)) | 2466 | if (copy_to_user(oldval, table->data, len)) |
2467 | return -EFAULT; | 2467 | return -EFAULT; |
2468 | if (put_user(len, oldlenp)) | 2468 | if (put_user(len, oldlenp)) |
2469 | return -EFAULT; | 2469 | return -EFAULT; |
2470 | } | 2470 | } |
2471 | } | 2471 | } |
2472 | 2472 | ||
2473 | if (newval && newlen) { | 2473 | if (newval && newlen) { |
2474 | if (newlen > table->maxlen) | 2474 | if (newlen > table->maxlen) |
2475 | newlen = table->maxlen; | 2475 | newlen = table->maxlen; |
2476 | 2476 | ||
2477 | if (copy_from_user(table->data, newval, newlen)) | 2477 | if (copy_from_user(table->data, newval, newlen)) |
2478 | return -EFAULT; | 2478 | return -EFAULT; |
2479 | } | 2479 | } |
2480 | return 1; | 2480 | return 1; |
2481 | } | 2481 | } |
2482 | 2482 | ||
2483 | /* The generic string strategy routine: */ | 2483 | /* The generic string strategy routine: */ |
2484 | int sysctl_string(struct ctl_table *table, int __user *name, int nlen, | 2484 | int sysctl_string(struct ctl_table *table, int __user *name, int nlen, |
2485 | void __user *oldval, size_t __user *oldlenp, | 2485 | void __user *oldval, size_t __user *oldlenp, |
2486 | void __user *newval, size_t newlen) | 2486 | void __user *newval, size_t newlen) |
2487 | { | 2487 | { |
2488 | if (!table->data || !table->maxlen) | 2488 | if (!table->data || !table->maxlen) |
2489 | return -ENOTDIR; | 2489 | return -ENOTDIR; |
2490 | 2490 | ||
2491 | if (oldval && oldlenp) { | 2491 | if (oldval && oldlenp) { |
2492 | size_t bufsize; | 2492 | size_t bufsize; |
2493 | if (get_user(bufsize, oldlenp)) | 2493 | if (get_user(bufsize, oldlenp)) |
2494 | return -EFAULT; | 2494 | return -EFAULT; |
2495 | if (bufsize) { | 2495 | if (bufsize) { |
2496 | size_t len = strlen(table->data), copied; | 2496 | size_t len = strlen(table->data), copied; |
2497 | 2497 | ||
2498 | /* This shouldn't trigger for a well-formed sysctl */ | 2498 | /* This shouldn't trigger for a well-formed sysctl */ |
2499 | if (len > table->maxlen) | 2499 | if (len > table->maxlen) |
2500 | len = table->maxlen; | 2500 | len = table->maxlen; |
2501 | 2501 | ||
2502 | /* Copy up to a max of bufsize-1 bytes of the string */ | 2502 | /* Copy up to a max of bufsize-1 bytes of the string */ |
2503 | copied = (len >= bufsize) ? bufsize - 1 : len; | 2503 | copied = (len >= bufsize) ? bufsize - 1 : len; |
2504 | 2504 | ||
2505 | if (copy_to_user(oldval, table->data, copied) || | 2505 | if (copy_to_user(oldval, table->data, copied) || |
2506 | put_user(0, (char __user *)(oldval + copied))) | 2506 | put_user(0, (char __user *)(oldval + copied))) |
2507 | return -EFAULT; | 2507 | return -EFAULT; |
2508 | if (put_user(len, oldlenp)) | 2508 | if (put_user(len, oldlenp)) |
2509 | return -EFAULT; | 2509 | return -EFAULT; |
2510 | } | 2510 | } |
2511 | } | 2511 | } |
2512 | if (newval && newlen) { | 2512 | if (newval && newlen) { |
2513 | size_t len = newlen; | 2513 | size_t len = newlen; |
2514 | if (len > table->maxlen) | 2514 | if (len > table->maxlen) |
2515 | len = table->maxlen; | 2515 | len = table->maxlen; |
2516 | if(copy_from_user(table->data, newval, len)) | 2516 | if(copy_from_user(table->data, newval, len)) |
2517 | return -EFAULT; | 2517 | return -EFAULT; |
2518 | if (len == table->maxlen) | 2518 | if (len == table->maxlen) |
2519 | len--; | 2519 | len--; |
2520 | ((char *) table->data)[len] = 0; | 2520 | ((char *) table->data)[len] = 0; |
2521 | } | 2521 | } |
2522 | return 1; | 2522 | return 1; |
2523 | } | 2523 | } |
2524 | 2524 | ||
2525 | /* | 2525 | /* |
2526 | * This function makes sure that all of the integers in the vector | 2526 | * This function makes sure that all of the integers in the vector |
2527 | * are between the minimum and maximum values given in the arrays | 2527 | * are between the minimum and maximum values given in the arrays |
2528 | * table->extra1 and table->extra2, respectively. | 2528 | * table->extra1 and table->extra2, respectively. |
2529 | */ | 2529 | */ |
2530 | int sysctl_intvec(struct ctl_table *table, int __user *name, int nlen, | 2530 | int sysctl_intvec(struct ctl_table *table, int __user *name, int nlen, |
2531 | void __user *oldval, size_t __user *oldlenp, | 2531 | void __user *oldval, size_t __user *oldlenp, |
2532 | void __user *newval, size_t newlen) | 2532 | void __user *newval, size_t newlen) |
2533 | { | 2533 | { |
2534 | 2534 | ||
2535 | if (newval && newlen) { | 2535 | if (newval && newlen) { |
2536 | int __user *vec = (int __user *) newval; | 2536 | int __user *vec = (int __user *) newval; |
2537 | int *min = (int *) table->extra1; | 2537 | int *min = (int *) table->extra1; |
2538 | int *max = (int *) table->extra2; | 2538 | int *max = (int *) table->extra2; |
2539 | size_t length; | 2539 | size_t length; |
2540 | int i; | 2540 | int i; |
2541 | 2541 | ||
2542 | if (newlen % sizeof(int) != 0) | 2542 | if (newlen % sizeof(int) != 0) |
2543 | return -EINVAL; | 2543 | return -EINVAL; |
2544 | 2544 | ||
2545 | if (!table->extra1 && !table->extra2) | 2545 | if (!table->extra1 && !table->extra2) |
2546 | return 0; | 2546 | return 0; |
2547 | 2547 | ||
2548 | if (newlen > table->maxlen) | 2548 | if (newlen > table->maxlen) |
2549 | newlen = table->maxlen; | 2549 | newlen = table->maxlen; |
2550 | length = newlen / sizeof(int); | 2550 | length = newlen / sizeof(int); |
2551 | 2551 | ||
2552 | for (i = 0; i < length; i++) { | 2552 | for (i = 0; i < length; i++) { |
2553 | int value; | 2553 | int value; |
2554 | if (get_user(value, vec + i)) | 2554 | if (get_user(value, vec + i)) |
2555 | return -EFAULT; | 2555 | return -EFAULT; |
2556 | if (min && value < min[i]) | 2556 | if (min && value < min[i]) |
2557 | return -EINVAL; | 2557 | return -EINVAL; |
2558 | if (max && value > max[i]) | 2558 | if (max && value > max[i]) |
2559 | return -EINVAL; | 2559 | return -EINVAL; |
2560 | } | 2560 | } |
2561 | } | 2561 | } |
2562 | return 0; | 2562 | return 0; |
2563 | } | 2563 | } |
2564 | 2564 | ||
2565 | /* Strategy function to convert jiffies to seconds */ | 2565 | /* Strategy function to convert jiffies to seconds */ |
2566 | int sysctl_jiffies(struct ctl_table *table, int __user *name, int nlen, | 2566 | int sysctl_jiffies(struct ctl_table *table, int __user *name, int nlen, |
2567 | void __user *oldval, size_t __user *oldlenp, | 2567 | void __user *oldval, size_t __user *oldlenp, |
2568 | void __user *newval, size_t newlen) | 2568 | void __user *newval, size_t newlen) |
2569 | { | 2569 | { |
2570 | if (oldval && oldlenp) { | 2570 | if (oldval && oldlenp) { |
2571 | size_t olen; | 2571 | size_t olen; |
2572 | 2572 | ||
2573 | if (get_user(olen, oldlenp)) | 2573 | if (get_user(olen, oldlenp)) |
2574 | return -EFAULT; | 2574 | return -EFAULT; |
2575 | if (olen) { | 2575 | if (olen) { |
2576 | int val; | 2576 | int val; |
2577 | 2577 | ||
2578 | if (olen < sizeof(int)) | 2578 | if (olen < sizeof(int)) |
2579 | return -EINVAL; | 2579 | return -EINVAL; |
2580 | 2580 | ||
2581 | val = *(int *)(table->data) / HZ; | 2581 | val = *(int *)(table->data) / HZ; |
2582 | if (put_user(val, (int __user *)oldval)) | 2582 | if (put_user(val, (int __user *)oldval)) |
2583 | return -EFAULT; | 2583 | return -EFAULT; |
2584 | if (put_user(sizeof(int), oldlenp)) | 2584 | if (put_user(sizeof(int), oldlenp)) |
2585 | return -EFAULT; | 2585 | return -EFAULT; |
2586 | } | 2586 | } |
2587 | } | 2587 | } |
2588 | if (newval && newlen) { | 2588 | if (newval && newlen) { |
2589 | int new; | 2589 | int new; |
2590 | if (newlen != sizeof(int)) | 2590 | if (newlen != sizeof(int)) |
2591 | return -EINVAL; | 2591 | return -EINVAL; |
2592 | if (get_user(new, (int __user *)newval)) | 2592 | if (get_user(new, (int __user *)newval)) |
2593 | return -EFAULT; | 2593 | return -EFAULT; |
2594 | *(int *)(table->data) = new*HZ; | 2594 | *(int *)(table->data) = new*HZ; |
2595 | } | 2595 | } |
2596 | return 1; | 2596 | return 1; |
2597 | } | 2597 | } |
2598 | 2598 | ||
2599 | /* Strategy function to convert jiffies to seconds */ | 2599 | /* Strategy function to convert jiffies to seconds */ |
2600 | int sysctl_ms_jiffies(struct ctl_table *table, int __user *name, int nlen, | 2600 | int sysctl_ms_jiffies(struct ctl_table *table, int __user *name, int nlen, |
2601 | void __user *oldval, size_t __user *oldlenp, | 2601 | void __user *oldval, size_t __user *oldlenp, |
2602 | void __user *newval, size_t newlen) | 2602 | void __user *newval, size_t newlen) |
2603 | { | 2603 | { |
2604 | if (oldval && oldlenp) { | 2604 | if (oldval && oldlenp) { |
2605 | size_t olen; | 2605 | size_t olen; |
2606 | 2606 | ||
2607 | if (get_user(olen, oldlenp)) | 2607 | if (get_user(olen, oldlenp)) |
2608 | return -EFAULT; | 2608 | return -EFAULT; |
2609 | if (olen) { | 2609 | if (olen) { |
2610 | int val; | 2610 | int val; |
2611 | 2611 | ||
2612 | if (olen < sizeof(int)) | 2612 | if (olen < sizeof(int)) |
2613 | return -EINVAL; | 2613 | return -EINVAL; |
2614 | 2614 | ||
2615 | val = jiffies_to_msecs(*(int *)(table->data)); | 2615 | val = jiffies_to_msecs(*(int *)(table->data)); |
2616 | if (put_user(val, (int __user *)oldval)) | 2616 | if (put_user(val, (int __user *)oldval)) |
2617 | return -EFAULT; | 2617 | return -EFAULT; |
2618 | if (put_user(sizeof(int), oldlenp)) | 2618 | if (put_user(sizeof(int), oldlenp)) |
2619 | return -EFAULT; | 2619 | return -EFAULT; |
2620 | } | 2620 | } |
2621 | } | 2621 | } |
2622 | if (newval && newlen) { | 2622 | if (newval && newlen) { |
2623 | int new; | 2623 | int new; |
2624 | if (newlen != sizeof(int)) | 2624 | if (newlen != sizeof(int)) |
2625 | return -EINVAL; | 2625 | return -EINVAL; |
2626 | if (get_user(new, (int __user *)newval)) | 2626 | if (get_user(new, (int __user *)newval)) |
2627 | return -EFAULT; | 2627 | return -EFAULT; |
2628 | *(int *)(table->data) = msecs_to_jiffies(new); | 2628 | *(int *)(table->data) = msecs_to_jiffies(new); |
2629 | } | 2629 | } |
2630 | return 1; | 2630 | return 1; |
2631 | } | 2631 | } |
2632 | 2632 | ||
2633 | 2633 | ||
2634 | 2634 | ||
2635 | #else /* CONFIG_SYSCTL_SYSCALL */ | 2635 | #else /* CONFIG_SYSCTL_SYSCALL */ |
2636 | 2636 | ||
2637 | 2637 | ||
2638 | asmlinkage long sys_sysctl(struct __sysctl_args __user *args) | 2638 | asmlinkage long sys_sysctl(struct __sysctl_args __user *args) |
2639 | { | 2639 | { |
2640 | struct __sysctl_args tmp; | 2640 | struct __sysctl_args tmp; |
2641 | int error; | 2641 | int error; |
2642 | 2642 | ||
2643 | if (copy_from_user(&tmp, args, sizeof(tmp))) | 2643 | if (copy_from_user(&tmp, args, sizeof(tmp))) |
2644 | return -EFAULT; | 2644 | return -EFAULT; |
2645 | 2645 | ||
2646 | error = deprecated_sysctl_warning(&tmp); | 2646 | error = deprecated_sysctl_warning(&tmp); |
2647 | 2647 | ||
2648 | /* If no error reading the parameters then just -ENOSYS ... */ | 2648 | /* If no error reading the parameters then just -ENOSYS ... */ |
2649 | if (!error) | 2649 | if (!error) |
2650 | error = -ENOSYS; | 2650 | error = -ENOSYS; |
2651 | 2651 | ||
2652 | return error; | 2652 | return error; |
2653 | } | 2653 | } |
2654 | 2654 | ||
2655 | int sysctl_data(struct ctl_table *table, int __user *name, int nlen, | 2655 | int sysctl_data(struct ctl_table *table, int __user *name, int nlen, |
2656 | void __user *oldval, size_t __user *oldlenp, | 2656 | void __user *oldval, size_t __user *oldlenp, |
2657 | void __user *newval, size_t newlen) | 2657 | void __user *newval, size_t newlen) |
2658 | { | 2658 | { |
2659 | return -ENOSYS; | 2659 | return -ENOSYS; |
2660 | } | 2660 | } |
2661 | 2661 | ||
2662 | int sysctl_string(struct ctl_table *table, int __user *name, int nlen, | 2662 | int sysctl_string(struct ctl_table *table, int __user *name, int nlen, |
2663 | void __user *oldval, size_t __user *oldlenp, | 2663 | void __user *oldval, size_t __user *oldlenp, |
2664 | void __user *newval, size_t newlen) | 2664 | void __user *newval, size_t newlen) |
2665 | { | 2665 | { |
2666 | return -ENOSYS; | 2666 | return -ENOSYS; |
2667 | } | 2667 | } |
2668 | 2668 | ||
2669 | int sysctl_intvec(struct ctl_table *table, int __user *name, int nlen, | 2669 | int sysctl_intvec(struct ctl_table *table, int __user *name, int nlen, |
2670 | void __user *oldval, size_t __user *oldlenp, | 2670 | void __user *oldval, size_t __user *oldlenp, |
2671 | void __user *newval, size_t newlen) | 2671 | void __user *newval, size_t newlen) |
2672 | { | 2672 | { |
2673 | return -ENOSYS; | 2673 | return -ENOSYS; |
2674 | } | 2674 | } |
2675 | 2675 | ||
2676 | int sysctl_jiffies(struct ctl_table *table, int __user *name, int nlen, | 2676 | int sysctl_jiffies(struct ctl_table *table, int __user *name, int nlen, |
2677 | void __user *oldval, size_t __user *oldlenp, | 2677 | void __user *oldval, size_t __user *oldlenp, |
2678 | void __user *newval, size_t newlen) | 2678 | void __user *newval, size_t newlen) |
2679 | { | 2679 | { |
2680 | return -ENOSYS; | 2680 | return -ENOSYS; |
2681 | } | 2681 | } |
2682 | 2682 | ||
2683 | int sysctl_ms_jiffies(struct ctl_table *table, int __user *name, int nlen, | 2683 | int sysctl_ms_jiffies(struct ctl_table *table, int __user *name, int nlen, |
2684 | void __user *oldval, size_t __user *oldlenp, | 2684 | void __user *oldval, size_t __user *oldlenp, |
2685 | void __user *newval, size_t newlen) | 2685 | void __user *newval, size_t newlen) |
2686 | { | 2686 | { |
2687 | return -ENOSYS; | 2687 | return -ENOSYS; |
2688 | } | 2688 | } |
2689 | 2689 | ||
2690 | #endif /* CONFIG_SYSCTL_SYSCALL */ | 2690 | #endif /* CONFIG_SYSCTL_SYSCALL */ |
2691 | 2691 | ||
2692 | static int deprecated_sysctl_warning(struct __sysctl_args *args) | 2692 | static int deprecated_sysctl_warning(struct __sysctl_args *args) |
2693 | { | 2693 | { |
2694 | static int msg_count; | 2694 | static int msg_count; |
2695 | int name[CTL_MAXNAME]; | 2695 | int name[CTL_MAXNAME]; |
2696 | int i; | 2696 | int i; |
2697 | 2697 | ||
2698 | /* Check args->nlen. */ | 2698 | /* Check args->nlen. */ |
2699 | if (args->nlen < 0 || args->nlen > CTL_MAXNAME) | 2699 | if (args->nlen < 0 || args->nlen > CTL_MAXNAME) |
2700 | return -ENOTDIR; | 2700 | return -ENOTDIR; |
2701 | 2701 | ||
2702 | /* Read in the sysctl name for better debug message logging */ | 2702 | /* Read in the sysctl name for better debug message logging */ |
2703 | for (i = 0; i < args->nlen; i++) | 2703 | for (i = 0; i < args->nlen; i++) |
2704 | if (get_user(name[i], args->name + i)) | 2704 | if (get_user(name[i], args->name + i)) |
2705 | return -EFAULT; | 2705 | return -EFAULT; |
2706 | 2706 | ||
2707 | /* Ignore accesses to kernel.version */ | 2707 | /* Ignore accesses to kernel.version */ |
2708 | if ((args->nlen == 2) && (name[0] == CTL_KERN) && (name[1] == KERN_VERSION)) | 2708 | if ((args->nlen == 2) && (name[0] == CTL_KERN) && (name[1] == KERN_VERSION)) |
2709 | return 0; | 2709 | return 0; |
2710 | 2710 | ||
2711 | if (msg_count < 5) { | 2711 | if (msg_count < 5) { |
2712 | msg_count++; | 2712 | msg_count++; |
2713 | printk(KERN_INFO | 2713 | printk(KERN_INFO |
2714 | "warning: process `%s' used the deprecated sysctl " | 2714 | "warning: process `%s' used the deprecated sysctl " |
2715 | "system call with ", current->comm); | 2715 | "system call with ", current->comm); |
2716 | for (i = 0; i < args->nlen; i++) | 2716 | for (i = 0; i < args->nlen; i++) |
2717 | printk("%d.", name[i]); | 2717 | printk("%d.", name[i]); |
2718 | printk("\n"); | 2718 | printk("\n"); |
2719 | } | 2719 | } |
2720 | return 0; | 2720 | return 0; |
2721 | } | 2721 | } |
2722 | 2722 | ||
2723 | /* | 2723 | /* |
2724 | * No sense putting this after each symbol definition, twice, | 2724 | * No sense putting this after each symbol definition, twice, |
2725 | * exception granted :-) | 2725 | * exception granted :-) |
2726 | */ | 2726 | */ |
2727 | EXPORT_SYMBOL(proc_dointvec); | 2727 | EXPORT_SYMBOL(proc_dointvec); |
2728 | EXPORT_SYMBOL(proc_dointvec_jiffies); | 2728 | EXPORT_SYMBOL(proc_dointvec_jiffies); |
2729 | EXPORT_SYMBOL(proc_dointvec_minmax); | 2729 | EXPORT_SYMBOL(proc_dointvec_minmax); |
2730 | EXPORT_SYMBOL(proc_dointvec_userhz_jiffies); | 2730 | EXPORT_SYMBOL(proc_dointvec_userhz_jiffies); |
2731 | EXPORT_SYMBOL(proc_dointvec_ms_jiffies); | 2731 | EXPORT_SYMBOL(proc_dointvec_ms_jiffies); |
2732 | EXPORT_SYMBOL(proc_dostring); | 2732 | EXPORT_SYMBOL(proc_dostring); |
2733 | EXPORT_SYMBOL(proc_doulongvec_minmax); | 2733 | EXPORT_SYMBOL(proc_doulongvec_minmax); |
2734 | EXPORT_SYMBOL(proc_doulongvec_ms_jiffies_minmax); | 2734 | EXPORT_SYMBOL(proc_doulongvec_ms_jiffies_minmax); |
2735 | EXPORT_SYMBOL(register_sysctl_table); | 2735 | EXPORT_SYMBOL(register_sysctl_table); |
2736 | EXPORT_SYMBOL(sysctl_intvec); | 2736 | EXPORT_SYMBOL(sysctl_intvec); |
2737 | EXPORT_SYMBOL(sysctl_jiffies); | 2737 | EXPORT_SYMBOL(sysctl_jiffies); |
2738 | EXPORT_SYMBOL(sysctl_ms_jiffies); | 2738 | EXPORT_SYMBOL(sysctl_ms_jiffies); |
2739 | EXPORT_SYMBOL(sysctl_string); | 2739 | EXPORT_SYMBOL(sysctl_string); |
2740 | EXPORT_SYMBOL(sysctl_data); | 2740 | EXPORT_SYMBOL(sysctl_data); |
2741 | EXPORT_SYMBOL(unregister_sysctl_table); | 2741 | EXPORT_SYMBOL(unregister_sysctl_table); |
2742 | 2742 |