struct page中的page_type

在某些时候,page->page_type 可以用来标示该页的用途,比如在内核中定义了以下 4 种 page_type:

/*  
 * For pages that are never mapped to userspace (and aren't PageSlab),
 * page_type may be used.  Because it is initialised to -1, we invert the
 * sense of the bit, so __SetPageFoo *clears* the bit used for PageFoo, and
 * __ClearPageFoo *sets* the bit used for PageFoo.  We reserve a few high and
 * low bits so that an underflow or overflow of page_mapcount() won't be
 * mistaken for a page type value.
 */ 
       
#define PAGE_TYPE_BASE  0xf0000000
/* Reserve      0x0000007f to catch underflows of page_mapcount */
#define PG_buddy    0x00000080
#define PG_balloon  0x00000100
#define PG_kmemcg   0x00000200
#define PG_table    0x00000400

使用方法

通过 PAGE_TYPE_OPS() 宏为每种 page_type 定义 get、set、clear 操作,比如,针对 PG_buddy 有如下定义:

PAGE_TYPE_OPS(Buddy, buddy)

它涉及以下宏定义:

#define PageType(page, flag)                        \
    ((page->page_type & (PAGE_TYPE_BASE | flag)) == PAGE_TYPE_BASE)
   
#define PAGE_TYPE_OPS(uname, lname)                 \
static __always_inline int Page##uname(struct page *page)       \
{                                   \
    return PageType(page, PG_##lname);              \
}                                   \
static __always_inline void __SetPage##uname(struct page *page)     \
{                                   \
    VM_BUG_ON_PAGE(!PageType(page, 0), page);           \
    page->page_type &= ~PG_##lname;                 \
}                                   \
static __always_inline void __ClearPage##uname(struct page *page)   \
{                                   \
    VM_BUG_ON_PAGE(!Page##uname(page), page);           \
    page->page_type |= PG_##lname;                  \
}

需要注意的一点是,在 page_type 中,如果某个属性位存在,则其对应的位取值为 0, 而不是 1,反之亦然。
 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值