Hi,
I have some doubt regarding virt_to_page().
This is based on 2.4.20 with i386
mm/page_alloc.c
+++++++++++++++++++
In free_area_init_core()
mem_map is populated by alloc_bootmem_node with a virtual address.
In a loop the pages are intialized per zone
In free_pages_ok()
This invoked from free_all_bootmem() adds the pages for free_list depending on order (buddy algorithm)
mm/slab.c
+++++++++
In kmem_cache_grow() calls kmem_getpages -> alloc_pages which returns a page from free_list depending on
order (buddy algorithm)
The obj returned here is a virtual address.
Let us consider that fourth page is free (page_idx = 3)
From system.map
mem_map = 0xC1038030 (for ZONE_NORMAL)
PAGE_OFFSET = 0XC0000000
PAGE_SHIFT = 12
sizeof(mem_map_t) = 40 bytes
Value returned from kmem_getpages is as follows.
obj = mem_map + offset (offset is page_idx = 3)
obj = 0xC1038030 + (3*sizeof(mem_map_t))
obj = c10380A8
Now page = virt_to_page(obj)
=> pfn_to_page(__pa(obj) >> PAGE_SHIFT)
=> pfn_to_page( (obj - PAGE_OFFSET) >> PAGE_SHIFT)
=> mem_map + ((obj - PAGE_OFFSET) >> PAGE_SHIFT)
=> 0xC1038030 + ((0XC10380A8 - 0xC0000000) >> 12)
=> 0xC1039068
Here original and calculated (by virt_to_page) does not match.
The obj returned by kmem_getpages can be directly used after typecasting to mem_map_t in kmem_cache_grow()
Why is that virt_to_page is used here, also as seen above the
values do not even match.
This is confusing can some one please clarify the same.
Thanks,
Sudharsan.