Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get the physical address of the associated data from a struct page?

Let's say we've got a struct page from the address space of a page cached file.

How could we get the starting physical address of the 4KB data from this struct page?

I suppose there should be something like the data pointer inside struct sk_buff, but I didn't find it.


EDIT

Thanks Mat and llya for the answers.

After looking at the answers, I think the first problem is to identify whether the struct page is located in ZONE_NORMAL or ZONE_HIGHMEM.

During a file I/O, when we don't find the cached page, we will at first allocate a new page using page_cache_alloc_cold(). page_cache_alloc_cold() will finally calls alloc_pages() which looks like it will use the ZONE_HIGHMEM (which in x86, is the kernel memory area starting at PAGE_OFFSET+896M) for its job.

So

  • I think Mat's answer is suitable for pages in ZONE_NORMAL
  • Suppose we use kmap() to find the starting physical address of the 4KB data associated with the struct page, is it correct that we should use (unsigned long)(&page)-PAGE_OFFSET to find the physical address where stores the structure itself?

Please correct.

like image 887
sliter Avatar asked Apr 04 '12 08:04

sliter


Video Answer


1 Answers

You need to map a page into the kernel memory as follows:

void * mapping = kmap_atomic(page, KM_USER0);
// work with mapping...
kunmap_atomic(mapping, KM_USER0);

This trick is required as there is a HighMemory concept in Linux (see this link for ex.).

UPD: You can use kmap instead of kmap_atomic in non-atomic contexts.

like image 117
Ilya Matveychikov Avatar answered Oct 03 '22 13:10

Ilya Matveychikov