@@ -34,6 +34,7 @@ typedef void (*postgp_func_t)(struct rcu_tasks *rtp);
34
34
* @rtp_blkd_tasks: List of tasks blocked as readers.
35
35
* @rtp_exit_list: List of tasks in the latter portion of do_exit().
36
36
* @cpu: CPU number corresponding to this entry.
37
+ * @index: Index of this CPU in rtpcp_array of the rcu_tasks structure.
37
38
* @rtpp: Pointer to the rcu_tasks structure.
38
39
*/
39
40
struct rcu_tasks_percpu {
@@ -49,6 +50,7 @@ struct rcu_tasks_percpu {
49
50
struct list_head rtp_blkd_tasks ;
50
51
struct list_head rtp_exit_list ;
51
52
int cpu ;
53
+ int index ;
52
54
struct rcu_tasks * rtpp ;
53
55
};
54
56
@@ -76,6 +78,7 @@ struct rcu_tasks_percpu {
76
78
* @call_func: This flavor's call_rcu()-equivalent function.
77
79
* @wait_state: Task state for synchronous grace-period waits (default TASK_UNINTERRUPTIBLE).
78
80
* @rtpcpu: This flavor's rcu_tasks_percpu structure.
81
+ * @rtpcp_array: Array of pointers to rcu_tasks_percpu structure of CPUs in cpu_possible_mask.
79
82
* @percpu_enqueue_shift: Shift down CPU ID this much when enqueuing callbacks.
80
83
* @percpu_enqueue_lim: Number of per-CPU callback queues in use for enqueuing.
81
84
* @percpu_dequeue_lim: Number of per-CPU callback queues in use for dequeuing.
@@ -110,6 +113,7 @@ struct rcu_tasks {
110
113
call_rcu_func_t call_func ;
111
114
unsigned int wait_state ;
112
115
struct rcu_tasks_percpu __percpu * rtpcpu ;
116
+ struct rcu_tasks_percpu * * rtpcp_array ;
113
117
int percpu_enqueue_shift ;
114
118
int percpu_enqueue_lim ;
115
119
int percpu_dequeue_lim ;
@@ -182,6 +186,8 @@ module_param(rcu_task_collapse_lim, int, 0444);
182
186
static int rcu_task_lazy_lim __read_mostly = 32 ;
183
187
module_param (rcu_task_lazy_lim , int , 0444 );
184
188
189
+ static int rcu_task_cpu_ids ;
190
+
185
191
/* RCU tasks grace-period state for debugging. */
186
192
#define RTGS_INIT 0
187
193
#define RTGS_WAIT_WAIT_CBS 1
@@ -245,6 +251,8 @@ static void cblist_init_generic(struct rcu_tasks *rtp)
245
251
int cpu ;
246
252
int lim ;
247
253
int shift ;
254
+ int maxcpu ;
255
+ int index = 0 ;
248
256
249
257
if (rcu_task_enqueue_lim < 0 ) {
250
258
rcu_task_enqueue_lim = 1 ;
@@ -254,14 +262,9 @@ static void cblist_init_generic(struct rcu_tasks *rtp)
254
262
}
255
263
lim = rcu_task_enqueue_lim ;
256
264
257
- if (lim > nr_cpu_ids )
258
- lim = nr_cpu_ids ;
259
- shift = ilog2 (nr_cpu_ids / lim );
260
- if (((nr_cpu_ids - 1 ) >> shift ) >= lim )
261
- shift ++ ;
262
- WRITE_ONCE (rtp -> percpu_enqueue_shift , shift );
263
- WRITE_ONCE (rtp -> percpu_dequeue_lim , lim );
264
- smp_store_release (& rtp -> percpu_enqueue_lim , lim );
265
+ rtp -> rtpcp_array = kcalloc (num_possible_cpus (), sizeof (struct rcu_tasks_percpu * ), GFP_KERNEL );
266
+ BUG_ON (!rtp -> rtpcp_array );
267
+
265
268
for_each_possible_cpu (cpu ) {
266
269
struct rcu_tasks_percpu * rtpcp = per_cpu_ptr (rtp -> rtpcpu , cpu );
267
270
@@ -273,14 +276,29 @@ static void cblist_init_generic(struct rcu_tasks *rtp)
273
276
INIT_WORK (& rtpcp -> rtp_work , rcu_tasks_invoke_cbs_wq );
274
277
rtpcp -> cpu = cpu ;
275
278
rtpcp -> rtpp = rtp ;
279
+ rtpcp -> index = index ;
280
+ rtp -> rtpcp_array [index ] = rtpcp ;
281
+ index ++ ;
276
282
if (!rtpcp -> rtp_blkd_tasks .next )
277
283
INIT_LIST_HEAD (& rtpcp -> rtp_blkd_tasks );
278
284
if (!rtpcp -> rtp_exit_list .next )
279
285
INIT_LIST_HEAD (& rtpcp -> rtp_exit_list );
286
+ maxcpu = cpu ;
280
287
}
281
288
282
- pr_info ("%s: Setting shift to %d and lim to %d rcu_task_cb_adjust=%d.\n" , rtp -> name ,
283
- data_race (rtp -> percpu_enqueue_shift ), data_race (rtp -> percpu_enqueue_lim ), rcu_task_cb_adjust );
289
+ rcu_task_cpu_ids = maxcpu + 1 ;
290
+ if (lim > rcu_task_cpu_ids )
291
+ lim = rcu_task_cpu_ids ;
292
+ shift = ilog2 (rcu_task_cpu_ids / lim );
293
+ if (((rcu_task_cpu_ids - 1 ) >> shift ) >= lim )
294
+ shift ++ ;
295
+ WRITE_ONCE (rtp -> percpu_enqueue_shift , shift );
296
+ WRITE_ONCE (rtp -> percpu_dequeue_lim , lim );
297
+ smp_store_release (& rtp -> percpu_enqueue_lim , lim );
298
+
299
+ pr_info ("%s: Setting shift to %d and lim to %d rcu_task_cb_adjust=%d rcu_task_cpu_ids=%d.\n" ,
300
+ rtp -> name , data_race (rtp -> percpu_enqueue_shift ), data_race (rtp -> percpu_enqueue_lim ),
301
+ rcu_task_cb_adjust , rcu_task_cpu_ids );
284
302
}
285
303
286
304
// Compute wakeup time for lazy callback timer.
@@ -348,7 +366,7 @@ static void call_rcu_tasks_generic(struct rcu_head *rhp, rcu_callback_t func,
348
366
rtpcp -> rtp_n_lock_retries = 0 ;
349
367
}
350
368
if (rcu_task_cb_adjust && ++ rtpcp -> rtp_n_lock_retries > rcu_task_contend_lim &&
351
- READ_ONCE (rtp -> percpu_enqueue_lim ) != nr_cpu_ids )
369
+ READ_ONCE (rtp -> percpu_enqueue_lim ) != rcu_task_cpu_ids )
352
370
needadjust = true; // Defer adjustment to avoid deadlock.
353
371
}
354
372
// Queuing callbacks before initialization not yet supported.
@@ -368,10 +386,10 @@ static void call_rcu_tasks_generic(struct rcu_head *rhp, rcu_callback_t func,
368
386
raw_spin_unlock_irqrestore_rcu_node (rtpcp , flags );
369
387
if (unlikely (needadjust )) {
370
388
raw_spin_lock_irqsave (& rtp -> cbs_gbl_lock , flags );
371
- if (rtp -> percpu_enqueue_lim != nr_cpu_ids ) {
389
+ if (rtp -> percpu_enqueue_lim != rcu_task_cpu_ids ) {
372
390
WRITE_ONCE (rtp -> percpu_enqueue_shift , 0 );
373
- WRITE_ONCE (rtp -> percpu_dequeue_lim , nr_cpu_ids );
374
- smp_store_release (& rtp -> percpu_enqueue_lim , nr_cpu_ids );
391
+ WRITE_ONCE (rtp -> percpu_dequeue_lim , rcu_task_cpu_ids );
392
+ smp_store_release (& rtp -> percpu_enqueue_lim , rcu_task_cpu_ids );
375
393
pr_info ("Switching %s to per-CPU callback queuing.\n" , rtp -> name );
376
394
}
377
395
raw_spin_unlock_irqrestore (& rtp -> cbs_gbl_lock , flags );
@@ -444,6 +462,8 @@ static int rcu_tasks_need_gpcb(struct rcu_tasks *rtp)
444
462
445
463
dequeue_limit = smp_load_acquire (& rtp -> percpu_dequeue_lim );
446
464
for (cpu = 0 ; cpu < dequeue_limit ; cpu ++ ) {
465
+ if (!cpu_possible (cpu ))
466
+ continue ;
447
467
struct rcu_tasks_percpu * rtpcp = per_cpu_ptr (rtp -> rtpcpu , cpu );
448
468
449
469
/* Advance and accelerate any new callbacks. */
@@ -481,7 +501,7 @@ static int rcu_tasks_need_gpcb(struct rcu_tasks *rtp)
481
501
if (rcu_task_cb_adjust && ncbs <= rcu_task_collapse_lim ) {
482
502
raw_spin_lock_irqsave (& rtp -> cbs_gbl_lock , flags );
483
503
if (rtp -> percpu_enqueue_lim > 1 ) {
484
- WRITE_ONCE (rtp -> percpu_enqueue_shift , order_base_2 (nr_cpu_ids ));
504
+ WRITE_ONCE (rtp -> percpu_enqueue_shift , order_base_2 (rcu_task_cpu_ids ));
485
505
smp_store_release (& rtp -> percpu_enqueue_lim , 1 );
486
506
rtp -> percpu_dequeue_gpseq = get_state_synchronize_rcu ();
487
507
gpdone = false;
@@ -496,7 +516,9 @@ static int rcu_tasks_need_gpcb(struct rcu_tasks *rtp)
496
516
pr_info ("Completing switch %s to CPU-0 callback queuing.\n" , rtp -> name );
497
517
}
498
518
if (rtp -> percpu_dequeue_lim == 1 ) {
499
- for (cpu = rtp -> percpu_dequeue_lim ; cpu < nr_cpu_ids ; cpu ++ ) {
519
+ for (cpu = rtp -> percpu_dequeue_lim ; cpu < rcu_task_cpu_ids ; cpu ++ ) {
520
+ if (!cpu_possible (cpu ))
521
+ continue ;
500
522
struct rcu_tasks_percpu * rtpcp = per_cpu_ptr (rtp -> rtpcpu , cpu );
501
523
502
524
WARN_ON_ONCE (rcu_segcblist_n_cbs (& rtpcp -> cblist ));
@@ -511,30 +533,32 @@ static int rcu_tasks_need_gpcb(struct rcu_tasks *rtp)
511
533
// Advance callbacks and invoke any that are ready.
512
534
static void rcu_tasks_invoke_cbs (struct rcu_tasks * rtp , struct rcu_tasks_percpu * rtpcp )
513
535
{
514
- int cpu ;
515
- int cpunext ;
516
536
int cpuwq ;
517
537
unsigned long flags ;
518
538
int len ;
539
+ int index ;
519
540
struct rcu_head * rhp ;
520
541
struct rcu_cblist rcl = RCU_CBLIST_INITIALIZER (rcl );
521
542
struct rcu_tasks_percpu * rtpcp_next ;
522
543
523
- cpu = rtpcp -> cpu ;
524
- cpunext = cpu * 2 + 1 ;
525
- if (cpunext < smp_load_acquire (& rtp -> percpu_dequeue_lim )) {
526
- rtpcp_next = per_cpu_ptr (rtp -> rtpcpu , cpunext );
527
- cpuwq = rcu_cpu_beenfullyonline (cpunext ) ? cpunext : WORK_CPU_UNBOUND ;
528
- queue_work_on (cpuwq , system_wq , & rtpcp_next -> rtp_work );
529
- cpunext ++ ;
530
- if (cpunext < smp_load_acquire (& rtp -> percpu_dequeue_lim )) {
531
- rtpcp_next = per_cpu_ptr (rtp -> rtpcpu , cpunext );
532
- cpuwq = rcu_cpu_beenfullyonline (cpunext ) ? cpunext : WORK_CPU_UNBOUND ;
544
+ index = rtpcp -> index * 2 + 1 ;
545
+ if (index < num_possible_cpus ()) {
546
+ rtpcp_next = rtp -> rtpcp_array [index ];
547
+ if (rtpcp_next -> cpu < smp_load_acquire (& rtp -> percpu_dequeue_lim )) {
548
+ cpuwq = rcu_cpu_beenfullyonline (rtpcp_next -> cpu ) ? rtpcp_next -> cpu : WORK_CPU_UNBOUND ;
533
549
queue_work_on (cpuwq , system_wq , & rtpcp_next -> rtp_work );
550
+ index ++ ;
551
+ if (index < num_possible_cpus ()) {
552
+ rtpcp_next = rtp -> rtpcp_array [index ];
553
+ if (rtpcp_next -> cpu < smp_load_acquire (& rtp -> percpu_dequeue_lim )) {
554
+ cpuwq = rcu_cpu_beenfullyonline (rtpcp_next -> cpu ) ? rtpcp_next -> cpu : WORK_CPU_UNBOUND ;
555
+ queue_work_on (cpuwq , system_wq , & rtpcp_next -> rtp_work );
556
+ }
557
+ }
534
558
}
535
559
}
536
560
537
- if (rcu_segcblist_empty (& rtpcp -> cblist ) || ! cpu_possible ( cpu ) )
561
+ if (rcu_segcblist_empty (& rtpcp -> cblist ))
538
562
return ;
539
563
raw_spin_lock_irqsave_rcu_node (rtpcp , flags );
540
564
rcu_segcblist_advance (& rtpcp -> cblist , rcu_seq_current (& rtp -> tasks_gp_seq ));
0 commit comments