Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 837cd0bd authored by Robin Holt's avatar Robin Holt Committed by Tony Luck
Browse files

[IA64] 4-level page tables



This patch introduces 4-level page tables to ia64.  I have run
some benchmarks and found nothing interesting.  Performance has
consistently fallen within the noise range.

It also introduces a config option (setting the default to 3
levels).  The config option prevents having 4 level page
tables with 64k base page size.

Signed-off-by: default avatarRobin Holt <holt@sgi.com>
Signed-off-by: default avatarTony Luck <tony.luck@intel.com>
parent d12eb7e1
Loading
Loading
Loading
Loading
+13 −0
Original line number Diff line number Diff line
@@ -164,6 +164,19 @@ config IA64_PAGE_SIZE_64KB

endchoice

choice
	prompt "Page Table Levels"
	default PGTABLE_3

config PGTABLE_3
	bool "3 Levels"

config PGTABLE_4
	depends on !IA64_PAGE_SIZE_64KB
	bool "4 Levels"

endchoice

source kernel/Kconfig.hz

config IA64_BRL_EMU
+2 −0
Original line number Diff line number Diff line
@@ -80,6 +80,8 @@ CONFIG_MCKINLEY=y
# CONFIG_IA64_PAGE_SIZE_8KB is not set
CONFIG_IA64_PAGE_SIZE_16KB=y
# CONFIG_IA64_PAGE_SIZE_64KB is not set
# CONFIG_PGTABLE_3 is not set
CONFIG_PGTABLE_4=y
# CONFIG_HZ_100 is not set
CONFIG_HZ_250=y
# CONFIG_HZ_1000 is not set
+2 −0
Original line number Diff line number Diff line
@@ -82,6 +82,8 @@ CONFIG_MCKINLEY=y
# CONFIG_IA64_PAGE_SIZE_8KB is not set
CONFIG_IA64_PAGE_SIZE_16KB=y
# CONFIG_IA64_PAGE_SIZE_64KB is not set
CONFIG_PGTABLE_3=y
# CONFIG_PGTABLE_4 is not set
# CONFIG_HZ_100 is not set
CONFIG_HZ_250=y
# CONFIG_HZ_1000 is not set
+48 −15
Original line number Diff line number Diff line
@@ -114,7 +114,7 @@ ENTRY(vhpt_miss)
	shl r21=r16,3				// shift bit 60 into sign bit
	shr.u r17=r16,61			// get the region number into r17
	;;
	shr r22=r21,3
	shr.u r22=r21,3
#ifdef CONFIG_HUGETLB_PAGE
	extr.u r26=r25,2,6
	;;
@@ -140,20 +140,34 @@ ENTRY(vhpt_miss)
(p6)	dep r17=r18,r19,3,(PAGE_SHIFT-3)	// r17=PTA + IFA(33,42)*8
(p7)	dep r17=r18,r17,3,(PAGE_SHIFT-6)	// r17=PTA + (((IFA(61,63) << 7) | IFA(33,39))*8)
	cmp.eq p7,p6=0,r21			// unused address bits all zeroes?
	shr.u r18=r22,PMD_SHIFT			// shift L2 index into position
#ifdef CONFIG_PGTABLE_4
	shr.u r28=r22,PUD_SHIFT			// shift L2 index into position
#else
	shr.u r18=r22,PMD_SHIFT			// shift L3 index into position
#endif
	;;
	ld8 r17=[r17]				// fetch the L1 entry (may be 0)
	;;
(p7)	cmp.eq p6,p7=r17,r0			// was L1 entry NULL?
	dep r17=r18,r17,3,(PAGE_SHIFT-3)	// compute address of L2 page table entry
#ifdef CONFIG_PGTABLE_4
	dep r28=r28,r17,3,(PAGE_SHIFT-3)	// compute address of L2 page table entry
	;;
	shr.u r18=r22,PMD_SHIFT			// shift L3 index into position
(p7)	ld8 r29=[r28]				// fetch the L2 entry (may be 0)
	;;
(p7)	ld8 r20=[r17]				// fetch the L2 entry (may be 0)
	shr.u r19=r22,PAGE_SHIFT		// shift L3 index into position
(p7)	cmp.eq.or.andcm p6,p7=r29,r0		// was L2 entry NULL?
	dep r17=r18,r29,3,(PAGE_SHIFT-3)	// compute address of L3 page table entry
#else
	dep r17=r18,r17,3,(PAGE_SHIFT-3)	// compute address of L3 page table entry
#endif
	;;
(p7)	cmp.eq.or.andcm p6,p7=r20,r0		// was L2 entry NULL?
	dep r21=r19,r20,3,(PAGE_SHIFT-3)	// compute address of L3 page table entry
(p7)	ld8 r20=[r17]				// fetch the L3 entry (may be 0)
	shr.u r19=r22,PAGE_SHIFT		// shift L4 index into position
	;;
(p7)	ld8 r18=[r21]				// read the L3 PTE
(p7)	cmp.eq.or.andcm p6,p7=r20,r0		// was L3 entry NULL?
	dep r21=r19,r20,3,(PAGE_SHIFT-3)	// compute address of L4 page table entry
	;;
(p7)	ld8 r18=[r21]				// read the L4 PTE
	mov r19=cr.isr				// cr.isr bit 0 tells us if this is an insn miss
	;;
(p7)	tbit.z p6,p7=r18,_PAGE_P_BIT		// page present bit cleared?
@@ -192,14 +206,21 @@ ENTRY(vhpt_miss)
	 * between reading the pagetable and the "itc".  If so, flush the entry we
	 * inserted and retry.
	 */
	ld8 r25=[r21]				// read L3 PTE again
	ld8 r26=[r17]				// read L2 entry again
	ld8 r25=[r21]				// read L4 entry again
	ld8 r26=[r17]				// read L3 PTE again
#ifdef CONFIG_PGTABLE_4
	ld8 r18=[r28]				// read L2 entry again
#endif
	cmp.ne p6,p7=r0,r0
	;;
	cmp.ne p6,p7=r26,r20			// did L2 entry change
	cmp.ne.or.andcm p6,p7=r26,r20		// did L3 entry change
#ifdef CONFIG_PGTABLE_4
	cmp.ne.or.andcm p6,p7=r29,r18		// did L4 PTE change
#endif
	mov r27=PAGE_SHIFT<<2
	;;
(p6)	ptc.l r22,r27				// purge PTE page translation
(p7)	cmp.ne.or.andcm p6,p7=r25,r18		// did L3 PTE change
(p7)	cmp.ne.or.andcm p6,p7=r25,r18		// did L4 PTE change
	;;
(p6)	ptc.l r16,r27				// purge translation
#endif
@@ -432,18 +453,30 @@ ENTRY(nested_dtlb_miss)
(p6)	dep r17=r18,r19,3,(PAGE_SHIFT-3)	// r17=PTA + IFA(33,42)*8
(p7)	dep r17=r18,r17,3,(PAGE_SHIFT-6)	// r17=PTA + (((IFA(61,63) << 7) | IFA(33,39))*8)
	cmp.eq p7,p6=0,r21			// unused address bits all zeroes?
	shr.u r18=r22,PMD_SHIFT			// shift L2 index into position
#ifdef CONFIG_PGTABLE_4
	shr.u r18=r22,PUD_SHIFT			// shift L2 index into position
#else
	shr.u r18=r22,PMD_SHIFT			// shift L3 index into position
#endif
	;;
	ld8 r17=[r17]				// fetch the L1 entry (may be 0)
	;;
(p7)	cmp.eq p6,p7=r17,r0			// was L1 entry NULL?
	dep r17=r18,r17,3,(PAGE_SHIFT-3)	// compute address of L2 page table entry
	;;
#ifdef CONFIG_PGTABLE_4
(p7)	ld8 r17=[r17]				// fetch the L2 entry (may be 0)
	shr.u r19=r22,PAGE_SHIFT		// shift L3 index into position
	shr.u r18=r22,PMD_SHIFT			// shift L3 index into position
	;;
(p7)	cmp.eq.or.andcm p6,p7=r17,r0		// was L2 entry NULL?
	dep r17=r19,r17,3,(PAGE_SHIFT-3)	// compute address of L3 page table entry
	dep r17=r18,r17,3,(PAGE_SHIFT-3)	// compute address of L2 page table entry
	;;
#endif
(p7)	ld8 r17=[r17]				// fetch the L3 entry (may be 0)
	shr.u r19=r22,PAGE_SHIFT		// shift L4 index into position
	;;
(p7)	cmp.eq.or.andcm p6,p7=r17,r0		// was L3 entry NULL?
	dep r17=r19,r17,3,(PAGE_SHIFT-3)	// compute address of L4 page table entry
(p6)	br.cond.spnt page_fault
	mov b0=r30
	br.sptk.many b0				// return to continuation point
+6 −2
Original line number Diff line number Diff line
@@ -47,8 +47,6 @@
#define PERCPU_PAGE_SHIFT	16	/* log2() of max. size of per-CPU area */
#define PERCPU_PAGE_SIZE	(__IA64_UL_CONST(1) << PERCPU_PAGE_SHIFT)

#define RGN_MAP_LIMIT	((1UL << (4*PAGE_SHIFT - 12)) - PAGE_SIZE)	/* per region addr limit */


#ifdef CONFIG_HUGETLB_PAGE
# define HPAGE_REGION_BASE	RGN_BASE(RGN_HPAGE)
@@ -175,11 +173,17 @@ get_order (unsigned long size)
   */
  typedef struct { unsigned long pte; } pte_t;
  typedef struct { unsigned long pmd; } pmd_t;
#ifdef CONFIG_PGTABLE_4
  typedef struct { unsigned long pud; } pud_t;
#endif
  typedef struct { unsigned long pgd; } pgd_t;
  typedef struct { unsigned long pgprot; } pgprot_t;

# define pte_val(x)	((x).pte)
# define pmd_val(x)	((x).pmd)
#ifdef CONFIG_PGTABLE_4
# define pud_val(x)	((x).pud)
#endif
# define pgd_val(x)	((x).pgd)
# define pgprot_val(x)	((x).pgprot)

Loading