Messages in this thread | | | Date | Fri, 4 Jul 2003 03:15:10 -0400 (EDT) | From | Zwane Mwaikambo <> | Subject | Re: 2.5.74-mm1 |
| |
On Thu, 3 Jul 2003, William Lee Irwin III wrote:
> On Thu, Jul 03, 2003 at 02:15:08PM -0700, Andrew Morton wrote: > > ok. If you're feeling keen could you please revert the cpumask_t patch. > > And please send the .config, thanks. > > Zwane reproduced this and when I compiled an identical kernel for him > it went away; the only difference wsa the compiler version.
This is definitely a compiler issue, i rebuilt with;
zwane@montezuma linux-2.5.74-cpumask {0:0} gcc296 -v Reading specs from /usr/lib/gcc-lib/i386-redhat-linux7/2.96/specs gcc version 2.96 20000731 (Red Hat Linux 7.3 2.96-118)
And that works with NR_CPUS = 3 (it also explains why my 8way test box with RH7.3 worked)
Also i ended up writing a userspace test case. I then narrowed it down to -O2 with gcc 3.2 (native RH9 compiler) which causes failure;
e.g.
zwane@montezuma linux-2.5.74-cpumask {0:0} gcc -v Reading specs from /usr/lib/gcc-lib/i386-redhat-linux/3.2.2/specs Configured with: ../configure --prefix=/usr --mandir=/usr/share/man --infodir=/usr/share/info --enable-shared --enable-threads=posix --disable-checking --with-system-zlib --enable-__cxa_atexit --host=i386-redhat-linux Thread model: posix gcc version 3.2.2 20030222 (Red Hat Linux 3.2.2-5)
zwane@montezuma linux-2.5.74-cpumask {0:0} gcc -O2 test.c -o test-gcc3.2 zwane@montezuma linux-2.5.74-cpumask {0:0} ./test-gcc3.2 main: tmp 1 main: phys_cpu_present_map before 0 main: phys_cpu_present_map after 0 main: tmp 8 main: phys_cpu_present_map before 0 main: phys_cpu_present_map after 0 main: tmp 10 main: phys_cpu_present_map before 0 main: phys_cpu_present_map after 0
zwane@montezuma linux-2.5.74-cpumask {0:0} gcc -O1 test.c -o test-gcc3.2 zwane@montezuma linux-2.5.74-cpumask {0:0} ./test-gcc3.2 main: tmp 1 main: phys_cpu_present_map before 0 main: phys_cpu_present_map after 1 main: tmp 8 main: phys_cpu_present_map before 1 main: phys_cpu_present_map after 9 main: tmp 10 main: phys_cpu_present_map before 9 main: phys_cpu_present_map after 19
The second one is correct. So one definite failing piece of code was in the cpus_or() path, i'm not so sure about the others. I have attached the test case. Bill says his gcc 3.3 works...
Andrew?
-- function.linuxpower.ca#include <stdio.h> #include <linux/bitops.h>
#define BITS_PER_LONG 32 #define NR_CPUS 3 #define printk(x...) printf(x)
#define BITS_TO_LONGS(bits) \ (((bits)+BITS_PER_LONG-1)/BITS_PER_LONG) #define DECLARE_BITMAP(name,bits) \ unsigned long name[BITS_TO_LONGS(bits)] #define CLEAR_BITMAP(name,bits) \ memset(name, 0, BITS_TO_LONGS(bits)*sizeof(unsigned long))
static inline void bitmap_or(volatile unsigned long *dst, const volatile unsigned long *bitmap1, const volatile unsigned long *bitmap2, int bits) { int k;
for (k = 0; k < BITS_TO_LONGS(bits); ++k) dst[k] = bitmap1[k] | bitmap2[k]; }
#define cpu_set(cpu, map) set_bit(cpu, (map).mask) #define cpus_or(dst,src1,src2) bitmap_or((dst).mask, (src1).mask, (src2).mask, NR_CPUS) #define cpus_coerce(map) ((map).mask[0])
#define CPU_ARRAY_SIZE BITS_TO_LONGS(NR_CPUS)
#define CPU_MASK_ALL { {[0 ... CPU_ARRAY_SIZE-1] = ~0UL} } #define CPU_MASK_NONE { {[0 ... CPU_ARRAY_SIZE-1] = 0UL} }
#define cpumask_of_cpu(cpu) ({ cpumask_t __cpu_mask = CPU_MASK_NONE;\ cpu_set(cpu, __cpu_mask); \ __cpu_mask; \ })
struct cpumask { unsigned long mask[CPU_ARRAY_SIZE]; };
typedef struct cpumask cpumask_t;
static inline cpumask_t apicid_to_cpu_present(int phys_apicid) { return cpumask_of_cpu(phys_apicid); }
int main(int argc, char **argv) { int bios_apicids[] = { 0, 3, 4, -1}, i, apicid; cpumask_t phys_cpu_present_map = CPU_MASK_NONE, tmp;
for (i = 0; bios_apicids[i] != -1; i++) { apicid = bios_apicids[i]; tmp = apicid_to_cpu_present(apicid); printk("%s: tmp %lx\n", __FUNCTION__, cpus_coerce(tmp)); printk("%s: phys_cpu_present_map before %lx\n", __FUNCTION__, cpus_coerce(phys_cpu_present_map)); cpus_or(phys_cpu_present_map, phys_cpu_present_map, tmp); printk("%s: phys_cpu_present_map after %lx\n", __FUNCTION__, cpus_coerce(phys_cpu_present_map)); } return 0; }
| |