Linux Kernel 3.0.8 内存管理函数


相关代码如下:

#define alloc_pages(gfp_mask, order)   alloc_pages_node(numa_node_id(), gfp_mask, order)
#define alloc_page_vma(gfp_mask, vma, addr) alloc_pages(gfp_mask, 0)
#define alloc_page(gfp_mask) alloc_pages(gfp_mask, 0)

#define __get_free_page(gfp_mask)   __get_free_pages((gfp_mask),0)
#define __get_dma_pages(gfp_mask, order)   __get_free_pages((gfp_mask) | GFP_DMA,(order))

 #define pfn_to_page(pfn) (mem_map + ((pfn) - PHYS_PFN_OFFSET))
#define page_to_pfn(page) ((unsigned long)((page) - mem_map) + PHYS_PFN_OFFSET)
#define pfn_valid(pfn) ((pfn) >= PHYS_PFN_OFFSET && (pfn) < (PHYS_PFN_OFFSET + max_mapnr))

#define phys_to_page(phys) (pfn_to_page(phys >> PAGE_SHIFT))
#define page_to_phys(page) (page_to_pfn(page) << PAGE_SHIFT)

#define virt_to_page(kaddr) pfn_to_page(__pa(kaddr) >> PAGE_SHIFT)
#define virt_addr_valid(kaddr) pfn_valid(__pa(kaddr) >> PAGE_SHIFT)
 


1)__get_free_pages实现代码如下,它返回页的虚拟地址

  1. unsigned long __get_free_pages(gfp_t gfp_mask, unsigned int order)  
  2. {  
  3.     struct page *page;  
  4.   
  5.     /* 
  6.      * __get_free_pages() returns a 32-bit address, which cannot represent 
  7.      * a highmem page 
  8.      */  
  9.     VM_BUG_ON((gfp_mask & __GFP_HIGHMEM) != 0);  
  10.   
  11.     page = alloc_pages(gfp_mask, order);  
  12.     if (!page)  
  13.         return 0;  
  14.     return (unsigned long) page_address(page);  
  15. }  
  1. /** 
  2.  * page_address - get the mapped virtual address of a page 
  3.  * @page: &struct page to get the virtual address of 
  4.  * 
  5.  * Returns the page's virtual address. 
  6.  */  
  7. void *page_address(struct page *page)  
  8. {  
  9.     unsigned long flags;  
  10.     void *ret;  
  11.     struct page_address_slot *pas;  
  12.   
  13.     if (!PageHighMem(page))  
  14.         return lowmem_page_address(page);  
  15.   
  16.     pas = page_slot(page);  
  17.     ret = NULL;  
  18.     spin_lock_irqsave(&pas->lock, flags);  
  19.     if (!list_empty(&pas->lh)) {  
  20.         struct page_address_map *pam;  
  21.   
  22.         list_for_each_entry(pam, &pas->lh, list) {  
  23.             if (pam->page == page) {  
  24.                 ret = pam->virtual;  
  25.                 goto done;  
  26.             }  
  27.         }  
  28.     }  
  29. done:  
  30.     spin_unlock_irqrestore(&pas->lock, flags);  
  31.     return ret;  
  32. }  
  1. static __always_inline void *lowmem_page_address(struct page *page)  
  2. {  
  3.     return __va(PFN_PHYS(page_to_pfn(page)));  
  4. }  

2)alloc_pages_node

  1. static inline struct page *alloc_pages_node(int nid, gfp_t gfp_mask,  
  2.                         unsigned int order)  
  3. {  
  4.     /* Unknown node is current node */  
  5.     if (nid < 0)  
  6.         nid = numa_node_id();  
  7.   
  8.     return __alloc_pages(gfp_mask, order, node_zonelist(nid, gfp_mask));  
  9. }  
  • 1
  • 2
  • 3
  • 下一页

相关内容