Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

sched/topology: Allocate per-CPU sched_domain_shared in s_data

The "sched_domain_shared" object is allocated for every topology level
in __sdt_alloc() and is freed post sched domain rebuild if they aren't
assigned during sd_init().

"sd->shared" is only assigned for SD_SHARE_LLC domains and out of all
the assigned objects, only "sd_llc_shared" is ever used by the
scheduler.

Since only "sd_llc_shared" is ever used, and since SD_SHARE_LLC domains
never overlap, allocate only a single range of per-CPU
"sched_domain_shared" object with s_data instead of doing it per
topology level.

The subsequent commit uses the degeneration path to correctly assign the
"sd->shared" to the topmost SD_SHARE_LLC domain.

No functional changes are expected at this point.

Signed-off-by: K Prateek Nayak <kprateek.nayak@amd.com>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Reviewed-by: Valentin Schneider <vschneid@redhat.com>
Reviewed-by: Chen Yu <yu.c.chen@intel.com>
Reviewed-by: Dietmar Eggemann <dietmar.eggemann@arm.com>
Tested-by: Dietmar Eggemann <dietmar.eggemann@arm.com>
Link: https://patch.msgid.link/20260312044434.1974-4-kprateek.nayak@amd.com

authored by

K Prateek Nayak and committed by
Peter Zijlstra
1cc8a33c 5a7b576b

+47 -1
+47 -1
kernel/sched/topology.c
··· 782 782 } 783 783 784 784 struct s_data { 785 + struct sched_domain_shared * __percpu *sds; 785 786 struct sched_domain * __percpu *sd; 786 787 struct root_domain *rd; 787 788 }; ··· 790 789 enum s_alloc { 791 790 sa_rootdomain, 792 791 sa_sd, 792 + sa_sd_shared, 793 793 sa_sd_storage, 794 794 sa_none, 795 795 }; ··· 1537 1535 static void __sdt_free(const struct cpumask *cpu_map); 1538 1536 static int __sdt_alloc(const struct cpumask *cpu_map); 1539 1537 1538 + static void __sds_free(struct s_data *d, const struct cpumask *cpu_map); 1539 + static int __sds_alloc(struct s_data *d, const struct cpumask *cpu_map); 1540 + 1540 1541 static void __free_domain_allocs(struct s_data *d, enum s_alloc what, 1541 1542 const struct cpumask *cpu_map) 1542 1543 { ··· 1550 1545 fallthrough; 1551 1546 case sa_sd: 1552 1547 free_percpu(d->sd); 1548 + fallthrough; 1549 + case sa_sd_shared: 1550 + __sds_free(d, cpu_map); 1553 1551 fallthrough; 1554 1552 case sa_sd_storage: 1555 1553 __sdt_free(cpu_map); ··· 1569 1561 1570 1562 if (__sdt_alloc(cpu_map)) 1571 1563 return sa_sd_storage; 1564 + if (__sds_alloc(d, cpu_map)) 1565 + return sa_sd_shared; 1572 1566 d->sd = alloc_percpu(struct sched_domain *); 1573 1567 if (!d->sd) 1574 - return sa_sd_storage; 1568 + return sa_sd_shared; 1575 1569 d->rd = alloc_rootdomain(); 1576 1570 if (!d->rd) 1577 1571 return sa_sd; ··· 2472 2462 free_percpu(sdd->sgc); 2473 2463 sdd->sgc = NULL; 2474 2464 } 2465 + } 2466 + 2467 + static int __sds_alloc(struct s_data *d, const struct cpumask *cpu_map) 2468 + { 2469 + int j; 2470 + 2471 + d->sds = alloc_percpu(struct sched_domain_shared *); 2472 + if (!d->sds) 2473 + return -ENOMEM; 2474 + 2475 + for_each_cpu(j, cpu_map) { 2476 + struct sched_domain_shared *sds; 2477 + 2478 + sds = kzalloc_node(sizeof(struct sched_domain_shared), 2479 + GFP_KERNEL, cpu_to_node(j)); 2480 + if (!sds) 2481 + return -ENOMEM; 2482 + 2483 + *per_cpu_ptr(d->sds, j) = sds; 2484 + } 2485 + 2486 + return 0; 2487 + } 2488 + 2489 + static void __sds_free(struct s_data *d, const struct cpumask *cpu_map) 2490 + { 2491 + int j; 2492 + 2493 + if (!d->sds) 2494 + return; 2495 + 2496 + for_each_cpu(j, cpu_map) 2497 + kfree(*per_cpu_ptr(d->sds, j)); 2498 + 2499 + free_percpu(d->sds); 2500 + d->sds = NULL; 2475 2501 } 2476 2502 2477 2503 static struct sched_domain *build_sched_domain(struct sched_domain_topology_level *tl,