From: "Bryan O'Sullivan" The recent merge of wli's cpumask changes into your -mm patches has spectacularly buggered the build on x86_64. Here's a patch that mostly fixes the problem. The one remaining thing that I don't like is that I'm no longer using atomic_set_mask to tell the other CPUs to flush their TLBs. This worries me a bit, but I'm going to ignore it for now, because I'm in a rush. arch/x86_64/kernel/io_apic.c | 10 +++++----- arch/x86_64/kernel/irq.c | 8 +++++--- arch/x86_64/kernel/ldt.c | 5 ++++- arch/x86_64/kernel/smp.c | 41 +++++++++++++++++++++++------------------ arch/x86_64/kernel/smpboot.c | 4 ++-- include/asm-x86_64/bitops.h | 1 + 6 files changed, 40 insertions(+), 29 deletions(-) diff -puN arch/x86_64/kernel/io_apic.c~cpumask_t-x86_64-fix arch/x86_64/kernel/io_apic.c --- 25/arch/x86_64/kernel/io_apic.c~cpumask_t-x86_64-fix 2003-07-09 02:33:23.000000000 -0700 +++ 25-akpm/arch/x86_64/kernel/io_apic.c 2003-07-09 02:33:23.000000000 -0700 @@ -1638,7 +1638,7 @@ void __init mp_config_ioapic_for_sci(int int __init io_apic_get_unique_id (int ioapic, int apic_id) { union IO_APIC_reg_00 reg_00; - static unsigned long apic_id_map = 0; + static cpumask_t apic_id_map; unsigned long flags; int i = 0; @@ -1651,7 +1651,7 @@ int __init io_apic_get_unique_id (int io * advantage of new APIC bus architecture. */ - if (!apic_id_map) + if (!cpus_empty(apic_id_map)) apic_id_map = phys_cpu_present_map; spin_lock_irqsave(&ioapic_lock, flags); @@ -1668,10 +1668,10 @@ int __init io_apic_get_unique_id (int io * Every APIC in a system must have a unique ID or we get lots of nice * 'stuck on smp_invalidate_needed IPI wait' messages. */ - if (apic_id_map & (1 << apic_id)) { + if (cpu_isset(apic_id, apic_id_map)) { for (i = 0; i < IO_APIC_MAX_ID; i++) { - if (!(apic_id_map & (1 << i))) + if (!cpu_isset(i, apic_id_map)) break; } @@ -1684,7 +1684,7 @@ int __init io_apic_get_unique_id (int io apic_id = i; } - apic_id_map |= (1 << apic_id); + cpu_set(apic_id, apic_id_map); if (reg_00.bits.ID != apic_id) { reg_00.bits.ID = apic_id; diff -puN arch/x86_64/kernel/irq.c~cpumask_t-x86_64-fix arch/x86_64/kernel/irq.c --- 25/arch/x86_64/kernel/irq.c~cpumask_t-x86_64-fix 2003-07-09 02:33:23.000000000 -0700 +++ 25-akpm/arch/x86_64/kernel/irq.c 2003-07-09 02:33:23.000000000 -0700 @@ -847,7 +847,7 @@ static int irq_affinity_read_proc (char if (count < HEX_DIGITS+1) return -EINVAL; - for (k = 0; k < sizeof(cpumask_t)/sizeof(u16); ++k) { + for (k = len = 0; k < sizeof(cpumask_t)/sizeof(u16); ++k) { int j = sprintf(page, "%04hx", (u16)cpus_coerce(tmp)); len += j; page += j; @@ -888,12 +888,14 @@ static int irq_affinity_write_proc (stru static int prof_cpu_mask_read_proc (char *page, char **start, off_t off, int count, int *eof, void *data) { - cpumask_t tmp, *mask = (unsigned long *) data; + cpumask_t tmp, *mask = (cpumask_t *) data; + int k, len; + if (count < HEX_DIGITS+1) return -EINVAL; tmp = *mask; - for (k = 0; k < sizeof(cpumask_t)/sizeof(u16); ++k) { + for (k = len = 0; k < sizeof(cpumask_t)/sizeof(u16); ++k) { int j = sprintf(page, "%04hx", (u16)cpus_coerce(tmp)); len += j; page += j; diff -puN arch/x86_64/kernel/ldt.c~cpumask_t-x86_64-fix arch/x86_64/kernel/ldt.c --- 25/arch/x86_64/kernel/ldt.c~cpumask_t-x86_64-fix 2003-07-09 02:33:23.000000000 -0700 +++ 25-akpm/arch/x86_64/kernel/ldt.c 2003-07-09 02:33:23.000000000 -0700 @@ -60,9 +60,12 @@ static int alloc_ldt(mm_context_t *pc, u wmb(); if (reload) { #ifdef CONFIG_SMP + cpumask_t mask; + preempt_disable(); + mask = cpumask_of_cpu(smp_processor_id()); load_LDT(pc); - if (current->mm->cpu_vm_mask != (1UL<mm->cpu_vm_mask, mask)) smp_call_function(flush_ldt, 0, 1, 1); preempt_enable(); #else diff -puN arch/x86_64/kernel/smpboot.c~cpumask_t-x86_64-fix arch/x86_64/kernel/smpboot.c --- 25/arch/x86_64/kernel/smpboot.c~cpumask_t-x86_64-fix 2003-07-09 02:33:23.000000000 -0700 +++ 25-akpm/arch/x86_64/kernel/smpboot.c 2003-07-09 02:33:23.000000000 -0700 @@ -54,7 +54,7 @@ #include /* Bitmask of currently online CPUs */ -cpumask_t cpu_online_map = cpumask_of_cpu(0); +cpumask_t cpu_online_map; static cpumask_t cpu_callin_map; cpumask_t cpu_callout_map; @@ -737,7 +737,7 @@ static void __init smp_boot_cpus(unsigne if (!cpu_isset(hard_smp_processor_id(), phys_cpu_present_map)) { printk("weird, boot CPU (#%d) not listed by the BIOS.\n", hard_smp_processor_id()); - cpu_set(hard_smp_processor_id(), phys_cpu_present_map()); + cpu_set(hard_smp_processor_id(), phys_cpu_present_map); } /* diff -puN arch/x86_64/kernel/smp.c~cpumask_t-x86_64-fix arch/x86_64/kernel/smp.c --- 25/arch/x86_64/kernel/smp.c~cpumask_t-x86_64-fix 2003-07-09 02:33:23.000000000 -0700 +++ 25-akpm/arch/x86_64/kernel/smp.c 2003-07-09 02:34:51.000000000 -0700 @@ -92,8 +92,9 @@ void send_IPI_self(int vector) __send_IPI_shortcut(APIC_DEST_SELF, vector); } -static inline void send_IPI_mask(int mask, int vector) +static inline void send_IPI_mask(cpumask_t cpumask, int vector) { + unsigned long mask = cpus_coerce(cpumask); unsigned long cfg; unsigned long flags; @@ -133,7 +134,7 @@ static inline void send_IPI_mask(int mas * Optimizations Manfred Spraul */ -static volatile unsigned long flush_cpumask; +static volatile cpumask_t flush_cpumask; static struct mm_struct * flush_mm; static unsigned long flush_va; static spinlock_t tlbstate_lock = SPIN_LOCK_UNLOCKED; @@ -203,7 +204,7 @@ asmlinkage void smp_invalidate_interrupt cpu = get_cpu(); - if (!test_bit(cpu, &flush_cpumask)) + if (!cpu_isset(cpu, flush_cpumask)) goto out; /* * This was a BUG() but until someone can quote me the @@ -224,7 +225,7 @@ asmlinkage void smp_invalidate_interrupt leave_mm(cpu); } ack_APIC_irq(); - clear_bit(cpu, &flush_cpumask); + cpu_clear(cpu, flush_cpumask); out: put_cpu_no_resched(); @@ -258,14 +259,15 @@ static void flush_tlb_others(cpumask_t c flush_mm = mm; flush_va = va; - atomic_set_mask(cpumask, &flush_cpumask); + cpus_or(flush_cpumask, cpumask, flush_cpumask); + /* * We have to send the IPI only to * CPUs affected. */ send_IPI_mask(cpumask, INVALIDATE_TLB_VECTOR); - while (flush_cpumask) + while (!cpus_empty(flush_cpumask)) /* nothing. lockup detection does not belong here */; flush_mm = NULL; @@ -276,23 +278,25 @@ static void flush_tlb_others(cpumask_t c void flush_tlb_current_task(void) { struct mm_struct *mm = current->mm; - unsigned long cpu_mask; + cpumask_t cpu_mask; preempt_disable(); - cpu_mask = mm->cpu_vm_mask & ~(1UL << smp_processor_id()); + cpu_mask = mm->cpu_vm_mask; + cpu_clear(smp_processor_id(), cpu_mask); local_flush_tlb(); - if (cpu_mask) + if (!cpus_empty(cpu_mask)) flush_tlb_others(cpu_mask, mm, FLUSH_ALL); preempt_enable(); } void flush_tlb_mm (struct mm_struct * mm) { - unsigned long cpu_mask; + cpumask_t cpu_mask; preempt_disable(); - cpu_mask = mm->cpu_vm_mask & ~(1UL << smp_processor_id()); + cpu_mask = mm->cpu_vm_mask; + cpu_clear(smp_processor_id(), cpu_mask); if (current->active_mm == mm) { if (current->mm) @@ -300,7 +304,7 @@ void flush_tlb_mm (struct mm_struct * mm else leave_mm(smp_processor_id()); } - if (cpu_mask) + if (!cpus_empty(cpu_mask)) flush_tlb_others(cpu_mask, mm, FLUSH_ALL); preempt_enable(); @@ -309,10 +313,11 @@ void flush_tlb_mm (struct mm_struct * mm void flush_tlb_page(struct vm_area_struct * vma, unsigned long va) { struct mm_struct *mm = vma->vm_mm; - unsigned long cpu_mask; + cpumask_t cpu_mask; preempt_disable(); - cpu_mask = mm->cpu_vm_mask & ~(1UL << smp_processor_id()); + cpu_mask = mm->cpu_vm_mask; + cpu_clear(smp_processor_id(), cpu_mask); if (current->active_mm == mm) { if(current->mm) @@ -321,7 +326,7 @@ void flush_tlb_page(struct vm_area_struc leave_mm(smp_processor_id()); } - if (cpu_mask) + if (!cpus_empty(cpu_mask)) flush_tlb_others(cpu_mask, mm, va); preempt_enable(); @@ -354,7 +359,7 @@ void smp_kdb_stop(void) void smp_send_reschedule(int cpu) { - send_IPI_mask(1 << cpu, RESCHEDULE_VECTOR); + send_IPI_mask(cpumask_of_cpu(cpu), RESCHEDULE_VECTOR); } /* @@ -490,8 +495,8 @@ int slow_smp_processor_id(void) unsigned long sp = (unsigned long)&stack_location; int offset = 0, cpu; - for (offset = 0; next_cpu(cpu_online_map, offset) < NR_CPUS; offset = cpu + 1) { - cpu = next_cpu(cpu_online_map, offset); + for (offset = 0; next_cpu(offset, cpu_online_map) < NR_CPUS; offset = cpu + 1) { + cpu = next_cpu(offset, cpu_online_map); if (sp >= (u64)cpu_pda[cpu].irqstackptr - IRQSTACKSIZE && sp <= (u64)cpu_pda[cpu].irqstackptr) diff -puN include/asm-x86_64/bitops.h~cpumask_t-x86_64-fix include/asm-x86_64/bitops.h --- 25/include/asm-x86_64/bitops.h~cpumask_t-x86_64-fix 2003-07-09 02:33:23.000000000 -0700 +++ 25-akpm/include/asm-x86_64/bitops.h 2003-07-09 02:33:23.000000000 -0700 @@ -477,6 +477,7 @@ static __inline__ int ffs(int x) * The Hamming Weight of a number is the total number of bits set in it. */ +#define hweight64(x) generic_hweight64(x) #define hweight32(x) generic_hweight32(x) #define hweight16(x) generic_hweight16(x) #define hweight8(x) generic_hweight8(x) _