From 5052f525fde2dcb550cc3b4f15d2bfdd2a5c8782 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Wed, 8 Apr 2009 19:55:47 -0700 Subject: sparc64: Refactor MDESC cpu scanning code using an iterator. Signed-off-by: David S. Miller --- arch/sparc/kernel/mdesc.c | 146 ++++++++++++++++++++++++++++------------------ 1 file changed, 89 insertions(+), 57 deletions(-) (limited to 'arch/sparc/kernel/mdesc.c') diff --git a/arch/sparc/kernel/mdesc.c b/arch/sparc/kernel/mdesc.c index f0e6ed23a468..f50af3f9a2c9 100644 --- a/arch/sparc/kernel/mdesc.c +++ b/arch/sparc/kernel/mdesc.c @@ -574,7 +574,7 @@ static void __init report_platform_properties(void) mdesc_release(hp); } -static void __devinit fill_in_one_cache(cpuinfo_sparc *c, +static void __cpuinit fill_in_one_cache(cpuinfo_sparc *c, struct mdesc_handle *hp, u64 mp) { @@ -619,8 +619,7 @@ static void __devinit fill_in_one_cache(cpuinfo_sparc *c, } } -static void __devinit mark_core_ids(struct mdesc_handle *hp, u64 mp, - int core_id) +static void __cpuinit mark_core_ids(struct mdesc_handle *hp, u64 mp, int core_id) { u64 a; @@ -653,7 +652,7 @@ static void __devinit mark_core_ids(struct mdesc_handle *hp, u64 mp, } } -static void __devinit set_core_ids(struct mdesc_handle *hp) +static void __cpuinit set_core_ids(struct mdesc_handle *hp) { int idx; u64 mp; @@ -678,8 +677,7 @@ static void __devinit set_core_ids(struct mdesc_handle *hp) } } -static void __devinit mark_proc_ids(struct mdesc_handle *hp, u64 mp, - int proc_id) +static void __cpuinit mark_proc_ids(struct mdesc_handle *hp, u64 mp, int proc_id) { u64 a; @@ -698,8 +696,7 @@ static void __devinit mark_proc_ids(struct mdesc_handle *hp, u64 mp, } } -static void __devinit __set_proc_ids(struct mdesc_handle *hp, - const char *exec_unit_name) +static void __cpuinit __set_proc_ids(struct mdesc_handle *hp, const char *exec_unit_name) { int idx; u64 mp; @@ -720,13 +717,13 @@ static void __devinit __set_proc_ids(struct mdesc_handle *hp, } } -static void __devinit set_proc_ids(struct mdesc_handle *hp) +static void __cpuinit set_proc_ids(struct mdesc_handle *hp) { __set_proc_ids(hp, "exec_unit"); __set_proc_ids(hp, "exec-unit"); } -static void __devinit get_one_mondo_bits(const u64 *p, unsigned int *mask, +static void __cpuinit get_one_mondo_bits(const u64 *p, unsigned int *mask, unsigned char def) { u64 val; @@ -745,7 +742,7 @@ use_default: *mask = ((1U << def) * 64U) - 1U; } -static void __devinit get_mondo_data(struct mdesc_handle *hp, u64 mp, +static void __cpuinit get_mondo_data(struct mdesc_handle *hp, u64 mp, struct trap_per_cpu *tb) { const u64 *val; @@ -763,23 +760,15 @@ static void __devinit get_mondo_data(struct mdesc_handle *hp, u64 mp, get_one_mondo_bits(val, &tb->nonresum_qmask, 2); } -void __cpuinit mdesc_fill_in_cpu_data(cpumask_t mask) +static void * __cpuinit mdesc_iterate_over_cpus(void *(*func)(struct mdesc_handle *, u64, int, void *), void *arg, cpumask_t *mask) { struct mdesc_handle *hp = mdesc_grab(); + void *ret = NULL; u64 mp; - ncpus_probed = 0; mdesc_for_each_node_by_name(hp, mp, "cpu") { const u64 *id = mdesc_get_property(hp, mp, "id", NULL); - const u64 *cfreq = mdesc_get_property(hp, mp, "clock-frequency", NULL); - struct trap_per_cpu *tb; - cpuinfo_sparc *c; - int cpuid; - u64 a; - - ncpus_probed++; - - cpuid = *id; + int cpuid = *id; #ifdef CONFIG_SMP if (cpuid >= NR_CPUS) { @@ -788,62 +777,105 @@ void __cpuinit mdesc_fill_in_cpu_data(cpumask_t mask) cpuid, NR_CPUS); continue; } - if (!cpu_isset(cpuid, mask)) - continue; -#else - /* On uniprocessor we only want the values for the - * real physical cpu the kernel booted onto, however - * cpu_data() only has one entry at index 0. - */ - if (cpuid != real_hard_smp_processor_id()) + if (!cpu_isset(cpuid, *mask)) continue; - cpuid = 0; #endif - c = &cpu_data(cpuid); - c->clock_tick = *cfreq; + ret = func(hp, mp, cpuid, arg); + if (ret) + goto out; + } +out: + mdesc_release(hp); + return ret; +} - tb = &trap_block[cpuid]; - get_mondo_data(hp, mp, tb); +static void * __cpuinit record_one_cpu(struct mdesc_handle *hp, u64 mp, int cpuid, void *arg) +{ + ncpus_probed++; +#ifdef CONFIG_SMP + set_cpu_present(cpuid, true); +#endif + return NULL; +} - mdesc_for_each_arc(a, hp, mp, MDESC_ARC_TYPE_FWD) { - u64 j, t = mdesc_arc_target(hp, a); - const char *t_name; +void __cpuinit mdesc_populate_present_mask(cpumask_t *mask) +{ + if (tlb_type != hypervisor) + return; - t_name = mdesc_node_name(hp, t); - if (!strcmp(t_name, "cache")) { - fill_in_one_cache(c, hp, t); - continue; - } + ncpus_probed = 0; + mdesc_iterate_over_cpus(record_one_cpu, NULL, mask); +} - mdesc_for_each_arc(j, hp, t, MDESC_ARC_TYPE_FWD) { - u64 n = mdesc_arc_target(hp, j); - const char *n_name; +static void * __cpuinit fill_in_one_cpu(struct mdesc_handle *hp, u64 mp, int cpuid, void *arg) +{ + const u64 *cfreq = mdesc_get_property(hp, mp, "clock-frequency", NULL); + struct trap_per_cpu *tb; + cpuinfo_sparc *c; + u64 a; - n_name = mdesc_node_name(hp, n); - if (!strcmp(n_name, "cache")) - fill_in_one_cache(c, hp, n); - } +#ifndef CONFIG_SMP + /* On uniprocessor we only want the values for the + * real physical cpu the kernel booted onto, however + * cpu_data() only has one entry at index 0. + */ + if (cpuid != real_hard_smp_processor_id()) + return NULL; + cpuid = 0; +#endif + + c = &cpu_data(cpuid); + c->clock_tick = *cfreq; + + tb = &trap_block[cpuid]; + get_mondo_data(hp, mp, tb); + + mdesc_for_each_arc(a, hp, mp, MDESC_ARC_TYPE_FWD) { + u64 j, t = mdesc_arc_target(hp, a); + const char *t_name; + + t_name = mdesc_node_name(hp, t); + if (!strcmp(t_name, "cache")) { + fill_in_one_cache(c, hp, t); + continue; } -#ifdef CONFIG_SMP - cpu_set(cpuid, cpu_present_map); -#endif + mdesc_for_each_arc(j, hp, t, MDESC_ARC_TYPE_FWD) { + u64 n = mdesc_arc_target(hp, j); + const char *n_name; - c->core_id = 0; - c->proc_id = -1; + n_name = mdesc_node_name(hp, n); + if (!strcmp(n_name, "cache")) + fill_in_one_cache(c, hp, n); + } } + c->core_id = 0; + c->proc_id = -1; + + return NULL; +} + +void __cpuinit mdesc_fill_in_cpu_data(cpumask_t mask) +{ + struct mdesc_handle *hp; + + mdesc_populate_present_mask(&mask); + mdesc_iterate_over_cpus(fill_in_one_cpu, NULL, &mask); + #ifdef CONFIG_SMP sparc64_multi_core = 1; #endif + hp = mdesc_grab(); + set_core_ids(hp); set_proc_ids(hp); - smp_fill_in_sib_core_maps(); - mdesc_release(hp); + + smp_fill_in_sib_core_maps(); } static ssize_t mdesc_read(struct file *file, char __user *buf, -- cgit v1.2.3 From 890db403d59fbeaf273ed019d0b1862223d80a9a Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Wed, 1 Apr 2009 03:13:15 -0700 Subject: sparc: Call OF and MD cpu scanning explicitly from paging_init() We need to split up the cpu present mask setup from the cpu_data initialization, and this is a first step towards that. Signed-off-by: David S. Miller --- arch/sparc/include/asm/prom.h | 1 + arch/sparc/kernel/mdesc.c | 4 ---- arch/sparc/kernel/prom.h | 1 - arch/sparc/kernel/prom_common.c | 2 -- arch/sparc/mm/init_32.c | 1 + arch/sparc/mm/init_64.c | 5 ++++- 6 files changed, 6 insertions(+), 8 deletions(-) (limited to 'arch/sparc/kernel/mdesc.c') diff --git a/arch/sparc/include/asm/prom.h b/arch/sparc/include/asm/prom.h index 1b15212563cd..be8d7aaeb60d 100644 --- a/arch/sparc/include/asm/prom.h +++ b/arch/sparc/include/asm/prom.h @@ -87,6 +87,7 @@ extern int of_node_to_nid(struct device_node *dp); extern void prom_build_devicetree(void); extern void of_populate_present_mask(void); +extern void of_fill_in_cpu_data(void); /* Dummy ref counting routines - to be implemented later */ static inline struct device_node *of_node_get(struct device_node *node) diff --git a/arch/sparc/kernel/mdesc.c b/arch/sparc/kernel/mdesc.c index f50af3f9a2c9..602cbb70dd51 100644 --- a/arch/sparc/kernel/mdesc.c +++ b/arch/sparc/kernel/mdesc.c @@ -919,7 +919,6 @@ void __init sun4v_mdesc_init(void) { struct mdesc_handle *hp; unsigned long len, real_len, status; - cpumask_t mask; (void) sun4v_mach_desc(0UL, 0UL, &len); @@ -943,7 +942,4 @@ void __init sun4v_mdesc_init(void) cur_mdesc = hp; report_platform_properties(); - - cpus_setall(mask); - mdesc_fill_in_cpu_data(mask); } diff --git a/arch/sparc/kernel/prom.h b/arch/sparc/kernel/prom.h index bb0f0fda6cab..453397fe5e14 100644 --- a/arch/sparc/kernel/prom.h +++ b/arch/sparc/kernel/prom.h @@ -22,7 +22,6 @@ static inline int is_root_node(const struct device_node *dp) extern char *build_path_component(struct device_node *dp); extern void of_console_init(void); -extern void of_fill_in_cpu_data(void); extern unsigned int prom_early_allocated; diff --git a/arch/sparc/kernel/prom_common.c b/arch/sparc/kernel/prom_common.c index ff7b591c8946..0fb5789d43c8 100644 --- a/arch/sparc/kernel/prom_common.c +++ b/arch/sparc/kernel/prom_common.c @@ -313,6 +313,4 @@ void __init prom_build_devicetree(void) printk("PROM: Built device tree with %u bytes of memory.\n", prom_early_allocated); - - of_fill_in_cpu_data(); } diff --git a/arch/sparc/mm/init_32.c b/arch/sparc/mm/init_32.c index cbb282dab5a7..26bb3919ff1f 100644 --- a/arch/sparc/mm/init_32.c +++ b/arch/sparc/mm/init_32.c @@ -358,6 +358,7 @@ void __init paging_init(void) protection_map[15] = PAGE_SHARED; btfixup(); prom_build_devicetree(); + of_fill_in_cpu_data(); device_scan(); } diff --git a/arch/sparc/mm/init_64.c b/arch/sparc/mm/init_64.c index f26a352c08a0..c589d6e65668 100644 --- a/arch/sparc/mm/init_64.c +++ b/arch/sparc/mm/init_64.c @@ -1806,9 +1806,12 @@ void __init paging_init(void) real_setup_per_cpu_areas(); prom_build_devicetree(); + of_fill_in_cpu_data(); - if (tlb_type == hypervisor) + if (tlb_type == hypervisor) { sun4v_mdesc_init(); + mdesc_fill_in_cpu_data(CPU_MASK_ALL); + } /* Once the OF device tree and MDESC have been setup, we know * the list of possible cpus. Therefore we can allocate the -- cgit v1.2.3 From a2094502dce23e9ace04d49702aa7a4d5996df55 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Wed, 1 Apr 2009 03:15:11 -0700 Subject: sparc64: Make mdesc_fill_in_cpu_data take a cpumask_t pointer. Signed-off-by: David S. Miller --- arch/sparc/include/asm/mdesc.h | 2 +- arch/sparc/kernel/ds.c | 2 +- arch/sparc/kernel/mdesc.c | 6 +++--- arch/sparc/mm/init_64.c | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) (limited to 'arch/sparc/kernel/mdesc.c') diff --git a/arch/sparc/include/asm/mdesc.h b/arch/sparc/include/asm/mdesc.h index 8f8a520d14b9..9faa046713fb 100644 --- a/arch/sparc/include/asm/mdesc.h +++ b/arch/sparc/include/asm/mdesc.h @@ -71,7 +71,7 @@ struct mdesc_notifier_client { extern void mdesc_register_notifier(struct mdesc_notifier_client *client); -extern void mdesc_fill_in_cpu_data(cpumask_t mask); +extern void mdesc_fill_in_cpu_data(cpumask_t *mask); extern void mdesc_populate_present_mask(cpumask_t *mask); extern void sun4v_mdesc_init(void); diff --git a/arch/sparc/kernel/ds.c b/arch/sparc/kernel/ds.c index 90350f838f05..51b05c498877 100644 --- a/arch/sparc/kernel/ds.c +++ b/arch/sparc/kernel/ds.c @@ -544,7 +544,7 @@ static int __cpuinit dr_cpu_configure(struct ds_info *dp, resp_len, ncpus, mask, DR_CPU_STAT_CONFIGURED); - mdesc_fill_in_cpu_data(*mask); + mdesc_fill_in_cpu_data(mask); for_each_cpu_mask(cpu, *mask) { int err; diff --git a/arch/sparc/kernel/mdesc.c b/arch/sparc/kernel/mdesc.c index 602cbb70dd51..6d2015e0e574 100644 --- a/arch/sparc/kernel/mdesc.c +++ b/arch/sparc/kernel/mdesc.c @@ -857,12 +857,12 @@ static void * __cpuinit fill_in_one_cpu(struct mdesc_handle *hp, u64 mp, int cpu return NULL; } -void __cpuinit mdesc_fill_in_cpu_data(cpumask_t mask) +void __cpuinit mdesc_fill_in_cpu_data(cpumask_t *mask) { struct mdesc_handle *hp; - mdesc_populate_present_mask(&mask); - mdesc_iterate_over_cpus(fill_in_one_cpu, NULL, &mask); + mdesc_populate_present_mask(mask); + mdesc_iterate_over_cpus(fill_in_one_cpu, NULL, mask); #ifdef CONFIG_SMP sparc64_multi_core = 1; diff --git a/arch/sparc/mm/init_64.c b/arch/sparc/mm/init_64.c index c589d6e65668..87fea94e5125 100644 --- a/arch/sparc/mm/init_64.c +++ b/arch/sparc/mm/init_64.c @@ -1810,7 +1810,7 @@ void __init paging_init(void) if (tlb_type == hypervisor) { sun4v_mdesc_init(); - mdesc_fill_in_cpu_data(CPU_MASK_ALL); + mdesc_fill_in_cpu_data(CPU_MASK_ALL_PTR); } /* Once the OF device tree and MDESC have been setup, we know -- cgit v1.2.3 From b696fdc259f0d94348a9327bed352fac44d4883d Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Tue, 26 May 2009 22:37:25 -0700 Subject: sparc64: Defer cpu_data() setup until end of per-cpu data initialization. Signed-off-by: David S. Miller --- arch/sparc/kernel/ds.c | 1 + arch/sparc/kernel/mdesc.c | 1 - arch/sparc/kernel/prom_64.c | 1 - arch/sparc/kernel/smp_64.c | 4 ++++ arch/sparc/mm/init_64.c | 12 ++++-------- 5 files changed, 9 insertions(+), 10 deletions(-) (limited to 'arch/sparc/kernel/mdesc.c') diff --git a/arch/sparc/kernel/ds.c b/arch/sparc/kernel/ds.c index 51b05c498877..4a700f4b79ce 100644 --- a/arch/sparc/kernel/ds.c +++ b/arch/sparc/kernel/ds.c @@ -544,6 +544,7 @@ static int __cpuinit dr_cpu_configure(struct ds_info *dp, resp_len, ncpus, mask, DR_CPU_STAT_CONFIGURED); + mdesc_populate_present_mask(mask); mdesc_fill_in_cpu_data(mask); for_each_cpu_mask(cpu, *mask) { diff --git a/arch/sparc/kernel/mdesc.c b/arch/sparc/kernel/mdesc.c index 6d2015e0e574..938da19dc065 100644 --- a/arch/sparc/kernel/mdesc.c +++ b/arch/sparc/kernel/mdesc.c @@ -861,7 +861,6 @@ void __cpuinit mdesc_fill_in_cpu_data(cpumask_t *mask) { struct mdesc_handle *hp; - mdesc_populate_present_mask(mask); mdesc_iterate_over_cpus(fill_in_one_cpu, NULL, mask); #ifdef CONFIG_SMP diff --git a/arch/sparc/kernel/prom_64.c b/arch/sparc/kernel/prom_64.c index 4d92f488fae1..fb06ac2bd38f 100644 --- a/arch/sparc/kernel/prom_64.c +++ b/arch/sparc/kernel/prom_64.c @@ -535,7 +535,6 @@ void __init of_fill_in_cpu_data(void) if (tlb_type == hypervisor) return; - of_populate_present_mask(); of_iterate_over_cpus(fill_in_one_cpu, 0); smp_fill_in_sib_core_maps(); diff --git a/arch/sparc/kernel/smp_64.c b/arch/sparc/kernel/smp_64.c index b20f253857b7..045fbb554a9c 100644 --- a/arch/sparc/kernel/smp_64.c +++ b/arch/sparc/kernel/smp_64.c @@ -1399,4 +1399,8 @@ void __init real_setup_per_cpu_areas(void) /* Setup %g5 for the boot cpu. */ __local_per_cpu_offset = __per_cpu_offset(smp_processor_id()); + + of_fill_in_cpu_data(); + if (tlb_type == hypervisor) + mdesc_fill_in_cpu_data(CPU_MASK_ALL_PTR); } diff --git a/arch/sparc/mm/init_64.c b/arch/sparc/mm/init_64.c index 87fea94e5125..785f0a24fcbf 100644 --- a/arch/sparc/mm/init_64.c +++ b/arch/sparc/mm/init_64.c @@ -1799,20 +1799,16 @@ void __init paging_init(void) if (tlb_type == hypervisor) sun4v_ktsb_register(); - /* We must setup the per-cpu areas before we pull in the - * PROM and the MDESC. The code there fills in cpu and - * other information into per-cpu data structures. - */ - real_setup_per_cpu_areas(); - prom_build_devicetree(); - of_fill_in_cpu_data(); + of_populate_present_mask(); if (tlb_type == hypervisor) { sun4v_mdesc_init(); - mdesc_fill_in_cpu_data(CPU_MASK_ALL_PTR); + mdesc_populate_present_mask(CPU_MASK_ALL_PTR); } + real_setup_per_cpu_areas(); + /* Once the OF device tree and MDESC have been setup, we know * the list of possible cpus. Therefore we can allocate the * IRQ stacks. -- cgit v1.2.3