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

sched/topology: Check SDF_SHARED_CHILD in highest_flag_domain()

Do not assume that all the children of a scheduling domain have a given
flag. Check whether it has the SDF_SHARED_CHILD meta flag.

Suggested-by: Ionela Voinescu <ionela.voinescu@arm.com>
Signed-off-by: Ricardo Neri <ricardo.neri-calderon@linux.intel.com>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Link: https://lore.kernel.org/r/20230406203148.19182-9-ricardo.neri-calderon@linux.intel.com

authored by

Ricardo Neri and committed by
Peter Zijlstra
40b4d3dc c9ca0788

+19 -3
+19 -3
kernel/sched/sched.h
··· 1772 1772 for (__sd = rcu_dereference_check_sched_domain(cpu_rq(cpu)->sd); \ 1773 1773 __sd; __sd = __sd->parent) 1774 1774 1775 + /* A mask of all the SD flags that have the SDF_SHARED_CHILD metaflag */ 1776 + #define SD_FLAG(name, mflags) (name * !!((mflags) & SDF_SHARED_CHILD)) | 1777 + static const unsigned int SD_SHARED_CHILD_MASK = 1778 + #include <linux/sched/sd_flags.h> 1779 + 0; 1780 + #undef SD_FLAG 1781 + 1775 1782 /** 1776 1783 * highest_flag_domain - Return highest sched_domain containing flag. 1777 1784 * @cpu: The CPU whose highest level of sched domain is to ··· 1786 1779 * @flag: The flag to check for the highest sched_domain 1787 1780 * for the given CPU. 1788 1781 * 1789 - * Returns the highest sched_domain of a CPU which contains the given flag. 1782 + * Returns the highest sched_domain of a CPU which contains @flag. If @flag has 1783 + * the SDF_SHARED_CHILD metaflag, all the children domains also have @flag. 1790 1784 */ 1791 1785 static inline struct sched_domain *highest_flag_domain(int cpu, int flag) 1792 1786 { 1793 1787 struct sched_domain *sd, *hsd = NULL; 1794 1788 1795 1789 for_each_domain(cpu, sd) { 1796 - if (!(sd->flags & flag)) 1790 + if (sd->flags & flag) { 1791 + hsd = sd; 1792 + continue; 1793 + } 1794 + 1795 + /* 1796 + * Stop the search if @flag is known to be shared at lower 1797 + * levels. It will not be found further up. 1798 + */ 1799 + if (flag & SD_SHARED_CHILD_MASK) 1797 1800 break; 1798 - hsd = sd; 1799 1801 } 1800 1802 1801 1803 return hsd;