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/linux | |
| 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/linux')
| -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> */ |
