diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2012-12-18 18:08:12 -0500 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2012-12-18 18:08:12 -0500 |
| commit | 673ab8783b596cda5b616b317b1a1b47480c66fd (patch) | |
| tree | d3fc9bb4279720c53d0dc69c2a34c40635cf05f3 /include/linux | |
| parent | d7b96ca5d08a8f2f836feb2b3b3bd721d2837a8e (diff) | |
| parent | 3cf23841b4b76eb94d3f8d0fb3627690e4431413 (diff) | |
Merge branch 'akpm' (more patches from Andrew)
Merge patches from Andrew Morton:
"Most of the rest of MM, plus a few dribs and drabs.
I still have quite a few irritating patches left around: ones with
dubious testing results, lack of review, ones which should have gone
via maintainer trees but the maintainers are slack, etc.
I need to be more activist in getting these things wrapped up outside
the merge window, but they're such a PITA."
* emailed patches from Andrew Morton <akpm@linux-foundation.org>: (48 commits)
mm/vmscan.c: avoid possible deadlock caused by too_many_isolated()
vmscan: comment too_many_isolated()
mm/kmemleak.c: remove obsolete simple_strtoul
mm/memory_hotplug.c: improve comments
mm/hugetlb: create hugetlb cgroup file in hugetlb_init
mm/mprotect.c: coding-style cleanups
Documentation: ABI: /sys/devices/system/node/
slub: drop mutex before deleting sysfs entry
memcg: add comments clarifying aspects of cache attribute propagation
kmem: add slab-specific documentation about the kmem controller
slub: slub-specific propagation changes
slab: propagate tunable values
memcg: aggregate memcg cache values in slabinfo
memcg/sl[au]b: shrink dead caches
memcg/sl[au]b: track all the memcg children of a kmem_cache
memcg: destroy memcg caches
sl[au]b: allocate objects from memcg cache
sl[au]b: always get the cache from its page in kmem_cache_free()
memcg: skip memcg kmem allocations in specified code regions
memcg: infrastructure to match an allocation to the right cache
...
Diffstat (limited to 'include/linux')
| -rw-r--r-- | include/linux/gfp.h | 5 | ||||
| -rw-r--r-- | include/linux/hugetlb_cgroup.h | 5 | ||||
| -rw-r--r-- | include/linux/memcontrol.h | 209 | ||||
| -rw-r--r-- | include/linux/res_counter.h | 12 | ||||
| -rw-r--r-- | include/linux/sched.h | 1 | ||||
| -rw-r--r-- | include/linux/slab.h | 48 | ||||
| -rw-r--r-- | include/linux/slab_def.h | 3 | ||||
| -rw-r--r-- | include/linux/slub_def.h | 9 | ||||
| -rw-r--r-- | include/linux/thread_info.h | 2 |
9 files changed, 285 insertions, 9 deletions
diff --git a/include/linux/gfp.h b/include/linux/gfp.h index f74856e17e4..0f615eb23d0 100644 --- a/include/linux/gfp.h +++ b/include/linux/gfp.h | |||
| @@ -30,6 +30,7 @@ struct vm_area_struct; | |||
| 30 | #define ___GFP_HARDWALL 0x20000u | 30 | #define ___GFP_HARDWALL 0x20000u |
| 31 | #define ___GFP_THISNODE 0x40000u | 31 | #define ___GFP_THISNODE 0x40000u |
| 32 | #define ___GFP_RECLAIMABLE 0x80000u | 32 | #define ___GFP_RECLAIMABLE 0x80000u |
| 33 | #define ___GFP_KMEMCG 0x100000u | ||
| 33 | #define ___GFP_NOTRACK 0x200000u | 34 | #define ___GFP_NOTRACK 0x200000u |
| 34 | #define ___GFP_NO_KSWAPD 0x400000u | 35 | #define ___GFP_NO_KSWAPD 0x400000u |
| 35 | #define ___GFP_OTHER_NODE 0x800000u | 36 | #define ___GFP_OTHER_NODE 0x800000u |
| @@ -89,6 +90,7 @@ struct vm_area_struct; | |||
| 89 | 90 | ||
| 90 | #define __GFP_NO_KSWAPD ((__force gfp_t)___GFP_NO_KSWAPD) | 91 | #define __GFP_NO_KSWAPD ((__force gfp_t)___GFP_NO_KSWAPD) |
| 91 | #define __GFP_OTHER_NODE ((__force gfp_t)___GFP_OTHER_NODE) /* On behalf of other node */ | 92 | #define __GFP_OTHER_NODE ((__force gfp_t)___GFP_OTHER_NODE) /* On behalf of other node */ |
| 93 | #define __GFP_KMEMCG ((__force gfp_t)___GFP_KMEMCG) /* Allocation comes from a memcg-accounted resource */ | ||
| 92 | #define __GFP_WRITE ((__force gfp_t)___GFP_WRITE) /* Allocator intends to dirty page */ | 94 | #define __GFP_WRITE ((__force gfp_t)___GFP_WRITE) /* Allocator intends to dirty page */ |
| 93 | 95 | ||
| 94 | /* | 96 | /* |
| @@ -365,6 +367,9 @@ extern void free_pages(unsigned long addr, unsigned int order); | |||
| 365 | extern void free_hot_cold_page(struct page *page, int cold); | 367 | extern void free_hot_cold_page(struct page *page, int cold); |
| 366 | extern void free_hot_cold_page_list(struct list_head *list, int cold); | 368 | extern void free_hot_cold_page_list(struct list_head *list, int cold); |
| 367 | 369 | ||
| 370 | extern void __free_memcg_kmem_pages(struct page *page, unsigned int order); | ||
| 371 | extern void free_memcg_kmem_pages(unsigned long addr, unsigned int order); | ||
| 372 | |||
| 368 | #define __free_page(page) __free_pages((page), 0) | 373 | #define __free_page(page) __free_pages((page), 0) |
| 369 | #define free_page(addr) free_pages((addr), 0) | 374 | #define free_page(addr) free_pages((addr), 0) |
| 370 | 375 | ||
diff --git a/include/linux/hugetlb_cgroup.h b/include/linux/hugetlb_cgroup.h index d73878c694b..ce8217f7b5c 100644 --- a/include/linux/hugetlb_cgroup.h +++ b/include/linux/hugetlb_cgroup.h | |||
| @@ -62,7 +62,7 @@ extern void hugetlb_cgroup_uncharge_page(int idx, unsigned long nr_pages, | |||
| 62 | struct page *page); | 62 | struct page *page); |
| 63 | extern void hugetlb_cgroup_uncharge_cgroup(int idx, unsigned long nr_pages, | 63 | extern void hugetlb_cgroup_uncharge_cgroup(int idx, unsigned long nr_pages, |
| 64 | struct hugetlb_cgroup *h_cg); | 64 | struct hugetlb_cgroup *h_cg); |
| 65 | extern int hugetlb_cgroup_file_init(int idx) __init; | 65 | extern void hugetlb_cgroup_file_init(void) __init; |
| 66 | extern void hugetlb_cgroup_migrate(struct page *oldhpage, | 66 | extern void hugetlb_cgroup_migrate(struct page *oldhpage, |
| 67 | struct page *newhpage); | 67 | struct page *newhpage); |
| 68 | 68 | ||
| @@ -111,9 +111,8 @@ hugetlb_cgroup_uncharge_cgroup(int idx, unsigned long nr_pages, | |||
| 111 | return; | 111 | return; |
| 112 | } | 112 | } |
| 113 | 113 | ||
| 114 | static inline int __init hugetlb_cgroup_file_init(int idx) | 114 | static inline void hugetlb_cgroup_file_init(void) |
| 115 | { | 115 | { |
| 116 | return 0; | ||
| 117 | } | 116 | } |
| 118 | 117 | ||
| 119 | static inline void hugetlb_cgroup_migrate(struct page *oldhpage, | 118 | static inline void hugetlb_cgroup_migrate(struct page *oldhpage, |
diff --git a/include/linux/memcontrol.h b/include/linux/memcontrol.h index e98a74c0c9c..0108a56f814 100644 --- a/include/linux/memcontrol.h +++ b/include/linux/memcontrol.h | |||
| @@ -21,11 +21,14 @@ | |||
| 21 | #define _LINUX_MEMCONTROL_H | 21 | #define _LINUX_MEMCONTROL_H |
| 22 | #include <linux/cgroup.h> | 22 | #include <linux/cgroup.h> |
| 23 | #include <linux/vm_event_item.h> | 23 | #include <linux/vm_event_item.h> |
| 24 | #include <linux/hardirq.h> | ||
| 25 | #include <linux/jump_label.h> | ||
| 24 | 26 | ||
| 25 | struct mem_cgroup; | 27 | struct mem_cgroup; |
| 26 | struct page_cgroup; | 28 | struct page_cgroup; |
| 27 | struct page; | 29 | struct page; |
| 28 | struct mm_struct; | 30 | struct mm_struct; |
| 31 | struct kmem_cache; | ||
| 29 | 32 | ||
| 30 | /* Stats that can be updated by kernel. */ | 33 | /* Stats that can be updated by kernel. */ |
| 31 | enum mem_cgroup_page_stat_item { | 34 | enum mem_cgroup_page_stat_item { |
| @@ -414,5 +417,211 @@ static inline void sock_release_memcg(struct sock *sk) | |||
| 414 | { | 417 | { |
| 415 | } | 418 | } |
| 416 | #endif /* CONFIG_INET && CONFIG_MEMCG_KMEM */ | 419 | #endif /* CONFIG_INET && CONFIG_MEMCG_KMEM */ |
| 420 | |||
| 421 | #ifdef CONFIG_MEMCG_KMEM | ||
| 422 | extern struct static_key memcg_kmem_enabled_key; | ||
| 423 | |||
| 424 | extern int memcg_limited_groups_array_size; | ||
| 425 | |||
| 426 | /* | ||
| 427 | * Helper macro to loop through all memcg-specific caches. Callers must still | ||
| 428 | * check if the cache is valid (it is either valid or NULL). | ||
| 429 | * the slab_mutex must be held when looping through those caches | ||
| 430 | */ | ||
| 431 | #define for_each_memcg_cache_index(_idx) \ | ||
| 432 | for ((_idx) = 0; i < memcg_limited_groups_array_size; (_idx)++) | ||
| 433 | |||
| 434 | static inline bool memcg_kmem_enabled(void) | ||
| 435 | { | ||
| 436 | return static_key_false(&memcg_kmem_enabled_key); | ||
| 437 | } | ||
| 438 | |||
| 439 | /* | ||
| 440 | * In general, we'll do everything in our power to not incur in any overhead | ||
| 441 | * for non-memcg users for the kmem functions. Not even a function call, if we | ||
| 442 | * can avoid it. | ||
| 443 | * | ||
| 444 | * Therefore, we'll inline all those functions so that in the best case, we'll | ||
| 445 | * see that kmemcg is off for everybody and proceed quickly. If it is on, | ||
| 446 | * we'll still do most of the flag checking inline. We check a lot of | ||
| 447 | * conditions, but because they are pretty simple, they are expected to be | ||
| 448 | * fast. | ||
| 449 | */ | ||
| 450 | bool __memcg_kmem_newpage_charge(gfp_t gfp, struct mem_cgroup **memcg, | ||
| 451 | int order); | ||
| 452 | void __memcg_kmem_commit_charge(struct page *page, | ||
| 453 | struct mem_cgroup *memcg, int order); | ||
| 454 | void __memcg_kmem_uncharge_pages(struct page *page, int order); | ||
| 455 | |||
| 456 | int memcg_cache_id(struct mem_cgroup *memcg); | ||
| 457 | int memcg_register_cache(struct mem_cgroup *memcg, struct kmem_cache *s, | ||
| 458 | struct kmem_cache *root_cache); | ||
| 459 | void memcg_release_cache(struct kmem_cache *cachep); | ||
| 460 | void memcg_cache_list_add(struct mem_cgroup *memcg, struct kmem_cache *cachep); | ||
| 461 | |||
| 462 | int memcg_update_cache_size(struct kmem_cache *s, int num_groups); | ||
| 463 | void memcg_update_array_size(int num_groups); | ||
| 464 | |||
| 465 | struct kmem_cache * | ||
| 466 | __memcg_kmem_get_cache(struct kmem_cache *cachep, gfp_t gfp); | ||
| 467 | |||
| 468 | void mem_cgroup_destroy_cache(struct kmem_cache *cachep); | ||
| 469 | void kmem_cache_destroy_memcg_children(struct kmem_cache *s); | ||
| 470 | |||
| 471 | /** | ||
| 472 | * memcg_kmem_newpage_charge: verify if a new kmem allocation is allowed. | ||
| 473 | * @gfp: the gfp allocation flags. | ||
| 474 | * @memcg: a pointer to the memcg this was charged against. | ||
| 475 | * @order: allocation order. | ||
| 476 | * | ||
| 477 | * returns true if the memcg where the current task belongs can hold this | ||
| 478 | * allocation. | ||
| 479 | * | ||
| 480 | * We return true automatically if this allocation is not to be accounted to | ||
| 481 | * any memcg. | ||
| 482 | */ | ||
| 483 | static inline bool | ||
| 484 | memcg_kmem_newpage_charge(gfp_t gfp, struct mem_cgroup **memcg, int order) | ||
| 485 | { | ||
| 486 | if (!memcg_kmem_enabled()) | ||
| 487 | return true; | ||
| 488 | |||
| 489 | /* | ||
| 490 | * __GFP_NOFAIL allocations will move on even if charging is not | ||
| 491 | * possible. Therefore we don't even try, and have this allocation | ||
| 492 | * unaccounted. We could in theory charge it with | ||
| 493 | * res_counter_charge_nofail, but we hope those allocations are rare, | ||
| 494 | * and won't be worth the trouble. | ||
| 495 | */ | ||
| 496 | if (!(gfp & __GFP_KMEMCG) || (gfp & __GFP_NOFAIL)) | ||
| 497 | return true; | ||
| 498 | if (in_interrupt() || (!current->mm) || (current->flags & PF_KTHREAD)) | ||
| 499 | return true; | ||
| 500 | |||
| 501 | /* If the test is dying, just let it go. */ | ||
| 502 | if (unlikely(fatal_signal_pending(current))) | ||
| 503 | return true; | ||
| 504 | |||
| 505 | return __memcg_kmem_newpage_charge(gfp, memcg, order); | ||
| 506 | } | ||
| 507 | |||
| 508 | /** | ||
| 509 | * memcg_kmem_uncharge_pages: uncharge pages from memcg | ||
| 510 | * @page: pointer to struct page being freed | ||
| 511 | * @order: allocation order. | ||
| 512 | * | ||
| 513 | * there is no need to specify memcg here, since it is embedded in page_cgroup | ||
| 514 | */ | ||
| 515 | static inline void | ||
| 516 | memcg_kmem_uncharge_pages(struct page *page, int order) | ||
| 517 | { | ||
| 518 | if (memcg_kmem_enabled()) | ||
| 519 | __memcg_kmem_uncharge_pages(page, order); | ||
