linux/include/linux/hugetlb_cgroup.h
<<
>>
Prefs
   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 {
  40        struct cgroup_subsys_state css;
  41
  42        /*
  43         * the counter to account for hugepages from hugetlb.
  44         */
  45        struct page_counter hugepage[HUGE_MAX_HSTATE];
  46
  47        /*
  48         * the counter to account for hugepage reservations from hugetlb.
  49         */
  50        struct page_counter rsvd_hugepage[HUGE_MAX_HSTATE];
  51
  52        atomic_long_t events[HUGE_MAX_HSTATE][HUGETLB_NR_MEMORY_EVENTS];
  53        atomic_long_t events_local[HUGE_MAX_HSTATE][HUGETLB_NR_MEMORY_EVENTS];
  54
  55        /* Handle for "hugetlb.events" */
  56        struct cgroup_file events_file[HUGE_MAX_HSTATE];
  57
  58        /* Handle for "hugetlb.events.local" */
  59        struct cgroup_file events_local_file[HUGE_MAX_HSTATE];
  60};
  61
  62static inline struct hugetlb_cgroup *
  63__hugetlb_cgroup_from_page(struct page *page, bool rsvd)
  64{
  65        VM_BUG_ON_PAGE(!PageHuge(page), page);
  66
  67        if (compound_order(page) < HUGETLB_CGROUP_MIN_ORDER)
  68                return NULL;
  69        if (rsvd)
  70                return (void *)page_private(page + SUBPAGE_INDEX_CGROUP_RSVD);
  71        else
  72                return (void *)page_private(page + SUBPAGE_INDEX_CGROUP);
  73}
  74
  75static inline struct hugetlb_cgroup *hugetlb_cgroup_from_page(struct page *page)
  76{
  77        return __hugetlb_cgroup_from_page(page, false);
  78}
  79
  80static inline struct hugetlb_cgroup *
  81hugetlb_cgroup_from_page_rsvd(struct page *page)
  82{
  83        return __hugetlb_cgroup_from_page(page, true);
  84}
  85
  86static inline int __set_hugetlb_cgroup(struct page *page,
  87                                       struct hugetlb_cgroup *h_cg, bool rsvd)
  88{
  89        VM_BUG_ON_PAGE(!PageHuge(page), page);
  90
  91        if (compound_order(page) < HUGETLB_CGROUP_MIN_ORDER)
  92                return -1;
  93        if (rsvd)
  94                set_page_private(page + SUBPAGE_INDEX_CGROUP_RSVD,
  95                                 (unsigned long)h_cg);
  96        else
  97                set_page_private(page + SUBPAGE_INDEX_CGROUP,
  98                                 (unsigned long)h_cg);
  99        return 0;
 100}
 101
 102static inline int set_hugetlb_cgroup(struct page *page,
 103                                     struct hugetlb_cgroup *h_cg)
 104{
 105        return __set_hugetlb_cgroup(page, h_cg, false);
 106}
 107
 108static inline int set_hugetlb_cgroup_rsvd(struct page *page,
 109                                          struct hugetlb_cgroup *h_cg)
 110{
 111        return __set_hugetlb_cgroup(page, h_cg, true);
 112}
 113
 114static inline bool hugetlb_cgroup_disabled(void)
 115{
 116        return !cgroup_subsys_enabled(hugetlb_cgrp_subsys);
 117}
 118
 119static inline void hugetlb_cgroup_put_rsvd_cgroup(struct hugetlb_cgroup *h_cg)
 120{
 121        css_put(&h_cg->css);
 122}
 123
 124static inline void resv_map_dup_hugetlb_cgroup_uncharge_info(
 125                                                struct resv_map *resv_map)
 126{
 127        if (resv_map->css)
 128                css_get(resv_map->css);
 129}
 130
 131static inline void resv_map_put_hugetlb_cgroup_uncharge_info(
 132                                                struct resv_map *resv_map)
 133{
 134        if (resv_map->css)
 135                css_put(resv_map->css);
 136}
 137
 138extern int hugetlb_cgroup_charge_cgroup(int idx, unsigned long nr_pages,
 139                                        struct hugetlb_cgroup **ptr);
 140extern int hugetlb_cgroup_charge_cgroup_rsvd(int idx, unsigned long nr_pages,
 141                                             struct hugetlb_cgroup **ptr);
 142extern void hugetlb_cgroup_commit_charge(int idx, unsigned long nr_pages,
 143                                         struct hugetlb_cgroup *h_cg,
 144                                         struct page *page);
 145extern void hugetlb_cgroup_commit_charge_rsvd(int idx, unsigned long nr_pages,
 146                                              struct hugetlb_cgroup *h_cg,
 147                                              struct page *page);
 148extern void hugetlb_cgroup_uncharge_page(int idx, unsigned long nr_pages,
 149                                         struct page *page);
 150extern void hugetlb_cgroup_uncharge_page_rsvd(int idx, unsigned long nr_pages,
 151                                              struct page *page);
 152
 153extern void hugetlb_cgroup_uncharge_cgroup(int idx, unsigned long nr_pages,
 154                                           struct hugetlb_cgroup *h_cg);
 155extern void hugetlb_cgroup_uncharge_cgroup_rsvd(int idx, unsigned long nr_pages,
 156                                                struct hugetlb_cgroup *h_cg);
 157extern void hugetlb_cgroup_uncharge_counter(struct resv_map *resv,
 158                                            unsigned long start,
 159                                            unsigned long end);
 160
 161extern void hugetlb_cgroup_uncharge_file_region(struct resv_map *resv,
 162                                                struct file_region *rg,
 163                                                unsigned long nr_pages,
 164                                                bool region_del);
 165
 166extern void hugetlb_cgroup_file_init(void) __init;
 167extern void hugetlb_cgroup_migrate(struct page *oldhpage,
 168                                   struct page *newhpage);
 169
 170#else
 171static inline void hugetlb_cgroup_uncharge_file_region(struct resv_map *resv,
 172                                                       struct file_region *rg,
 173                                                       unsigned long nr_pages,
 174                                                       bool region_del)
 175{
 176}
 177
 178static inline struct hugetlb_cgroup *hugetlb_cgroup_from_page(struct page *page)
 179{
 180        return NULL;
 181}
 182
 183static inline struct hugetlb_cgroup *
 184hugetlb_cgroup_from_page_resv(struct page *page)
 185{
 186        return NULL;
 187}
 188
 189static inline struct hugetlb_cgroup *
 190hugetlb_cgroup_from_page_rsvd(struct page *page)
 191{
 192        return NULL;
 193}
 194
 195static inline int set_hugetlb_cgroup(struct page *page,
 196                                     struct hugetlb_cgroup *h_cg)
 197{
 198        return 0;
 199}
 200
 201static inline int set_hugetlb_cgroup_rsvd(struct page *page,
 202                                          struct hugetlb_cgroup *h_cg)
 203{
 204        return 0;
 205}
 206
 207static inline bool hugetlb_cgroup_disabled(void)
 208{
 209        return true;
 210}
 211
 212static inline void hugetlb_cgroup_put_rsvd_cgroup(struct hugetlb_cgroup *h_cg)
 213{
 214}
 215
 216static inline void resv_map_dup_hugetlb_cgroup_uncharge_info(
 217                                                struct resv_map *resv_map)
 218{
 219}
 220
 221static inline void resv_map_put_hugetlb_cgroup_uncharge_info(
 222                                                struct resv_map *resv_map)
 223{
 224}
 225
 226static inline int hugetlb_cgroup_charge_cgroup(int idx, unsigned long nr_pages,
 227                                               struct hugetlb_cgroup **ptr)
 228{
 229        return 0;
 230}
 231
 232static inline int hugetlb_cgroup_charge_cgroup_rsvd(int idx,
 233                                                    unsigned long nr_pages,
 234                                                    struct hugetlb_cgroup **ptr)
 235{
 236        return 0;
 237}
 238
 239static inline void hugetlb_cgroup_commit_charge(int idx, unsigned long nr_pages,
 240                                                struct hugetlb_cgroup *h_cg,
 241                                                struct page *page)
 242{
 243}
 244
 245static inline void
 246hugetlb_cgroup_commit_charge_rsvd(int idx, unsigned long nr_pages,
 247                                  struct hugetlb_cgroup *h_cg,
 248                                  struct page *page)
 249{
 250}
 251
 252static inline void hugetlb_cgroup_uncharge_page(int idx, unsigned long nr_pages,
 253                                                struct page *page)
 254{
 255}
 256
 257static inline void hugetlb_cgroup_uncharge_page_rsvd(int idx,
 258                                                     unsigned long nr_pages,
 259                                                     struct page *page)
 260{
 261}
 262static inline void hugetlb_cgroup_uncharge_cgroup(int idx,
 263                                                  unsigned long nr_pages,
 264                                                  struct hugetlb_cgroup *h_cg)
 265{
 266}
 267
 268static inline void
 269hugetlb_cgroup_uncharge_cgroup_rsvd(int idx, unsigned long nr_pages,
 270                                    struct hugetlb_cgroup *h_cg)
 271{
 272}
 273
 274static inline void hugetlb_cgroup_uncharge_counter(struct resv_map *resv,
 275                                                   unsigned long start,
 276                                                   unsigned long end)
 277{
 278}
 279
 280static inline void hugetlb_cgroup_file_init(void)
 281{
 282}
 283
 284static inline void hugetlb_cgroup_migrate(struct page *oldhpage,
 285                                          struct page *newhpage)
 286{
 287}
 288
 289#endif  /* CONFIG_MEM_RES_CTLR_HUGETLB */
 290#endif
 291