at v3.3 4.5 kB view raw
1#ifndef __LINUX_PAGE_CGROUP_H 2#define __LINUX_PAGE_CGROUP_H 3 4enum { 5 /* flags for mem_cgroup */ 6 PCG_LOCK, /* Lock for pc->mem_cgroup and following bits. */ 7 PCG_CACHE, /* charged as cache */ 8 PCG_USED, /* this object is in use. */ 9 PCG_MIGRATION, /* under page migration */ 10 /* flags for mem_cgroup and file and I/O status */ 11 PCG_MOVE_LOCK, /* For race between move_account v.s. following bits */ 12 PCG_FILE_MAPPED, /* page is accounted as "mapped" */ 13 __NR_PCG_FLAGS, 14}; 15 16#ifndef __GENERATING_BOUNDS_H 17#include <generated/bounds.h> 18 19#ifdef CONFIG_CGROUP_MEM_RES_CTLR 20#include <linux/bit_spinlock.h> 21 22/* 23 * Page Cgroup can be considered as an extended mem_map. 24 * A page_cgroup page is associated with every page descriptor. The 25 * page_cgroup helps us identify information about the cgroup 26 * All page cgroups are allocated at boot or memory hotplug event, 27 * then the page cgroup for pfn always exists. 28 */ 29struct page_cgroup { 30 unsigned long flags; 31 struct mem_cgroup *mem_cgroup; 32}; 33 34void __meminit pgdat_page_cgroup_init(struct pglist_data *pgdat); 35 36#ifdef CONFIG_SPARSEMEM 37static inline void __init page_cgroup_init_flatmem(void) 38{ 39} 40extern void __init page_cgroup_init(void); 41#else 42void __init page_cgroup_init_flatmem(void); 43static inline void __init page_cgroup_init(void) 44{ 45} 46#endif 47 48struct page_cgroup *lookup_page_cgroup(struct page *page); 49struct page *lookup_cgroup_page(struct page_cgroup *pc); 50 51#define TESTPCGFLAG(uname, lname) \ 52static inline int PageCgroup##uname(struct page_cgroup *pc) \ 53 { return test_bit(PCG_##lname, &pc->flags); } 54 55#define SETPCGFLAG(uname, lname) \ 56static inline void SetPageCgroup##uname(struct page_cgroup *pc)\ 57 { set_bit(PCG_##lname, &pc->flags); } 58 59#define CLEARPCGFLAG(uname, lname) \ 60static inline void ClearPageCgroup##uname(struct page_cgroup *pc) \ 61 { clear_bit(PCG_##lname, &pc->flags); } 62 63#define TESTCLEARPCGFLAG(uname, lname) \ 64static inline int TestClearPageCgroup##uname(struct page_cgroup *pc) \ 65 { return test_and_clear_bit(PCG_##lname, &pc->flags); } 66 67/* Cache flag is set only once (at allocation) */ 68TESTPCGFLAG(Cache, CACHE) 69CLEARPCGFLAG(Cache, CACHE) 70SETPCGFLAG(Cache, CACHE) 71 72TESTPCGFLAG(Used, USED) 73CLEARPCGFLAG(Used, USED) 74SETPCGFLAG(Used, USED) 75 76SETPCGFLAG(FileMapped, FILE_MAPPED) 77CLEARPCGFLAG(FileMapped, FILE_MAPPED) 78TESTPCGFLAG(FileMapped, FILE_MAPPED) 79 80SETPCGFLAG(Migration, MIGRATION) 81CLEARPCGFLAG(Migration, MIGRATION) 82TESTPCGFLAG(Migration, MIGRATION) 83 84static inline void lock_page_cgroup(struct page_cgroup *pc) 85{ 86 /* 87 * Don't take this lock in IRQ context. 88 * This lock is for pc->mem_cgroup, USED, CACHE, MIGRATION 89 */ 90 bit_spin_lock(PCG_LOCK, &pc->flags); 91} 92 93static inline void unlock_page_cgroup(struct page_cgroup *pc) 94{ 95 bit_spin_unlock(PCG_LOCK, &pc->flags); 96} 97 98static inline void move_lock_page_cgroup(struct page_cgroup *pc, 99 unsigned long *flags) 100{ 101 /* 102 * We know updates to pc->flags of page cache's stats are from both of 103 * usual context or IRQ context. Disable IRQ to avoid deadlock. 104 */ 105 local_irq_save(*flags); 106 bit_spin_lock(PCG_MOVE_LOCK, &pc->flags); 107} 108 109static inline void move_unlock_page_cgroup(struct page_cgroup *pc, 110 unsigned long *flags) 111{ 112 bit_spin_unlock(PCG_MOVE_LOCK, &pc->flags); 113 local_irq_restore(*flags); 114} 115 116#else /* CONFIG_CGROUP_MEM_RES_CTLR */ 117struct page_cgroup; 118 119static inline void __meminit pgdat_page_cgroup_init(struct pglist_data *pgdat) 120{ 121} 122 123static inline struct page_cgroup *lookup_page_cgroup(struct page *page) 124{ 125 return NULL; 126} 127 128static inline void page_cgroup_init(void) 129{ 130} 131 132static inline void __init page_cgroup_init_flatmem(void) 133{ 134} 135 136#endif /* CONFIG_CGROUP_MEM_RES_CTLR */ 137 138#include <linux/swap.h> 139 140#ifdef CONFIG_CGROUP_MEM_RES_CTLR_SWAP 141extern unsigned short swap_cgroup_cmpxchg(swp_entry_t ent, 142 unsigned short old, unsigned short new); 143extern unsigned short swap_cgroup_record(swp_entry_t ent, unsigned short id); 144extern unsigned short lookup_swap_cgroup_id(swp_entry_t ent); 145extern int swap_cgroup_swapon(int type, unsigned long max_pages); 146extern void swap_cgroup_swapoff(int type); 147#else 148 149static inline 150unsigned short swap_cgroup_record(swp_entry_t ent, unsigned short id) 151{ 152 return 0; 153} 154 155static inline 156unsigned short lookup_swap_cgroup_id(swp_entry_t ent) 157{ 158 return 0; 159} 160 161static inline int 162swap_cgroup_swapon(int type, unsigned long max_pages) 163{ 164 return 0; 165} 166 167static inline void swap_cgroup_swapoff(int type) 168{ 169 return; 170} 171 172#endif /* CONFIG_CGROUP_MEM_RES_CTLR_SWAP */ 173 174#endif /* !__GENERATING_BOUNDS_H */ 175 176#endif /* __LINUX_PAGE_CGROUP_H */