[PATCH] Scalable phys_cpu_present_map implementation

Russ Weight (rweight@us.ibm.com)
Tue, 29 Jan 2002 16:35:56 -0800


Linus,

Please consider this patch for 2.5.3. It is built against
2.5.3-pre6. Note that this patch depends on my previous patch
entitled: "[PATCH] Scalable CPU bitmasks".

This patch modifies the phys_cpu_present_map bitmask to
be a "scalable CPU bitmask". The datatype is changed to cpumap_t,
and all accesses to the bitmask are done through the appropriate
supporting functions.

This patch has been tested on a 2-quad NUMA system. It
affects i386 architecture specific code, but does not affect
other architectures.

- Russ

-- 
Russ Weight (rweight@us.ibm.com)
Linux Technology Center

diff -u cpumap/include/asm-i386/smp.h linux/include/asm-i386/smp.h --- cpumap/include/asm-i386/smp.h Mon Jan 21 16:28:09 2002 +++ linux/include/asm-i386/smp.h Tue Jan 29 15:04:41 2002 @@ -8,6 +8,7 @@ #include <linux/config.h> #include <linux/threads.h> #include <linux/ptrace.h> +#include <linux/cpumap.h> #endif #ifdef CONFIG_X86_LOCAL_APIC @@ -53,7 +54,7 @@ */ extern void smp_alloc_memory(void); -extern unsigned long phys_cpu_present_map; +extern cpumap_t phys_cpu_present_map; extern unsigned long cpu_online_map; extern volatile unsigned long smp_invalidate_needed; extern int pic_mode; diff -u cpumap/include/asm-i386/mpspec.h linux/include/asm-i386/mpspec.h --- cpumap/include/asm-i386/mpspec.h Mon Jan 21 16:28:09 2002 +++ linux/include/asm-i386/mpspec.h Tue Jan 29 15:04:41 2002 @@ -1,6 +1,8 @@ #ifndef __ASM_MPSPEC_H #define __ASM_MPSPEC_H +#include <linux/cpumap.h> + /* * Structure definitions for SMP machines following the * Intel Multiprocessing Specification 1.1 and 1.4. @@ -201,7 +203,7 @@ extern int mp_bus_id_to_pci_bus [MAX_MP_BUSSES]; extern unsigned int boot_cpu_physical_apicid; -extern unsigned long phys_cpu_present_map; +extern cpumap_t phys_cpu_present_map; extern int smp_found_config; extern void find_smp_config (void); extern void get_smp_config (void); diff -u cpumap/arch/i386/kernel/process.c linux/arch/i386/kernel/process.c --- cpumap/arch/i386/kernel/process.c Tue Jan 29 14:33:08 2002 +++ linux/arch/i386/kernel/process.c Tue Jan 29 15:04:41 2002 @@ -370,7 +370,7 @@ if its not, default to the BSP */ if ((reboot_cpu == -1) || (reboot_cpu > (NR_CPUS -1)) || - !(phys_cpu_present_map & (1<<cpuid))) + !(cpumap_test_bit(cpuid, phys_cpu_present_map))) reboot_cpu = boot_cpu_physical_apicid; reboot_smp = 0; /* use this as a flag to only go through this once*/ diff -u cpumap/arch/i386/kernel/io_apic.c linux/arch/i386/kernel/io_apic.c --- cpumap/arch/i386/kernel/io_apic.c Tue Nov 13 17:28:41 2001 +++ linux/arch/i386/kernel/io_apic.c Tue Jan 29 15:04:41 2002 @@ -1006,7 +1006,8 @@ static void __init setup_ioapic_ids_from_mpc (void) { struct IO_APIC_reg_00 reg_00; - unsigned long phys_id_present_map = phys_cpu_present_map; + unsigned long phys_id_present_map = + cpumap_to_ulong(phys_cpu_present_map); int apic; int i; unsigned char old_id; diff -u cpumap/arch/i386/kernel/smpboot.c linux/arch/i386/kernel/smpboot.c --- cpumap/arch/i386/kernel/smpboot.c Tue Jan 29 14:33:08 2002 +++ linux/arch/i386/kernel/smpboot.c Tue Jan 29 15:04:41 2002 @@ -984,6 +984,9 @@ void __init smp_boot_cpus(void) { int apicid, cpu, bit; +#ifdef SMP_DEBUG + char buf[CPUMAP_BUFSIZE]; +#endif if (clustered_apic_mode) { /* remap the 1st quad's 256k range for cross-quad I/O */ @@ -1036,7 +1039,9 @@ #ifndef CONFIG_VISWS io_apic_irqs = 0; #endif - cpu_online_map = phys_cpu_present_map = 1; + cpu_online_map = 1; + cpumap_clear_mask(phys_cpu_present_map); + cpumap_set_bit(0, phys_cpu_present_map); smp_num_cpus = 1; if (APIC_init_uniprocessor()) printk(KERN_NOTICE "Local APIC not detected." @@ -1050,10 +1055,10 @@ * Makes no sense to do this check in clustered apic mode, so skip it */ if (!clustered_apic_mode && - !test_bit(boot_cpu_physical_apicid, &phys_cpu_present_map)) { + !cpumap_test_bit(boot_cpu_physical_apicid, phys_cpu_present_map)) { printk("weird, boot CPU (#%d) not listed by the BIOS.\n", boot_cpu_physical_apicid); - phys_cpu_present_map |= (1 << hard_smp_processor_id()); + cpumap_set_bit(hard_smp_processor_id(), phys_cpu_present_map); } /* @@ -1067,7 +1072,9 @@ #ifndef CONFIG_VISWS io_apic_irqs = 0; #endif - cpu_online_map = phys_cpu_present_map = 1; + cpu_online_map = 1; + cpumap_clear_mask(phys_cpu_present_map); + cpumap_set_bit(0, phys_cpu_present_map); smp_num_cpus = 1; goto smp_done; } @@ -1083,7 +1090,9 @@ #ifndef CONFIG_VISWS io_apic_irqs = 0; #endif - cpu_online_map = phys_cpu_present_map = 1; + cpu_online_map = 1; + cpumap_clear_mask(phys_cpu_present_map); + cpumap_set_bit(0, phys_cpu_present_map); smp_num_cpus = 1; goto smp_done; } @@ -1101,7 +1110,8 @@ * bits 0-3 are quad0, 4-7 are quad1, etc. A perverse twist on the * clustered apic ID. */ - Dprintk("CPU present map: %lx\n", phys_cpu_present_map); + Dprintk("CPU present map: %s\n", + cpumap_format(phys_cpu_present_map, buf, CPUMAP_BUFSIZE)); for (bit = 0; bit < NR_CPUS; bit++) { apicid = cpu_present_to_apicid(bit); @@ -1111,7 +1121,7 @@ if (apicid == boot_cpu_apicid) continue; - if (!(phys_cpu_present_map & (1 << bit))) + if (!(cpumap_test_bit(bit, phys_cpu_present_map))) continue; if ((max_cpus >= 0) && (max_cpus <= cpucount+1)) continue; @@ -1122,7 +1132,7 @@ * Make sure we unmap all failed CPUs */ if ((boot_apicid_to_cpu(apicid) == -1) && - (phys_cpu_present_map & (1 << bit))) + (cpumap_test_bit(bit, phys_cpu_present_map))) printk("CPU #%d not responding - cannot use it.\n", apicid); } diff -u cpumap/arch/i386/kernel/apic.c linux/arch/i386/kernel/apic.c --- cpumap/arch/i386/kernel/apic.c Tue Jan 29 14:33:08 2002 +++ linux/arch/i386/kernel/apic.c Tue Jan 29 15:04:41 2002 @@ -283,7 +283,7 @@ * This is meaningless in clustered apic mode, so we skip it. */ if (!clustered_apic_mode && - !test_bit(GET_APIC_ID(apic_read(APIC_ID)), &phys_cpu_present_map)) + !cpumap_test_bit(GET_APIC_ID(apic_read(APIC_ID)), phys_cpu_present_map)) BUG(); /* @@ -1137,7 +1137,8 @@ connect_bsp_APIC(); - phys_cpu_present_map = 1; + cpumap_clear_mask(phys_cpu_present_map); + cpumap_set_bit(0, phys_cpu_present_map); apic_write_around(APIC_ID, boot_cpu_physical_apicid); apic_pm_init2(); diff -u cpumap/arch/i386/kernel/mpparse.c linux/arch/i386/kernel/mpparse.c --- cpumap/arch/i386/kernel/mpparse.c Fri Nov 9 14:58:18 2001 +++ linux/arch/i386/kernel/mpparse.c Tue Jan 29 15:04:41 2002 @@ -61,7 +61,7 @@ static unsigned int num_processors; /* Bitmask of physically existing CPUs */ -unsigned long phys_cpu_present_map; +cpumap_t phys_cpu_present_map; /* * Intel MP BIOS table parsing routines: @@ -224,9 +224,10 @@ ver = m->mpc_apicver; if (clustered_apic_mode) { - phys_cpu_present_map |= (logical_apicid&0xf) << (4*quad); + int cpuid = ffs(logical_apicid&0xf) - 1 + (4*quad); + cpumap_set_bit(cpuid, phys_cpu_present_map); } else { - phys_cpu_present_map |= 1 << m->mpc_apicid; + cpumap_set_bit(m->mpc_apicid, phys_cpu_present_map); } /* * Validate version @@ -819,7 +820,7 @@ { smp_found_config = 1; - phys_cpu_present_map |= 2; /* or in id 1 */ + cpumap_set_bit(1, phys_cpu_present_map); apic_version[1] |= 0x10; /* integrated APIC */ apic_version[0] |= 0x10; - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/