lkml.org 
[lkml]   [2008]   [Jan]   [3]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH CPA] [10/28] CPA: Change kernel_map_pages to not use c_p_a()
    Date

    CONFIG_DEBUG_PAGEALLOC uses change_page_attr to map/unmap mappings for catching
    stray kernel mappings. But standard c_p_a() does a lot of unnecessary work for
    this simple case with pre-split mappings.

    Change kernel_map_pages to just access the page table directly which
    is simpler and faster.

    I also fixed it to use INVLPG if available.

    This is required for changes to c_p_a() later that make it use kmalloc. Without
    this we would risk infinite recursion. Also in general things are easier when
    sleeping is allowed.

    Signed-off-by: Andi Kleen <ak@suse.de>

    ---
    arch/x86/mm/pageattr_32.c | 34 ++++++++++++++++++++++++----------
    1 file changed, 24 insertions(+), 10 deletions(-)

    Index: linux/arch/x86/mm/pageattr_32.c
    ===================================================================
    --- linux.orig/arch/x86/mm/pageattr_32.c
    +++ linux/arch/x86/mm/pageattr_32.c
    @@ -258,22 +258,36 @@ void global_flush_tlb(void)
    }

    #ifdef CONFIG_DEBUG_PAGEALLOC
    +/* Map or unmap pages in the kernel direct mapping for kernel debugging. */
    void kernel_map_pages(struct page *page, int numpages, int enable)
    {
    + unsigned long addr;
    + int i;
    +
    if (PageHighMem(page))
    return;
    + addr = (unsigned long)page_address(page);
    if (!enable)
    - debug_check_no_locks_freed(page_address(page),
    - numpages * PAGE_SIZE);
    + debug_check_no_locks_freed((void *)addr, numpages * PAGE_SIZE);
    +
    + /* Bootup has forced 4K pages so this is very simple */
    +
    + for (i = 0; i < numpages; i++, addr += PAGE_SIZE, page++) {
    + int level;
    + pte_t *pte = lookup_address(addr, &level);

    - /* the return value is ignored - the calls cannot fail,
    - * large pages are disabled at boot time.
    - */
    - change_page_attr(page, numpages, enable ? PAGE_KERNEL : __pgprot(0));
    - /* we should perform an IPI and flush all tlbs,
    - * but that can deadlock->flush only current cpu.
    - */
    - __flush_tlb_all();
    + BUG_ON(level != 3);
    + if (enable) {
    + set_pte_atomic(pte, mk_pte(page, PAGE_KERNEL));
    + /*
    + * We should perform an IPI and flush all tlbs,
    + * but that can deadlock->flush only current cpu.
    + */
    + __flush_tlb_one(addr);
    + } else {
    + kpte_clear_flush(pte, addr);
    + }
    + }
    }
    #endif


    \
     
     \ /
      Last update: 2008-01-03 16:31    [W:0.023 / U:29.660 seconds]
    ©2003-2016 Jasper Spaans. hosted at Digital OceanAdvertise on this site