MM: Make Page Tables Relocatable -- relocation code.
Subsystems (13)
PATCH 2/2 MM: Make Page Tables Relocatable -- relocation code.
-----
arch/powerpc/mm/fault.c renamed from home/rossb/local/linux-2.6.25-rc9/arch/powerpc/mm/fault.c +2 -0
@@ -299,6 +299,8 @@ good_area:if (get_pteptr (mm, address, &ptep, &pmdp)) {spinlock_t *ptl =pte_lockptr (mm, pmdp);spin_lock (ptl); +delimbo_pte (&ptep, &ptl, &pmdp, mm, address); +if (pte_present (*ptep)) {struct page *page =pte_page (*ptep);
arch/powerpc/mm/hugetlbpage.c renamed from home/rossb/local/linux-2.6.25-rc9/arch/powerpc/mm/hugetlbpage.c +1 -0
@@ -73,6 +73,7 @@ static int __hugepte_alloc(struct mm_strreturn -ENOMEM ;spin_lock (&mm->page_table_lock); +delimbo_hpd (&hpdp, mm, address);if (!hugepd_none (*hpdp))kmem_cache_free (huge_pgtable_cache, new);else
arch/ppc/mm/fault.c renamed from home/rossb/local/linux-2.6.25-rc9/arch/ppc/mm/fault.c +1 -0
@@ -219,6 +219,7 @@ good_area:if (get_pteptr (mm, address, &ptep, &pmdp)) {spinlock_t *ptl =pte_lockptr (mm, pmdp);spin_lock (ptl); +delimbo_pte (&ptep, &ptl, &pmdp, mm, address);if (pte_present (*ptep)) {struct page *page =pte_page (*ptep);
arch/x86/mm/hugetlbpage.c renamed from home/rossb/local/linux-2.6.25-rc9/arch/x86/mm/hugetlbpage.c +1 -0
@@ -88,6 +88,7 @@ static void huge_pmd_share(struct mm_str goto out;spin_lock (&mm->page_table_lock); +delimbo_pud (&pud, mm, addr);if (pud_none (*pud))pud_populate (mm, pud, (pmd_t *)((unsigned long )spte &PAGE_MASK ));else
include/asm-generic/pgalloc.h renamed from home/rossb/local/linux-2.6.25-rc9/include/asm-generic/pgalloc.h +37 -0
@@ -0,0 +1,37 @@ +#ifndef _ASM_GENERIC_PGALLOC_H +#define _ASM_GENERIC_PGALLOC_H + + + +/* Page Table Levels used for alloc_page_table. */ +#define PAGE_TABLE_PGD 0 +#define PAGE_TABLE_PUD 1 +#define PAGE_TABLE_PMD 2 +#define PAGE_TABLE_PTE 3 + +static inline struct page *alloc_page_table_node (struct mm_struct *mm, +unsigned long addr, +int node, +int page_table_level) +{ +switch (page_table_level) { +case PAGE_TABLE_PGD : +return virt_to_page (pgd_alloc_node (mm, node)); + +case PAGE_TABLE_PUD : +return virt_to_page (pud_alloc_one_node (mm, addr, node)); + +case PAGE_TABLE_PMD : +return virt_to_page (pmd_alloc_one_node (mm, addr, node)); + +case PAGE_TABLE_PTE : +return pte_alloc_one_node (mm, addr, node); + +default : +BUG (); +return NULL ; + } +} + + +#endif /* _ASM_GENERIC_PGALLOC_H */
include/asm-generic/pgtable.h renamed from home/rossb/local/linux-2.6.25-rc9/include/asm-generic/pgtable.h +50 -0
62 lines not on this page · raw message
include/asm-x86/pgalloc_64.h renamed from home/rossb/local/linux-2.6.25-rc9/include/asm-x86/pgalloc_64.h +138 -33
205 lines not on this page · raw message
include/linux/migrate.h renamed from home/rossb/local/linux-2.6.25-rc9/include/linux/migrate.h +4 -0
@@ -6,6 +6,10 @@#include <linux/pagemap.h> typedef struct page *new_page_t (struct page *,unsigned long private,int **); +typedef struct page *new_page_table_t (struct mm_struct *, +unsigned long addr, +unsigned long private, +int **,int page_table_level);#ifdef CONFIG_MIGRATION /* Check if a vma is migratable */
include/linux/mm.h renamed from home/rossb/local/linux-2.6.25-rc9/include/linux/mm.h +112 -0
130 lines not on this page · raw message
kernel/fork.c renamed from home/rossb/local/linux-2.6.25-rc9/kernel/fork.c +4 -0
@@ -360,6 +360,10 @@ static struct mm_struct * mm_init(struct mm->cached_hole_size = ~0UL ;mm_init_cgroup (mm, p); +#ifdef CONFIG_RELOCATE_PAGE_TABLES + mm->page_table_relocation_count =0 ; +#endif +if (likely (!mm_alloc_pgd (mm))) { mm->def_flags =0 ;return mm;
mm/Kconfig renamed from home/rossb/local/linux-2.6.25-rc9/mm/Kconfig +4 -0
@@ -143,6 +143,10 @@ config MEMORY_HOTREMOVE depends on MEMORY_HOTPLUG && ARCH_ENABLE_MEMORY_HOTREMOVE depends on MIGRATION +config RELOCATE_PAGE_TABLES + def_bool y + depends on X86_64 && MIGRATION + # Heavily threaded applications may benefit from splitting the mm-wide # page_table_lock, so that faults on different parts of the user address # space can be handled with less contention: split it at this NR_CPUS.
mm/hugetlb.c renamed from home/rossb/local/linux-2.6.25-rc9/mm/hugetlb.c +4 -0
@@ -762,6 +762,8 @@ int copy_hugetlb_page_range(struct mm_stspin_lock (&dst->page_table_lock);spin_lock (&src->page_table_lock); +delimbo_huge_pte (&src_pte, src, addr); +delimbo_huge_pte (&dst_pte, dst, addr);if (!pte_none (*src_pte)) {if (cow)ptep_set_wrprotect (src, addr, src_pte);
@@ -937,6 +939,7 @@ retry: }spin_lock (&mm->page_table_lock); +delimbo_huge_pte (&ptep, mm, address); size =i_size_read (mapping->host) >>HPAGE_SHIFT ;if (idx >= size) goto backout;
@@ -994,6 +997,7 @@ int hugetlb_fault(struct mm_struct *mm, ret =0 ;spin_lock (&mm->page_table_lock); +delimbo_huge_pte (&ptep, mm, address);/* Check for a racing update before calling hugetlb_cow */ if (likely (pte_same (entry, *ptep)))if (write_access && !pte_write (entry))
mm/memory.c renamed from home/rossb/local/linux-2.6.25-rc9/mm/memory.c +31 -3
@@ -312,6 +312,7 @@ int __pte_alloc(struct mm_struct *mm, pmreturn -ENOMEM ;spin_lock (&mm->page_table_lock); +delimbo_pmd (&pmd, mm, address);if (!pmd_present (*pmd)) {/* Has another populated it ? */ mm->nr_ptes++;pmd_populate (mm, pmd, new);
@@ -330,6 +331,7 @@ int __pte_alloc_kernel(pmd_t *pmd, unsigreturn -ENOMEM ;spin_lock (&init_mm.page_table_lock); +delimbo_pmd (&pmd, &init_mm, address);if (!pmd_present (*pmd)) {/* Has another populated it ? */ pmd_populate_kernel (&init_mm, pmd, new); new =NULL ;
@@ -513,6 +515,9 @@ again: src_pte =pte_offset_map_nested (src_pmd, addr); src_ptl =pte_lockptr (src_mm, src_pmd);spin_lock_nested (src_ptl,SINGLE_DEPTH_NESTING ); + +delimbo_pte_nested (&src_pte, &src_ptl, &src_pmd, src_mm, addr, +SINGLE_DEPTH_NESTING , dst_ptl);arch_enter_lazy_mmu_mode (); do {
@@ -1488,13 +1493,15 @@ EXPORT_SYMBOL_GPL(apply_to_page_range);* and do_anonymous_page and do_no_page can safely check later on). */ static inline int pte_unmap_same (struct mm_struct *mm,pmd_t *pmd, -pte_t *page_table,pte_t orig_pte) +pte_t *page_table,pte_t orig_pte, +unsigned long address) {int same =1 ;#if defined(CONFIG_SMP ) || defined(CONFIG_PREEMPT )if (sizeof (pte_t) >sizeof (unsigned long )) {spinlock_t *ptl =pte_lockptr (mm, pmd);spin_lock (ptl); +delimbo_pte (&page_table, &ptl, &pmd, mm, address); same =pte_same (*page_table, orig_pte);spin_unlock (ptl); }
@@ -2021,7 +2028,7 @@ static int do_swap_page(struct mm_structpte_t pte;int ret =0 ; -if (!pte_unmap_same (mm, pmd, page_table, orig_pte)) +if (!pte_unmap_same (mm, pmd, page_table, orig_pte, address)) goto out; entry =pte_to_swp_entry (orig_pte);
@@ -2100,6 +2107,10 @@ static int do_swap_page(struct mm_struct }/* No need to invalidate - it was non-present before */ +/* Unless of course the cpu might be looking at an old +copy of the pte. */ +maybe_reload_tlb_mm (mm); +update_mmu_cache (vma, address, pte); unlock:pte_unmap_unlock (page_table, ptl);
@@ -2151,6 +2162,10 @@ static int do_anonymous_page(struct mm_sset_pte_at (mm, address, page_table, entry);/* No need to invalidate - it was non-present before */ +/* Unless of course the cpu might be looking at an old +copy of the pte. */ +maybe_reload_tlb_mm (mm); +update_mmu_cache (vma, address, entry); unlock:pte_unmap_unlock (page_table, ptl);
@@ -2312,6 +2327,10 @@ static int __do_fault(struct mm_struct * }/* no need to invalidate: a not-present page won't be cached */ +/* Unless of course the cpu could be looking at an old page +table entry. */ +maybe_reload_tlb_mm (mm); +update_mmu_cache (vma, address, entry); }else {mem_cgroup_uncharge_page (page);
@@ -2418,7 +2437,7 @@ static int do_nonlinear_fault(struct mm_ (write_access ?FAULT_FLAG_WRITE :0 );pgoff_t pgoff; -if (!pte_unmap_same (mm, pmd, page_table, orig_pte)) +if (!pte_unmap_same (mm, pmd, page_table, orig_pte, address))return 0 ; if (unlikely(!(vma->vm_flags & VM_NONLINEAR) ||
@@ -2477,6 +2496,7 @@ static inline int handle_pte_fault(struc ptl =pte_lockptr (mm, pmd);spin_lock (ptl); +delimbo_pte (&pte, &ptl, &pmd, mm, address);if (unlikely (!pte_same (*pte, entry))) goto unlock;if (write_access) {
@@ -2498,6 +2518,12 @@ static inline int handle_pte_fault(strucif (write_access)flush_tlb_page (vma, address); } + +/* if the cpu could be looking at an old page table, we need to +flush out everything. */ +maybe_reload_tlb_mm (mm); + + unlock:pte_unmap_unlock (pte, ptl);return 0 ;
@@ -2547,6 +2573,7 @@ int __pud_alloc(struct mm_struct *mm, pgreturn -ENOMEM ;spin_lock (&mm->page_table_lock); +delimbo_pgd (&pgd, mm, address);if (pgd_present (*pgd))/* Another has populated it */ pud_free (mm, new);else
@@ -2568,6 +2595,7 @@ int __pmd_alloc(struct mm_struct *mm, pureturn -ENOMEM ;spin_lock (&mm->page_table_lock); +delimbo_pud (&pud, mm, address);#ifndef __ARCH_HAS_4LEVEL_HACKif (pud_present (*pud))/* Another has populated it */ pmd_free (mm, new);
mm/mempolicy.c renamed from home/rossb/local/linux-2.6.25-rc9/mm/mempolicy.c +26 -0
@@ -101,6 +101,12 @@static struct kmem_cache *policy_cache;static struct kmem_cache *sn_cache; +#ifdef CONFIG_RELOCATE_PAGE_TABLES +int migrate_page_tables_mm (struct mm_struct *mm,int source, +new_page_table_t get_new_page, +unsigned long private); +#endif +/* Highest zone. An specific allocation for a zone below that is not policied. */ enum zone_type policy_zone =0 ;
@@ -627,6 +633,20 @@ static struct page *new_node_page(structreturn alloc_pages_node (node,GFP_HIGHUSER_MOVABLE ,0 ); } +#ifdef CONFIG_RELOCATE_PAGE_TABLES +static struct page *new_node_page_page_tables (struct mm_struct *mm, +unsigned long addr, +unsigned long node, +int **x, +int level) +{ +struct page *p; + p =alloc_page_table_node (mm, addr, node, level); +return p; +} + +#endif /* CONFIG_RELOCATE_PAGE_TABLES */ +/* * Migrate pages from one node to a target node. * Returns error or the number of pages not migrated.
@@ -647,6 +667,12 @@ static int migrate_to_node(struct mm_strif (!list_empty (&pagelist)) err =migrate_pages (&pagelist, new_node_page, dest); +#ifdef CONFIG_RELOCATE_PAGE_TABLES +if (!err) + err =migrate_page_tables_mm (mm, source, + new_node_page_page_tables, dest); +#endif /* CONFIG_RELOCATE_PAGE_TABLES */ +return err; }
mm/migrate.c renamed from home/rossb/local/linux-2.6.25-rc9/mm/migrate.c +523 -1
550 lines not on this page · raw message
mm/mremap.c renamed from home/rossb/local/linux-2.6.25-rc9/mm/mremap.c +2 -0
@@ -98,6 +98,8 @@ static void move_ptes(struct vm_area_str new_ptl =pte_lockptr (mm, new_pmd);if (new_ptl != old_ptl)spin_lock_nested (new_ptl,SINGLE_DEPTH_NESTING ); +delimbo_pte_nested (&new_pte, &new_ptl, &new_pmd, mm, new_addr, +SINGLE_DEPTH_NESTING , old_ptl);arch_enter_lazy_mmu_mode (); for (; old_addr < old_end; old_pte++, old_addr += PAGE_SIZE,
mm/rmap.c renamed from home/rossb/local/linux-2.6.25-rc9/mm/rmap.c +1 -0
@@ -255,6 +255,7 @@ pte_t *page_check_address(struct page *p ptl =pte_lockptr (mm, pmd);spin_lock (ptl); +delimbo_pte (&pte, &ptl, &pmd, mm, address);if (pte_present (*pte) &&page_to_pfn (page) ==pte_pfn (*pte)) { *ptlp = ptl;return pte;
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>