[RFC] implicit hugetlb pages (mmu_context_to_struct)
David Gibson
david at gibson.dropbear.id.au
Mon Feb 2 17:48:41 EST 2004
On Fri, Jan 09, 2004 at 01:29:38PM -0800, Adam Litke wrote:
>
> mmu_context_to_struct (2.6.0):
> This patch converts the mmu_context variable to a structure. It is
> needed for the dynamic address space resizing patch.
Ok, I've made a revised version of this patch. As well as handling
the various changes in ameslab since Adam's version, it uses a better
name for the mm_context fields, separates out the low_hpages flag, and
avoids putting extraneous info in the mmu_context_queue.
I'm slightly concerned about whether it has zero-impact in the
!CONFIG_HUGETLB_PAGE case. I think theoretically it could/should, but
there's a couple of cases where I don't know if gcc will be clever
enough to optimise everything away.
Anton, if you approve I can push this to ameslab and/or akpm.
mmu-context-struct (2.6.0):
This patch converts the mmu_context variable to a structure. It is
needed for the dynamic HTLB address space resizing patch.
Index: working-2.6/arch/ppc64/kernel/stab.c
===================================================================
--- working-2.6.orig/arch/ppc64/kernel/stab.c 2004-02-02 17:04:37.000000000 +1100
+++ working-2.6/arch/ppc64/kernel/stab.c 2004-02-02 17:36:30.961032128 +1100
@@ -175,13 +175,13 @@
/* Kernel or user address? */
if (REGION_ID(ea) >= KERNEL_REGION_ID) {
vsid = get_kernel_vsid(ea);
- context = REGION_ID(ea);
+ context = KERNEL_CONTEXT(ea);
} else {
if (!current->mm)
return 1;
context = current->mm->context;
- vsid = get_vsid(context, ea);
+ vsid = get_vsid(context.id, ea);
}
esid = GET_ESID(ea);
@@ -214,7 +214,7 @@
if (!IS_VALID_EA(pc) || (REGION_ID(pc) >= KERNEL_REGION_ID))
return;
- vsid = get_vsid(mm->context, pc);
+ vsid = get_vsid(mm->context.id, pc);
__ste_allocate(pc_esid, vsid);
if (pc_esid == stack_esid)
@@ -222,7 +222,7 @@
if (!IS_VALID_EA(stack) || (REGION_ID(stack) >= KERNEL_REGION_ID))
return;
- vsid = get_vsid(mm->context, stack);
+ vsid = get_vsid(mm->context.id, stack);
__ste_allocate(stack_esid, vsid);
if (pc_esid == unmapped_base_esid || stack_esid == unmapped_base_esid)
@@ -231,7 +231,7 @@
if (!IS_VALID_EA(unmapped_base) ||
(REGION_ID(unmapped_base) >= KERNEL_REGION_ID))
return;
- vsid = get_vsid(mm->context, unmapped_base);
+ vsid = get_vsid(mm->context.id, unmapped_base);
__ste_allocate(unmapped_base_esid, vsid);
/* Order update */
@@ -396,14 +396,14 @@
/* Kernel or user address? */
if (REGION_ID(ea) >= KERNEL_REGION_ID) {
- context = REGION_ID(ea);
+ context = KERNEL_CONTEXT(ea);
vsid = get_kernel_vsid(ea);
} else {
if (unlikely(!current->mm))
return 1;
context = current->mm->context;
- vsid = get_vsid(context, ea);
+ vsid = get_vsid(context.id, ea);
}
esid = GET_ESID(ea);
@@ -434,7 +434,7 @@
if (!IS_VALID_EA(pc) || (REGION_ID(pc) >= KERNEL_REGION_ID))
return;
- vsid = get_vsid(mm->context, pc);
+ vsid = get_vsid(mm->context.id, pc);
__slb_allocate(pc_esid, vsid, mm->context);
if (pc_esid == stack_esid)
@@ -442,7 +442,7 @@
if (!IS_VALID_EA(stack) || (REGION_ID(stack) >= KERNEL_REGION_ID))
return;
- vsid = get_vsid(mm->context, stack);
+ vsid = get_vsid(mm->context.id, stack);
__slb_allocate(stack_esid, vsid, mm->context);
if (pc_esid == unmapped_base_esid || stack_esid == unmapped_base_esid)
@@ -451,7 +451,7 @@
if (!IS_VALID_EA(unmapped_base) ||
(REGION_ID(unmapped_base) >= KERNEL_REGION_ID))
return;
- vsid = get_vsid(mm->context, unmapped_base);
+ vsid = get_vsid(mm->context.id, unmapped_base);
__slb_allocate(unmapped_base_esid, vsid, mm->context);
}
Index: working-2.6/arch/ppc64/mm/hugetlbpage.c
===================================================================
--- working-2.6.orig/arch/ppc64/mm/hugetlbpage.c 2004-02-02 10:44:47.000000000 +1100
+++ working-2.6/arch/ppc64/mm/hugetlbpage.c 2004-02-02 17:36:30.964031672 +1100
@@ -244,7 +244,7 @@
struct vm_area_struct *vma;
unsigned long addr;
- if (mm->context & CONTEXT_LOW_HPAGES)
+ if (mm->context.low_hpages)
return 0; /* The window is already open */
/* Check no VMAs are in the region */
@@ -281,7 +281,7 @@
/* FIXME: do we need to scan for PTEs too? */
- mm->context |= CONTEXT_LOW_HPAGES;
+ mm->context.low_hpages = 1;
/* the context change must make it to memory before the slbia,
* so that further SLB misses do the right thing. */
@@ -589,7 +589,6 @@
}
}
-
unsigned long hugetlb_get_unmapped_area(struct file *file, unsigned long addr,
unsigned long len, unsigned long pgoff,
unsigned long flags)
@@ -778,7 +777,7 @@
BUG_ON(hugepte_bad(pte));
BUG_ON(!in_hugepage_area(context, ea));
- vsid = get_vsid(context, ea);
+ vsid = get_vsid(context.id, ea);
va = (vsid << 28) | (ea & 0x0fffffff);
vpn = va >> LARGE_PAGE_SHIFT;
Index: working-2.6/arch/ppc64/mm/init.c
===================================================================
--- working-2.6.orig/arch/ppc64/mm/init.c 2004-01-22 10:53:08.000000000 +1100
+++ working-2.6/arch/ppc64/mm/init.c 2004-02-02 17:36:30.967031216 +1100
@@ -502,7 +502,7 @@
break;
case USER_REGION_ID:
pgd = pgd_offset( vma->vm_mm, vmaddr );
- context = vma->vm_mm->context;
+ context = vma->vm_mm->context.id;
/* XXX are there races with checking cpu_vm_mask? - Anton */
tmp = cpumask_of_cpu(smp_processor_id());
@@ -554,7 +554,7 @@
break;
case USER_REGION_ID:
pgd = pgd_offset(mm, start);
- context = mm->context;
+ context = mm->context.id;
/* XXX are there races with checking cpu_vm_mask? - Anton */
tmp = cpumask_of_cpu(smp_processor_id());
@@ -943,7 +943,7 @@
if (!ptep)
return;
- vsid = get_vsid(vma->vm_mm->context, ea);
+ vsid = get_vsid(vma->vm_mm->context.id, ea);
tmp = cpumask_of_cpu(smp_processor_id());
if (cpus_equal(vma->vm_mm->cpu_vm_mask, tmp))
Index: working-2.6/arch/ppc64/mm/hash_utils.c
===================================================================
--- working-2.6.orig/arch/ppc64/mm/hash_utils.c 2004-01-22 10:53:08.000000000 +1100
+++ working-2.6/arch/ppc64/mm/hash_utils.c 2004-02-02 15:16:34.000000000 +1100
@@ -237,7 +237,7 @@
if (mm == NULL)
return 1;
- vsid = get_vsid(mm->context, ea);
+ vsid = get_vsid(mm->context.id, ea);
break;
case IO_REGION_ID:
mm = &ioremap_mm;
Index: working-2.6/arch/ppc64/xmon/xmon.c
===================================================================
--- working-2.6.orig/arch/ppc64/xmon/xmon.c 2004-01-22 10:53:08.000000000 +1100
+++ working-2.6/arch/ppc64/xmon/xmon.c 2004-02-02 17:36:30.972030456 +1100
@@ -1952,7 +1952,7 @@
// if in user range, use the current task's page directory
else if ( ( ea >= USER_START ) && ( ea <= USER_END ) ) {
mm = current->mm;
- vsid = get_vsid(mm->context, ea );
+ vsid = get_vsid(mm->context.id, ea );
}
pgdir = mm->pgd;
va = ( vsid << 28 ) | ( ea & 0x0fffffff );
Index: working-2.6/include/asm-ppc64/mmu.h
===================================================================
--- working-2.6.orig/include/asm-ppc64/mmu.h 2004-02-02 10:44:49.000000000 +1100
+++ working-2.6/include/asm-ppc64/mmu.h 2004-02-02 17:36:30.975030000 +1100
@@ -18,15 +18,25 @@
#ifndef __ASSEMBLY__
-/* Default "unsigned long" context */
-typedef unsigned long mm_context_t;
+/* Time to allow for more things here */
+typedef unsigned long mm_context_id_t;
+typedef struct {
+ mm_context_id_t id;
+#ifdef CONFIG_HUGETLB_PAGE
+ int low_hpages;
+#endif
+} mm_context_t;
#ifdef CONFIG_HUGETLB_PAGE
-#define CONTEXT_LOW_HPAGES (1UL<<63)
+#define KERNEL_LOW_HPAGES .low_hpages = 0,
#else
-#define CONTEXT_LOW_HPAGES 0
+#define KERNEL_LOW_HPAGES
#endif
+#define KERNEL_CONTEXT(ea) ({ \
+ mm_context_t ctx = { .id = REGION_ID(ea), KERNEL_LOW_HPAGES}; \
+ ctx; })
+
/*
* Hardware Segment Lookaside Buffer Entry
* This structure has been padded out to two 64b doublewords (actual SLBE's are
Index: working-2.6/include/asm-ppc64/mmu_context.h
===================================================================
--- working-2.6.orig/include/asm-ppc64/mmu_context.h 2004-02-02 10:44:49.000000000 +1100
+++ working-2.6/include/asm-ppc64/mmu_context.h 2004-02-02 17:36:30.977029696 +1100
@@ -52,7 +52,7 @@
long head;
long tail;
long size;
- mm_context_t elements[LAST_USER_CONTEXT];
+ mm_context_id_t elements[LAST_USER_CONTEXT];
};
extern struct mmu_context_queue_t mmu_context_queue;
@@ -83,7 +83,6 @@
long head;
unsigned long flags;
/* This does the right thing across a fork (I hope) */
- unsigned long low_hpages = mm->context & CONTEXT_LOW_HPAGES;
spin_lock_irqsave(&mmu_context_queue.lock, flags);
@@ -93,8 +92,7 @@
}
head = mmu_context_queue.head;
- mm->context = mmu_context_queue.elements[head];
- mm->context |= low_hpages;
+ mm->context.id = mmu_context_queue.elements[head];
head = (head < LAST_USER_CONTEXT-1) ? head+1 : 0;
mmu_context_queue.head = head;
@@ -132,8 +130,7 @@
#endif
mmu_context_queue.size++;
- mmu_context_queue.elements[index] =
- mm->context & ~CONTEXT_LOW_HPAGES;
+ mmu_context_queue.elements[index] = mm->context.id;
spin_unlock_irqrestore(&mmu_context_queue.lock, flags);
}
@@ -210,8 +207,6 @@
{
unsigned long ordinal, vsid;
- context &= ~CONTEXT_LOW_HPAGES;
-
ordinal = (((ea >> 28) & 0x1fffff) * LAST_USER_CONTEXT) | context;
vsid = (ordinal * VSID_RANDOMIZER) & VSID_MASK;
Index: working-2.6/include/asm-ppc64/page.h
===================================================================
--- working-2.6.orig/include/asm-ppc64/page.h 2004-01-09 11:11:12.000000000 +1100
+++ working-2.6/include/asm-ppc64/page.h 2004-02-02 17:36:30.979029392 +1100
@@ -32,6 +32,7 @@
/* For 64-bit processes the hugepage range is 1T-1.5T */
#define TASK_HPAGE_BASE (0x0000010000000000UL)
#define TASK_HPAGE_END (0x0000018000000000UL)
+
/* For 32-bit processes the hugepage range is 2-3G */
#define TASK_HPAGE_BASE_32 (0x80000000UL)
#define TASK_HPAGE_END_32 (0xc0000000UL)
@@ -39,7 +40,7 @@
#define ARCH_HAS_HUGEPAGE_ONLY_RANGE
#define is_hugepage_only_range(addr, len) \
( ((addr > (TASK_HPAGE_BASE-len)) && (addr < TASK_HPAGE_END)) || \
- ((current->mm->context & CONTEXT_LOW_HPAGES) && \
+ (current->mm->context.low_hpages && \
(addr > (TASK_HPAGE_BASE_32-len)) && (addr < TASK_HPAGE_END_32)) )
#define hugetlb_free_pgtables free_pgtables
#define HAVE_ARCH_HUGETLB_UNMAPPED_AREA
@@ -47,7 +48,7 @@
#define in_hugepage_area(context, addr) \
((cur_cpu_spec->cpu_features & CPU_FTR_16M_PAGE) && \
((((addr) >= TASK_HPAGE_BASE) && ((addr) < TASK_HPAGE_END)) || \
- (((context) & CONTEXT_LOW_HPAGES) && \
+ ((context).low_hpages && \
(((addr) >= TASK_HPAGE_BASE_32) && ((addr) < TASK_HPAGE_END_32)))))
#else /* !CONFIG_HUGETLB_PAGE */
Index: working-2.6/include/asm-ppc64/tlb.h
===================================================================
--- working-2.6.orig/include/asm-ppc64/tlb.h 2004-01-22 10:53:21.000000000 +1100
+++ working-2.6/include/asm-ppc64/tlb.h 2004-02-02 17:36:30.980029240 +1100
@@ -65,7 +65,7 @@
if (cpus_equal(tlb->mm->cpu_vm_mask, local_cpumask))
local = 1;
- flush_hash_range(tlb->mm->context, i, local);
+ flush_hash_range(tlb->mm->context.id, i, local);
i = 0;
}
}
@@ -86,7 +86,7 @@
if (cpus_equal(tlb->mm->cpu_vm_mask, local_cpumask))
local = 1;
- flush_hash_range(tlb->mm->context, batch->index, local);
+ flush_hash_range(tlb->mm->context.id, batch->index, local);
batch->index = 0;
pte_free_finish();
--
David Gibson | For every complex problem there is a
david AT gibson.dropbear.id.au | solution which is simple, neat and
| wrong.
http://www.ozlabs.org/people/dgibson
** Sent via the linuxppc64-dev mail list. See http://lists.linuxppc.org/
More information about the Linuxppc64-dev
mailing list