@@ -3215,6 +3215,74 @@ static s32 scx_pick_idle_cpu(const struct cpumask *cpus_allowed, u64 flags)
3215
3215
goto retry ;
3216
3216
}
3217
3217
3218
+ /*
3219
+ * Return the amount of CPUs in the same LLC domain of @cpu (or zero if the LLC
3220
+ * domain is not defined).
3221
+ */
3222
+ static unsigned int llc_weight (s32 cpu )
3223
+ {
3224
+ struct sched_domain * sd ;
3225
+
3226
+ sd = rcu_dereference (per_cpu (sd_llc , cpu ));
3227
+ if (!sd )
3228
+ return 0 ;
3229
+
3230
+ return sd -> span_weight ;
3231
+ }
3232
+
3233
+ /*
3234
+ * Return the cpumask representing the LLC domain of @cpu (or NULL if the LLC
3235
+ * domain is not defined).
3236
+ */
3237
+ static struct cpumask * llc_span (s32 cpu )
3238
+ {
3239
+ struct sched_domain * sd ;
3240
+
3241
+ sd = rcu_dereference (per_cpu (sd_llc , cpu ));
3242
+ if (!sd )
3243
+ return 0 ;
3244
+
3245
+ return sched_domain_span (sd );
3246
+ }
3247
+
3248
+ /*
3249
+ * Return the amount of CPUs in the same NUMA domain of @cpu (or zero if the
3250
+ * NUMA domain is not defined).
3251
+ */
3252
+ static unsigned int numa_weight (s32 cpu )
3253
+ {
3254
+ struct sched_domain * sd ;
3255
+ struct sched_group * sg ;
3256
+
3257
+ sd = rcu_dereference (per_cpu (sd_numa , cpu ));
3258
+ if (!sd )
3259
+ return 0 ;
3260
+ sg = sd -> groups ;
3261
+ if (!sg )
3262
+ return 0 ;
3263
+
3264
+ return sg -> group_weight ;
3265
+ }
3266
+
3267
+ /*
3268
+ * Return the cpumask representing the NUMA domain of @cpu (or NULL if the NUMA
3269
+ * domain is not defined).
3270
+ */
3271
+ static struct cpumask * numa_span (s32 cpu )
3272
+ {
3273
+ struct sched_domain * sd ;
3274
+ struct sched_group * sg ;
3275
+
3276
+ sd = rcu_dereference (per_cpu (sd_numa , cpu ));
3277
+ if (!sd )
3278
+ return NULL ;
3279
+ sg = sd -> groups ;
3280
+ if (!sg )
3281
+ return NULL ;
3282
+
3283
+ return sched_group_span (sg );
3284
+ }
3285
+
3218
3286
/*
3219
3287
* Return true if the LLC domains do not perfectly overlap with the NUMA
3220
3288
* domains, false otherwise.
@@ -3246,19 +3314,10 @@ static bool llc_numa_mismatch(void)
3246
3314
* overlapping, which is incorrect (as NUMA 1 has two distinct LLC
3247
3315
* domains).
3248
3316
*/
3249
- for_each_online_cpu (cpu ) {
3250
- const struct cpumask * numa_cpus ;
3251
- struct sched_domain * sd ;
3252
-
3253
- sd = rcu_dereference (per_cpu (sd_llc , cpu ));
3254
- if (!sd )
3317
+ for_each_online_cpu (cpu )
3318
+ if (llc_weight (cpu ) != numa_weight (cpu ))
3255
3319
return true ;
3256
3320
3257
- numa_cpus = cpumask_of_node (cpu_to_node (cpu ));
3258
- if (sd -> span_weight != cpumask_weight (numa_cpus ))
3259
- return true;
3260
- }
3261
-
3262
3321
return false;
3263
3322
}
3264
3323
@@ -3276,8 +3335,7 @@ static bool llc_numa_mismatch(void)
3276
3335
static void update_selcpu_topology (void )
3277
3336
{
3278
3337
bool enable_llc = false, enable_numa = false;
3279
- struct sched_domain * sd ;
3280
- const struct cpumask * cpus ;
3338
+ unsigned int nr_cpus ;
3281
3339
s32 cpu = cpumask_first (cpu_online_mask );
3282
3340
3283
3341
/*
@@ -3291,10 +3349,12 @@ static void update_selcpu_topology(void)
3291
3349
* CPUs.
3292
3350
*/
3293
3351
rcu_read_lock ();
3294
- sd = rcu_dereference ( per_cpu ( sd_llc , cpu ) );
3295
- if (sd ) {
3296
- if (sd -> span_weight < num_online_cpus ())
3352
+ nr_cpus = llc_weight ( cpu );
3353
+ if (nr_cpus > 0 ) {
3354
+ if (nr_cpus < num_online_cpus ())
3297
3355
enable_llc = true;
3356
+ pr_debug ("sched_ext: LLC=%*pb weight=%u\n" ,
3357
+ cpumask_pr_args (llc_span (cpu )), llc_weight (cpu ));
3298
3358
}
3299
3359
3300
3360
/*
@@ -3306,9 +3366,13 @@ static void update_selcpu_topology(void)
3306
3366
* enabling both NUMA and LLC optimizations is unnecessary, as checking
3307
3367
* for an idle CPU in the same domain twice is redundant.
3308
3368
*/
3309
- cpus = cpumask_of_node (cpu_to_node (cpu ));
3310
- if ((cpumask_weight (cpus ) < num_online_cpus ()) && llc_numa_mismatch ())
3311
- enable_numa = true;
3369
+ nr_cpus = numa_weight (cpu );
3370
+ if (nr_cpus > 0 ) {
3371
+ if (nr_cpus < num_online_cpus () && llc_numa_mismatch ())
3372
+ enable_numa = true;
3373
+ pr_debug ("sched_ext: NUMA=%*pb weight=%u\n" ,
3374
+ cpumask_pr_args (numa_span (cpu )), numa_weight (cpu ));
3375
+ }
3312
3376
rcu_read_unlock ();
3313
3377
3314
3378
pr_debug ("sched_ext: LLC idle selection %s\n" ,
@@ -3360,7 +3424,6 @@ static s32 scx_select_cpu_dfl(struct task_struct *p, s32 prev_cpu,
3360
3424
3361
3425
* found = false;
3362
3426
3363
-
3364
3427
/*
3365
3428
* This is necessary to protect llc_cpus.
3366
3429
*/
@@ -3379,15 +3442,10 @@ static s32 scx_select_cpu_dfl(struct task_struct *p, s32 prev_cpu,
3379
3442
*/
3380
3443
if (p -> nr_cpus_allowed >= num_possible_cpus ()) {
3381
3444
if (static_branch_maybe (CONFIG_NUMA , & scx_selcpu_topo_numa ))
3382
- numa_cpus = cpumask_of_node (cpu_to_node (prev_cpu ));
3383
-
3384
- if (static_branch_maybe (CONFIG_SCHED_MC , & scx_selcpu_topo_llc )) {
3385
- struct sched_domain * sd ;
3445
+ numa_cpus = numa_span (prev_cpu );
3386
3446
3387
- sd = rcu_dereference (per_cpu (sd_llc , prev_cpu ));
3388
- if (sd )
3389
- llc_cpus = sched_domain_span (sd );
3390
- }
3447
+ if (static_branch_maybe (CONFIG_SCHED_MC , & scx_selcpu_topo_llc ))
3448
+ llc_cpus = llc_span (prev_cpu );
3391
3449
}
3392
3450
3393
3451
/*
0 commit comments