diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2012-05-31 21:47:30 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2012-05-31 21:47:30 -0400 |
commit | fb21affa49204acd409328415b49bfe90136653c (patch) | |
tree | 3535dbe0c0aad049a38cadfcffe78409397a1b32 /include | |
parent | a00b6151a2ae4c52576c35d3998e144a993d50b8 (diff) | |
parent | f23ca335462e3c84f13270b9e65f83936068ec2c (diff) |
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/signal
Pull second pile of signal handling patches from Al Viro:
"This one is just task_work_add() series + remaining prereqs for it.
There probably will be another pull request from that tree this
cycle - at least for helpers, to get them out of the way for per-arch
fixes remaining in the tree."
Fix trivial conflict in kernel/irq/manage.c: the merge of Andrew's pile
had brought in commit 97fd75b7b8e0 ("kernel/irq/manage.c: use the
pr_foo() infrastructure to prefix printks") which changed one of the
pr_err() calls that this merge moves around.
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/signal:
keys: kill task_struct->replacement_session_keyring
keys: kill the dummy key_replace_session_keyring()
keys: change keyctl_session_to_parent() to use task_work_add()
genirq: reimplement exit_irq_thread() hook via task_work_add()
task_work_add: generic process-context callbacks
avr32: missed _TIF_NOTIFY_RESUME on one of do_notify_resume callers
parisc: need to check NOTIFY_RESUME when exiting from syscall
move key_repace_session_keyring() into tracehook_notify_resume()
TIF_NOTIFY_RESUME is defined on all targets now
Diffstat (limited to 'include')
-rw-r--r-- | include/linux/interrupt.h | 4 | ||||
-rw-r--r-- | include/linux/key.h | 4 | ||||
-rw-r--r-- | include/linux/sched.h | 14 | ||||
-rw-r--r-- | include/linux/task_work.h | 33 | ||||
-rw-r--r-- | include/linux/tracehook.h | 13 |
5 files changed, 48 insertions, 20 deletions
diff --git a/include/linux/interrupt.h b/include/linux/interrupt.h index c91171599cb6..e68a8e53bb59 100644 --- a/include/linux/interrupt.h +++ b/include/linux/interrupt.h | |||
@@ -142,8 +142,6 @@ request_any_context_irq(unsigned int irq, irq_handler_t handler, | |||
142 | extern int __must_check | 142 | extern int __must_check |
143 | request_percpu_irq(unsigned int irq, irq_handler_t handler, | 143 | request_percpu_irq(unsigned int irq, irq_handler_t handler, |
144 | const char *devname, void __percpu *percpu_dev_id); | 144 | const char *devname, void __percpu *percpu_dev_id); |
145 | |||
146 | extern void exit_irq_thread(void); | ||
147 | #else | 145 | #else |
148 | 146 | ||
149 | extern int __must_check | 147 | extern int __must_check |
@@ -177,8 +175,6 @@ request_percpu_irq(unsigned int irq, irq_handler_t handler, | |||
177 | { | 175 | { |
178 | return request_irq(irq, handler, 0, devname, percpu_dev_id); | 176 | return request_irq(irq, handler, 0, devname, percpu_dev_id); |
179 | } | 177 | } |
180 | |||
181 | static inline void exit_irq_thread(void) { } | ||
182 | #endif | 178 | #endif |
183 | 179 | ||
184 | extern void free_irq(unsigned int, void *); | 180 | extern void free_irq(unsigned int, void *); |
diff --git a/include/linux/key.h b/include/linux/key.h index 5231800770e1..4cd22ed627ef 100644 --- a/include/linux/key.h +++ b/include/linux/key.h | |||
@@ -308,9 +308,6 @@ static inline bool key_is_instantiated(const struct key *key) | |||
308 | #ifdef CONFIG_SYSCTL | 308 | #ifdef CONFIG_SYSCTL |
309 | extern ctl_table key_sysctls[]; | 309 | extern ctl_table key_sysctls[]; |
310 | #endif | 310 | #endif |
311 | |||
312 | extern void key_replace_session_keyring(void); | ||
313 | |||
314 | /* | 311 | /* |
315 | * the userspace interface | 312 | * the userspace interface |
316 | */ | 313 | */ |
@@ -334,7 +331,6 @@ extern void key_init(void); | |||
334 | #define key_fsuid_changed(t) do { } while(0) | 331 | #define key_fsuid_changed(t) do { } while(0) |
335 | #define key_fsgid_changed(t) do { } while(0) | 332 | #define key_fsgid_changed(t) do { } while(0) |
336 | #define key_init() do { } while(0) | 333 | #define key_init() do { } while(0) |
337 | #define key_replace_session_keyring() do { } while(0) | ||
338 | 334 | ||
339 | #endif /* CONFIG_KEYS */ | 335 | #endif /* CONFIG_KEYS */ |
340 | #endif /* __KERNEL__ */ | 336 | #endif /* __KERNEL__ */ |
diff --git a/include/linux/sched.h b/include/linux/sched.h index f45c0b280b5d..660c8ae93471 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h | |||
@@ -1301,11 +1301,6 @@ struct task_struct { | |||
1301 | unsigned sched_reset_on_fork:1; | 1301 | unsigned sched_reset_on_fork:1; |
1302 | unsigned sched_contributes_to_load:1; | 1302 | unsigned sched_contributes_to_load:1; |
1303 | 1303 | ||
1304 | #ifdef CONFIG_GENERIC_HARDIRQS | ||
1305 | /* IRQ handler threads */ | ||
1306 | unsigned irq_thread:1; | ||
1307 | #endif | ||
1308 | |||
1309 | pid_t pid; | 1304 | pid_t pid; |
1310 | pid_t tgid; | 1305 | pid_t tgid; |
1311 | 1306 | ||
@@ -1313,10 +1308,9 @@ struct task_struct { | |||
1313 | /* Canary value for the -fstack-protector gcc feature */ | 1308 | /* Canary value for the -fstack-protector gcc feature */ |
1314 | unsigned long stack_canary; | 1309 | unsigned long stack_canary; |
1315 | #endif | 1310 | #endif |
1316 | 1311 | /* | |
1317 | /* | ||
1318 | * pointers to (original) parent process, youngest child, younger sibling, | 1312 | * pointers to (original) parent process, youngest child, younger sibling, |
1319 | * older sibling, respectively. (p->father can be replaced with | 1313 | * older sibling, respectively. (p->father can be replaced with |
1320 | * p->real_parent->pid) | 1314 | * p->real_parent->pid) |
1321 | */ | 1315 | */ |
1322 | struct task_struct __rcu *real_parent; /* real parent process */ | 1316 | struct task_struct __rcu *real_parent; /* real parent process */ |
@@ -1363,8 +1357,6 @@ struct task_struct { | |||
1363 | * credentials (COW) */ | 1357 | * credentials (COW) */ |
1364 | const struct cred __rcu *cred; /* effective (overridable) subjective task | 1358 | const struct cred __rcu *cred; /* effective (overridable) subjective task |
1365 | * credentials (COW) */ | 1359 | * credentials (COW) */ |
1366 | struct cred *replacement_session_keyring; /* for KEYCTL_SESSION_TO_PARENT */ | ||
1367 | |||
1368 | char comm[TASK_COMM_LEN]; /* executable name excluding path | 1360 | char comm[TASK_COMM_LEN]; /* executable name excluding path |
1369 | - access with [gs]et_task_comm (which lock | 1361 | - access with [gs]et_task_comm (which lock |
1370 | it with task_lock()) | 1362 | it with task_lock()) |
@@ -1400,6 +1392,8 @@ struct task_struct { | |||
1400 | int (*notifier)(void *priv); | 1392 | int (*notifier)(void *priv); |
1401 | void *notifier_data; | 1393 | void *notifier_data; |
1402 | sigset_t *notifier_mask; | 1394 | sigset_t *notifier_mask; |
1395 | struct hlist_head task_works; | ||
1396 | |||
1403 | struct audit_context *audit_context; | 1397 | struct audit_context *audit_context; |
1404 | #ifdef CONFIG_AUDITSYSCALL | 1398 | #ifdef CONFIG_AUDITSYSCALL |
1405 | uid_t loginuid; | 1399 | uid_t loginuid; |
diff --git a/include/linux/task_work.h b/include/linux/task_work.h new file mode 100644 index 000000000000..294d5d5e90b1 --- /dev/null +++ b/include/linux/task_work.h | |||
@@ -0,0 +1,33 @@ | |||
1 | #ifndef _LINUX_TASK_WORK_H | ||
2 | #define _LINUX_TASK_WORK_H | ||
3 | |||
4 | #include <linux/list.h> | ||
5 | #include <linux/sched.h> | ||
6 | |||
7 | struct task_work; | ||
8 | typedef void (*task_work_func_t)(struct task_work *); | ||
9 | |||
10 | struct task_work { | ||
11 | struct hlist_node hlist; | ||
12 | task_work_func_t func; | ||
13 | void *data; | ||
14 | }; | ||
15 | |||
16 | static inline void | ||
17 | init_task_work(struct task_work *twork, task_work_func_t func, void *data) | ||
18 | { | ||
19 | twork->func = func; | ||
20 | twork->data = data; | ||
21 | } | ||
22 | |||
23 | int task_work_add(struct task_struct *task, struct task_work *twork, bool); | ||
24 | struct task_work *task_work_cancel(struct task_struct *, task_work_func_t); | ||
25 | void task_work_run(void); | ||
26 | |||
27 | static inline void exit_task_work(struct task_struct *task) | ||
28 | { | ||
29 | if (unlikely(!hlist_empty(&task->task_works))) | ||
30 | task_work_run(); | ||
31 | } | ||
32 | |||
33 | #endif /* _LINUX_TASK_WORK_H */ | ||
diff --git a/include/linux/tracehook.h b/include/linux/tracehook.h index 51bd91d911c3..6a4d82bedb03 100644 --- a/include/linux/tracehook.h +++ b/include/linux/tracehook.h | |||
@@ -49,6 +49,7 @@ | |||
49 | #include <linux/sched.h> | 49 | #include <linux/sched.h> |
50 | #include <linux/ptrace.h> | 50 | #include <linux/ptrace.h> |
51 | #include <linux/security.h> | 51 | #include <linux/security.h> |
52 | #include <linux/task_work.h> | ||
52 | struct linux_binprm; | 53 | struct linux_binprm; |
53 | 54 | ||
54 | /* | 55 | /* |
@@ -153,7 +154,6 @@ static inline void tracehook_signal_handler(int sig, siginfo_t *info, | |||
153 | ptrace_notify(SIGTRAP); | 154 | ptrace_notify(SIGTRAP); |
154 | } | 155 | } |
155 | 156 | ||
156 | #ifdef TIF_NOTIFY_RESUME | ||
157 | /** | 157 | /** |
158 | * set_notify_resume - cause tracehook_notify_resume() to be called | 158 | * set_notify_resume - cause tracehook_notify_resume() to be called |
159 | * @task: task that will call tracehook_notify_resume() | 159 | * @task: task that will call tracehook_notify_resume() |
@@ -165,8 +165,10 @@ static inline void tracehook_signal_handler(int sig, siginfo_t *info, | |||
165 | */ | 165 | */ |
166 | static inline void set_notify_resume(struct task_struct *task) | 166 | static inline void set_notify_resume(struct task_struct *task) |
167 | { | 167 | { |
168 | #ifdef TIF_NOTIFY_RESUME | ||
168 | if (!test_and_set_tsk_thread_flag(task, TIF_NOTIFY_RESUME)) | 169 | if (!test_and_set_tsk_thread_flag(task, TIF_NOTIFY_RESUME)) |
169 | kick_process(task); | 170 | kick_process(task); |
171 | #endif | ||
170 | } | 172 | } |
171 | 173 | ||
172 | /** | 174 | /** |
@@ -184,7 +186,14 @@ static inline void set_notify_resume(struct task_struct *task) | |||
184 | */ | 186 | */ |
185 | static inline void tracehook_notify_resume(struct pt_regs *regs) | 187 | static inline void tracehook_notify_resume(struct pt_regs *regs) |
186 | { | 188 | { |
189 | /* | ||
190 | * The caller just cleared TIF_NOTIFY_RESUME. This barrier | ||
191 | * pairs with task_work_add()->set_notify_resume() after | ||
192 | * hlist_add_head(task->task_works); | ||
193 | */ | ||
194 | smp_mb__after_clear_bit(); | ||
195 | if (unlikely(!hlist_empty(¤t->task_works))) | ||
196 | task_work_run(); | ||
187 | } | 197 | } |
188 | #endif /* TIF_NOTIFY_RESUME */ | ||
189 | 198 | ||
190 | #endif /* <linux/tracehook.h> */ | 199 | #endif /* <linux/tracehook.h> */ |