@@ -211,6 +211,69 @@ static void __init rcu_tasks_bootup_oddness(void)
211
211
212
212
#ifdef CONFIG_TASKS_RCU
213
213
214
+ ////////////////////////////////////////////////////////////////////////
215
+ //
216
+ // Shared code between task-list-scanning variants of Tasks RCU.
217
+
218
+ /* Wait for one RCU-tasks grace period. */
219
+ static void rcu_tasks_wait_gp (struct rcu_tasks * rtp )
220
+ {
221
+ struct task_struct * g , * t ;
222
+ unsigned long lastreport ;
223
+ LIST_HEAD (holdouts );
224
+ int fract ;
225
+
226
+ rtp -> pregp_func ();
227
+
228
+ /*
229
+ * There were callbacks, so we need to wait for an RCU-tasks
230
+ * grace period. Start off by scanning the task list for tasks
231
+ * that are not already voluntarily blocked. Mark these tasks
232
+ * and make a list of them in holdouts.
233
+ */
234
+ rcu_read_lock ();
235
+ for_each_process_thread (g , t )
236
+ rtp -> pertask_func (t , & holdouts );
237
+ rcu_read_unlock ();
238
+
239
+ rtp -> postscan_func ();
240
+
241
+ /*
242
+ * Each pass through the following loop scans the list of holdout
243
+ * tasks, removing any that are no longer holdouts. When the list
244
+ * is empty, we are done.
245
+ */
246
+ lastreport = jiffies ;
247
+
248
+ /* Start off with HZ/10 wait and slowly back off to 1 HZ wait. */
249
+ fract = 10 ;
250
+
251
+ for (;;) {
252
+ bool firstreport ;
253
+ bool needreport ;
254
+ int rtst ;
255
+
256
+ if (list_empty (& holdouts ))
257
+ break ;
258
+
259
+ /* Slowly back off waiting for holdouts */
260
+ schedule_timeout_interruptible (HZ /fract );
261
+
262
+ if (fract > 1 )
263
+ fract -- ;
264
+
265
+ rtst = READ_ONCE (rcu_task_stall_timeout );
266
+ needreport = rtst > 0 && time_after (jiffies , lastreport + rtst );
267
+ if (needreport )
268
+ lastreport = jiffies ;
269
+ firstreport = true;
270
+ WARN_ON (signal_pending (current ));
271
+ rtp -> holdouts_func (& holdouts , needreport , & firstreport );
272
+ }
273
+
274
+ rtp -> postgp_func ();
275
+ }
276
+
214
277
////////////////////////////////////////////////////////////////////////
215
278
//
216
279
// Simple variant of RCU whose quiescent states are voluntary context
@@ -333,65 +396,6 @@ static void rcu_tasks_postgp(void)
333
396
synchronize_rcu ();
334
397
}
335
398
336
- /* Wait for one RCU-tasks grace period. */
337
- static void rcu_tasks_wait_gp (struct rcu_tasks * rtp )
338
- {
339
- struct task_struct * g , * t ;
340
- unsigned long lastreport ;
341
- LIST_HEAD (holdouts );
342
- int fract ;
343
-
344
- rtp -> pregp_func ();
345
-
346
- /*
347
- * There were callbacks, so we need to wait for an RCU-tasks
348
- * grace period. Start off by scanning the task list for tasks
349
- * that are not already voluntarily blocked. Mark these tasks
350
- * and make a list of them in holdouts.
351
- */
352
- rcu_read_lock ();
353
- for_each_process_thread (g , t )
354
- rtp -> pertask_func (t , & holdouts );
355
- rcu_read_unlock ();
356
-
357
- rtp -> postscan_func ();
358
-
359
- /*
360
- * Each pass through the following loop scans the list of holdout
361
- * tasks, removing any that are no longer holdouts. When the list
362
- * is empty, we are done.
363
- */
364
- lastreport = jiffies ;
365
-
366
- /* Start off with HZ/10 wait and slowly back off to 1 HZ wait. */
367
- fract = 10 ;
368
-
369
- for (;;) {
370
- bool firstreport ;
371
- bool needreport ;
372
- int rtst ;
373
-
374
- if (list_empty (& holdouts ))
375
- break ;
376
-
377
- /* Slowly back off waiting for holdouts */
378
- schedule_timeout_interruptible (HZ /fract );
379
-
380
- if (fract > 1 )
381
- fract -- ;
382
-
383
- rtst = READ_ONCE (rcu_task_stall_timeout );
384
- needreport = rtst > 0 && time_after (jiffies , lastreport + rtst );
385
- if (needreport )
386
- lastreport = jiffies ;
387
- firstreport = true;
388
- WARN_ON (signal_pending (current ));
389
- rtp -> holdouts_func (& holdouts , needreport , & firstreport );
390
- }
391
-
392
- rtp -> postgp_func ();
393
- }
394
-
395
399
void call_rcu_tasks (struct rcu_head * rhp , rcu_callback_t func );
396
400
DEFINE_RCU_TASKS (rcu_tasks , rcu_tasks_wait_gp , call_rcu_tasks , "RCU Tasks" );
397
401
0 commit comments