歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux基礎 >> Linux教程 >> Linux Kernel 3.0.8 內存管理函數

Linux Kernel 3.0.8 內存管理函數

日期:2017/2/28 15:55:15   编辑:Linux教程

相關代碼如下:

#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. * __get_free_pages() returns a 32-bit address, which cannot represent
  6. * a highmem page
  7. */
  8. VM_BUG_ON((gfp_mask & __GFP_HIGHMEM) != 0);
  9. page = alloc_pages(gfp_mask, order);
  10. if (!page)
  11. return 0;
  12. return (unsigned long) page_address(page);
  13. }
  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. if (!PageHighMem(page))
  13. return lowmem_page_address(page);
  14. pas = page_slot(page);
  15. ret = NULL;
  16. spin_lock_irqsave(&pas->lock, flags);
  17. if (!list_empty(&pas->lh)) {
  18. struct page_address_map *pam;
  19. list_for_each_entry(pam, &pas->lh, list) {
  20. if (pam->page == page) {
  21. ret = pam->virtual;
  22. goto done;
  23. }
  24. }
  25. }
  26. done:
  27. spin_unlock_irqrestore(&pas->lock, flags);
  28. return ret;
  29. }
  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. return __alloc_pages(gfp_mask, order, node_zonelist(nid, gfp_mask));
  8. }
Copyright © Linux教程網 All Rights Reserved