From: Paul Davies <pauld@gelato.unsw.edu.au>
To: linux-mm@kvack.org
Cc: Paul Davies <pauld@gelato.unsw.edu.au>
Subject: [PATCH 8/18] PTI - Page fault handler
Date: Thu, 13 Jul 2006 14:27:55 +1000 [thread overview]
Message-ID: <20060713042755.9978.16103.sendpatchset@localhost.localdomain> (raw)
In-Reply-To: <20060713042630.9978.66924.sendpatchset@localhost.localdomain>
1) Continues calling the PTI interface to abstract page table dependent
calls from the page fault handler functions.
2) Remove get_locked_pte from memory.c to be replaced by build_page_table.
3) Call lookup_page_table in filemap_xip.c
Signed-Off-By: Paul Davies <pauld@gelato.unsw.edu.au>
---
include/linux/mm.h | 2 -
mm/filemap_xip.c | 26 +++++++++++++++++++---
mm/memory.c | 62 +++++++++++++++++++++--------------------------------
3 files changed, 48 insertions(+), 42 deletions(-)
Index: linux-2.6.17.2/mm/memory.c
===================================================================
--- linux-2.6.17.2.orig/mm/memory.c 2006-07-08 20:35:44.823860064 +1000
+++ linux-2.6.17.2/mm/memory.c 2006-07-08 20:38:43.631677144 +1000
@@ -934,18 +934,6 @@
return err;
}
-pte_t * fastcall get_locked_pte(struct mm_struct *mm, unsigned long addr, spinlock_t **ptl)
-{
- pgd_t * pgd = pgd_offset(mm, addr);
- pud_t * pud = pud_alloc(mm, pgd, addr);
- if (pud) {
- pmd_t * pmd = pmd_alloc(mm, pud, addr);
- if (pmd)
- return pte_alloc_map_lock(mm, pmd, addr, ptl);
- }
- return NULL;
-}
-
/*
* This is the old fallback for page remapping.
*
@@ -957,14 +945,14 @@
{
int retval;
pte_t *pte;
- spinlock_t *ptl;
+ pt_path_t pt_path;
retval = -EINVAL;
if (PageAnon(page))
goto out;
retval = -ENOMEM;
flush_dcache_page(page);
- pte = get_locked_pte(mm, addr, &ptl);
+ pte = build_page_table(mm, addr, &pt_path);
if (!pte)
goto out;
retval = -EBUSY;
@@ -979,7 +967,8 @@
retval = 0;
out_unlock:
- pte_unmap_unlock(pte, ptl);
+ unlock_pte(mm, pt_path);
+ pte_unmap(pte);
out:
return retval;
}
@@ -1136,17 +1125,13 @@
* (but do_wp_page is only called after already making such a check;
* 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,
+static inline int pte_unmap_same(struct mm_struct *mm, pt_path_t pt_path,
pte_t *page_table, pte_t orig_pte)
{
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);
- same = pte_same(*page_table, orig_pte);
- spin_unlock(ptl);
- }
+ if (sizeof(pte_t) > sizeof(unsigned long))
+ same = atomic_pte_same(mm, page_table, orig_pte, pt_path);
#endif
pte_unmap(page_table);
return same;
@@ -1210,10 +1195,9 @@
* but allow concurrent faults), with pte both mapped and locked.
* We return with mmap_sem still held, but pte unmapped and unlocked.
*/
-
static int do_wp_page(struct mm_struct *mm, struct vm_area_struct *vma,
- unsigned long address, pte_t *page_table, pmd_t *pmd,
- spinlock_t *ptl, pte_t orig_pte)
+ unsigned long address, pte_t *page_table, pt_path_t pt_path,
+ pte_t orig_pte)
{
struct page *old_page, *new_page;
pte_t entry;
@@ -1243,7 +1227,8 @@
*/
page_cache_get(old_page);
gotten:
- pte_unmap_unlock(page_table, ptl);
+ unlock_pte(mm, pt_path);
+ pte_unmap(page_table);
if (unlikely(anon_vma_prepare(vma)))
goto oom;
@@ -1261,7 +1246,7 @@
/*
* Re-check the pte - we dropped the lock
*/
- page_table = pte_offset_map_lock(mm, pmd, address, &ptl);
+ page_table = lookup_page_table_fast(mm, pt_path, address);
if (likely(pte_same(*page_table, orig_pte))) {
if (old_page) {
page_remove_rmap(old_page);
@@ -1289,7 +1274,8 @@
if (old_page)
page_cache_release(old_page);
unlock:
- pte_unmap_unlock(page_table, ptl);
+ unlock_pte(mm, pt_path);
+ pte_unmap(page_table);
return ret;
oom:
if (old_page)
@@ -1638,16 +1624,15 @@
* We return with mmap_sem still held, but pte unmapped and unlocked.
*/
static int do_swap_page(struct mm_struct *mm, struct vm_area_struct *vma,
- unsigned long address, pte_t *page_table, pmd_t *pmd,
+ unsigned long address, pte_t *page_table, pt_path_t pt_path,
int write_access, pte_t orig_pte)
{
- spinlock_t *ptl;
struct page *page;
swp_entry_t entry;
pte_t pte;
int ret = VM_FAULT_MINOR;
- if (!pte_unmap_same(mm, pmd, page_table, orig_pte))
+ if (!pte_unmap_same(mm, pt_path, page_table, orig_pte))
goto out;
entry = pte_to_swp_entry(orig_pte);
@@ -1661,7 +1646,7 @@
* Back out if somebody else faulted in this pte
* while we released the pte lock.
*/
- page_table = pte_offset_map_lock(mm, pmd, address, &ptl);
+ page_table = lookup_page_table_fast(mm, pt_path, address);
if (likely(pte_same(*page_table, orig_pte)))
ret = VM_FAULT_OOM;
goto unlock;
@@ -1685,7 +1670,7 @@
/*
* Back out if somebody else already faulted in this pte.
*/
- page_table = pte_offset_map_lock(mm, pmd, address, &ptl);
+ page_table = lookup_page_table_fast(mm, pt_path, address);
if (unlikely(!pte_same(*page_table, orig_pte)))
goto out_nomap;
@@ -1713,8 +1698,8 @@
unlock_page(page);
if (write_access) {
- if (do_wp_page(mm, vma, address,
- page_table, pmd, ptl, pte) == VM_FAULT_OOM)
+ if (do_wp_page(mm, vma, address,
+ page_table, pt_path, pte) == VM_FAULT_OOM)
ret = VM_FAULT_OOM;
goto out;
}
@@ -1723,11 +1708,14 @@
update_mmu_cache(vma, address, pte);
lazy_mmu_prot_update(pte);
unlock:
- pte_unmap_unlock(page_table, ptl);
+ unlock_pte(mm, pt_path);
+ pte_unmap(page_table);
out:
return ret;
out_nomap:
- pte_unmap_unlock(page_table, ptl);
+ unlock_pte(mm, pt_path);
+ pte_unmap(page_table);
+
unlock_page(page);
page_cache_release(page);
return ret;
Index: linux-2.6.17.2/mm/filemap_xip.c
===================================================================
--- linux-2.6.17.2.orig/mm/filemap_xip.c 2006-07-08 20:35:44.823860064 +1000
+++ linux-2.6.17.2/mm/filemap_xip.c 2006-07-08 20:35:46.151658208 +1000
@@ -16,6 +16,8 @@
#include <asm/tlbflush.h>
#include "filemap.h"
+#include <linux/pt.h>
+
/*
* This is a file read routine for execute in place files, and uses
* the mapping->a_ops->get_xip_page() function for the actual low-level
@@ -174,7 +176,7 @@
unsigned long address;
pte_t *pte;
pte_t pteval;
- spinlock_t *ptl;
+ pt_path_t pt_path;
struct page *page;
spin_lock(&mapping->i_mmap_lock);
@@ -184,7 +186,23 @@
((pgoff - vma->vm_pgoff) << PAGE_SHIFT);
BUG_ON(address < vma->vm_start || address >= vma->vm_end);
page = ZERO_PAGE(address);
- pte = page_check_address(page, mm, address, &ptl);
+ pte = lookup_page_table(mm, address, &pt_path);
+ if(!pte)
+ goto out;
+
+ /* Make a quick check before getting the lock */
+ if (!pte_present(*pte)) {
+ pte_unmap(pte);
+ goto out;
+ }
+
+ lock_pte(mm, pt_path);
+ if (!(pte_present(*pte) && page_to_pfn(page) == pte_pfn(*pte))) {
+ unlock_pte(mm, pt_path);
+ pte_unmap(pte);
+ goto out;
+ }
+
if (pte) {
/* Nuke the page table entry. */
flush_cache_page(vma, address, pte_pfn(*pte));
@@ -192,10 +210,12 @@
page_remove_rmap(page);
dec_mm_counter(mm, file_rss);
BUG_ON(pte_dirty(pteval));
- pte_unmap_unlock(pte, ptl);
+ unlock_pte(mm, pt_path);
+ pte_unmap(pte);
page_cache_release(page);
}
}
+out:
spin_unlock(&mapping->i_mmap_lock);
}
Index: linux-2.6.17.2/include/linux/mm.h
===================================================================
--- linux-2.6.17.2.orig/include/linux/mm.h 2006-07-08 20:35:44.899848512 +1000
+++ linux-2.6.17.2/include/linux/mm.h 2006-07-08 20:35:46.153657904 +1000
@@ -796,8 +796,6 @@
unsigned long private_dirty;
};
-extern pte_t *FASTCALL(get_locked_pte(struct mm_struct *mm, unsigned long addr, spinlock_t **ptl));
-
#include <linux/pt-mm.h>
extern void free_area_init(unsigned long * zones_size);
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
next prev parent reply other threads:[~2006-07-13 4:27 UTC|newest]
Thread overview: 19+ messages / expand[flat|nested] mbox.gz Atom feed top
2006-07-13 4:26 [PATCH 0/18] PTI - Explanation Paul Davies
2006-07-13 4:26 ` [PATCH 1/18] PTI - Introduce page table interface Paul Davies
2006-07-13 4:26 ` [PATCH 2/18] PTI - Page table type Paul Davies
2006-07-13 4:27 ` [PATCH 3/18] PTI - Abstract default page table Paul Davies
2006-07-13 4:27 ` [PATCH 4/18] " Paul Davies
2006-07-13 4:27 ` [PATCH 5/18] " Paul Davies
2006-07-13 4:27 ` [PATCH 6/18] " Paul Davies
2006-07-13 4:27 ` [PATCH 7/18] PTI - Page fault handler Paul Davies
2006-07-13 4:27 ` Paul Davies [this message]
2006-07-13 4:28 ` [PATCH 9/18] PTI - Call interface Paul Davies
2006-07-13 4:28 ` [PATCH 10/18] PTI - Copy iterator abstraction Paul Davies
2006-07-13 4:28 ` [PATCH 11/18] PTI - Unmap page range abstraction Paul Davies
2006-07-13 4:28 ` [PATCH 12/18] PTI - Zeromap iterator abstraction Paul Davies
2006-07-13 4:28 ` [PATCH 13/18] PTI - Msync " Paul Davies
2006-07-13 4:29 ` [PATCH 14/18] PTI - Vmalloc iterators asbstractions Paul Davies
2006-07-13 4:29 ` [PATCH 15/18] PTI - Change protection iterator abstraction Paul Davies
2006-07-13 4:29 ` [PATCH 16/18] PTI - Mremap " Paul Davies
2006-07-13 4:29 ` [PATCH 17/18] PTI - Swapfile " Paul Davies
2006-07-13 4:29 ` [PATCH 18/18] PTI - Mempolicy " Paul Davies
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20060713042755.9978.16103.sendpatchset@localhost.localdomain \
--to=pauld@gelato.unsw.edu.au \
--cc=linux-mm@kvack.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.