Re: [PATCH] sched/topology: fix the issue groups don't span domain->span for NUMA diameter > 2

From: kernel test robot
Date: Mon Feb 01 2021 - 00:44:39 EST


Hi Barry,

I love your patch! Perhaps something to improve:

[auto build test WARNING on tip/sched/core]
[also build test WARNING on next-20210125]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url: https://github.com/0day-ci/linux/commits/Barry-Song/sched-topology-fix-the-issue-groups-don-t-span-domain-span-for-NUMA-diameter-2/20210201-114807
base: https://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git 7a976f77bb962ce9486e09eb839aa135619b54f3
config: i386-randconfig-s001-20210201 (attached as .config)
compiler: gcc-9 (Debian 9.3.0-15) 9.3.0
reproduce:
# apt-get install sparse
# sparse version: v0.6.3-215-g0fb77bb6-dirty
# https://github.com/0day-ci/linux/commit/a8f7eae6bc5ac37efd8cbe15e0a388127619f1b0
git remote add linux-review https://github.com/0day-ci/linux
git fetch --no-tags linux-review Barry-Song/sched-topology-fix-the-issue-groups-don-t-span-domain-span-for-NUMA-diameter-2/20210201-114807
git checkout a8f7eae6bc5ac37efd8cbe15e0a388127619f1b0
# save the attached .config to linux build tree
make W=1 C=1 CF='-fdiagnostic-prefix -D__CHECK_ENDIAN__' ARCH=i386

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@xxxxxxxxx>


"sparse warnings: (new ones prefixed by >>)"
kernel/sched/topology.c:106:56: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected struct sched_domain *sd @@ got struct sched_domain [noderef] __rcu *child @@
kernel/sched/topology.c:106:56: sparse: expected struct sched_domain *sd
kernel/sched/topology.c:106:56: sparse: got struct sched_domain [noderef] __rcu *child
kernel/sched/topology.c:125:60: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected struct sched_domain *sd @@ got struct sched_domain [noderef] __rcu *parent @@
kernel/sched/topology.c:125:60: sparse: expected struct sched_domain *sd
kernel/sched/topology.c:125:60: sparse: got struct sched_domain [noderef] __rcu *parent
kernel/sched/topology.c:148:20: sparse: sparse: incorrect type in assignment (different address spaces) @@ expected struct sched_domain *sd @@ got struct sched_domain [noderef] __rcu *parent @@
kernel/sched/topology.c:148:20: sparse: expected struct sched_domain *sd
kernel/sched/topology.c:148:20: sparse: got struct sched_domain [noderef] __rcu *parent
kernel/sched/topology.c:431:13: sparse: sparse: incorrect type in assignment (different address spaces) @@ expected struct perf_domain *[assigned] tmp @@ got struct perf_domain [noderef] __rcu *pd @@
kernel/sched/topology.c:431:13: sparse: expected struct perf_domain *[assigned] tmp
kernel/sched/topology.c:431:13: sparse: got struct perf_domain [noderef] __rcu *pd
kernel/sched/topology.c:440:13: sparse: sparse: incorrect type in assignment (different address spaces) @@ expected struct perf_domain *[assigned] tmp @@ got struct perf_domain [noderef] __rcu *pd @@
kernel/sched/topology.c:440:13: sparse: expected struct perf_domain *[assigned] tmp
kernel/sched/topology.c:440:13: sparse: got struct perf_domain [noderef] __rcu *pd
kernel/sched/topology.c:461:19: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected struct perf_domain *[assigned] pd @@ got struct perf_domain [noderef] __rcu *pd @@
kernel/sched/topology.c:461:19: sparse: expected struct perf_domain *[assigned] pd
kernel/sched/topology.c:461:19: sparse: got struct perf_domain [noderef] __rcu *pd
kernel/sched/topology.c:623:49: sparse: sparse: incorrect type in initializer (different address spaces) @@ expected struct sched_domain *parent @@ got struct sched_domain [noderef] __rcu *parent @@
kernel/sched/topology.c:623:49: sparse: expected struct sched_domain *parent
kernel/sched/topology.c:623:49: sparse: got struct sched_domain [noderef] __rcu *parent
kernel/sched/topology.c:695:50: sparse: sparse: incorrect type in initializer (different address spaces) @@ expected struct sched_domain *parent @@ got struct sched_domain [noderef] __rcu *parent @@
kernel/sched/topology.c:695:50: sparse: expected struct sched_domain *parent
kernel/sched/topology.c:695:50: sparse: got struct sched_domain [noderef] __rcu *parent
kernel/sched/topology.c:702:55: sparse: sparse: incorrect type in assignment (different address spaces) @@ expected struct sched_domain [noderef] __rcu *[noderef] __rcu child @@ got struct sched_domain *[assigned] tmp @@
kernel/sched/topology.c:702:55: sparse: expected struct sched_domain [noderef] __rcu *[noderef] __rcu child
kernel/sched/topology.c:702:55: sparse: got struct sched_domain *[assigned] tmp
kernel/sched/topology.c:712:29: sparse: sparse: incorrect type in assignment (different address spaces) @@ expected struct sched_domain *[assigned] tmp @@ got struct sched_domain [noderef] __rcu *parent @@
kernel/sched/topology.c:712:29: sparse: expected struct sched_domain *[assigned] tmp
kernel/sched/topology.c:712:29: sparse: got struct sched_domain [noderef] __rcu *parent
kernel/sched/topology.c:717:20: sparse: sparse: incorrect type in assignment (different address spaces) @@ expected struct sched_domain *sd @@ got struct sched_domain [noderef] __rcu *parent @@
kernel/sched/topology.c:717:20: sparse: expected struct sched_domain *sd
kernel/sched/topology.c:717:20: sparse: got struct sched_domain [noderef] __rcu *parent
kernel/sched/topology.c:723:33: sparse: sparse: incorrect type in assignment (different address spaces) @@ expected struct sched_domain *[assigned] tmp @@ got struct sched_domain [noderef] __rcu *parent @@
kernel/sched/topology.c:723:33: sparse: expected struct sched_domain *[assigned] tmp
kernel/sched/topology.c:723:33: sparse: got struct sched_domain [noderef] __rcu *parent
kernel/sched/topology.c:729:13: sparse: sparse: incorrect type in assignment (different address spaces) @@ expected struct sched_domain *[assigned] tmp @@ got struct sched_domain [noderef] __rcu *sd @@
kernel/sched/topology.c:729:13: sparse: expected struct sched_domain *[assigned] tmp
kernel/sched/topology.c:729:13: sparse: got struct sched_domain [noderef] __rcu *sd
kernel/sched/topology.c:891:66: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected struct sched_domain *sd @@ got struct sched_domain [noderef] __rcu *child @@
kernel/sched/topology.c:891:66: sparse: expected struct sched_domain *sd
kernel/sched/topology.c:891:66: sparse: got struct sched_domain [noderef] __rcu *child
>> kernel/sched/topology.c:893:33: sparse: sparse: incorrect type in assignment (different address spaces) @@ expected struct sched_domain *[assigned] sibling @@ got struct sched_domain [noderef] __rcu *child @@
kernel/sched/topology.c:893:33: sparse: expected struct sched_domain *[assigned] sibling
kernel/sched/topology.c:893:33: sparse: got struct sched_domain [noderef] __rcu *child
kernel/sched/topology.c:896:70: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected struct sched_domain *sd @@ got struct sched_domain [noderef] __rcu *child @@
kernel/sched/topology.c:896:70: sparse: expected struct sched_domain *sd
kernel/sched/topology.c:896:70: sparse: got struct sched_domain [noderef] __rcu *child
kernel/sched/topology.c:925:59: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected struct sched_domain *sd @@ got struct sched_domain [noderef] __rcu *child @@
kernel/sched/topology.c:925:59: sparse: expected struct sched_domain *sd
kernel/sched/topology.c:925:59: sparse: got struct sched_domain [noderef] __rcu *child
kernel/sched/topology.c:1033:65: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected struct sched_domain *sd @@ got struct sched_domain [noderef] __rcu *child @@
kernel/sched/topology.c:1033:65: sparse: expected struct sched_domain *sd
kernel/sched/topology.c:1033:65: sparse: got struct sched_domain [noderef] __rcu *child
kernel/sched/topology.c:1035:33: sparse: sparse: incorrect type in assignment (different address spaces) @@ expected struct sched_domain *[assigned] sibling @@ got struct sched_domain [noderef] __rcu *child @@
kernel/sched/topology.c:1035:33: sparse: expected struct sched_domain *[assigned] sibling
kernel/sched/topology.c:1035:33: sparse: got struct sched_domain [noderef] __rcu *child
kernel/sched/topology.c:1140:40: sparse: sparse: incorrect type in initializer (different address spaces) @@ expected struct sched_domain *child @@ got struct sched_domain [noderef] __rcu *child @@
kernel/sched/topology.c:1140:40: sparse: expected struct sched_domain *child
kernel/sched/topology.c:1140:40: sparse: got struct sched_domain [noderef] __rcu *child
kernel/sched/topology.c:1441:43: sparse: sparse: incorrect type in initializer (different address spaces) @@ expected struct sched_domain [noderef] __rcu *child @@ got struct sched_domain *child @@
kernel/sched/topology.c:1441:43: sparse: expected struct sched_domain [noderef] __rcu *child
kernel/sched/topology.c:1441:43: sparse: got struct sched_domain *child
kernel/sched/topology.c:1926:31: sparse: sparse: incorrect type in assignment (different address spaces) @@ expected struct sched_domain [noderef] __rcu *parent @@ got struct sched_domain *sd @@
kernel/sched/topology.c:1926:31: sparse: expected struct sched_domain [noderef] __rcu *parent
kernel/sched/topology.c:1926:31: sparse: got struct sched_domain *sd
kernel/sched/topology.c:2094:57: sparse: sparse: incorrect type in assignment (different address spaces) @@ expected struct sched_domain *[assigned] sd @@ got struct sched_domain [noderef] __rcu *parent @@
kernel/sched/topology.c:2094:57: sparse: expected struct sched_domain *[assigned] sd
kernel/sched/topology.c:2094:57: sparse: got struct sched_domain [noderef] __rcu *parent
kernel/sched/topology.c:2111:57: sparse: sparse: incorrect type in assignment (different address spaces) @@ expected struct sched_domain *[assigned] sd @@ got struct sched_domain [noderef] __rcu *parent @@
kernel/sched/topology.c:2111:57: sparse: expected struct sched_domain *[assigned] sd
kernel/sched/topology.c:2111:57: sparse: got struct sched_domain [noderef] __rcu *parent
kernel/sched/topology.c:59:25: sparse: sparse: dereference of noderef expression
kernel/sched/topology.c:64:25: sparse: sparse: dereference of noderef expression
kernel/sched/topology.c: note: in included file:
kernel/sched/sched.h:1455:9: sparse: sparse: incorrect type in assignment (different address spaces) @@ expected struct sched_domain *[assigned] sd @@ got struct sched_domain [noderef] __rcu *parent @@
kernel/sched/sched.h:1455:9: sparse: expected struct sched_domain *[assigned] sd
kernel/sched/sched.h:1455:9: sparse: got struct sched_domain [noderef] __rcu *parent
kernel/sched/sched.h:1468:9: sparse: sparse: incorrect type in assignment (different address spaces) @@ expected struct sched_domain *[assigned] sd @@ got struct sched_domain [noderef] __rcu *parent @@
kernel/sched/sched.h:1468:9: sparse: expected struct sched_domain *[assigned] sd
kernel/sched/sched.h:1468:9: sparse: got struct sched_domain [noderef] __rcu *parent
kernel/sched/sched.h:1455:9: sparse: sparse: incorrect type in assignment (different address spaces) @@ expected struct sched_domain *[assigned] sd @@ got struct sched_domain [noderef] __rcu *parent @@
kernel/sched/sched.h:1455:9: sparse: expected struct sched_domain *[assigned] sd
kernel/sched/sched.h:1455:9: sparse: got struct sched_domain [noderef] __rcu *parent
kernel/sched/sched.h:1468:9: sparse: sparse: incorrect type in assignment (different address spaces) @@ expected struct sched_domain *[assigned] sd @@ got struct sched_domain [noderef] __rcu *parent @@
kernel/sched/sched.h:1468:9: sparse: expected struct sched_domain *[assigned] sd
kernel/sched/sched.h:1468:9: sparse: got struct sched_domain [noderef] __rcu *parent
kernel/sched/topology.c:1456:19: sparse: sparse: dereference of noderef expression

vim +893 kernel/sched/topology.c

762
763
764 /*
765 * NUMA topology (first read the regular topology blurb below)
766 *
767 * Given a node-distance table, for example:
768 *
769 * node 0 1 2 3
770 * 0: 10 20 30 20
771 * 1: 20 10 20 30
772 * 2: 30 20 10 20
773 * 3: 20 30 20 10
774 *
775 * which represents a 4 node ring topology like:
776 *
777 * 0 ----- 1
778 * | |
779 * | |
780 * | |
781 * 3 ----- 2
782 *
783 * We want to construct domains and groups to represent this. The way we go
784 * about doing this is to build the domains on 'hops'. For each NUMA level we
785 * construct the mask of all nodes reachable in @level hops.
786 *
787 * For the above NUMA topology that gives 3 levels:
788 *
789 * NUMA-2 0-3 0-3 0-3 0-3
790 * groups: {0-1,3},{1-3} {0-2},{0,2-3} {1-3},{0-1,3} {0,2-3},{0-2}
791 *
792 * NUMA-1 0-1,3 0-2 1-3 0,2-3
793 * groups: {0},{1},{3} {0},{1},{2} {1},{2},{3} {0},{2},{3}
794 *
795 * NUMA-0 0 1 2 3
796 *
797 *
798 * As can be seen; things don't nicely line up as with the regular topology.
799 * When we iterate a domain in child domain chunks some nodes can be
800 * represented multiple times -- hence the "overlap" naming for this part of
801 * the topology.
802 *
803 * In order to minimize this overlap, we only build enough groups to cover the
804 * domain. For instance Node-0 NUMA-2 would only get groups: 0-1,3 and 1-3.
805 *
806 * Because:
807 *
808 * - the first group of each domain is its child domain; this
809 * gets us the first 0-1,3
810 * - the only uncovered node is 2, who's child domain is 1-3.
811 *
812 * However, because of the overlap, computing a unique CPU for each group is
813 * more complicated. Consider for instance the groups of NODE-1 NUMA-2, both
814 * groups include the CPUs of Node-0, while those CPUs would not in fact ever
815 * end up at those groups (they would end up in group: 0-1,3).
816 *
817 * To correct this we have to introduce the group balance mask. This mask
818 * will contain those CPUs in the group that can reach this group given the
819 * (child) domain tree.
820 *
821 * With this we can once again compute balance_cpu and sched_group_capacity
822 * relations.
823 *
824 * XXX include words on how balance_cpu is unique and therefore can be
825 * used for sched_group_capacity links.
826 *
827 *
828 * Another 'interesting' topology is:
829 *
830 * node 0 1 2 3
831 * 0: 10 20 20 30
832 * 1: 20 10 20 20
833 * 2: 20 20 10 20
834 * 3: 30 20 20 10
835 *
836 * Which looks a little like:
837 *
838 * 0 ----- 1
839 * | / |
840 * | / |
841 * | / |
842 * 2 ----- 3
843 *
844 * This topology is asymmetric, nodes 1,2 are fully connected, but nodes 0,3
845 * are not.
846 *
847 * This leads to a few particularly weird cases where the sched_domain's are
848 * not of the same number for each CPU. Consider:
849 *
850 * NUMA-2 0-3 0-3
851 * groups: {0-2},{1-3} {1-3},{0-2}
852 *
853 * NUMA-1 0-2 0-3 0-3 1-3
854 *
855 * NUMA-0 0 1 2 3
856 *
857 */
858
859
860 /*
861 * Build the balance mask; it contains only those CPUs that can arrive at this
862 * group and should be considered to continue balancing.
863 *
864 * We do this during the group creation pass, therefore the group information
865 * isn't complete yet, however since each group represents a (child) domain we
866 * can fully construct this using the sched_domain bits (which are already
867 * complete).
868 */
869 static void
870 build_balance_mask(struct sched_domain *sd, struct sched_group *sg, struct cpumask *mask)
871 {
872 const struct cpumask *sg_span = sched_group_span(sg);
873 struct sd_data *sdd = sd->private;
874 struct sched_domain *sibling;
875 int i;
876
877 cpumask_clear(mask);
878
879 for_each_cpu(i, sg_span) {
880 sibling = *per_cpu_ptr(sdd->sd, i);
881
882 /*
883 * Can happen in the asymmetric case, where these siblings are
884 * unused. The mask will not be empty because those CPUs that
885 * do have the top domain _should_ span the domain.
886 */
887 if (!sibling->child)
888 continue;
889
890 while (sibling->child &&
891 !cpumask_subset(sched_domain_span(sibling->child),
892 sched_domain_span(sd)))
> 893 sibling = sibling->child;
894
895 /* If we would not end up here, we can't continue from here */
896 if (!cpumask_equal(sg_span, sched_domain_span(sibling->child)))
897 continue;
898
899 cpumask_set_cpu(i, mask);
900 }
901
902 /* We must not have empty masks here */
903 WARN_ON_ONCE(cpumask_empty(mask));
904 }
905

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all@xxxxxxxxxxxx

Attachment: .config.gz
Description: application/gzip