aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sparc
diff options
context:
space:
mode:
Diffstat (limited to 'arch/sparc')
-rw-r--r--arch/sparc/Kconfig3
-rw-r--r--arch/sparc/kernel/smp_64.c53
2 files changed, 47 insertions, 9 deletions
diff --git a/arch/sparc/Kconfig b/arch/sparc/Kconfig
index 97fca4695e0b..ac45aab741a5 100644
--- a/arch/sparc/Kconfig
+++ b/arch/sparc/Kconfig
@@ -102,6 +102,9 @@ config HAVE_SETUP_PER_CPU_AREA
102config NEED_PER_CPU_EMBED_FIRST_CHUNK 102config NEED_PER_CPU_EMBED_FIRST_CHUNK
103 def_bool y if SPARC64 103 def_bool y if SPARC64
104 104
105config NEED_PER_CPU_PAGE_FIRST_CHUNK
106 def_bool y if SPARC64
107
105config GENERIC_HARDIRQS_NO__DO_IRQ 108config GENERIC_HARDIRQS_NO__DO_IRQ
106 bool 109 bool
107 def_bool y if SPARC64 110 def_bool y if SPARC64
diff --git a/arch/sparc/kernel/smp_64.c b/arch/sparc/kernel/smp_64.c
index ff68373ce6d6..aa36223497b9 100644
--- a/arch/sparc/kernel/smp_64.c
+++ b/arch/sparc/kernel/smp_64.c
@@ -1420,7 +1420,7 @@ static void __init pcpu_free_bootmem(void *ptr, size_t size)
1420 free_bootmem(__pa(ptr), size); 1420 free_bootmem(__pa(ptr), size);
1421} 1421}
1422 1422
1423static int pcpu_cpu_distance(unsigned int from, unsigned int to) 1423static int __init pcpu_cpu_distance(unsigned int from, unsigned int to)
1424{ 1424{
1425 if (cpu_to_node(from) == cpu_to_node(to)) 1425 if (cpu_to_node(from) == cpu_to_node(to))
1426 return LOCAL_DISTANCE; 1426 return LOCAL_DISTANCE;
@@ -1428,18 +1428,53 @@ static int pcpu_cpu_distance(unsigned int from, unsigned int to)
1428 return REMOTE_DISTANCE; 1428 return REMOTE_DISTANCE;
1429} 1429}
1430 1430
1431static void __init pcpu_populate_pte(unsigned long addr)
1432{
1433 pgd_t *pgd = pgd_offset_k(addr);
1434 pud_t *pud;
1435 pmd_t *pmd;
1436
1437 pud = pud_offset(pgd, addr);
1438 if (pud_none(*pud)) {
1439 pmd_t *new;
1440
1441 new = __alloc_bootmem(PAGE_SIZE, PAGE_SIZE, PAGE_SIZE);
1442 pud_populate(&init_mm, pud, new);
1443 }
1444
1445 pmd = pmd_offset(pud, addr);
1446 if (!pmd_present(*pmd)) {
1447 pte_t *new;
1448
1449 new = __alloc_bootmem(PAGE_SIZE, PAGE_SIZE, PAGE_SIZE);
1450 pmd_populate_kernel(&init_mm, pmd, new);
1451 }
1452}
1453
1431void __init setup_per_cpu_areas(void) 1454void __init setup_per_cpu_areas(void)
1432{ 1455{
1433 unsigned long delta; 1456 unsigned long delta;
1434 unsigned int cpu; 1457 unsigned int cpu;
1435 int rc; 1458 int rc = -EINVAL;
1436 1459
1437 rc = pcpu_embed_first_chunk(PERCPU_MODULE_RESERVE, 1460 if (pcpu_chosen_fc != PCPU_FC_PAGE) {
1438 PERCPU_DYNAMIC_RESERVE, 4 << 20, 1461 rc = pcpu_embed_first_chunk(PERCPU_MODULE_RESERVE,
1439 pcpu_cpu_distance, pcpu_alloc_bootmem, 1462 PERCPU_DYNAMIC_RESERVE, 4 << 20,
1440 pcpu_free_bootmem); 1463 pcpu_cpu_distance,
1441 if (rc) 1464 pcpu_alloc_bootmem,
1442 panic("failed to initialize first chunk (%d)", rc); 1465 pcpu_free_bootmem);
1466 if (rc)
1467 pr_warning("PERCPU: %s allocator failed (%d), "
1468 "falling back to page size\n",
1469 pcpu_fc_names[pcpu_chosen_fc], rc);
1470 }
1471 if (rc < 0)
1472 rc = pcpu_page_first_chunk(PERCPU_MODULE_RESERVE,
1473 pcpu_alloc_bootmem,
1474 pcpu_free_bootmem,
1475 pcpu_populate_pte);
1476 if (rc < 0)
1477 panic("cannot initialize percpu area (err=%d)", rc);
1443 1478
1444 delta = (unsigned long)pcpu_base_addr - (unsigned long)__per_cpu_start; 1479 delta = (unsigned long)pcpu_base_addr - (unsigned long)__per_cpu_start;
1445 for_each_possible_cpu(cpu) 1480 for_each_possible_cpu(cpu)