Memory Management API: page_address, apipage_address
Memory Management API: page_address
Void * page_address (const struct page * page) is used to obtain the virtual address of the page. The page here can be a high-end page or a low-end page. Its source code analysis is as follows: void * page_address (const struct page * page) {unsigned long flags; void * ret; struct page_address_slot * pas; # You can see that the parameters of this function can be high-end or low-end pages. If it is a low-end page, directly call lowmem_page_address to return the page address if (! PageHighMem (page) return lowmem_page_address (page); # obtain page_address_slotpas = page_slot (page) based on the page address; ret = NULL; # Use the page_address_slot member variable lock for protection. It seems that page_address_slot is a critical variable and requires a lock to protect the spin_lock_irqsave (& pas-> lock, flags); if (! List_empty (& pas-> lh) {struct page_address_map * pam; # All page_address_map are on the lh list, so we traverse this list here, check whether the page has been mapped. # If the page parameter is found in the mapped page, the virtual address corresponding to the page is returned. Otherwise, null is returned. 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;} The lowmem_page_address function here is as follows. You can see that all the low-end pages have virtual addresses. You just need to convert them. static _ always_inline void * lowmem_page_address (const struct page * page) {return page_to_virt (page );}