Chinaunix首页 | 论坛 | 博客
  • 博客访问: 620067
  • 博文数量: 69
  • 博客积分: 1891
  • 博客等级: 上尉
  • 技术积分: 1359
  • 用 户 组: 普通用户
  • 注册时间: 2010-11-20 23:38
文章分类

全部博文(69)

文章存档

2012年(46)

2011年(23)

分类: LINUX

2012-03-20 00:29:49

接下来就是page,该结构的定义如下:
悲剧,总算找着page的源码了,在include/linux/Mm_types.h里面,貌似很多参考资料都说在include/linux/mm.h里,坑爹啊,废话不多说了,上代码

点击(此处)折叠或打开

  1. struct page {
  2.     unsigned long flags;        /* Atomic flags, some possibly
  3.                      * updated asynchronously */
  4.     atomic_t _count;        /* Usage count, see below. */
  5.     union {
  6.         atomic_t _mapcount;    /* Count of ptes mapped in mms,
  7.                      * to show when page is mapped
  8.                      * & limit reverse map searches.
  9.                      */
  10.         struct {        /* SLUB */
  11.             u16 inuse;
  12.             u16 objects;
  13.         };
  14.     };
  15.     union {
  16.      struct {
  17.         unsigned long private;        /* Mapping-private opaque data:
  18.                           * usually used for buffer_heads
  19.                          * if PagePrivate set; used for
  20.                          * swp_entry_t if PageSwapCache;
  21.                          * indicates order in the buddy
  22.                          * system if PG_buddy is set.
  23.                          */
  24.         struct address_space *mapping;    /* If low bit clear, points to
  25.                          * inode address_space, or NULL.
  26.                          * If page mapped as anonymous
  27.                          * memory, low bit is set, and
  28.                          * it points to anon_vma object:
  29.                          * see PAGE_MAPPING_ANON below.
  30.                          */
  31.      };
  32. #if USE_SPLIT_PTLOCKS
  33.      spinlock_t ptl;
  34. #endif
  35.      struct kmem_cache *slab;    /* SLUB: Pointer to slab */
  36.      struct page *first_page;    /* Compound tail pages */
  37.     };
  38.     union {
  39.         pgoff_t index;        /* Our offset within mapping. */
  40.         void *freelist;        /* SLUB: freelist req. slab lock */
  41.     };
  42.     struct list_head lru;        /* Pageout list, eg. active_list
  43.                      * protected by zone->lru_lock !
  44.                      */
  45.     /*
  46.      * On machines where all RAM is mapped into kernel address space,
  47.      * we can simply calculate the virtual address. On machines with
  48.      * highmem some memory is mapped into kernel virtual memory
  49.      * dynamically, so we need a place to store that address.
  50.      * Note that this field could be 16 bits on x86 ... ;)
  51.      *
  52.      * Architectures with slow multiplication can define
  53.      * WANT_PAGE_VIRTUAL in asm/page.h
  54.      */
  55. #if defined(WANT_PAGE_VIRTUAL)
  56.     void *virtual;            /* Kernel virtual address (NULL if
  57.                      not kmapped, ie. highmem) */
  58. #endif /* WANT_PAGE_VIRTUAL */
  59. #ifdef CONFIG_WANT_PAGE_DEBUG_FLAGS
  60.     unsigned long debug_flags;    /* Use atomic bitops on this */
  61. #endif

  62. #ifdef CONFIG_KMEMCHECK
  63.     /*
  64.      * kmemcheck wants to track the status of each byte in a page; this
  65.      * is a pointer to such a status block. NULL if not tracked.
  66.      */
  67.     void *shadow;
  68. #endif
  69. };
     page这个结构是比较值得仔细斟酌的,因为页帧是系统管理内存的最小单位,对于内存中的每个页都会创建struct page的一个实例,所以这个结构要尽量保持小,但是页帧在系统内部广泛使用,内核的很多部分都依赖页帧所提供的信息,但是这些信息也有可能对其他部分完全没有用。所以,用union来维护一些数据是比较合适的。另外,由于页帧的广泛使用,所以对其所作的任何修改都有可能导致保持所有page实例所需的内存暴涨。
    下面简单讲解一下各个字段的意义:
  • flags:描叙了体系结构无关的一些标志,用于描叙页的属性,定义如下:

点击(此处)折叠或打开

  1. enum pageflags {
  2.     PG_locked,        /* Page is locked. Don't touch. */
  3.     PG_error,
  4.     PG_referenced,
  5.     PG_uptodate,
  6.     PG_dirty,
  7.     PG_lru,
  8.     PG_active,
  9.     PG_slab,
  10.     PG_owner_priv_1,    /* Owner use. If pagecache, fs may use*/
  11.     PG_arch_1,
  12.     PG_reserved,
  13.     PG_private,        /* If pagecache, has fs-private data */
  14.     PG_private_2,        /* If pagecache, has fs aux data */
  15.     PG_writeback,        /* Page is under writeback */
  16. #ifdef CONFIG_PAGEFLAGS_EXTENDED
  17.     PG_head,        /* A head page */
  18.     PG_tail,        /* A tail page */
  19. #else
  20.     PG_compound,        /* A compound page */
  21. #endif
  22.     PG_swapcache,        /* Swap page: swp_entry_t in private */
  23.     PG_mappedtodisk,    /* Has blocks allocated on-disk */
  24.     PG_reclaim,        /* To be reclaimed asap */
  25.     PG_swapbacked,        /* Page is backed by RAM/swap */
  26.     PG_unevictable,        /* Page is "unevictable" */
  27. #ifdef CONFIG_MMU
  28.     PG_mlocked,        /* Page is vma mlocked */
  29. #endif
  30. #ifdef CONFIG_ARCH_USES_PG_UNCACHED
  31.     PG_uncached,        /* Page has been mapped as uncached */
  32. #endif
  33. #ifdef CONFIG_MEMORY_FAILURE
  34.     PG_hwpoison,        /* hardware poisoned page. Don't touch */
  35. #endif
  36. #ifdef CONFIG_TRANSPARENT_HUGEPAGE
  37.     PG_compound_lock,
  38. #endif
  39.     __NR_PAGEFLAGS,

  40.     /* Filesystems */
  41.     PG_checked = PG_owner_priv_1,

  42.     /* Two page bits are conscripted by FS-Cache to maintain local caching
  43.      * state. These bits are set on pages belonging to the netfs's inodes
  44.      * when those inodes are being locally cached.
  45.      */
  46.     PG_fscache = PG_private_2,    /* page backed by cache */

  47.     /* XEN */
  48.     PG_pinned = PG_owner_priv_1,
  49.     PG_savepinned = PG_dirty,

  50.     /* SLOB */
  51.     PG_slob_free = PG_private,

  52.     /* SLUB */
  53.     PG_slub_frozen = PG_active,
  54. };
    
  1. PG_locked指定了页是否锁定。如果该位置位,内核的其他部分不允许访问该页
  2. PG_error如果在设计该页的I/O操作期间发生错误,则置该位
  3. PG_referenced和PG_active控制了系统使用该页的活动程度
  4. PG_update表示页的数据已经从块设备读取,没有出错
  5. PG_dirty如果内存页上的数据有修改,但是没有同步到硬盘上,则置位
  6. PG_lru内核用LRU算法来回收页帧,如果页在活动或不活动页链表其中一个,则设置该标志
  7. PG_high表示页在高端内存中,无法持久映射到内核内存中
  8. PG_writeback表示页的内容处于想块设备歇会的过程中
  9. PG_slab如果页是slab分配器的一部分,则设置PG_slab位
  10. PG_swapcache如果页处于交换缓存,则置位
  11. PG_reclaim如果内存打算回收某页,会设置该标志
  12. PG_buddy,若果空闲页包含在伙伴系统的列表中
  13. PG_compound表示页属于一个更大的复合页
同时,内核也提供了一些标准宏,用于检查标志位,或者操作某个标志位
  1. PageXXX(page)会检查是否设置了PG_XXX位,例如,PageDirty检查是否设置了PG_dirty位
  2. SetPageXXX会在比特位没有设置的情况下设置PG_XXX位,并返回原值
  3. ClearPageXXX无条件地清除某个特定的比特位
  4. TestClearPageXXX清除某个设置的比特位,并返回原值
 
  • atomic_t _count 引用计数器,表示内核中引用该页的次数
  • atomic_t _mapcount 表示在页表中有多少个pte指向该页

  • 点击(此处)折叠或打开

    1. struct {        /* SLUB */
    2.             u16 inuse;
    3.             u16 objects;
    4.         };
    用于SLUB分配器,对象的数目
  • lru是一个表头,用于在各种链表上维护该页,一遍将页按照不同类别分组,主要是按照活动页和不活动页分组
  • mapping 指定了页帧所在的地址空间。
  • private是一个指向私有数据的指针
  • virtual用于高端内存域中的页,
 
阅读(4001) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~