Посмотрите на /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 () из pagetable внутри вашего модуля ядра, модуль ядра работает в контексте процесса вашего insmod-процесса (просто printk «comm», и вы можете увидеть «insmod»), что означает, что mmap_sem заблокирован, это также означает, что процессНЕ работает, и, следовательно, нет вывода на консоль до завершения процесса (все выходные данные printk () отправляются только в память).
Звучит логично?