Skip to content

Commit b81dce7

Browse files
svanheuleakpm00
authored andcommitted
cpumask: Fix invalid uniprocessor mask assumption
On uniprocessor builds, any CPU mask is assumed to contain exactly one CPU (cpu0). This assumption ignores the existence of empty masks, resulting in incorrect behaviour. cpumask_first_zero(), cpumask_next_zero(), and for_each_cpu_not() don't provide behaviour matching the assumption that a UP mask is always "1", and instead provide behaviour matching the empty mask. Drop the incorrectly optimised code and use the generic implementations in all cases. Link: https://lkml.kernel.org/r/86bf3f005abba2d92120ddd0809235cab4f759a6.1656777646.git.sander@svanheule.net Signed-off-by: Sander Vanheule <[email protected]> Suggested-by: Yury Norov <[email protected]> Cc: Andy Shevchenko <[email protected]> Cc: Borislav Petkov <[email protected]> Cc: Dave Hansen <[email protected]> Cc: Greg Kroah-Hartman <[email protected]> Cc: "H. Peter Anvin" <[email protected]> Cc: Ingo Molnar <[email protected]> Cc: Marco Elver <[email protected]> Cc: Peter Zijlstra <[email protected]> Cc: Thomas Gleixner <[email protected]> Cc: Valentin Schneider <[email protected]> Signed-off-by: Andrew Morton <[email protected]>
1 parent 4f09903 commit b81dce7

File tree

3 files changed

+22
-82
lines changed

3 files changed

+22
-82
lines changed

include/linux/cpumask.h

Lines changed: 19 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -116,85 +116,6 @@ static __always_inline unsigned int cpumask_check(unsigned int cpu)
116116
return cpu;
117117
}
118118

119-
#if NR_CPUS == 1
120-
/* Uniprocessor. Assume all masks are "1". */
121-
static inline unsigned int cpumask_first(const struct cpumask *srcp)
122-
{
123-
return 0;
124-
}
125-
126-
static inline unsigned int cpumask_first_zero(const struct cpumask *srcp)
127-
{
128-
return 0;
129-
}
130-
131-
static inline unsigned int cpumask_first_and(const struct cpumask *srcp1,
132-
const struct cpumask *srcp2)
133-
{
134-
return 0;
135-
}
136-
137-
static inline unsigned int cpumask_last(const struct cpumask *srcp)
138-
{
139-
return 0;
140-
}
141-
142-
/* Valid inputs for n are -1 and 0. */
143-
static inline unsigned int cpumask_next(int n, const struct cpumask *srcp)
144-
{
145-
return n+1;
146-
}
147-
148-
static inline unsigned int cpumask_next_zero(int n, const struct cpumask *srcp)
149-
{
150-
return n+1;
151-
}
152-
153-
static inline unsigned int cpumask_next_and(int n,
154-
const struct cpumask *srcp,
155-
const struct cpumask *andp)
156-
{
157-
return n+1;
158-
}
159-
160-
static inline unsigned int cpumask_next_wrap(int n, const struct cpumask *mask,
161-
int start, bool wrap)
162-
{
163-
/* cpu0 unless stop condition, wrap and at cpu0, then nr_cpumask_bits */
164-
return (wrap && n == 0);
165-
}
166-
167-
/* cpu must be a valid cpu, ie 0, so there's no other choice. */
168-
static inline unsigned int cpumask_any_but(const struct cpumask *mask,
169-
unsigned int cpu)
170-
{
171-
return 1;
172-
}
173-
174-
static inline unsigned int cpumask_local_spread(unsigned int i, int node)
175-
{
176-
return 0;
177-
}
178-
179-
static inline int cpumask_any_and_distribute(const struct cpumask *src1p,
180-
const struct cpumask *src2p) {
181-
return cpumask_first_and(src1p, src2p);
182-
}
183-
184-
static inline int cpumask_any_distribute(const struct cpumask *srcp)
185-
{
186-
return cpumask_first(srcp);
187-
}
188-
189-
#define for_each_cpu(cpu, mask) \
190-
for ((cpu) = 0; (cpu) < 1; (cpu)++, (void)mask)
191-
#define for_each_cpu_not(cpu, mask) \
192-
for ((cpu) = 0; (cpu) < 1; (cpu)++, (void)mask)
193-
#define for_each_cpu_wrap(cpu, mask, start) \
194-
for ((cpu) = 0; (cpu) < 1; (cpu)++, (void)mask, (void)(start))
195-
#define for_each_cpu_and(cpu, mask1, mask2) \
196-
for ((cpu) = 0; (cpu) < 1; (cpu)++, (void)mask1, (void)mask2)
197-
#else
198119
/**
199120
* cpumask_first - get the first cpu in a cpumask
200121
* @srcp: the cpumask pointer
@@ -260,10 +181,29 @@ static inline unsigned int cpumask_next_zero(int n, const struct cpumask *srcp)
260181

261182
int __pure cpumask_next_and(int n, const struct cpumask *, const struct cpumask *);
262183
int __pure cpumask_any_but(const struct cpumask *mask, unsigned int cpu);
184+
185+
#if NR_CPUS == 1
186+
/* Uniprocessor: there is only one valid CPU */
187+
static inline unsigned int cpumask_local_spread(unsigned int i, int node)
188+
{
189+
return 0;
190+
}
191+
192+
static inline int cpumask_any_and_distribute(const struct cpumask *src1p,
193+
const struct cpumask *src2p) {
194+
return cpumask_first_and(src1p, src2p);
195+
}
196+
197+
static inline int cpumask_any_distribute(const struct cpumask *srcp)
198+
{
199+
return cpumask_first(srcp);
200+
}
201+
#else
263202
unsigned int cpumask_local_spread(unsigned int i, int node);
264203
int cpumask_any_and_distribute(const struct cpumask *src1p,
265204
const struct cpumask *src2p);
266205
int cpumask_any_distribute(const struct cpumask *srcp);
206+
#endif /* NR_CPUS */
267207

268208
/**
269209
* for_each_cpu - iterate over every cpu in a mask
@@ -324,7 +264,6 @@ extern int cpumask_next_wrap(int n, const struct cpumask *mask, int start, bool
324264
for ((cpu) = -1; \
325265
(cpu) = cpumask_next_and((cpu), (mask1), (mask2)), \
326266
(cpu) < nr_cpu_ids;)
327-
#endif /* SMP */
328267

329268
#define CPU_BITS_NONE \
330269
{ \

lib/Makefile

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,10 +34,9 @@ lib-y := ctype.o string.o vsprintf.o cmdline.o \
3434
is_single_threaded.o plist.o decompress.o kobject_uevent.o \
3535
earlycpio.o seq_buf.o siphash.o dec_and_lock.o \
3636
nmi_backtrace.o nodemask.o win_minmax.o memcat_p.o \
37-
buildid.o
37+
buildid.o cpumask.o
3838

3939
lib-$(CONFIG_PRINTK) += dump_stack.o
40-
lib-$(CONFIG_SMP) += cpumask.o
4140

4241
lib-y += kobject.o klist.o
4342
obj-y += lockref.o

lib/cpumask.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -192,6 +192,7 @@ void __init free_bootmem_cpumask_var(cpumask_var_t mask)
192192
}
193193
#endif
194194

195+
#if NR_CPUS > 1
195196
/**
196197
* cpumask_local_spread - select the i'th cpu with local numa cpu's first
197198
* @i: index number
@@ -279,3 +280,4 @@ int cpumask_any_distribute(const struct cpumask *srcp)
279280
return next;
280281
}
281282
EXPORT_SYMBOL(cpumask_any_distribute);
283+
#endif /* NR_CPUS */

0 commit comments

Comments
 (0)