Skip to content

Commit 0c7fc30

Browse files
committed
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/sparc
Pull sparc fixes from David Miller: 1) Fix section mismatches in some builds, from Paul Gortmaker. 2) Need to count huge zero page mappings when doing TSB sizing, from Mike Kravetz. 3) Fix handing of cpu_possible_mask when nr_cpus module option is specified, from Atish Patra. 4) Don't allocate irq stacks until nr_irqs has been processed, also from Atish Patra. * git://git.kernel.org/pub/scm/linux/kernel/git/davem/sparc: sparc64: Fix non-SMP build. sparc64: Fix irq stack bootmem allocation. sparc64: Fix cpu_possible_mask if nr_cpus is set sparc64 mm: Fix more TSB sizing issues sparc64: fix section mismatch in find_numa_latencies_for_group
2 parents bb6bbc7 + 2a0100d commit 0c7fc30

File tree

8 files changed

+90
-29
lines changed

8 files changed

+90
-29
lines changed

arch/sparc/include/asm/page_64.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
#define HPAGE_MASK (~(HPAGE_SIZE - 1UL))
2626
#define HUGETLB_PAGE_ORDER (HPAGE_SHIFT - PAGE_SHIFT)
2727
#define HAVE_ARCH_HUGETLB_UNMAPPED_AREA
28+
#define REAL_HPAGE_PER_HPAGE (_AC(1,UL) << (HPAGE_SHIFT - REAL_HPAGE_SHIFT))
2829
#endif
2930

3031
#ifndef __ASSEMBLY__

arch/sparc/include/asm/smp_64.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ void arch_send_call_function_ipi_mask(const struct cpumask *mask);
4343
int hard_smp_processor_id(void);
4444
#define raw_smp_processor_id() (current_thread_info()->cpu)
4545

46+
void smp_fill_in_cpu_possible_map(void);
4647
void smp_fill_in_sib_core_maps(void);
4748
void cpu_play_dead(void);
4849

@@ -72,6 +73,7 @@ void __cpu_die(unsigned int cpu);
7273
#define smp_fill_in_sib_core_maps() do { } while (0)
7374
#define smp_fetch_global_regs() do { } while (0)
7475
#define smp_fetch_global_pmu() do { } while (0)
76+
#define smp_fill_in_cpu_possible_map() do { } while (0)
7577

7678
#endif /* !(CONFIG_SMP) */
7779

arch/sparc/kernel/setup_64.c

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
#include <linux/initrd.h>
3232
#include <linux/module.h>
3333
#include <linux/start_kernel.h>
34+
#include <linux/bootmem.h>
3435

3536
#include <asm/io.h>
3637
#include <asm/processor.h>
@@ -50,6 +51,8 @@
5051
#include <asm/elf.h>
5152
#include <asm/mdesc.h>
5253
#include <asm/cacheflush.h>
54+
#include <asm/dma.h>
55+
#include <asm/irq.h>
5356

5457
#ifdef CONFIG_IP_PNP
5558
#include <net/ipconfig.h>
@@ -590,6 +593,22 @@ static void __init init_sparc64_elf_hwcap(void)
590593
pause_patch();
591594
}
592595

596+
void __init alloc_irqstack_bootmem(void)
597+
{
598+
unsigned int i, node;
599+
600+
for_each_possible_cpu(i) {
601+
node = cpu_to_node(i);
602+
603+
softirq_stack[i] = __alloc_bootmem_node(NODE_DATA(node),
604+
THREAD_SIZE,
605+
THREAD_SIZE, 0);
606+
hardirq_stack[i] = __alloc_bootmem_node(NODE_DATA(node),
607+
THREAD_SIZE,
608+
THREAD_SIZE, 0);
609+
}
610+
}
611+
593612
void __init setup_arch(char **cmdline_p)
594613
{
595614
/* Initialize PROM console and command line. */
@@ -650,6 +669,13 @@ void __init setup_arch(char **cmdline_p)
650669

651670
paging_init();
652671
init_sparc64_elf_hwcap();
672+
smp_fill_in_cpu_possible_map();
673+
/*
674+
* Once the OF device tree and MDESC have been setup and nr_cpus has
675+
* been parsed, we know the list of possible cpus. Therefore we can
676+
* allocate the IRQ stacks.
677+
*/
678+
alloc_irqstack_bootmem();
653679
}
654680

655681
extern int stop_a_enabled;

arch/sparc/kernel/smp_64.c

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1227,6 +1227,20 @@ void __init smp_setup_processor_id(void)
12271227
xcall_deliver_impl = hypervisor_xcall_deliver;
12281228
}
12291229

1230+
void __init smp_fill_in_cpu_possible_map(void)
1231+
{
1232+
int possible_cpus = num_possible_cpus();
1233+
int i;
1234+
1235+
if (possible_cpus > nr_cpu_ids)
1236+
possible_cpus = nr_cpu_ids;
1237+
1238+
for (i = 0; i < possible_cpus; i++)
1239+
set_cpu_possible(i, true);
1240+
for (; i < NR_CPUS; i++)
1241+
set_cpu_possible(i, false);
1242+
}
1243+
12301244
void smp_fill_in_sib_core_maps(void)
12311245
{
12321246
unsigned int i;

arch/sparc/mm/fault_64.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -484,6 +484,7 @@ asmlinkage void __kprobes do_sparc64_fault(struct pt_regs *regs)
484484
tsb_grow(mm, MM_TSB_BASE, mm_rss);
485485
#if defined(CONFIG_HUGETLB_PAGE) || defined(CONFIG_TRANSPARENT_HUGEPAGE)
486486
mm_rss = mm->context.hugetlb_pte_count + mm->context.thp_pte_count;
487+
mm_rss *= REAL_HPAGE_PER_HPAGE;
487488
if (unlikely(mm_rss >
488489
mm->context.tsb_block[MM_TSB_HUGE].tsb_rss_limit)) {
489490
if (mm->context.tsb_block[MM_TSB_HUGE].tsb)

arch/sparc/mm/init_64.c

Lines changed: 3 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1160,7 +1160,7 @@ int __node_distance(int from, int to)
11601160
return numa_latency[from][to];
11611161
}
11621162

1163-
static int find_best_numa_node_for_mlgroup(struct mdesc_mlgroup *grp)
1163+
static int __init find_best_numa_node_for_mlgroup(struct mdesc_mlgroup *grp)
11641164
{
11651165
int i;
11661166

@@ -1173,8 +1173,8 @@ static int find_best_numa_node_for_mlgroup(struct mdesc_mlgroup *grp)
11731173
return i;
11741174
}
11751175

1176-
static void find_numa_latencies_for_group(struct mdesc_handle *md, u64 grp,
1177-
int index)
1176+
static void __init find_numa_latencies_for_group(struct mdesc_handle *md,
1177+
u64 grp, int index)
11781178
{
11791179
u64 arc;
11801180

@@ -2081,7 +2081,6 @@ void __init paging_init(void)
20812081
{
20822082
unsigned long end_pfn, shift, phys_base;
20832083
unsigned long real_end, i;
2084-
int node;
20852084

20862085
setup_page_offset();
20872086

@@ -2250,21 +2249,6 @@ void __init paging_init(void)
22502249
/* Setup bootmem... */
22512250
last_valid_pfn = end_pfn = bootmem_init(phys_base);
22522251

2253-
/* Once the OF device tree and MDESC have been setup, we know
2254-
* the list of possible cpus. Therefore we can allocate the
2255-
* IRQ stacks.
2256-
*/
2257-
for_each_possible_cpu(i) {
2258-
node = cpu_to_node(i);
2259-
2260-
softirq_stack[i] = __alloc_bootmem_node(NODE_DATA(node),
2261-
THREAD_SIZE,
2262-
THREAD_SIZE, 0);
2263-
hardirq_stack[i] = __alloc_bootmem_node(NODE_DATA(node),
2264-
THREAD_SIZE,
2265-
THREAD_SIZE, 0);
2266-
}
2267-
22682252
kernel_physical_mapping_init();
22692253

22702254
{

arch/sparc/mm/tlb.c

Lines changed: 31 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -174,10 +174,25 @@ void set_pmd_at(struct mm_struct *mm, unsigned long addr,
174174
return;
175175

176176
if ((pmd_val(pmd) ^ pmd_val(orig)) & _PAGE_PMD_HUGE) {
177-
if (pmd_val(pmd) & _PAGE_PMD_HUGE)
178-
mm->context.thp_pte_count++;
179-
else
180-
mm->context.thp_pte_count--;
177+
/*
178+
* Note that this routine only sets pmds for THP pages.
179+
* Hugetlb pages are handled elsewhere. We need to check
180+
* for huge zero page. Huge zero pages are like hugetlb
181+
* pages in that there is no RSS, but there is the need
182+
* for TSB entries. So, huge zero page counts go into
183+
* hugetlb_pte_count.
184+
*/
185+
if (pmd_val(pmd) & _PAGE_PMD_HUGE) {
186+
if (is_huge_zero_page(pmd_page(pmd)))
187+
mm->context.hugetlb_pte_count++;
188+
else
189+
mm->context.thp_pte_count++;
190+
} else {
191+
if (is_huge_zero_page(pmd_page(orig)))
192+
mm->context.hugetlb_pte_count--;
193+
else
194+
mm->context.thp_pte_count--;
195+
}
181196

182197
/* Do not try to allocate the TSB hash table if we
183198
* don't have one already. We have various locks held
@@ -204,6 +219,9 @@ void set_pmd_at(struct mm_struct *mm, unsigned long addr,
204219
}
205220
}
206221

222+
/*
223+
* This routine is only called when splitting a THP
224+
*/
207225
void pmdp_invalidate(struct vm_area_struct *vma, unsigned long address,
208226
pmd_t *pmdp)
209227
{
@@ -213,6 +231,15 @@ void pmdp_invalidate(struct vm_area_struct *vma, unsigned long address,
213231

214232
set_pmd_at(vma->vm_mm, address, pmdp, entry);
215233
flush_tlb_range(vma, address, address + HPAGE_PMD_SIZE);
234+
235+
/*
236+
* set_pmd_at() will not be called in a way to decrement
237+
* thp_pte_count when splitting a THP, so do it now.
238+
* Sanity check pmd before doing the actual decrement.
239+
*/
240+
if ((pmd_val(entry) & _PAGE_PMD_HUGE) &&
241+
!is_huge_zero_page(pmd_page(entry)))
242+
(vma->vm_mm)->context.thp_pte_count--;
216243
}
217244

218245
void pgtable_trans_huge_deposit(struct mm_struct *mm, pmd_t *pmdp,

arch/sparc/mm/tsb.c

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -469,8 +469,10 @@ void tsb_grow(struct mm_struct *mm, unsigned long tsb_index, unsigned long rss)
469469

470470
int init_new_context(struct task_struct *tsk, struct mm_struct *mm)
471471
{
472+
unsigned long mm_rss = get_mm_rss(mm);
472473
#if defined(CONFIG_HUGETLB_PAGE) || defined(CONFIG_TRANSPARENT_HUGEPAGE)
473-
unsigned long total_huge_pte_count;
474+
unsigned long saved_hugetlb_pte_count;
475+
unsigned long saved_thp_pte_count;
474476
#endif
475477
unsigned int i;
476478

@@ -483,10 +485,12 @@ int init_new_context(struct task_struct *tsk, struct mm_struct *mm)
483485
* will re-increment the counters as the parent PTEs are
484486
* copied into the child address space.
485487
*/
486-
total_huge_pte_count = mm->context.hugetlb_pte_count +
487-
mm->context.thp_pte_count;
488+
saved_hugetlb_pte_count = mm->context.hugetlb_pte_count;
489+
saved_thp_pte_count = mm->context.thp_pte_count;
488490
mm->context.hugetlb_pte_count = 0;
489491
mm->context.thp_pte_count = 0;
492+
493+
mm_rss -= saved_thp_pte_count * (HPAGE_SIZE / PAGE_SIZE);
490494
#endif
491495

492496
/* copy_mm() copies over the parent's mm_struct before calling
@@ -499,11 +503,13 @@ int init_new_context(struct task_struct *tsk, struct mm_struct *mm)
499503
/* If this is fork, inherit the parent's TSB size. We would
500504
* grow it to that size on the first page fault anyways.
501505
*/
502-
tsb_grow(mm, MM_TSB_BASE, get_mm_rss(mm));
506+
tsb_grow(mm, MM_TSB_BASE, mm_rss);
503507

504508
#if defined(CONFIG_HUGETLB_PAGE) || defined(CONFIG_TRANSPARENT_HUGEPAGE)
505-
if (unlikely(total_huge_pte_count))
506-
tsb_grow(mm, MM_TSB_HUGE, total_huge_pte_count);
509+
if (unlikely(saved_hugetlb_pte_count + saved_thp_pte_count))
510+
tsb_grow(mm, MM_TSB_HUGE,
511+
(saved_hugetlb_pte_count + saved_thp_pte_count) *
512+
REAL_HPAGE_PER_HPAGE);
507513
#endif
508514

509515
if (unlikely(!mm->context.tsb_block[MM_TSB_BASE].tsb))

0 commit comments

Comments
 (0)