pte_unmap(ptep);
hilang tepat sebelum label keluar. Cobalah untuk mengubah kode dengan cara ini:
...
page = pte_page(pte);
if (page)
printk(KERN_INFO "page frame struct is @ %p", page);
pte_unmap(ptep);
out:
Lihat /proc/<pid>/smaps
sistem file, Anda dapat melihat memori ruang pengguna:
cat smaps
bfa60000-bfa81000 rw-p 00000000 00:00 0 [stack]
Size: 136 kB
Rss: 44 kB
dan cara mencetaknya adalah melalui fs/proc/task_mmu.c
(dari sumber kernel):
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"
Dan fungsi Anda agak mirip dengan walk_page_range(). Melihat walk_page_range() Anda dapat melihat bahwa struktur smaps_walk seharusnya tidak berubah saat sedang berjalan:
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
Jika konten memori berubah, maka semua pemeriksaan di atas mungkin tidak konsisten.
Semua ini berarti Anda harus mengunci mmap_sem saat berjalan di tabel halaman:
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);
}
lalu diikuti dengan membuka kunci:
up_read(&mm->mmap_sem);
Dan tentu saja, ketika Anda menerbitkan printk() dari pagetable di dalam modul kernel Anda, modul kernel berjalan dalam konteks proses dari proses insmod Anda (cukup printk "comm" dan Anda dapat melihat "insmod") yang berarti mmap_sem adalah lock, itu juga berarti proses TIDAK berjalan, dan dengan demikian tidak ada output konsol sampai proses selesai (semua output printk() masuk ke memori saja).
Kedengarannya logis?