On Sun, Dec 08, 2024 at 10:25:21AM -0800, Yury Norov wrote: > On Sun, Dec 08, 2024 at 09:42:28PM +0530, Nilay Shroff wrote: > > So the above statements expands to: > > memcpy(pinst->cpumask.pcpu->bits, pcpumask->bits, nr_cpu_ids) > > memcpy(pinst->cpumask.cbcpu->bits, cbcpumask->bits, nr_cpu_ids) > > > > Now the compiler complains about "error: ‘__builtin_memcpy’ reading > > between 257 and 536870904 bytes from a region of size 256". So the > > value of nr_cpu_ids which gcc calculated is between 257 and 536870904. > > This looks strange and incorrect. > > Thanks for the detour into internals. I did the same by myself, and > spent quite a lot of my time trying to understand why GCC believes > that here we're trying to access memory beyond idx == 256 and up to > a pretty random 536870904. > > 256 is most likely NR_CPUS/8, and that makes sense. But I have no ideas > what does this 536870904 mean. OK, it's ((u32)-64)>>3, but to me it's a > random number. I'm quite sure cpumasks machinery can't be involved in > generating it. That can also be written as (UINT_MAX - 63) / 8, which I believe matches the ultimate math of bitmap_size() if nbits is UINT_MAX (but I did not fully verify) in bitmap_copy(). I tried building this code with the in-review -fdiagnostics-details option from GCC [1] but it does not really provide any other insight here. UINT_MAX probably comes from the fact that for this configuration, large_cpumask_bits is an indeterminate value for the compiler without link time optimization because it is an extern in kernel/padata.c: | #if (NR_CPUS == 1) || defined(CONFIG_FORCE_NR_CPUS) | #define nr_cpu_ids ((unsigned int)NR_CPUS) | #else | extern unsigned int nr_cpu_ids; | #endif | ... | #if NR_CPUS <= BITS_PER_LONG | #define small_cpumask_bits ((unsigned int)NR_CPUS) | #define large_cpumask_bits ((unsigned int)NR_CPUS) | #elif NR_CPUS <= 4*BITS_PER_LONG | #define small_cpumask_bits nr_cpu_ids | #define large_cpumask_bits ((unsigned int)NR_CPUS) | #else | #define small_cpumask_bits nr_cpu_ids | #define large_cpumask_bits nr_cpu_ids | #endif