pte_unmap(ptep);
ラベルアウト直前で欠品。この方法でコードを変更してみてください:
...
page = pte_page(pte);
if (page)
printk(KERN_INFO "page frame struct is @ %p", page);
pte_unmap(ptep);
out:
/proc/<pid>/smaps
を見てください ファイルシステム、ユーザー空間メモリを見ることができます:
cat smaps
bfa60000-bfa81000 rw-p 00000000 00:00 0 [stack]
Size: 136 kB
Rss: 44 kB
それがどのように印刷されるかは fs/proc/task_mmu.c
経由です (カーネルソースから):
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"
そして、あなたの関数は walk_page_range() の関数に多少似ています。 walk_page_range() を調べてみると、smaps_walk 構造体はウォーキング中に変更されるべきではないことがわかります:
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
メモリの内容が変更された場合、上記のすべてのチェックが矛盾する可能性があります。
これらはすべて、ページ テーブルを移動するときに mmap_sem をロックする必要があることを意味します:
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);
}
その後、ロックを解除します:
up_read(&mm->mmap_sem);
もちろん、カーネル モジュール内のページテーブルの printk() を発行すると、カーネル モジュールは insmod プロセスのプロセス コンテキストで実行されます ("comm" を printk すると "insmod" が表示されます)。つまり、mmap_sem はプロセスが実行されていないことも意味するため、プロセスが完了するまでコンソール出力はありません (すべての printk() 出力はメモリのみに送信されます)。
論理的に聞こえますか?