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
 131extern int hugetlb_cgroup_charge_cgroup(int idx, unsigned long nr_pages,
 132                                        struct hugetlb_cgroup **ptr);
 133extern int hugetlb_cgroup_charge_cgroup_rsvd(int idx, unsigned long nr_pages,
 134                                             struct hugetlb_cgroup **ptr);
 135extern void hugetlb_cgroup_commit_charge(int idx, unsigned long nr_pages,
 136                                         struct hugetlb_cgroup *h_cg,
 137                                         struct page *page);
 138extern void hugetlb_cgroup_commit_charge_rsvd(int idx, unsigned long nr_pages,
 139                                              struct hugetlb_cgroup *h_cg,
 140                                              struct page *page);
 141extern void hugetlb_cgroup_uncharge_page(int idx, unsigned long nr_pages,
 142                                         struct page *page);
 143extern void hugetlb_cgroup_uncharge_page_rsvd(int idx, unsigned long nr_pages,
 144                                              struct page *page);
 145
 146extern void hugetlb_cgroup_uncharge_cgroup(int idx, unsigned long nr_pages,
 147                                           struct hugetlb_cgroup *h_cg);
 148extern void hugetlb_cgroup_uncharge_cgroup_rsvd(int idx, unsigned long nr_pages,
 149                                                struct hugetlb_cgroup *h_cg);
 150extern void hugetlb_cgroup_uncharge_counter(struct resv_map *resv,
 151                                            unsigned long start,
 152                                            unsigned long end);
 153
 154extern void hugetlb_cgroup_uncharge_file_region(struct resv_map *resv,
 155                                                struct file_region *rg,
 156                                                unsigned long nr_pages,
 157                                                bool region_del);
 158
 159extern void hugetlb_cgroup_file_init(void) __init;
 160extern void hugetlb_cgroup_migrate(struct page *oldhpage,
 161                                   struct page *newhpage);
 162
 163#else
 164static inline void hugetlb_cgroup_uncharge_file_region(struct resv_map *resv,
 165                                                       struct file_region *rg,
 166                                                       unsigned long nr_pages,
 167                                                       bool region_del)
 168{
 169}
 170
 171static inline struct hugetlb_cgroup *hugetlb_cgroup_from_page(struct page *page)
 172{
 173        return NULL;
 174}
 175
 176static inline struct hugetlb_cgroup *
 177hugetlb_cgroup_from_page_resv(struct page *page)
 178{
 179        return NULL;
 180}
 181
 182static inline struct hugetlb_cgroup *
 183hugetlb_cgroup_from_page_rsvd(struct page *page)
 184{
 185        return NULL;
 186}
 187
 188static inline int set_hugetlb_cgroup(struct page *page,
 189                                     struct hugetlb_cgroup *h_cg)
 190{
 191        return 0;
 192}
 193
 194static inline int set_hugetlb_cgroup_rsvd(struct page *page,
 195                                          struct hugetlb_cgroup *h_cg)
 196{
 197        return 0;
 198}
 199
 200static inline bool hugetlb_cgroup_disabled(void)
 201{
 202        return true;
 203}
 204
 205static inline void hugetlb_cgroup_put_rsvd_cgroup(struct hugetlb_cgroup *h_cg)
 206{
 207}
 208
 209static inline void resv_map_dup_hugetlb_cgroup_uncharge_info(
 210                                                struct resv_map *resv_map)
 211{
 212}
 213
 214static inline int hugetlb_cgroup_charge_cgroup(int idx, unsigned long nr_pages,
 215                                               struct hugetlb_cgroup **ptr)
 216{
 217        return 0;
 218}
 219
 220static inline int hugetlb_cgroup_charge_cgroup_rsvd(int idx,
 221                                                    unsigned long nr_pages,
 222                                                    struct hugetlb_cgroup **ptr)
 223{
 224        return 0;
 225}
 226
 227static inline void hugetlb_cgroup_commit_charge(int idx, unsigned long nr_pages,
 228                                                struct hugetlb_cgroup *h_cg,
 229                                                struct page *page)
 230{
 231}
 232
 233static inline void
 234hugetlb_cgroup_commit_charge_rsvd(int idx, unsigned long nr_pages,
 235                                  struct hugetlb_cgroup *h_cg,
 236                                  struct page *page)
 237{
 238}
 239
 240static inline void hugetlb_cgroup_uncharge_page(int idx, unsigned long nr_pages,
 241                                                struct page *page)
 242{
 243}
 244
 245static inline void hugetlb_cgroup_uncharge_page_rsvd(int idx,
 246                                                     unsigned long nr_pages,
 247                                                     struct page *page)
 248{
 249}
 250static inline void hugetlb_cgroup_uncharge_cgroup(int idx,
 251                                                  unsigned long nr_pages,
 252                                                  struct hugetlb_cgroup *h_cg)
 253{
 254}
 255
 256static inline void
 257hugetlb_cgroup_uncharge_cgroup_rsvd(int idx, unsigned long nr_pages,
 258                                    struct hugetlb_cgroup *h_cg)
 259{
 260}
 261
 262static inline void hugetlb_cgroup_uncharge_counter(struct resv_map *resv,
 263                                                   unsigned long start,
 264                                                   unsigned long end)
 265{
 266}
 267
 268static inline void hugetlb_cgroup_file_init(void)
 269{
 270}
 271
 272static inline void hugetlb_cgroup_migrate(struct page *oldhpage,
 273                                          struct page *newhpage)
 274{
 275}
 276
 277#endif  /* CONFIG_MEM_RES_CTLR_HUGETLB */
 278#endif
 279