1. 程式人生 > >linux如何管理物理內存?

linux如何管理物理內存?

管理 arm64 -c ive 是什麽 ati linux enc generic

Linux kernel version: 5.0.1

arm64

  1.將物理內存劃分為若幹頁,每頁的大小為4KiB(可以為8KiB或16KiB),那麽如何知道每個頁當前是什麽情況呢?

  那就需要一個結構體來描述每一頁的情況,那麽就出現了結構體struct page.

  2.有若幹頁,意味著需要若幹個struct page這樣的結構體來描述若幹頁的狀態;

  3.這些struct page存放在哪裏呢?肯定是存放在物理內存裏;

  4.存放在物理內存裏,那麽假設物理內存有4MiB,指定頁面大小為4KiB,那麽這些物理內存能被劃分為多少個頁面呢?又需要多少物理內存來存放struct page結構體呢?

  頁面個數=4MiB/4KiB=4*1024 KiB/4KiB=1024個;

  那麽就需要1024個struct page來描述這1024個頁面的情況,這麽多結構體需要多少內存呢?

  1024 * sizeof(struct page)

  5.如何獲取sizeof(struct page)的大小呢?

  struct page結構體(結構體定義在include/linux/mm_types.h)如下:

技術分享圖片
  1   struct page {
  2       unsigned long flags;        /* Atomic flags, some possibly
  3
* updated asynchronously */ 4 /* 5 * Five words (20/40 bytes) are available in this union. 6 * WARNING: bit 0 of the first word is used for PageTail(). That 7 * means the other users of this union MUST NOT use the bit to 8 * avoid collision and false-positive PageTail().
9 */ 10 union { 11 struct { /* Page cache and anonymous pages */ 12 /** 13 * @lru: Pageout list, eg. active_list protected by 14 * zone_lru_lock. Sometimes used as a generic list 15 * by the page owner. 16 */ 17 struct list_head lru; 18 /* See page-flags.h for PAGE_MAPPING_FLAGS */ 19 struct address_space *mapping; 20 pgoff_t index; /* Our offset within mapping. */ 21 /** 22 * @private: Mapping-private opaque data. 23 * Usually used for buffer_heads if PagePrivate. 24 * Used for swp_entry_t if PageSwapCache. 25 * Indicates order in the buddy system if PageBuddy. 26 */ 27 unsigned long private; 28 }; 29 struct { /* slab, slob and slub */ 30 union { 31 struct list_head slab_list; /* uses lru */ 32 struct { /* Partial pages */ 33 struct page *next; 34 #ifdef CONFIG_64BIT 35 int pages; /* Nr of pages left */ 36 int pobjects; /* Approximate count */ 37 #else 38 short int pages; 39 short int pobjects; 40 #endif 41 }; 42 }; 43 struct kmem_cache *slab_cache; /* not slob */ 44 /* Double-word boundary */ 45 void *freelist; /* first free object */ 46 union { 47 void *s_mem; /* slab: first object */ 48 unsigned long counters; /* SLUB */ 49 struct { /* SLUB */ 50 unsigned inuse:16; 51 unsigned objects:15; 52 unsigned frozen:1; 53 }; 54 }; 55 }; 56 struct { /* Tail pages of compound page */ 57 unsigned long compound_head; /* Bit zero is set */ 58 59 /* First tail page only */ 60 unsigned char compound_dtor; 61 unsigned char compound_order; 62 atomic_t compound_mapcount; 63 }; 64 struct { /* Second tail page of compound page */ 65 unsigned long _compound_pad_1; /* compound_head */ 66 unsigned long _compound_pad_2; 67 struct list_head deferred_list; 68 }; 69 struct { /* Page table pages */ 70 unsigned long _pt_pad_1; /* compound_head */ 71 pgtable_t pmd_huge_pte; /* protected by page->ptl */ 72 unsigned long _pt_pad_2; /* mapping */ 73 union { 74 struct mm_struct *pt_mm; /* x86 pgds only */ 75 atomic_t pt_frag_refcount; /* powerpc */ 76 }; 77 #if ALLOC_SPLIT_PTLOCKS 78 spinlock_t *ptl; 79 #else 80 spinlock_t ptl; 81 #endif 82 }; 83 struct { /* ZONE_DEVICE pages */ 84 /** @pgmap: Points to the hosting device page map. */ 85 struct dev_pagemap *pgmap; 86 unsigned long hmm_data; 87 unsigned long _zd_pad_1; /* uses mapping */ 88 }; 89 90 /** @rcu_head: You can use this to free a page by RCU. */ 91 struct rcu_head rcu_head; 92 }; 93 94 union { /* This union is 4 bytes in size. */ 95 /* 96 * If the page can be mapped to userspace, encodes the number 97 * of times this page is referenced by a page table. 98 */ 99 atomic_t _mapcount; 100 101 /* 102 * If the page is neither PageSlab nor mappable to userspace, 103 * the value stored here may help determine what this page 104 * is used for. See page-flags.h for a list of page types 105 * which are currently stored here. 106 */ 107 unsigned int page_type; 108 109 unsigned int active; /* SLAB */ 110 int units; /* SLOB */ 111 }; 112 113 /* Usage count. *DO NOT USE DIRECTLY*. See page_ref.h */ 114 atomic_t _refcount; 115 116 #ifdef CONFIG_MEMCG 117 struct mem_cgroup *mem_cgroup; 118 #endif 119 120 /* 121 * On machines where all RAM is mapped into kernel address space, 122 * we can simply calculate the virtual address. On machines with 123 * highmem some memory is mapped into kernel virtual memory 124 * dynamically, so we need a place to store that address. 125 * Note that this field could be 16 bits on x86 ... ;) 126 * 127 * Architectures with slow multiplication can define 128 * WANT_PAGE_VIRTUAL in asm/page.h 129 */ 130 #if defined(WANT_PAGE_VIRTUAL) 131 void *virtual; /* Kernel virtual address (NULL if 132 not kmapped, ie. highmem) */ 133 #endif /* WANT_PAGE_VIRTUAL */ 134 135 #ifdef LAST_CPUPID_NOT_IN_PAGE_FLAGS 136 int _last_cpupid; 137 #endif 138 } _struct_page_alignment;
View Code

  使用此內核模塊獲取,編譯方法為:make CROSS_COMPILE=1 KDIR=<linux kernel source code path>

  所以:

  1024 * sizeof(struct page) = 1024 * 64 = 64 KiB = 16 個頁面

  6.既然有部分物理內存用來存儲每個頁面的情況,那麽可用的物理內存必然少於4MiB,那麽具體是多少呢?

  1024 - 16 = 1008 個頁面 = 1008 * 4 KiB = 4032 KiB

  

linux如何管理物理內存?