aboutsummaryrefslogtreecommitdiffstats
path: root/include
diff options
context:
space:
mode:
authorIngo Molnar <mingo@elte.hu>2006-01-08 04:01:37 -0500
committerLinus Torvalds <torvalds@g5.osdl.org>2006-01-08 23:13:40 -0500
commite56d090310d7625ecb43a1eeebd479f04affb48b (patch)
tree2f479215dff4a2d8f3a9ed85200a5bc4f51534be /include
parent4369ef3c3e9d3bd9b879580678778f558d481e90 (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')
-rw-r--r--include/linux/sched.h32
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
357extern void sighand_free_cb(struct rcu_head *rhp);
358
359static 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
849static inline pid_t process_group(struct task_struct *tsk) 859static inline pid_t process_group(struct task_struct *tsk)
@@ -867,8 +877,26 @@ static inline int pid_alive(struct task_struct *p)
867extern void free_task(struct task_struct *tsk); 877extern void free_task(struct task_struct *tsk);
868extern void __put_task_struct(struct task_struct *tsk); 878extern 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
871do { if (atomic_dec_and_test(&(tsk)->usage)) __put_task_struct(tsk); } while(0) 881static 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
893extern void __put_task_struct_cb(struct rcu_head *rhp);
894
895static 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