diff options
author | Ingo Molnar <mingo@elte.hu> | 2006-01-08 04:01:37 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-01-08 23:13:40 -0500 |
commit | e56d090310d7625ecb43a1eeebd479f04affb48b (patch) | |
tree | 2f479215dff4a2d8f3a9ed85200a5bc4f51534be /include/linux | |
parent | 4369ef3c3e9d3bd9b879580678778f558d481e90 (diff) |
[PATCH] RCU signal handling
RCU tasklist_lock and RCU signal handling: send signals RCU-read-locked
instead of tasklist_lock read-locked. This is a scalability improvement on
SMP and a preemption-latency improvement under PREEMPT_RCU.
Signed-off-by: Paul E. McKenney <paulmck@us.ibm.com>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Acked-by: William Irwin <wli@holomorphy.com>
Cc: Roland McGrath <roland@redhat.com>
Cc: Oleg Nesterov <oleg@tv-sign.ru>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'include/linux')
-rw-r--r-- | include/linux/sched.h | 32 |
1 files changed, 30 insertions, 2 deletions
diff --git a/include/linux/sched.h b/include/linux/sched.h index a74662077d60..a6af77e9b4cf 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h | |||
@@ -34,6 +34,7 @@ | |||
34 | #include <linux/percpu.h> | 34 | #include <linux/percpu.h> |
35 | #include <linux/topology.h> | 35 | #include <linux/topology.h> |
36 | #include <linux/seccomp.h> | 36 | #include <linux/seccomp.h> |
37 | #include <linux/rcupdate.h> | ||
37 | 38 | ||
38 | #include <linux/auxvec.h> /* For AT_VECTOR_SIZE */ | 39 | #include <linux/auxvec.h> /* For AT_VECTOR_SIZE */ |
39 | 40 | ||
@@ -350,8 +351,16 @@ struct sighand_struct { | |||
350 | atomic_t count; | 351 | atomic_t count; |
351 | struct k_sigaction action[_NSIG]; | 352 | struct k_sigaction action[_NSIG]; |
352 | spinlock_t siglock; | 353 | spinlock_t siglock; |
354 | struct rcu_head rcu; | ||
353 | }; | 355 | }; |
354 | 356 | ||
357 | extern void sighand_free_cb(struct rcu_head *rhp); | ||
358 | |||
359 | static inline void sighand_free(struct sighand_struct *sp) | ||
360 | { | ||
361 | call_rcu(&sp->rcu, sighand_free_cb); | ||
362 | } | ||
363 | |||
355 | /* | 364 | /* |
356 | * NOTE! "signal_struct" does not have it's own | 365 | * NOTE! "signal_struct" does not have it's own |
357 | * locking, because a shared signal_struct always | 366 | * locking, because a shared signal_struct always |
@@ -844,6 +853,7 @@ struct task_struct { | |||
844 | int cpuset_mems_generation; | 853 | int cpuset_mems_generation; |
845 | #endif | 854 | #endif |
846 | atomic_t fs_excl; /* holding fs exclusive resources */ | 855 | atomic_t fs_excl; /* holding fs exclusive resources */ |
856 | struct rcu_head rcu; | ||
847 | }; | 857 | }; |
848 | 858 | ||
849 | static inline pid_t process_group(struct task_struct *tsk) | 859 | static inline pid_t process_group(struct task_struct *tsk) |
@@ -867,8 +877,26 @@ static inline int pid_alive(struct task_struct *p) | |||
867 | extern void free_task(struct task_struct *tsk); | 877 | extern void free_task(struct task_struct *tsk); |
868 | extern void __put_task_struct(struct task_struct *tsk); | 878 | extern void __put_task_struct(struct task_struct *tsk); |
869 | #define get_task_struct(tsk) do { atomic_inc(&(tsk)->usage); } while(0) | 879 | #define get_task_struct(tsk) do { atomic_inc(&(tsk)->usage); } while(0) |
870 | #define put_task_struct(tsk) \ | 880 | |
871 | do { if (atomic_dec_and_test(&(tsk)->usage)) __put_task_struct(tsk); } while(0) | 881 | static inline int get_task_struct_rcu(struct task_struct *t) |
882 | { | ||
883 | int oldusage; | ||
884 | |||
885 | do { | ||
886 | oldusage = atomic_read(&t->usage); | ||
887 | if (oldusage == 0) | ||
888 | return 0; | ||
889 | } while (cmpxchg(&t->usage.counter, oldusage, oldusage+1) != oldusage); | ||
890 | return 1; | ||
891 | } | ||
892 | |||
893 | extern void __put_task_struct_cb(struct rcu_head *rhp); | ||
894 | |||
895 | static inline void put_task_struct(struct task_struct *t) | ||
896 | { | ||
897 | if (atomic_dec_and_test(&t->usage)) | ||
898 | call_rcu(&t->rcu, __put_task_struct_cb); | ||
899 | } | ||
872 | 900 | ||
873 | /* | 901 | /* |
874 | * Per process flags | 902 | * Per process flags |