Walking page tables of a process in Linux

前端 未结 2 596
粉色の甜心
粉色の甜心 2020-12-12 18:21

i\'m trying to navigate the page tables for a process in linux. In a kernel module i realized the following function:

static struct page *walk_page_table(uns         


        
相关标签:
2条回答
  • 2020-12-12 19:05
    pte_unmap(ptep); 
    

    is missing just before the label out. Try to change the code in this way:

        ...
        page = pte_page(pte);
        if (page)
            printk(KERN_INFO "page frame struct is @ %p", page);
    
        pte_unmap(ptep); 
    
    out:
    
    0 讨论(0)
  • 2020-12-12 19:13

    Look at /proc/<pid>/smaps filesystem, you can see the userspace memory:

    cat smaps 
    bfa60000-bfa81000 rw-p 00000000 00:00 0          [stack]
    Size:                136 kB
    Rss:                  44 kB
    

    and how it is printed is via fs/proc/task_mmu.c (from kernel source):

    http://lxr.linux.no/linux+v3.0.4/fs/proc/task_mmu.c

       if (vma->vm_mm && !is_vm_hugetlb_page(vma))
                   walk_page_range(vma->vm_start, vma->vm_end, &smaps_walk);
                   show_map_vma(m, vma.....);
            seq_printf(m,
                       "Size:           %8lu kB\n"
                       "Rss:            %8lu kB\n"
                       "Pss:            %8lu kB\n"
    

    And your function is somewhat like that of walk_page_range(). Looking into walk_page_range() you can see that the smaps_walk structure is not supposed to change while it is walking:

    http://lxr.linux.no/linux+v3.0.4/mm/pagewalk.c#L153
    
    For eg:
    
                    }
     201                if (walk->pgd_entry)
     202                        err = walk->pgd_entry(pgd, addr, next, walk);
     203                if (!err &&
     204                    (walk->pud_entry || walk->pmd_entry || walk->pte_entry
    

    If memory contents were to change, then all the above checking may get inconsistent.

    All these just mean that you have to lock the mmap_sem when walking the page table:

       if (!down_read_trylock(&mm->mmap_sem)) {
                /*
                 * Activate page so shrink_inactive_list is unlikely to unmap
                 * its ptes while lock is dropped, so swapoff can make progress.
                 */
                activate_page(page);
                unlock_page(page);
                down_read(&mm->mmap_sem);
                lock_page(page);
        }
    

    and then followed by unlocking:

    up_read(&mm->mmap_sem);
    

    And of course, when you issue printk() of the pagetable inside your kernel module, the kernel module is running in the process context of your insmod process (just printk the "comm" and you can see "insmod") meaning the mmap_sem is lock, it also mean the process is NOT running, and thus there is no console output till the process is completed (all printk() output goes to memory only).

    Sounds logical?

    0 讨论(0)
提交回复
热议问题