core changes for 2.5.67-bk6
Subsystems (8)
PATCH 1/3 core changes for 2.5.67-bk6
Core changes for extended cpu masks. Basically use a machine word #if NR_CPUS < BITS_PER_LONG, otherwise, use a structure with an array of unsigned longs for it. Sprinkle it around the scheduler and a few other odd places that play with the cpu bitmasks. Back-ended by a bitmap ADT capable of dealing with arbitrary-width bitmaps, with the obvious micro-optimizations for NR_CPUS < BITS_PER_LONG and UP.
NR_CPUS % BITS_PER_LONG != 0 is invalid while NR_CPUS > BITS_PER_LONG.
cpus_weight(), cpus_shift_left(), cpus_shift_right(), and cpus_complement() are from Martin Hicks.
drivers/base/node.c +11 -2
@@ -7,7 +7,7 @@#include <linux/init.h> #include <linux/mm.h> #include <linux/node.h> - +#include <linux/cpumask.h> #include <asm/topology.h>
@@ -31,7 +31,16 @@ struct device_driver node_driver = {static ssize_t node_read_cpumap (struct device * dev,char * buf) {struct node *node_dev =to_node (to_root (dev)); -return sprintf (buf,"%lx\n" ,node_dev->cpumap); +cpumask_t tmp = node_dev->cpumap; +int k, len =0 ; + +for (k =0 ; k <CPU_ARRAY_SIZE ; ++k) { +int j =sprintf (buf,"%lx\n" ,cpus_coerce (tmp)); + len += j; + buf += j; +cpus_shift_right (tmp, tmp,BITS_PER_LONG ); + } +return len; } static DEVICE_ATTR(cpumap,S_IRUGO,node_read_cpumap,NULL);
include/linux/bitmap.h +131 -0
131 lines not on this page · raw message
include/linux/cpumask.h +112 -0
112 lines not on this page · raw message
include/linux/init_task.h +1 -1
@@ -68,7 +68,7 @@ .prio = MAX_PRIO-20, \ .static_prio = MAX_PRIO-20, \ .policy = SCHED_NORMAL, \ - .cpus_allowed = ~0UL, \ + .cpus_allowed = CPU_MASK_ALL, \ .mm = NULL, \ .active_mm = &init_mm, \ .run_list = LIST_HEAD_INIT(tsk.run_list), \
include/linux/irq.h +1 -1
@@ -44,7 +44,7 @@ struct hw_interrupt_type {void (*disable)(unsigned int irq);void (*ack)(unsigned int irq);void (*end)(unsigned int irq); -void (*set_affinity)(unsigned int irq,unsigned long mask); +void (*set_affinity)(unsigned int irq,unsigned long dest); };typedef struct hw_interrupt_type hw_irq_controller ;
include/linux/node.h +2 -1
@@ -20,9 +20,10 @@#define _LINUX_NODE_H_#include <linux/device.h> +#include <linux/cpumask.h> struct node { -unsigned long cpumap;/* Bitmap of CPUs on the Node */ +cpumask_t cpumap;/* Bitmap of CPUs on the Node */ struct sys_root sysroot; };
include/linux/rcupdate.h +3 -2
@@ -40,6 +40,7 @@#include <linux/spinlock.h> #include <linux/threads.h> #include <linux/percpu.h> +#include <linux/cpumask.h> /** * struct rcu_head - callback structure for use with RCU
@@ -67,7 +68,7 @@ struct rcu_ctrlblk {spinlock_t mutex;/* Guard this struct */ long curbatch;/* Current batch number. */ long maxbatch;/* Max requested batch number. */ -unsigned long rcu_cpu_mask;/* CPUs that need to switch in order */ +cpumask_t rcu_cpu_mask;/* CPUs that need to switch in order */ /* for current batch to proceed. */ };
@@ -114,7 +115,7 @@ static inline int rcu_pending(int cpu) rcu_batch_before(RCU_batch(cpu), rcu_ctrlblk.curbatch)) || (list_empty (&RCU_curlist (cpu)) && !list_empty (&RCU_nxtlist (cpu))) || - test_bit(cpu, &rcu_ctrlblk.rcu_cpu_mask)) + cpu_isset(cpu, rcu_ctrlblk.rcu_cpu_mask)) return 1; else return 0;
include/linux/sched.h +4 -3
@@ -12,6 +12,7 @@#include <linux/jiffies.h> #include <linux/rbtree.h> #include <linux/thread_info.h> +#include <linux/cpumask.h> #include <asm/system.h> #include <asm/semaphore.h>
@@ -197,7 +198,7 @@ struct mm_struct {unsigned long arg_start, arg_end, env_start, env_end;unsigned long rss, total_vm, locked_vm;unsigned long def_flags; -unsigned long cpu_vm_mask; +cpumask_t cpu_vm_mask;unsigned long swap_address; unsigned dumpable:1;
@@ -331,7 +332,7 @@ struct task_struct {unsigned long last_run;unsigned long policy; -unsigned long cpus_allowed; +cpumask_t cpus_allowed;unsigned int time_slice, first_time_slice;struct list_head tasks;
@@ -467,7 +468,7 @@ do { if (atomic_dec_and_test(&(tsk)->usa#define PF_KSWAPD 0x00040000/* I am kswapd */ #if CONFIG_SMP -extern void set_cpus_allowed (task_t *p,unsigned long new_mask); +extern void set_cpus_allowed (task_t *p,cpumask_t new_mask);#else # define set_cpus_allowed (p, new_mask) do { } while (0)#endif
include/linux/smp.h +0 -3
@@ -115,9 +115,6 @@ void smp_prepare_boot_cpu(void);#define on_each_cpu (func,info,retry,wait) ({ func(info); 0; })static inline void smp_send_reschedule (int cpu) { }static inline void smp_send_reschedule_all (void ) { } -#define cpu_online_map 1 -#define cpu_online (cpu) ({ BUG_ON((cpu) != 0); 1; }) -#define num_online_cpus () 1#define num_booting_cpus () 1#define cpu_possible (cpu) ({ BUG_ON((cpu) != 0); 1; })#define smp_prepare_boot_cpu () do {} while (0)
kernel/fork.c +1 -1
@@ -257,7 +257,7 @@ static inline int dup_mmap(struct mm_str mm->free_area_cache =TASK_UNMAPPED_BASE ; mm->map_count =0 ; mm->rss =0 ; - mm->cpu_vm_mask =0 ; +cpus_clear (mm->cpu_vm_mask); pprev = &mm->mmap;/*
kernel/module.c +6 -3
@@ -300,6 +300,7 @@ static int stopref(void *cpu) {int irqs_disabled =0 ;int prepared =0 ; +cpumask_t allowed_mask =CPU_MASK_NONE ;sprintf (current->comm,"kmodule%lu\n" , (unsigned long )cpu);
@@ -308,7 +309,8 @@ static int stopref(void *cpu)struct sched_param param = { .sched_priority =MAX_RT_PRIO -1 };setscheduler (current->pid,SCHED_FIFO , ¶m);#endif -set_cpus_allowed (current,1UL << (unsigned long )cpu); +cpu_set ((int )cpu, allowed_mask); +set_cpus_allowed (current, allowed_mask);/* Ack: we are alive */ atomic_inc (&stopref_thread_ack);
@@ -361,7 +363,7 @@ static void stopref_set_state(enum stoprstatic int stop_refcounts (void ) {unsigned int i, cpu; -unsigned long old_allowed; +cpumask_t old_allowed, allowed_mask =CPU_MASK_NONE ;int ret =0 ;/* One thread per cpu. We'll do our own. */
@@ -369,7 +371,8 @@ static int stop_refcounts(void)/* FIXME: racy with set_cpus_allowed. */ old_allowed = current->cpus_allowed; -set_cpus_allowed (current,1UL << (unsigned long )cpu); +cpu_set (cpu, allowed_mask); +set_cpus_allowed (current, allowed_mask);atomic_set (&stopref_thread_ack,0 ); stopref_num_threads =0 ;
kernel/rcupdate.c +6 -6
@@ -47,7 +47,7 @@/* Definition for rcupdate control block. */ struct rcu_ctrlblk rcu_ctrlblk = { .mutex =SPIN_LOCK_UNLOCKED , .curbatch =1 , - .maxbatch =1 , .rcu_cpu_mask =0 }; + .maxbatch =1 , .rcu_cpu_mask =CPU_MASK_NONE }; DEFINE_PER_CPU(struct rcu_data, rcu_data) = { 0L };/* Fake initialization required by compiler */
@@ -106,7 +106,7 @@ static void rcu_start_batch(long newbatc rcu_ctrlblk.maxbatch = newbatch; }if (rcu_batch_before (rcu_ctrlblk.maxbatch, rcu_ctrlblk.curbatch) || - (rcu_ctrlblk.rcu_cpu_mask !=0 )) { + !cpus_empty (rcu_ctrlblk.rcu_cpu_mask)) {return ; } rcu_ctrlblk.rcu_cpu_mask = cpu_online_map;
@@ -121,7 +121,7 @@ static void rcu_check_quiescent_state(vo {int cpu =smp_processor_id (); -if (!test_bit (cpu, &rcu_ctrlblk.rcu_cpu_mask)) { +if (!cpu_isset (cpu, rcu_ctrlblk.rcu_cpu_mask)) {return ; }
@@ -139,13 +139,13 @@ static void rcu_check_quiescent_state(vo }spin_lock (&rcu_ctrlblk.mutex); -if (!test_bit (cpu, &rcu_ctrlblk.rcu_cpu_mask)) { +if (!cpu_isset (cpu, rcu_ctrlblk.rcu_cpu_mask)) {spin_unlock (&rcu_ctrlblk.mutex);return ; } -clear_bit (cpu, &rcu_ctrlblk.rcu_cpu_mask); +cpu_clear (cpu, rcu_ctrlblk.rcu_cpu_mask);RCU_last_qsctr (cpu) =RCU_QSCTR_INVALID ; -if (rcu_ctrlblk.rcu_cpu_mask !=0 ) { +if (!cpus_empty (rcu_ctrlblk.rcu_cpu_mask)) {spin_unlock (&rcu_ctrlblk.mutex);return ; }
kernel/sched.c +31 -25
182 lines not on this page · raw message
kernel/softirq.c +4 -3
@@ -308,15 +308,16 @@ void __init softirq_init(void)static int ksoftirqd (void * __bind_cpu) {int cpu = (int ) (long ) __bind_cpu; +cpumask_t allowed_mask =CPU_MASK_NONE ;daemonize ("ksoftirqd/%d" , cpu);set_user_nice (current,19 ); current->flags |=PF_IOTHREAD ;/* Migrate to the right CPU */ -set_cpus_allowed (current,1UL << cpu); -if (smp_processor_id () != cpu) -BUG (); +cpu_set (cpu, allowed_mask); +set_cpus_allowed (current, allowed_mask); +BUG_ON (smp_processor_id () != cpu);__set_current_state (TASK_INTERRUPTIBLE );mb ();
kernel/workqueue.c +3 -1
@@ -169,6 +169,7 @@ static int worker_thread(void *__startupint cpu = cwq - cwq->wq->cpu_wq;DECLARE_WAITQUEUE (wait, current);struct k_sigaction sa; +cpumask_t allowed_mask =CPU_MASK_NONE ;daemonize ("%s/%d" , startup->name, cpu);allow_signal (SIGCHLD );
@@ -176,7 +177,8 @@ static int worker_thread(void *__startup cwq->thread = current;set_user_nice (current,-10 ); -set_cpus_allowed (current,1UL << cpu); +cpu_set (cpu, allowed_mask); +set_cpus_allowed (current, allowed_mask);complete (&startup->done);
PATCH 2/3 i386 changes for 2.5.67-bk6
Quoted 1 line · William Lee Irwin III
Core changes for extended cpu masks. Basically use a machine word
i386 changes for extended cpu masks. Basically force various things that can possibly be used with NR_CPUS > BITS_PER_LONG in arch/i386 to pass typechecking and use the cpumask_t data type. For things that simply can't be used with the larger systems, I use the cpus_coerce() escape hatch to avoid things getting awkward.
Changes made only for flat logical tinySMP boxen and NUMA-Q; voyager and "other" (not sure what "bigsmp" refers to) kind of got left out since I don't really know my way around their code and I don't have any systems of their kind to testboot on.
arch/i386/kernel/apic.c +2 -1
@@ -1136,7 +1136,8 @@ int __init APIC_init_uniprocessor (void)connect_bsp_APIC (); - phys_cpu_present_map =1 << boot_cpu_physical_apicid; +cpus_clear (phys_cpu_present_map); +cpu_set (boot_cpu_physical_apicid, phys_cpu_present_map);setup_local_APIC ();
arch/i386/kernel/cpu/proc.c +1 -1
@@ -60,7 +60,7 @@ static int show_cpuinfo(struct seq_fileint fpu_exception;#ifdef CONFIG_SMP -if (!(cpu_online_map & (1 <<n))) +if (!cpu_online (n))return 0 ;#endif seq_printf(m, "processor\t: %d\n"
arch/i386/kernel/io_apic.c +28 -21
143 lines not on this page · raw message
arch/i386/kernel/irq.c +30 -13
108 lines not on this page · raw message
arch/i386/kernel/ldt.c +3 -1
@@ -56,9 +56,11 @@ static int alloc_ldt(mm_context_t *pc, iif (reload) {#ifdef CONFIG_SMP +cpumask_t tmp =CPU_MASK_NONE ;preempt_disable (); +cpu_set (smp_processor_id (), tmp);load_LDT (pc); -if (current->mm->cpu_vm_mask != (1 <<smp_processor_id ())) +if (!cpu_isset (smp_processor_id (), current->mm->cpu_vm_mask))smp_call_function (flush_ldt,0 ,1 ,1 );preempt_enable ();#else
arch/i386/kernel/mpparse.c +4 -2
@@ -70,7 +70,7 @@ unsigned int boot_cpu_logical_apicid = -static unsigned int __initdata num_processors;/* Bitmask of physically existing CPUs */ -unsigned long phys_cpu_present_map; +cpumask_t phys_cpu_present_map;int x86_summit =0 ;u8 bios_cpu_apicid[NR_CPUS ] = { [0 ...NR_CPUS -1 ] =BAD_APICID };
@@ -106,6 +106,7 @@ static struct mpc_config_translation *trvoid __init MP_processor_info (struct mpc_config_processor *m) {int ver, apicid; +cpumask_t tmp;if (!(m->mpc_cpuflag &CPU_ENABLED ))return ;
@@ -176,7 +177,8 @@ void __init MP_processor_info (struct mp } ver = m->mpc_apicver; - phys_cpu_present_map |=apicid_to_cpu_present (apicid); + tmp =apicid_to_cpu_present (apicid); +cpus_or (phys_cpu_present_map, phys_cpu_present_map, tmp);/* * Validate version
arch/i386/kernel/reboot.c +1 -1
@@ -226,7 +226,7 @@ void machine_restart(char * __unused)if its not, default to the BSP */ if ((reboot_cpu ==-1 ) || (reboot_cpu > (NR_CPUS -1 )) || - !(phys_cpu_present_map & (1 <<cpuid))) + !(cpu_isset (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*/
arch/i386/kernel/smp.c +47 -33
201 lines not on this page · raw message
arch/i386/kernel/smpboot.c +36 -34
225 lines not on this page · raw message
include/asm-i386/highmem.h +6 -0
@@ -22,6 +22,7 @@#include <linux/config.h> #include <linux/interrupt.h> +#include <linux/threads.h> #include <asm/kmap_types.h> #include <asm/tlbflush.h>
@@ -39,7 +40,12 @@ extern void kmap_init(void);* easily, subsequent pte tables have to be allocated in one physical * chunk of RAM. */ +#if NR_CPUS <=32 #define PKMAP_BASE (0xff800000UL) +#else +#define PKMAP_BASE (0xff600000UL) +#endif +#ifdef CONFIG_X86_PAE #define LAST_PKMAP 512#else
include/asm-i386/mach-default/mach_apic.h +21 -9
@@ -3,8 +3,12 @@#define APIC_DFR_VALUE (APIC_DFR_FLAT) +/* +* Flat mode can't support large numbers of cpus. +* The first word of cpu_online_map should cover us. +*/ #ifdef CONFIG_SMP -#define TARGET_CPUS (cpu_online_map) +#define TARGET_CPUS cpus_coerce(cpu_online_map)#else #define TARGET_CPUS 0x01#endif
@@ -17,12 +21,13 @@#define APIC_BROADCAST_ID 0x0F#define check_apicid_used (bitmap, apicid) (bitmap & (1 << apicid)) -#define check_apicid_present (bit) (phys_cpu_present_map & (1 << bit)) +#define check_apicid_present (bit) cpu_isset(bit, phys_cpu_present_map) +#if defined(CONFIG_X86_LOCAL_APIC ) || defined(CONFIG_X86_UP_APIC )static inline int apic_id_registered (void ) { -return (test_bit (GET_APIC_ID (apic_read (APIC_ID )), - &phys_cpu_present_map)); +return cpu_isset (GET_APIC_ID (apic_read (APIC_ID )), + phys_cpu_present_map); }/*
@@ -41,10 +46,14 @@ static inline void init_apic_ldr(void) val |=SET_APIC_LOGICAL_ID (1UL <<smp_processor_id ()); apic_write_around(APIC_LDR, val); } +#endif -static inline ulong ioapic_phys_id_map (ulong phys_map) +/* +* Only small machines use this APIC mode. +*/ +static inline unsigned long ioapic_phys_id_map (cpumask_t phys_map) { -return phys_map; +return cpus_coerce (phys_map); }static inline void clustered_apic_check (void )
@@ -74,9 +83,12 @@ static inline int cpu_present_to_apicid(return mps_cpu; } -static inline unsigned long apicid_to_cpu_present (int phys_apicid) +static inline cpumask_t apicid_to_cpu_present (int phys_apicid) { -return (1ul << phys_apicid); +cpumask_t mask; +cpus_clear (mask); +cpu_set (phys_apicid, mask); +return mask; } static inline int mpc_apic_id(struct mpc_config_processor *m,
@@ -96,7 +108,7 @@ static inline void setup_portio_remap(vostatic inline int check_phys_apicid_present (int boot_cpu_physical_apicid) { -return test_bit (boot_cpu_physical_apicid, &phys_cpu_present_map); +return cpu_isset (boot_cpu_physical_apicid, phys_cpu_present_map); }#endif /* __ASM_MACH_APIC_H */
include/asm-i386/mach-default/mach_ipi.h +2 -2
@@ -1,10 +1,10 @@#ifndef __ASM_MACH_IPI_H#define __ASM_MACH_IPI_H -static inline void send_IPI_mask_bitmask (int mask,int vector); +static inline void send_IPI_mask_bitmask (cpumask_t cpumask,int vector);static inline void __send_IPI_shortcut (unsigned int shortcut,int vector); -static inline void send_IPI_mask (int mask,int vector) +static inline void send_IPI_mask (cpumask_t mask,int vector) {send_IPI_mask_bitmask (mask, vector); }
include/asm-i386/mach-numaq/mach_apic.h +12 -7
@@ -12,12 +12,12 @@#define INT_DEST_MODE 0/* physical delivery on LOCAL quad */ #define APIC_BROADCAST_ID 0x0F -#define check_apicid_used (bitmap, apicid) ((bitmap) & (1 << (apicid))) -#define check_apicid_present (bit) (phys_cpu_present_map & (1 << bit)) +#define check_apicid_used (bitmap, apicid) cpu_isset(apicid, bitmap) +#define check_apicid_present (bit) cpu_isset(bit, phys_cpu_present_map)static inline int apic_id_registered (void ) { -return (1 ); +return 1 ; }static inline void init_apic_ldr (void )
@@ -40,10 +40,10 @@ static inline int multi_timer_check(intreturn (apic !=0 && irq ==0 ); } -static inline ulong ioapic_phys_id_map (ulong phys_map) +static inline unsigned long ioapic_phys_id_map (cpumask_t phys_map) {/* We don't have a good way to do this yet - hack */ -return 0xf ; +return 0xFUL ; }/* Mapping from cpu number to logical apicid */
@@ -68,9 +68,14 @@ static inline int apicid_to_node(int logreturn (logical_apicid >>4 ); } -static inline unsigned long apicid_to_cpu_present (int logical_apicid) +static inline cpumask_t apicid_to_cpu_present (int logical_apicid) { -return ( (logical_apicid&0xf ) << (4 *apicid_to_node (logical_apicid)) ); +cpumask_t mask =CPU_MASK_NONE ; +int node =apicid_to_node (logical_apicid); +int cpu =__ffs (logical_apicid &0xf ); + +cpu_set (cpu +4 *node, mask); +return mask; } static inline int mpc_apic_id(struct mpc_config_processor *m,
include/asm-i386/mach-numaq/mach_ipi.h +5 -4
@@ -1,18 +1,19 @@#ifndef __ASM_MACH_IPI_H#define __ASM_MACH_IPI_H -static inline void send_IPI_mask_sequence (int mask,int vector); +static inline void send_IPI_mask_sequence (cpumask_t ,int vector); -static inline void send_IPI_mask (int mask,int vector) +static inline void send_IPI_mask (cpumask_t mask,int vector) {send_IPI_mask_sequence (mask, vector); }static inline void send_IPI_allbutself (int vector) { -unsigned long mask = cpu_online_map & ~(1 <<smp_processor_id ()); +cpumask_t mask = cpu_online_map; +cpu_clear (smp_processor_id (), mask); -if (mask) +if (!cpus_empty (mask))send_IPI_mask (mask, vector); }
include/asm-i386/mmu_context.h +4 -5
@@ -26,12 +26,12 @@ static inline void switch_mm(struct mm_s {if (likely (prev != next)) {/* stop flush ipis for the previous mm */ -clear_bit (cpu, &prev->cpu_vm_mask); +cpu_clear (cpu, prev->cpu_vm_mask);#ifdef CONFIG_SMP cpu_tlbstate[cpu].state =TLBSTATE_OK ; cpu_tlbstate[cpu].active_mm = next;#endif -set_bit (cpu, &next->cpu_vm_mask); +cpu_set (cpu, next->cpu_vm_mask);/* Re-load page tables */ load_cr3 (next->pgd);
@@ -45,9 +45,8 @@ static inline void switch_mm(struct mm_s#ifdef CONFIG_SMP else { cpu_tlbstate[cpu].state =TLBSTATE_OK ; -if (cpu_tlbstate[cpu].active_mm != next) -BUG (); -if (!test_and_set_bit (cpu, &next->cpu_vm_mask)) { +BUG_ON (cpu_tlbstate[cpu].active_mm != next); +if (!cpu_test_and_set (cpu, next->cpu_vm_mask)) {/* We were in lazy tlb mode and leave_mm disabled * tlb flush IPI delivery. We must reload %cr3. */
include/asm-i386/mpspec.h +3 -1
@@ -1,6 +1,8 @@#ifndef __ASM_MPSPEC_H#define __ASM_MPSPEC_H +#include <linux/cpumask.h> +/* * Structure definitions for SMP machines following the * Intel Multiprocessing Specification 1.1 and 1.4.
@@ -206,7 +208,7 @@ extern int quad_local_to_mp_bus_id [NR_Cextern 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 cpumask_t phys_cpu_present_map;extern int smp_found_config;extern void find_smp_config (void );extern void get_smp_config (void );
include/asm-i386/numaq.h +2 -2
@@ -28,7 +28,7 @@#ifdef CONFIG_X86_NUMAQ -#define MAX_NUMNODES 8 +#define MAX_NUMNODES 16extern void get_memcfg_numaq (void );#define get_memcfg_numa () get_memcfg_numaq()
@@ -159,7 +159,7 @@ struct sys_cfg_data {static inline unsigned long *get_zholes_size (int nid) { -return 0 ; +return NULL ; }#endif /* CONFIG_X86_NUMAQ */ #endif /* NUMAQ_H */
include/asm-i386/smp.h +6 -23
@@ -8,6 +8,7 @@#include <linux/config.h> #include <linux/kernel.h> #include <linux/threads.h> +#include <linux/cpumask.h> #endif #ifdef CONFIG_X86_LOCAL_APIC
@@ -31,8 +32,8 @@*/ extern void smp_alloc_memory (void ); -extern unsigned long phys_cpu_present_map; -extern unsigned long cpu_online_map; +extern cpumask_t phys_cpu_present_map; +extern cpumask_t cpu_online_map;extern volatile unsigned long smp_invalidate_needed;extern int pic_mode;extern int smp_num_siblings;
@@ -55,37 +56,19 @@ extern void zap_low_mappings (void);*/ #define smp_processor_id () (current_thread_info()->cpu) -extern volatile unsigned long cpu_callout_map; +extern volatile cpumask_t cpu_callout_map; -#define cpu_possible (cpu) (cpu_callout_map & (1<<(cpu))) -#define cpu_online (cpu) (cpu_online_map & (1<<(cpu))) - -#define for_each_cpu (cpu, mask) \ - for(mask = cpu_online_map; \ - cpu = __ffs(mask), mask != 0; \ - mask &= ~(1<<cpu)) - -extern inline unsigned int num_online_cpus (void ) -{ -return hweight32 (cpu_online_map); -} +#define cpu_possible (cpu) cpu_isset(cpu, cpu_callout_map)/* We don't mark CPUs online until __cpu_up(), so we need another measure */ static inline int num_booting_cpus (void ) { -return hweight32 (cpu_callout_map); +return cpus_weight (cpu_callout_map); }extern void map_cpu_to_logical_apicid (void );extern void unmap_cpu_to_logical_apicid (int cpu); -extern inline int any_online_cpu (unsigned int mask) -{ -if (mask & cpu_online_map) -return __ffs (mask & cpu_online_map); - -return -1 ; -}#ifdef CONFIG_X86_LOCAL_APIC static __inlineint hard_smp_processor_id (void ) {
include/asm-i386/topology.h +7 -4
@@ -31,8 +31,10 @@#include <asm/mpspec.h> +#include <linux/cpumask.h> +/* Mappings between logical cpu number and node number */ -extern volatile unsigned long node_2_cpu_mask[]; +extern volatile cpumask_t node_2_cpu_mask[];extern volatile int cpu_2_node[];/* Returns the number of the node containing CPU 'cpu' */
@@ -49,7 +51,7 @@ static inline int cpu_to_node(int cpu)#define parent_node (node) (node)/* Returns a bitmask of CPUs on Node 'node'. */ -static inline unsigned long node_to_cpumask (int node) +static inline cpumask_t node_to_cpumask (int node) {return node_2_cpu_mask[node]; }
@@ -57,14 +59,15 @@ static inline unsigned long node_to_cpum/* Returns the number of the first CPU on Node 'node'. */ static inline int node_to_first_cpu (int node) { -return __ffs (node_to_cpumask (node)); +cpumask_t mask =node_to_cpumask (node); +return first_cpu (mask); }/* Returns the number of the first MemBlk on Node 'node' */ #define node_to_memblk (node) (node)/* Returns the number of the node containing PCI bus 'bus' */ -static inline unsigned long pcibus_to_cpumask (int bus) +static inline cpumask_t pcibus_to_cpumask (int bus) {return node_to_cpumask (mp_bus_id_to_node[bus]); }
PATCH 3/3 ia64 changes for 2.5.67-bk6
Quoted 1 line · William Lee Irwin III
i386 changes for extended cpu masks. Basically force various things
ia64 changes for extended cpu masks. Written by Martin Hicks, with some porting between 2.5.67 virgin and 2.5.67-bk6 by me (i.e. blame me for mistakes in perfmon.c and palinfo.c, the rest is his fault =).
The same principles as i386 hold, though without quite as much cruft to work around since it's a 64-bit arch and the interrupt controller wasn't lobotomized at birth (or so it seems at first glance...).
arch/ia64/kernel/iosapic.c +7 -4
@@ -274,7 +274,7 @@ unmask_irq (unsigned int irq)static void -iosapic_set_affinity (unsigned int irq,unsigned long mask) +iosapic_set_affinity (unsigned int irq,unsigned long arg) {#ifdef CONFIG_SMP unsigned long flags;
@@ -283,16 +283,19 @@ iosapic_set_affinity (unsigned int irq,char *addr;int redir = (irq &IA64_IRQ_REDIRECTED ) ?1 :0 ;ia64_vector vec; +cpumask_t tmp, mask = *(cpumask_t *)arg; irq &= (~IA64_IRQ_REDIRECTED ); vec =irq_to_vector (irq); - mask &= cpu_online_map; +cpus_and (mask, mask, cpu_online_map); -if (!mask || vec >=IA64_NUM_VECTORS ) +if (cpus_empty (mask) || vec >=IA64_NUM_VECTORS )return ; - dest =cpu_physical_id (ffz (~mask)); + tmp = mask; +cpus_complement (tmp); + dest =cpu_physical_id (first_cpu (tmp)); rte_index = iosapic_intr_info[vec].rte_index; addr = iosapic_intr_info[vec].addr;
arch/ia64/kernel/irq.c +41 -19
134 lines not on this page · raw message
arch/ia64/kernel/perfmon.c +31 -38
193 lines not on this page · raw message
arch/ia64/kernel/setup.c +1 -1
@@ -541,7 +541,7 @@ static void * c_start (struct seq_file *m, loff_t *pos) { #ifdef CONFIG_SMP - while (*pos < NR_CPUS && !(cpu_online_map & (1UL << *pos))) + while (*pos < NR_CPUS && !cpu_isset(*pos, cpu_online_map)) ++*pos;#endif return *pos <NR_CPUS ?cpu_data (*pos) :NULL ;
arch/ia64/kernel/smp.c +1 -1
@@ -81,7 +81,7 @@ stop_this_cpu (void)/* * Remove this CPU: */ -clear_bit (smp_processor_id (), &cpu_online_map); +cpu_clear (smp_processor_id (), cpu_online_map);max_xtp ();local_irq_disable ();cpu_halt ();
arch/ia64/kernel/smpboot.c +22 -18
@@ -79,13 +79,13 @@ int cpucount;task_t *task_for_booting_cpu;/* Bitmask of currently online CPUs */ -volatile unsigned long cpu_online_map; -unsigned long phys_cpu_present_map; +volatile cpumask_t cpu_online_map; +cpumask_t phys_cpu_present_map;/* which logical CPU number maps to which CPU (physical APIC ID) */ volatile int ia64_cpu_to_sapicid[NR_CPUS ]; -static volatile unsigned long cpu_callin_map; +static volatile cpumask_t cpu_callin_map;struct smp_boot_data smp_boot_data__initdata ;
@@ -271,7 +271,7 @@ smp_callin (void) cpuid =smp_processor_id (); phys_id =hard_smp_processor_id (); -if (test_and_set_bit (cpuid, &cpu_online_map)) { +if (cpu_test_and_set (cpuid, cpu_online_map)) {printk (KERN_ERR "huh, phys CPU#0x%x, CPU#0x%x already present??\n" , phys_id, cpuid);BUG ();
@@ -313,7 +313,7 @@ smp_callin (void)/* * Allow the master to continue. */ -set_bit (cpuid, &cpu_callin_map); +cpu_set (cpuid, cpu_callin_map);Dprintk ("Stack on CPU %d at about %p\n" ,cpuid, &cpuid); }
@@ -376,19 +376,19 @@ do_boot_cpu (int sapicid, int cpu)*/ Dprintk ("Waiting on callin_map ..." );for (timeout =0 ; timeout <100000 ; timeout++) { -if (test_bit (cpu, &cpu_callin_map)) +if (cpu_isset (cpu, cpu_callin_map))break ;/* It has booted */ udelay (100 ); }Dprintk ("\n" ); -if (test_bit (cpu, &cpu_callin_map)) { +if (cpu_isset (cpu, cpu_callin_map)) {/* number CPUs logically, starting from 1 (BSP is 0) */ printk (KERN_INFO "CPU%d: CPU has booted.\n" , cpu); }else {printk (KERN_ERR "Processor 0x%x/0x%x is stuck.\n" , cpu, sapicid); ia64_cpu_to_sapicid[cpu] =-1 ; -clear_bit (cpu, &cpu_online_map);/* was set in smp_callin() */ +cpu_clear (cpu, cpu_online_map);/* was set in smp_callin() */ return -EINVAL ; }return 0 ;
@@ -418,13 +418,14 @@ smp_build_cpu_map (void) ia64_cpu_to_sapicid[cpu] =-1 ; ia64_cpu_to_sapicid[0 ] = boot_cpu_id; - phys_cpu_present_map =1 ; +cpus_clear (phys_cpu_present_map); +cpu_set (1 , phys_cpu_present_map);for (cpu =1 , i =0 ; i < smp_boot_data.cpu_count; i++) { sapicid = smp_boot_data.cpu_phys_id[i];if (sapicid ==-1 || sapicid == boot_cpu_id)continue ; - phys_cpu_present_map |= (1 << cpu); +cpu_set (cpu, phys_cpu_present_map); ia64_cpu_to_sapicid[cpu] = sapicid; cpu++; }
@@ -435,7 +436,7 @@ smp_build_cpu_map (void)/* on which node is each logical CPU (one cacheline even for 64 CPUs) */ volatile char cpu_to_node_map[NR_CPUS] __cacheline_aligned;/* which logical CPUs are on which nodes */ -volatile unsigned long node_to_cpu_mask[MAX_NUMNODES] __cacheline_aligned; +volatile cpumask_t node_to_cpu_mask[MAX_NUMNODES] __cacheline_aligned;/* * Build cpu to node mapping and initialize the per node cpu masks.
@@ -446,7 +447,7 @@ build_cpu_to_node_map (void)int cpu, i, node;for (node=0 ; node<MAX_NUMNODES ; node++) - node_to_cpu_mask[node] =0 ; +cpus_clear (node_to_cpu_mask[node]);for (cpu =0 ; cpu <NR_CPUS ; ++cpu) {/* * All Itanium NUMA platforms I know use ACPI, so maybe we
@@ -464,7 +465,7 @@ build_cpu_to_node_map (void)#endif cpu_to_node_map[cpu] = node;if (node >=0 ) - node_to_cpu_mask[node] |= (1UL << cpu); +cpu_set (cpu, node_to_cpu_mask[node]); } }
@@ -487,8 +488,8 @@ smp_prepare_cpus (unsigned int max_cpus)/* * We have the boot CPU online for sure. */ -set_bit (0 , &cpu_online_map); -set_bit (0 , &cpu_callin_map); +cpu_set (0 , cpu_online_map); +cpu_set (0 , cpu_callin_map); local_cpu_data->loops_per_jiffy = loops_per_jiffy; ia64_cpu_to_sapicid[0 ] = boot_cpu_id;
@@ -503,15 +504,18 @@ smp_prepare_cpus (unsigned int max_cpus)*/ if (!max_cpus) {printk (KERN_INFO "SMP mode deactivated.\n" ); - cpu_online_map = phys_cpu_present_map =1 ; +cpus_clear (cpu_online_map); +cpus_clear (phys_cpu_present_map); +cpu_set (1 , cpu_online_map); +cpu_set (1 , phys_cpu_present_map);return ; } }void __devinit smp_prepare_boot_cpu (void ) { -set_bit (smp_processor_id (), &cpu_online_map); -set_bit (smp_processor_id (), &cpu_callin_map); +cpu_set (smp_processor_id (), cpu_online_map); +cpu_set (smp_processor_id (), cpu_callin_map); }void
arch/ia64/kernel/time.c +2 -2
@@ -38,13 +38,13 @@ unsigned long last_cli_ip;static void do_profile (unsigned long ip) { -extern unsigned long prof_cpu_mask; +extern cpumask_t prof_cpu_mask;extern char _stext;if (!prof_buffer)return ; -if (!((1UL <<smp_processor_id ()) & prof_cpu_mask)) +if (!cpu_isset (smp_processor_id (), prof_cpu_mask))return ; ip -= (unsigned long ) &_stext;
include/asm-ia64/perfmon.h +1 -1
@@ -71,7 +71,7 @@ typedef struct {int ctx_flags;/* noblock/block, inherit flags */ void *ctx_smpl_vaddr;/* returns address of BTB buffer */ -unsigned long ctx_cpu_mask;/* on which CPU to enable perfmon (systemwide) */ +cpumask_t ctx_cpu_mask;/* on which CPU to enable perfmon (systemwide) */ unsigned long reserved[8 ];/* for future use */ } pfarg_context_t;
include/asm-ia64/smp.h +3 -19
@@ -16,6 +16,7 @@#include <linux/init.h> #include <linux/threads.h> #include <linux/kernel.h> +#include <linux/cpumask.h> #include <asm/bitops.h> #include <asm/io.h>
@@ -37,8 +38,8 @@ extern struct smp_boot_data {extern char no_int_routing__initdata ; -extern unsigned long phys_cpu_present_map; -extern volatile unsigned long cpu_online_map; +extern cpumask_t phys_cpu_present_map; +extern volatile cpumask_t cpu_online_map;extern unsigned long ipi_base_addr;extern unsigned char smp_int_redirect;
@@ -47,23 +48,6 @@ extern volatile int ia64_cpu_to_sapicid[extern unsigned long ap_wakeup_vector; -#define cpu_possible (cpu) (phys_cpu_present_map & (1UL << (cpu))) -#define cpu_online (cpu) (cpu_online_map & (1UL << (cpu))) - -static inline unsigned int -num_online_cpus (void ) -{ -return hweight64 (cpu_online_map); -} - -static inline int -any_online_cpu (unsigned int mask) -{ -if (mask & cpu_online_map) -return __ffs (mask & cpu_online_map); -return -1 ; -} -/* * Function to map hard smp processor id to logical id. Slow, so don't use this in * performance-critical code.
On Tue, 15 Apr 2003 15:50:36 -0700 William Lee Irwin III <[email protected]> wrote:
| Core changes for extended cpu masks. Basically use a machine word | #if NR_CPUS < BITS_PER_LONG, otherwise, use a structure with an array | of unsigned longs for it. Sprinkle it around the scheduler and a few | other odd places that play with the cpu bitmasks. Back-ended by a | bitmap ADT capable of dealing with arbitrary-width bitmaps, with the | obvious micro-optimizations for NR_CPUS < BITS_PER_LONG and UP. | | NR_CPUS % BITS_PER_LONG != 0 is invalid while NR_CPUS > BITS_PER_LONG.
Where/why this restriction (above)?
I don't see the need for it or implementation of it.
I'm only looking at the core patch.
| diff -urpN linux-2.5.67-bk6/include/linux/bitmap.h cpu-2.5.67-bk6-1/include/linux/bitmap.h | --- linux-2.5.67-bk6/include/linux/bitmap.h 1969-12-31 16:00:00.000000000 -0800 | +++ cpu-2.5.67-bk6-1/include/linux/bitmap.h 2003-04-15 14:39:40.000000000 -0700
| +static inline void bitmap_shift_left(volatile unsigned long *,volatile unsigned long *,int,int);
Do you need this prototype? I don't see why.
Rest of core looks good to me.
--
~Randy
Quoted 7 lines · On Tue, 15 Apr 2003 15:50:36 -0700 William Lee Irwin III wrote:
| Core changes for extended cpu masks. Basically use a machine word | #if NR_CPUS < BITS_PER_LONG, otherwise, use a structure with an array | of unsigned longs for it. Sprinkle it around the scheduler and a few | other odd places that play with the cpu bitmasks. Back-ended by a | bitmap ADT capable of dealing with arbitrary-width bitmaps, with the | obvious micro-optimizations for NR_CPUS < BITS_PER_LONG and UP. | NR_CPUS % BITS_PER_LONG != 0 is invalid while NR_CPUS > BITS_PER_LONG.
Quoted 3 lines · Randy.Dunlap
Where/why this restriction (above)?
I don't see the need for it or implementation of it. I'm only looking at the core patch.
I leave bits dangling otherwise.
Quoted 1 line · On Tue, 15 Apr 2003 15:50:36 -0700 William Lee Irwin III wrote:
| +static inline void
bitmap_shift_left(volatile unsigned long *,volatile unsigned long *,int,int);
Quoted 2 lines · Randy.Dunlap
Do you need this prototype? I don't see why. Rest of core looks good to me.
Probably not. I'll nuke it.
-- wli