Ingo Molnar wrote:How about something like the below? (I haven't tried compiling it yet.) [I also thought about not restricting it to only NR_CPUS type variables to allow for example, node-local node maps/variables.] Thanks, Mike ------------------------------------------------------------ include/linux/percpu.h: #ifdef CONFIG_SMP #define DEFINE_EARLY_PER_CPU(type, name, initvalue) \ DEFINE_PER_CPU(type, name) = initvalue; \ type name##_early_map[NR_CPUS] __initdata = \ { [0 ... NR_CPUS-1] = initvalue; } \ type *name##_early_ptr = name##_early_map #define DECLARE_EARLY_PER_CPU(type, name) \ DECLARE_PER_CPU(type, name); \ extern type *name##_early_ptr; \ extern type name##_early_map[] #define EXPORT_EARLY_PER_CPU(name) \ EXPORT_PER_CPU(name) /* rvalue only */ #define early_per_cpu(name, cpu) \ (name##ptr? name##ptr[cpu] : per_cpu(name, cpu)) #define early_per_cpu_ptr(name) (name##_early_ptr) #define early_per_cpu_map(name, idx) (name##_early_map[idx]) #else /* !CONFIG_SMP */ #define DEFINE_EARLY_PER_CPU(type, name, initvalue) \ DEFINE_PER_CPU(type, name) = initvalue #define DECLARE_EARLY_PER_CPU(name) \ DECLARE_PER_CPU(name) #define EXPORT_EARLY_PER_CPU(name) \ EXPORT_PER_CPU(name) #define early_per_cpu(name, cpu) per_cpu(name, cpu) #define early_per_cpu_ptr(name) NULL /* no early_per_cpu_map() */ #endif /* !CONFIG_SMP */ ------------------------------------------------------------ include/asm-x86/smp.h: DECLARE_EARLY_PER_CPU(u16, x86_cpu_to_apicid); DECLARE_EARLY_PER_CPU(u16, x86_bios_cpu_apicid); ------------------------------------------------------------ arch/x86/kernel/setup.c: /* which logical CPU number maps to which CPU (physical APIC ID) */ DEFINE_EARLY_PER_CPU(u16, x86_cpu_to_apicid, BAD_APICID); DEFINE_EARLY_PER_CPU(u16, x86_bios_cpu_apicid, BAD_APICID); EXPORT_EARLY_PER_CPU(x86_cpu_to_apicid); EXPORT_EARLY_PER_CPU(x86_bios_cpu_apicid); #ifdef CONFIG_NUMA DEFINE_EARLY_PER_CPU(int, x86_cpu_to_node, NUMA_NO_NODE); EXPORT_EARLY_PER_CPU(x86_cpu_to_node); #endif ... #if defined(CONFIG_HAVE_SETUP_PER_CPU_AREA) && defined(CONFIG_SMP) /* * Copy data used in early init routines from the initial arrays to the * per cpu data areas. These arrays then become expendable and the * *_early_ptr's are zeroed indicating that the static arrays are gone. */ static void __init setup_per_cpu_maps(void) { int cpu; for_each_possible_cpu(cpu) { per_cpu(x86_cpu_to_apicid, cpu) = early_per_cpu_map(x86_cpu_to_apicid, cpu); per_cpu(x86_bios_cpu_apicid, cpu) = early_per_cpu_map(x86_bios_cpu_apicid, cpu); #ifdef CONFIG_NUMA per_cpu(x86_cpu_to_node_map, cpu) = early_per_cpu_map(x86_cpu_to_node_map, cpu); #endif } /* indicate the early static arrays will soon be gone */ early_per_cpu_ptr(x86_cpu_to_apicid) = NULL; early_per_cpu_ptr(x86_bios_cpu_apicid) = NULL; #ifdef CONFIG_NUMA early_per_cpu_ptr(x86_cpu_to_node_map) = NULL; #endif ... ------------------------------------------------------------ arch/x86/mm/numa_64.c: void __cpuinit numa_set_node(int cpu, int node) { int *cpu_to_node_map = early_per_cpu_ptr(x86_cpu_to_node_map); if(cpu_to_node_map) cpu_to_node_map[cpu] = node; else if(per_cpu_offset(cpu)) per_cpu(x86_cpu_to_node_map, cpu) = node; ... void __init init_cpu_to_node(void) { int i; for (i = 0; i < NR_CPUS; i++) { int node; u16 apicid = early_per_cpu(x86_cpu_to_apicid, i); if (apicid == BAD_APICID) continue; ... ------------------------------------------------------------ --
| Linus Torvalds | Linux 2.6.27-rc8 |
| Greg KH | [GIT PATCH] driver core patches against 2.6.24 |
| Linus Torvalds | Linux 2.6.27 |
| Rafael J. Wysocki | [Bug #10714] powerpc: Badness seen on 2.6.26-rc2 with lockdep enabled |
git: | |
| Peter Stahlir | Git as a filesystem |
| skimo | [PATCH 02/15] git-config: add --remote option for reading config from remote repo |
| Aaron Bentley | Re: VCS comparison table |
| Carlos Rica | Re: If you would write git from scratch now, what would you change? |
| Pavel Machek | Re: [PATCH] [Request for inclusion] Filesystem in Userspace |
| Arjan van de Ven | Re: GFS, what's remaining |
| Badari Pulavarty | Bufferheads & page-cache reference |
| Suparna Bhattacharya | Reviewing ext3 improvement patches (delalloc, mballoc, extents) |
| Richard Stallman | Real men don't attack straw men |
| Kevin | uvm_mapent_alloc: out of static map entries on 4.3 i386 |
| Brandon Lee | DELL PERC 5iR slow performance |
| Todd Pytel | IDE or SCSI virtual disks for VMWare image? |
| usb mic not detected | 3 hours ago | Applications and Utilities |
| Problem in Inserting a module | 4 hours ago | Linux kernel |
| Treason Uncloaked | 9 hours ago | Linux kernel |
| Shared swap partition | 20 hours ago | Linux general |
| high memory | 2 days ago | Linux kernel |
| semaphore access speed | 2 days ago | Applications and Utilities |
| the kernel how to power off the machine | 2 days ago | Linux kernel |
| Easter Eggs in windows XP | 2 days ago | Windows |
| Root password | 2 days ago | Linux general |
| Where/when DNOTIFY is used? | 3 days ago | Linux kernel |
