diff options
Diffstat (limited to 'include/linux/sched.h')
-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 |