hugetlb_cgroup.h (7657B)
1/* 2 * Copyright IBM Corporation, 2012 3 * Author Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com> 4 * 5 * This program is free software; you can redistribute it and/or modify it 6 * under the terms of version 2.1 of the GNU Lesser General Public License 7 * as published by the Free Software Foundation. 8 * 9 * This program is distributed in the hope that it would be useful, but 10 * WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 12 * 13 */ 14 15#ifndef _LINUX_HUGETLB_CGROUP_H 16#define _LINUX_HUGETLB_CGROUP_H 17 18#include <linux/mmdebug.h> 19 20struct hugetlb_cgroup; 21struct resv_map; 22struct file_region; 23 24#ifdef CONFIG_CGROUP_HUGETLB 25/* 26 * Minimum page order trackable by hugetlb cgroup. 27 * At least 4 pages are necessary for all the tracking information. 28 * The second tail page (hpage[SUBPAGE_INDEX_CGROUP]) is the fault 29 * usage cgroup. The third tail page (hpage[SUBPAGE_INDEX_CGROUP_RSVD]) 30 * is the reservation usage cgroup. 31 */ 32#define HUGETLB_CGROUP_MIN_ORDER order_base_2(__MAX_CGROUP_SUBPAGE_INDEX + 1) 33 34enum hugetlb_memory_event { 35 HUGETLB_MAX, 36 HUGETLB_NR_MEMORY_EVENTS, 37}; 38 39struct hugetlb_cgroup_per_node { 40 /* hugetlb usage in pages over all hstates. */ 41 unsigned long usage[HUGE_MAX_HSTATE]; 42}; 43 44struct hugetlb_cgroup { 45 struct cgroup_subsys_state css; 46 47 /* 48 * the counter to account for hugepages from hugetlb. 49 */ 50 struct page_counter hugepage[HUGE_MAX_HSTATE]; 51 52 /* 53 * the counter to account for hugepage reservations from hugetlb. 54 */ 55 struct page_counter rsvd_hugepage[HUGE_MAX_HSTATE]; 56 57 atomic_long_t events[HUGE_MAX_HSTATE][HUGETLB_NR_MEMORY_EVENTS]; 58 atomic_long_t events_local[HUGE_MAX_HSTATE][HUGETLB_NR_MEMORY_EVENTS]; 59 60 /* Handle for "hugetlb.events" */ 61 struct cgroup_file events_file[HUGE_MAX_HSTATE]; 62 63 /* Handle for "hugetlb.events.local" */ 64 struct cgroup_file events_local_file[HUGE_MAX_HSTATE]; 65 66 struct hugetlb_cgroup_per_node *nodeinfo[]; 67}; 68 69static inline struct hugetlb_cgroup * 70__hugetlb_cgroup_from_page(struct page *page, bool rsvd) 71{ 72 VM_BUG_ON_PAGE(!PageHuge(page), page); 73 74 if (compound_order(page) < HUGETLB_CGROUP_MIN_ORDER) 75 return NULL; 76 if (rsvd) 77 return (void *)page_private(page + SUBPAGE_INDEX_CGROUP_RSVD); 78 else 79 return (void *)page_private(page + SUBPAGE_INDEX_CGROUP); 80} 81 82static inline struct hugetlb_cgroup *hugetlb_cgroup_from_page(struct page *page) 83{ 84 return __hugetlb_cgroup_from_page(page, false); 85} 86 87static inline struct hugetlb_cgroup * 88hugetlb_cgroup_from_page_rsvd(struct page *page) 89{ 90 return __hugetlb_cgroup_from_page(page, true); 91} 92 93static inline int __set_hugetlb_cgroup(struct page *page, 94 struct hugetlb_cgroup *h_cg, bool rsvd) 95{ 96 VM_BUG_ON_PAGE(!PageHuge(page), page); 97 98 if (compound_order(page) < HUGETLB_CGROUP_MIN_ORDER) 99 return -1; 100 if (rsvd) 101 set_page_private(page + SUBPAGE_INDEX_CGROUP_RSVD, 102 (unsigned long)h_cg); 103 else 104 set_page_private(page + SUBPAGE_INDEX_CGROUP, 105 (unsigned long)h_cg); 106 return 0; 107} 108 109static inline int set_hugetlb_cgroup(struct page *page, 110 struct hugetlb_cgroup *h_cg) 111{ 112 return __set_hugetlb_cgroup(page, h_cg, false); 113} 114 115static inline int set_hugetlb_cgroup_rsvd(struct page *page, 116 struct hugetlb_cgroup *h_cg) 117{ 118 return __set_hugetlb_cgroup(page, h_cg, true); 119} 120 121static inline bool hugetlb_cgroup_disabled(void) 122{ 123 return !cgroup_subsys_enabled(hugetlb_cgrp_subsys); 124} 125 126static inline void hugetlb_cgroup_put_rsvd_cgroup(struct hugetlb_cgroup *h_cg) 127{ 128 css_put(&h_cg->css); 129} 130 131static inline void resv_map_dup_hugetlb_cgroup_uncharge_info( 132 struct resv_map *resv_map) 133{ 134 if (resv_map->css) 135 css_get(resv_map->css); 136} 137 138static inline void resv_map_put_hugetlb_cgroup_uncharge_info( 139 struct resv_map *resv_map) 140{ 141 if (resv_map->css) 142 css_put(resv_map->css); 143} 144 145extern int hugetlb_cgroup_charge_cgroup(int idx, unsigned long nr_pages, 146 struct hugetlb_cgroup **ptr); 147extern int hugetlb_cgroup_charge_cgroup_rsvd(int idx, unsigned long nr_pages, 148 struct hugetlb_cgroup **ptr); 149extern void hugetlb_cgroup_commit_charge(int idx, unsigned long nr_pages, 150 struct hugetlb_cgroup *h_cg, 151 struct page *page); 152extern void hugetlb_cgroup_commit_charge_rsvd(int idx, unsigned long nr_pages, 153 struct hugetlb_cgroup *h_cg, 154 struct page *page); 155extern void hugetlb_cgroup_uncharge_page(int idx, unsigned long nr_pages, 156 struct page *page); 157extern void hugetlb_cgroup_uncharge_page_rsvd(int idx, unsigned long nr_pages, 158 struct page *page); 159 160extern void hugetlb_cgroup_uncharge_cgroup(int idx, unsigned long nr_pages, 161 struct hugetlb_cgroup *h_cg); 162extern void hugetlb_cgroup_uncharge_cgroup_rsvd(int idx, unsigned long nr_pages, 163 struct hugetlb_cgroup *h_cg); 164extern void hugetlb_cgroup_uncharge_counter(struct resv_map *resv, 165 unsigned long start, 166 unsigned long end); 167 168extern void hugetlb_cgroup_uncharge_file_region(struct resv_map *resv, 169 struct file_region *rg, 170 unsigned long nr_pages, 171 bool region_del); 172 173extern void hugetlb_cgroup_file_init(void) __init; 174extern void hugetlb_cgroup_migrate(struct page *oldhpage, 175 struct page *newhpage); 176 177#else 178static inline void hugetlb_cgroup_uncharge_file_region(struct resv_map *resv, 179 struct file_region *rg, 180 unsigned long nr_pages, 181 bool region_del) 182{ 183} 184 185static inline struct hugetlb_cgroup *hugetlb_cgroup_from_page(struct page *page) 186{ 187 return NULL; 188} 189 190static inline struct hugetlb_cgroup * 191hugetlb_cgroup_from_page_resv(struct page *page) 192{ 193 return NULL; 194} 195 196static inline struct hugetlb_cgroup * 197hugetlb_cgroup_from_page_rsvd(struct page *page) 198{ 199 return NULL; 200} 201 202static inline int set_hugetlb_cgroup(struct page *page, 203 struct hugetlb_cgroup *h_cg) 204{ 205 return 0; 206} 207 208static inline int set_hugetlb_cgroup_rsvd(struct page *page, 209 struct hugetlb_cgroup *h_cg) 210{ 211 return 0; 212} 213 214static inline bool hugetlb_cgroup_disabled(void) 215{ 216 return true; 217} 218 219static inline void hugetlb_cgroup_put_rsvd_cgroup(struct hugetlb_cgroup *h_cg) 220{ 221} 222 223static inline void resv_map_dup_hugetlb_cgroup_uncharge_info( 224 struct resv_map *resv_map) 225{ 226} 227 228static inline void resv_map_put_hugetlb_cgroup_uncharge_info( 229 struct resv_map *resv_map) 230{ 231} 232 233static inline int hugetlb_cgroup_charge_cgroup(int idx, unsigned long nr_pages, 234 struct hugetlb_cgroup **ptr) 235{ 236 return 0; 237} 238 239static inline int hugetlb_cgroup_charge_cgroup_rsvd(int idx, 240 unsigned long nr_pages, 241 struct hugetlb_cgroup **ptr) 242{ 243 return 0; 244} 245 246static inline void hugetlb_cgroup_commit_charge(int idx, unsigned long nr_pages, 247 struct hugetlb_cgroup *h_cg, 248 struct page *page) 249{ 250} 251 252static inline void 253hugetlb_cgroup_commit_charge_rsvd(int idx, unsigned long nr_pages, 254 struct hugetlb_cgroup *h_cg, 255 struct page *page) 256{ 257} 258 259static inline void hugetlb_cgroup_uncharge_page(int idx, unsigned long nr_pages, 260 struct page *page) 261{ 262} 263 264static inline void hugetlb_cgroup_uncharge_page_rsvd(int idx, 265 unsigned long nr_pages, 266 struct page *page) 267{ 268} 269static inline void hugetlb_cgroup_uncharge_cgroup(int idx, 270 unsigned long nr_pages, 271 struct hugetlb_cgroup *h_cg) 272{ 273} 274 275static inline void 276hugetlb_cgroup_uncharge_cgroup_rsvd(int idx, unsigned long nr_pages, 277 struct hugetlb_cgroup *h_cg) 278{ 279} 280 281static inline void hugetlb_cgroup_uncharge_counter(struct resv_map *resv, 282 unsigned long start, 283 unsigned long end) 284{ 285} 286 287static inline void hugetlb_cgroup_file_init(void) 288{ 289} 290 291static inline void hugetlb_cgroup_migrate(struct page *oldhpage, 292 struct page *newhpage) 293{ 294} 295 296#endif /* CONFIG_MEM_RES_CTLR_HUGETLB */ 297#endif