Re: Anticipatory prefaulting in the page fault handler V1

Akinobu Mita
2004-12-14T15:25:34Z

On Tuesday 14 December 2004 21:24, Akinobu Mita wrote:

> But there is not any guarantee that the page_tables for addr+PAGE_SIZE,
> addr+2*PAGE_SIZE, ... have not been mapped yet.
>
> Anyway, I will try your V2 patch.
>

Below patch fixes V2 patch, and adds debug printk.
The output coincides with segfaulted processes.

# dmesg | grep ^comm:

comm: xscreensaver, addr_orig: ccdc40, addr: cce000, pid: 2995
comm: rhn-applet-gui, addr_orig: b6fd8020, addr: b6fd9000, pid: 3029
comm: rhn-applet-gui, addr_orig: b6e95020, addr: b6e96000, pid: 3029
comm: rhn-applet-gui, addr_orig: b6fd8020, addr: b6fd9000, pid: 3029
comm: rhn-applet-gui, addr_orig: b6e95020, addr: b6e96000, pid: 3029
comm: rhn-applet-gui, addr_orig: b6fd8020, addr: b6fd9000, pid: 3029
comm: X, addr_orig: 87e8000, addr: 87e9000, pid: 2874
comm: X, addr_orig: 87ea000, addr: 87eb000, pid: 2874

---
The read access prefaulting may override the page_table which has been
already mapped. this patch fixes it. and it shows which process might
suffer this problem.

--- 2.6-rc/mm/memory.c.orig 2004-12-14 22:06:08.000000000 +0900
+++ 2.6-rc/mm/memory.c 2004-12-14 23:42:34.000000000 +0900
@@ -1434,6 +1434,7 @@ do_anonymous_page(struct mm_struct *mm,
{
pte_t entry;
unsigned long end_addr;
+ unsigned long addr_orig = addr;

addr &= PAGE_MASK;

@@ -1517,9 +1518,15 @@ do_anonymous_page(struct mm_struct *mm,
/* Read */
entry = pte_wrprotect(mk_pte(ZERO_PAGE(addr), vma->vm_page_prot));
nextread:
- set_pte(page_table, entry);
- pte_unmap(page_table);
- update_mmu_cache(vma, addr, entry);
+ if (!pte_none(*page_table)) {
+ printk("comm: %s, addr_orig: %lx, addr: %lx, pid: %d\n",
+ current->comm, addr_orig, addr, current->pid);
+ pte_unmap(page_table);
+ } else {
+ set_pte(page_table, entry);
+ pte_unmap(page_table);
+ update_mmu_cache(vma, addr, entry);
+ }
addr += PAGE_SIZE;
if (unlikely(addr < end_addr)) {
pte_offset_map(pmd, addr);