History

tasks: Add a count of task RCU users

Add a count of the number of RCU users (currently 1) of the task struct so that we can later add the scheduler case and get rid of the very subtle task_rcu_dereference(), and just use rcu_dereference(). As suggested by Oleg have the count overlap rcu_head so that no additional space in task_struct is required.

Eric W. Biederman committed 7 years ago

Commit 3fbd7ee1 parent 42fd8ba4 files · +14 −6Browse files

Unified · Split

4 files
  1. include/linux/sched.h +4 −1
  2. include/linux/sched/task.h +1 −0
  3. kernel/exit.c +6 −1
  4. kernel/fork.c +3 −4
include/linux/sched.h+4−1
@@ -1147,7 +1147,10 @@ struct task_struct { · 1146 unmodified lines
11471147
11481148 struct tlbflush_unmap_batch tlb_ubc;
11491149
1150− struct rcu_head rcu;
1150+ union {
1151+ refcount_t rcu_users;
1152+ struct rcu_head rcu;
1153+ };
11511154
11521155 /* Cache last used pipe for splice(): */
11531156 struct pipe_inode_info *splice_pipe;
include/linux/sched/task.h+1−0
@@ -120,6 +120,7 @@ static inline void put_task_struct(struct task_struct *t) · 119 unmodified lines
120120 }
121121
122122 struct task_struct *task_rcu_dereference(struct task_struct **ptask);
123+void put_task_struct_rcu_user(struct task_struct *task);
123124
124125 #ifdef CONFIG_ARCH_WANTS_DYNAMIC_TASK_STRUCT
125126 extern int arch_task_struct_size __read_mostly;
kernel/exit.c+6−1
@@ -182,6 +182,11 @@ static void delayed_put_task_struct(struct rcu_head *rhp) · 181 unmodified lines
182182 put_task_struct(tsk);
183183 }
184184
185+void put_task_struct_rcu_user(struct task_struct *task)
186+{
187+ if (refcount_dec_and_test(&task->rcu_users))
188+ call_rcu(&task->rcu, delayed_put_task_struct);
189+}
185190
186191 void release_task(struct task_struct *p)
187192 {
@@ -222,7 +227,7 @@ repeat: · 34 unmodified lines
222227
223228 write_unlock_irq(&tasklist_lock);
224229 release_thread(p);
225− call_rcu(&p->rcu, delayed_put_task_struct);
230+ put_task_struct_rcu_user(p);
226231
227232 p = leader;
228233 if (unlikely(zap_leader))
kernel/fork.c+3−4
@@ -902,10 +902,9 @@ static struct task_struct *dup_task_struct(struct task_struct *orig, int node) · 901 unmodified lines
902902 if (orig->cpus_ptr == &orig->cpus_mask)
903903 tsk->cpus_ptr = &tsk->cpus_mask;
904904
905− /*
906− * One for us, one for whoever does the "release_task()" (usually
907− * parent)
908− */
905+ /* One for the user space visible state that goes away when reaped. */
906+ refcount_set(&tsk->rcu_users, 1);
907+ /* One for the rcu users, and one for the scheduler */
909908 refcount_set(&tsk->usage, 2);
910909 #ifdef CONFIG_BLK_DEV_IO_TRACE
911910 tsk->btrace_seq = 0;

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t