参照元†
- WANT_PAGE_VIRTUAL はアーキテクチャ依存の値で、定義されているのは下記 3つのみ。
- HASHED_PAGE_VIRTUAL は CONFIG_HIGHMEM 有効、WANT_PAGE_VIRTUAL 無効のときに有効
- 要するに、下記の 3パターンがあるってことです。
- WANT_PAGE_VIRTUAL 有効
- WANT_PAGE_VIRTUAL 無効、CONFIG_HIGHMEM 無効
- WANT_PAGE_VIRTUAL 無効、CONFIG_HIGHMEM 有効
返り値†
WANT_PAGE_VIRTUAL 有効: include/linux/mm.h†
- 特殊ケース。CONFIG_HIGHMEM は無視されて、下記の実装が選択される。
#if defined(WANT_PAGE_VIRTUAL)
static inline void *page_address(const struct page *page)
{
return page->virtual;
}
...
WANT_PAGE_VIRTUAL 無効、CONFIG_HIGHMEM 無効: include/linux/mm.h†
#if !defined(HASHED_PAGE_VIRTUAL) && !defined(WANT_PAGE_VIRTUAL)
#define page_address(page) lowmem_page_address(page)
...
WANT_PAGE_VIRTUAL 無効、CONFIG_HIGHMEM 有効: mm/highmem.c†
/**
* page_address - get the mapped virtual address of a page
* @page: &struct page to get the virtual address of
*
* Returns the page's virtual address.
*/
void *page_address(const struct page *page)
{
unsigned long flags;
void *ret;
struct page_address_slot *pas;
if (!PageHighMem(page))
return lowmem_page_address(page);
pas = page_slot(page);
ret = NULL;
spin_lock_irqsave(&pas->lock, flags);
if (!list_empty(&pas->lh)) {
struct page_address_map *pam;
list_for_each_entry(pam, &pas->lh, list) {
if (pam->page == page) {
ret = pam->virtual;
goto done;
}
}
}
done:
spin_unlock_irqrestore(&pas->lock, flags);
return ret;
}
EXPORT_SYMBOL(page_address);
コメント†