diff options
-rw-r--r-- | fs/pipe.c | 3 | ||||
-rw-r--r-- | include/linux/memcontrol.h | 37 | ||||
-rw-r--r-- | mm/memcontrol.c | 16 | ||||
-rw-r--r-- | mm/page_alloc.c | 4 | ||||
-rw-r--r-- | mm/slab.h | 4 |
5 files changed, 44 insertions, 20 deletions
@@ -140,8 +140,7 @@ static int anon_pipe_buf_steal(struct pipe_inode_info *pipe, | |||
140 | struct page *page = buf->page; | 140 | struct page *page = buf->page; |
141 | 141 | ||
142 | if (page_count(page) == 1) { | 142 | if (page_count(page) == 1) { |
143 | if (memcg_kmem_enabled()) | 143 | memcg_kmem_uncharge(page, 0); |
144 | memcg_kmem_uncharge(page, 0); | ||
145 | __SetPageLocked(page); | 144 | __SetPageLocked(page); |
146 | return 0; | 145 | return 0; |
147 | } | 146 | } |
diff --git a/include/linux/memcontrol.h b/include/linux/memcontrol.h index 83ae11cbd12c..b0eb29ea0d9c 100644 --- a/include/linux/memcontrol.h +++ b/include/linux/memcontrol.h | |||
@@ -1273,12 +1273,12 @@ static inline bool mem_cgroup_under_socket_pressure(struct mem_cgroup *memcg) | |||
1273 | 1273 | ||
1274 | struct kmem_cache *memcg_kmem_get_cache(struct kmem_cache *cachep); | 1274 | struct kmem_cache *memcg_kmem_get_cache(struct kmem_cache *cachep); |
1275 | void memcg_kmem_put_cache(struct kmem_cache *cachep); | 1275 | void memcg_kmem_put_cache(struct kmem_cache *cachep); |
1276 | int memcg_kmem_charge_memcg(struct page *page, gfp_t gfp, int order, | ||
1277 | struct mem_cgroup *memcg); | ||
1278 | 1276 | ||
1279 | #ifdef CONFIG_MEMCG_KMEM | 1277 | #ifdef CONFIG_MEMCG_KMEM |
1280 | int memcg_kmem_charge(struct page *page, gfp_t gfp, int order); | 1278 | int __memcg_kmem_charge(struct page *page, gfp_t gfp, int order); |
1281 | void memcg_kmem_uncharge(struct page *page, int order); | 1279 | void __memcg_kmem_uncharge(struct page *page, int order); |
1280 | int __memcg_kmem_charge_memcg(struct page *page, gfp_t gfp, int order, | ||
1281 | struct mem_cgroup *memcg); | ||
1282 | 1282 | ||
1283 | extern struct static_key_false memcg_kmem_enabled_key; | 1283 | extern struct static_key_false memcg_kmem_enabled_key; |
1284 | extern struct workqueue_struct *memcg_kmem_cache_wq; | 1284 | extern struct workqueue_struct *memcg_kmem_cache_wq; |
@@ -1300,6 +1300,26 @@ static inline bool memcg_kmem_enabled(void) | |||
1300 | return static_branch_unlikely(&memcg_kmem_enabled_key); | 1300 | return static_branch_unlikely(&memcg_kmem_enabled_key); |
1301 | } | 1301 | } |
1302 | 1302 | ||
1303 | static inline int memcg_kmem_charge(struct page *page, gfp_t gfp, int order) | ||
1304 | { | ||
1305 | if (memcg_kmem_enabled()) | ||
1306 | return __memcg_kmem_charge(page, gfp, order); | ||
1307 | return 0; | ||
1308 | } | ||
1309 | |||
1310 | static inline void memcg_kmem_uncharge(struct page *page, int order) | ||
1311 | { | ||
1312 | if (memcg_kmem_enabled()) | ||
1313 | __memcg_kmem_uncharge(page, order); | ||
1314 | } | ||
1315 | |||
1316 | static inline int memcg_kmem_charge_memcg(struct page *page, gfp_t gfp, | ||
1317 | int order, struct mem_cgroup *memcg) | ||
1318 | { | ||
1319 | if (memcg_kmem_enabled()) | ||
1320 | return __memcg_kmem_charge_memcg(page, gfp, order, memcg); | ||
1321 | return 0; | ||
1322 | } | ||
1303 | /* | 1323 | /* |
1304 | * helper for accessing a memcg's index. It will be used as an index in the | 1324 | * helper for accessing a memcg's index. It will be used as an index in the |
1305 | * child cache array in kmem_cache, and also to derive its name. This function | 1325 | * child cache array in kmem_cache, and also to derive its name. This function |
@@ -1325,6 +1345,15 @@ static inline void memcg_kmem_uncharge(struct page *page, int order) | |||
1325 | { | 1345 | { |
1326 | } | 1346 | } |
1327 | 1347 | ||
1348 | static inline int __memcg_kmem_charge(struct page *page, gfp_t gfp, int order) | ||
1349 | { | ||
1350 | return 0; | ||
1351 | } | ||
1352 | |||
1353 | static inline void __memcg_kmem_uncharge(struct page *page, int order) | ||
1354 | { | ||
1355 | } | ||
1356 | |||
1328 | #define for_each_memcg_cache_index(_idx) \ | 1357 | #define for_each_memcg_cache_index(_idx) \ |
1329 | for (; NULL; ) | 1358 | for (; NULL; ) |
1330 | 1359 | ||
diff --git a/mm/memcontrol.c b/mm/memcontrol.c index af7f18b32389..72414bb7e226 100644 --- a/mm/memcontrol.c +++ b/mm/memcontrol.c | |||
@@ -2573,7 +2573,7 @@ void memcg_kmem_put_cache(struct kmem_cache *cachep) | |||
2573 | } | 2573 | } |
2574 | 2574 | ||
2575 | /** | 2575 | /** |
2576 | * memcg_kmem_charge_memcg: charge a kmem page | 2576 | * __memcg_kmem_charge_memcg: charge a kmem page |
2577 | * @page: page to charge | 2577 | * @page: page to charge |
2578 | * @gfp: reclaim mode | 2578 | * @gfp: reclaim mode |
2579 | * @order: allocation order | 2579 | * @order: allocation order |
@@ -2581,7 +2581,7 @@ void memcg_kmem_put_cache(struct kmem_cache *cachep) | |||
2581 | * | 2581 | * |
2582 | * Returns 0 on success, an error code on failure. | 2582 | * Returns 0 on success, an error code on failure. |
2583 | */ | 2583 | */ |
2584 | int memcg_kmem_charge_memcg(struct page *page, gfp_t gfp, int order, | 2584 | int __memcg_kmem_charge_memcg(struct page *page, gfp_t gfp, int order, |
2585 | struct mem_cgroup *memcg) | 2585 | struct mem_cgroup *memcg) |
2586 | { | 2586 | { |
2587 | unsigned int nr_pages = 1 << order; | 2587 | unsigned int nr_pages = 1 << order; |
@@ -2604,24 +2604,24 @@ int memcg_kmem_charge_memcg(struct page *page, gfp_t gfp, int order, | |||
2604 | } | 2604 | } |
2605 | 2605 | ||
2606 | /** | 2606 | /** |
2607 | * memcg_kmem_charge: charge a kmem page to the current memory cgroup | 2607 | * __memcg_kmem_charge: charge a kmem page to the current memory cgroup |
2608 | * @page: page to charge | 2608 | * @page: page to charge |
2609 | * @gfp: reclaim mode | 2609 | * @gfp: reclaim mode |
2610 | * @order: allocation order | 2610 | * @order: allocation order |
2611 | * | 2611 | * |
2612 | * Returns 0 on success, an error code on failure. | 2612 | * Returns 0 on success, an error code on failure. |
2613 | */ | 2613 | */ |
2614 | int memcg_kmem_charge(struct page *page, gfp_t gfp, int order) | 2614 | int __memcg_kmem_charge(struct page *page, gfp_t gfp, int order) |
2615 | { | 2615 | { |
2616 | struct mem_cgroup *memcg; | 2616 | struct mem_cgroup *memcg; |
2617 | int ret = 0; | 2617 | int ret = 0; |
2618 | 2618 | ||
2619 | if (mem_cgroup_disabled() || memcg_kmem_bypass()) | 2619 | if (memcg_kmem_bypass()) |
2620 | return 0; | 2620 | return 0; |
2621 | 2621 | ||
2622 | memcg = get_mem_cgroup_from_current(); | 2622 | memcg = get_mem_cgroup_from_current(); |
2623 | if (!mem_cgroup_is_root(memcg)) { | 2623 | if (!mem_cgroup_is_root(memcg)) { |
2624 | ret = memcg_kmem_charge_memcg(page, gfp, order, memcg); | 2624 | ret = __memcg_kmem_charge_memcg(page, gfp, order, memcg); |
2625 | if (!ret) | 2625 | if (!ret) |
2626 | __SetPageKmemcg(page); | 2626 | __SetPageKmemcg(page); |
2627 | } | 2627 | } |
@@ -2629,11 +2629,11 @@ int memcg_kmem_charge(struct page *page, gfp_t gfp, int order) | |||
2629 | return ret; | 2629 | return ret; |
2630 | } | 2630 | } |
2631 | /** | 2631 | /** |
2632 | * memcg_kmem_uncharge: uncharge a kmem page | 2632 | * __memcg_kmem_uncharge: uncharge a kmem page |
2633 | * @page: page to uncharge | 2633 | * @page: page to uncharge |
2634 | * @order: allocation order | 2634 | * @order: allocation order |
2635 | */ | 2635 | */ |
2636 | void memcg_kmem_uncharge(struct page *page, int order) | 2636 | void __memcg_kmem_uncharge(struct page *page, int order) |
2637 | { | 2637 | { |
2638 | struct mem_cgroup *memcg = page->mem_cgroup; | 2638 | struct mem_cgroup *memcg = page->mem_cgroup; |
2639 | unsigned int nr_pages = 1 << order; | 2639 | unsigned int nr_pages = 1 << order; |
diff --git a/mm/page_alloc.c b/mm/page_alloc.c index 1f9f1409df9b..034b8b6043a3 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c | |||
@@ -1056,7 +1056,7 @@ static __always_inline bool free_pages_prepare(struct page *page, | |||
1056 | if (PageMappingFlags(page)) | 1056 | if (PageMappingFlags(page)) |
1057 | page->mapping = NULL; | 1057 | page->mapping = NULL; |
1058 | if (memcg_kmem_enabled() && PageKmemcg(page)) | 1058 | if (memcg_kmem_enabled() && PageKmemcg(page)) |
1059 | memcg_kmem_uncharge(page, order); | 1059 | __memcg_kmem_uncharge(page, order); |
1060 | if (check_free) | 1060 | if (check_free) |
1061 | bad += free_pages_check(page); | 1061 | bad += free_pages_check(page); |
1062 | if (bad) | 1062 | if (bad) |
@@ -4568,7 +4568,7 @@ __alloc_pages_nodemask(gfp_t gfp_mask, unsigned int order, int preferred_nid, | |||
4568 | 4568 | ||
4569 | out: | 4569 | out: |
4570 | if (memcg_kmem_enabled() && (gfp_mask & __GFP_ACCOUNT) && page && | 4570 | if (memcg_kmem_enabled() && (gfp_mask & __GFP_ACCOUNT) && page && |
4571 | unlikely(memcg_kmem_charge(page, gfp_mask, order) != 0)) { | 4571 | unlikely(__memcg_kmem_charge(page, gfp_mask, order) != 0)) { |
4572 | __free_pages(page, order); | 4572 | __free_pages(page, order); |
4573 | page = NULL; | 4573 | page = NULL; |
4574 | } | 4574 | } |
@@ -276,8 +276,6 @@ static __always_inline int memcg_charge_slab(struct page *page, | |||
276 | gfp_t gfp, int order, | 276 | gfp_t gfp, int order, |
277 | struct kmem_cache *s) | 277 | struct kmem_cache *s) |
278 | { | 278 | { |
279 | if (!memcg_kmem_enabled()) | ||
280 | return 0; | ||
281 | if (is_root_cache(s)) | 279 | if (is_root_cache(s)) |
282 | return 0; | 280 | return 0; |
283 | return memcg_kmem_charge_memcg(page, gfp, order, s->memcg_params.memcg); | 281 | return memcg_kmem_charge_memcg(page, gfp, order, s->memcg_params.memcg); |
@@ -286,8 +284,6 @@ static __always_inline int memcg_charge_slab(struct page *page, | |||
286 | static __always_inline void memcg_uncharge_slab(struct page *page, int order, | 284 | static __always_inline void memcg_uncharge_slab(struct page *page, int order, |
287 | struct kmem_cache *s) | 285 | struct kmem_cache *s) |
288 | { | 286 | { |
289 | if (!memcg_kmem_enabled()) | ||
290 | return; | ||
291 | memcg_kmem_uncharge(page, order); | 287 | memcg_kmem_uncharge(page, order); |
292 | } | 288 | } |
293 | 289 | ||