lkml.org 
[lkml]   [2010]   [Jan]   [4]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Date
    From
    Subject[RFC][PATCH 6/8] mm: handle_speculative_fault()
    Generic speculative fault handler, tries to service a pagefault
    without holding mmap_sem.

    Signed-off-by: Peter Zijlstra <a.p.zijlstra@chello.nl>
    ---
    include/linux/mm.h | 2 +
    mm/memory.c | 59 ++++++++++++++++++++++++++++++++++++++++++++++++++++-
    2 files changed, 60 insertions(+), 1 deletion(-)

    Index: linux-2.6/mm/memory.c
    ===================================================================
    --- linux-2.6.orig/mm/memory.c
    +++ linux-2.6/mm/memory.c
    @@ -1998,7 +1998,7 @@ again:
    if (!*ptep)
    goto out;

    - if (vma_is_dead(vma, seq))
    + if (vma && vma_is_dead(vma, seq))
    goto unlock;

    unpin_page_tables();
    @@ -3112,6 +3112,63 @@ int handle_mm_fault(struct mm_struct *mm
    return handle_pte_fault(mm, vma, address, entry, pmd, flags, 0);
    }

    +int handle_speculative_fault(struct mm_struct *mm, unsigned long address,
    + unsigned int flags)
    +{
    + pmd_t *pmd = NULL;
    + pte_t *pte, entry;
    + spinlock_t *ptl;
    + struct vm_area_struct *vma;
    + unsigned int seq;
    + int ret = VM_FAULT_RETRY;
    + int dead;
    +
    + __set_current_state(TASK_RUNNING);
    + flags |= FAULT_FLAG_SPECULATIVE;
    +
    + count_vm_event(PGFAULT);
    +
    + rcu_read_lock();
    + if (!pte_map_lock(mm, NULL, address, pmd, flags, 0, &pte, &ptl))
    + goto out_unlock;
    +
    + vma = find_vma(mm, address);
    +
    + if (!vma)
    + goto out_unmap;
    +
    + dead = RB_EMPTY_NODE(&vma->vm_rb);
    + seq = vma->vm_sequence.sequence;
    + /*
    + * Matches both the wmb in write_seqcount_begin/end() and
    + * the wmb in detach_vmas_to_be_unmapped()/__unlink_vma().
    + */
    + smp_rmb();
    + if (dead || seq & 1)
    + goto out_unmap;
    +
    + if (!(vma->vm_end > address && vma->vm_start <= address))
    + goto out_unmap;
    +
    + if (read_seqcount_retry(&vma->vm_sequence, seq))
    + goto out_unmap;
    +
    + entry = *pte;
    +
    + pte_unmap_unlock(pte, ptl);
    +
    + ret = handle_pte_fault(mm, vma, address, entry, pmd, flags, seq);
    +
    +out_unlock:
    + rcu_read_unlock();
    + return ret;
    +
    +out_unmap:
    + pte_unmap_unlock(pte, ptl);
    + goto out_unlock;
    +}
    +
    +
    #ifndef __PAGETABLE_PUD_FOLDED
    /*
    * Allocate page upper directory.
    Index: linux-2.6/include/linux/mm.h
    ===================================================================
    --- linux-2.6.orig/include/linux/mm.h
    +++ linux-2.6/include/linux/mm.h
    @@ -829,6 +829,8 @@ int invalidate_inode_page(struct page *p
    #ifdef CONFIG_MMU
    extern int handle_mm_fault(struct mm_struct *mm, struct vm_area_struct *vma,
    unsigned long address, unsigned int flags);
    +extern int handle_speculative_fault(struct mm_struct *mm,
    + unsigned long address, unsigned int flags);
    #else
    static inline int handle_mm_fault(struct mm_struct *mm,
    struct vm_area_struct *vma, unsigned long address,
    --



    \
     
     \ /
      Last update: 2010-01-04 21:51    [W:0.028 / U:0.004 seconds]
    ©2003-2016 Jasper Spaans. hosted at Digital OceanAdvertise on this site