]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
workqueue: validate cpumask_first() result in llc_populate_cpu_shard_id()
authorBreno Leitao <leitao@debian.org>
Mon, 13 Apr 2026 14:26:47 +0000 (07:26 -0700)
committerTejun Heo <tj@kernel.org>
Mon, 13 Apr 2026 16:15:26 +0000 (06:15 -1000)
On uniprocessor (UP) configs such as nios2, NR_CPUS is 1, so
cpu_shard_id[] is a single-element array (int[1]). In
llc_populate_cpu_shard_id(), cpumask_first(sibling_cpus) returns an
unsigned int that the compiler cannot prove is always 0, triggering
a -Warray-bounds warning when the result is used to index
cpu_shard_id[]:

  kernel/workqueue.c:8321:55: warning: array subscript 1 is above
  array bounds of 'int[1]' [-Warray-bounds]
   8321 |  cpu_shard_id[c] = cpu_shard_id[cpumask_first(sibling_cpus)];
        |                    ~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~

This is a false positive: sibling_cpus can never be empty here because
'c' itself is always set in it, so cpumask_first() will always return a
valid CPU. However, the compiler cannot prove this statically, and the
warning only manifests on UP configs where the array size is 1.

Add a bounds check with WARN_ON_ONCE to silence the warning, and store
the result in a local variable to make the code clearer and avoid calling
cpumask_first() twice.

Fixes: 5920d046f7ae ("workqueue: add WQ_AFFN_CACHE_SHARD affinity scope")
Reported-by: kernel test robot <lkp@intel.com>
Closes: https://lore.kernel.org/oe-kbuild-all/202604022343.GQtkF2vO-lkp@intel.com/
Signed-off-by: Breno Leitao <leitao@debian.org>
Signed-off-by: Tejun Heo <tj@kernel.org>
kernel/workqueue.c

index 900b864a30b042dc99794ad5f7a11c6ebcded9f6..ed7330b9ddf94830b529c4602f5fb2cd83e39201 100644 (file)
@@ -8266,6 +8266,7 @@ static void __init llc_populate_cpu_shard_id(const struct cpumask *pod_cpus,
        const struct cpumask *sibling_cpus;
        /* Count the number of cores in the current shard_id */
        int cores_in_shard = 0;
+       unsigned int leader;
        /* This is a cursor for the shards. Go from zero to nr_shards - 1*/
        int shard_id = 0;
        int c;
@@ -8286,7 +8287,17 @@ static void __init llc_populate_cpu_shard_id(const struct cpumask *pod_cpus,
                         * The siblings' shard MUST be the same as the leader.
                         * never split threads in the same core.
                         */
-                       cpu_shard_id[c] = cpu_shard_id[cpumask_first(sibling_cpus)];
+                       leader = cpumask_first(sibling_cpus);
+
+                       /*
+                        * This check silences a Warray-bounds warning on UP
+                        * configs where NR_CPUS=1 makes cpu_shard_id[]
+                        * a single-element array, and the compiler can't
+                        * prove the index is always 0.
+                        */
+                       if (WARN_ON_ONCE(leader >= nr_cpu_ids))
+                               continue;
+                       cpu_shard_id[c] = cpu_shard_id[leader];
                }
        }