Messages in this thread Patch in this message | | | Subject | Re: [PATCH 1/7] mm: allocate mm_cpumask dynamically based on nr_cpu_ids | From | Mike Galbraith <> | Date | Sun, 08 Jul 2018 16:13:52 +0200 |
| |
On Sat, 2018-07-07 at 17:25 -0400, Rik van Riel wrote: > > > ./include/linux/bitmap.h:208:3: warning: ‘memset’ writing 64 bytes > > into a region of size 0 overflows the destination [-Wstringop- > > overflow=] > > memset(dst, 0, len); > > ^~~~~~~~~~~~~~~~~~~ > > I don't understand this one. > > Inside init_mm we have this line: > .cpu_bitmap = { [BITS_TO_LONGS(NR_CPUS)] = 0}, > > which is the way the documentation suggests statically > allocated variable size arrays should be allocated > and initialized. > > How does that result in a memset of the same size, > on the same array, to throw an error like above?
Compiler knows that ->cpu_bitmap is 64 bits of storage, and with !CPUMASK_OFFSTACK, nr_cpumask_bits = NR_CPUS. With NR_CPUS > 64, compiler gripes, with NR_CPUS <= 64 it's a happy camper.
> What am I doing wrong?
Below is what I did to get box to both STHU, and to boot with the openSUSE master branch config I sent. Without the efi_mm hunk, boot hangs early with or without the other hunk.
I build and boot tested the openSUSE config, a NOPREEMPT+MAXSMP config, my local config w. NR_CPUS=8, and master-rt w. NR_CPUS=256, which is the only one that got any real exercise (building the others).
--- drivers/firmware/efi/efi.c | 1 + include/linux/mm_types.h | 5 ++++- 2 files changed, 5 insertions(+), 1 deletion(-)
--- a/drivers/firmware/efi/efi.c +++ b/drivers/firmware/efi/efi.c @@ -82,6 +82,7 @@ struct mm_struct efi_mm = { .mmap_sem = __RWSEM_INITIALIZER(efi_mm.mmap_sem), .page_table_lock = __SPIN_LOCK_UNLOCKED(efi_mm.page_table_lock), .mmlist = LIST_HEAD_INIT(efi_mm.mmlist), + .cpu_bitmap = { [BITS_TO_LONGS(NR_CPUS)] = 0}, }; static bool disable_runtime; --- a/include/linux/mm_types.h +++ b/include/linux/mm_types.h @@ -501,7 +501,10 @@ extern struct mm_struct init_mm; static inline void mm_init_cpumask(struct mm_struct *mm) { - cpumask_clear((struct cpumask *)&mm->cpu_bitmap); + unsigned long cpu_bitmap = (unsigned long)mm; + + cpu_bitmap += offsetof(struct mm_struct, cpu_bitmap); + cpumask_clear((struct cpumask *)cpu_bitmap); } /* Future-safe accessor for struct mm_struct's cpu_vm_mask. */
| |