pte_unmap(ptep);
manque juste avant la sortie de l'étiquette. Essayez de modifier le code de cette manière :
...
page = pte_page(pte);
if (page)
printk(KERN_INFO "page frame struct is @ %p", page);
pte_unmap(ptep);
out:
Regardez /proc/<pid>/smaps
système de fichiers, vous pouvez voir la mémoire de l'espace utilisateur :
cat smaps
bfa60000-bfa81000 rw-p 00000000 00:00 0 [stack]
Size: 136 kB
Rss: 44 kB
et comment il est imprimé via fs/proc/task_mmu.c
(depuis la source du noyau) :
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"
Et votre fonction ressemble un peu à celle de walk_page_range(). En regardant dans walk_page_range(), vous pouvez voir que la structure smaps_walk n'est pas censée changer pendant qu'elle marche :
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
Si le contenu de la mémoire devait changer, toutes les vérifications ci-dessus pourraient devenir incohérentes.
Tout cela signifie simplement que vous devez verrouiller le mmap_sem lorsque vous parcourez le tableau des pages :
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);
}
puis suivi du déverrouillage :
up_read(&mm->mmap_sem);
Et bien sûr, lorsque vous émettez printk() de la table des pages à l'intérieur de votre module noyau, le module noyau s'exécute dans le contexte de processus de votre processus insmod (imprimez simplement le "comm" et vous pouvez voir "insmod"), ce qui signifie que le mmap_sem est lock, cela signifie également que le processus n'est PAS en cours d'exécution et qu'il n'y a donc pas de sortie de console tant que le processus n'est pas terminé (toutes les sorties printk() vont uniquement en mémoire).
Cela semble logique ?