zoukankan      html  css  js  c++  java
  • linux如何管理物理内存?

    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

      

  • 相关阅读:
    char nvarchar varchar
    第32月第8天 打包 Framework 时使用 CocoaPods 引入第三方库的方法
    第31月第25天 xcode debug 限制uitextfiled输入
    第31月第22天 draw
    第31月第19天 NV12
    第31月第17天 resolveInstanceMethod
    第31月第15天 -fembed-bitcode
    第31月第10天 tableview头部空白 Other Linker Flags rtmp
    第31月 第9天 责任链AppDelegate
    第30月第18天 autolayout代码
  • 原文地址:https://www.cnblogs.com/dakewei/p/10525165.html
Copyright © 2011-2022 走看看