diff options
author | Joonsoo Kim <iamjoonsoo.kim@lge.com> | 2013-10-23 21:07:37 -0400 |
---|---|---|
committer | Pekka Enberg <penberg@iki.fi> | 2013-10-24 13:17:19 -0400 |
commit | 73293c2f900d0adbb6a415b312cd57976d5ae242 (patch) | |
tree | ff87b3e043fc9774431469a5b5d917bf6c28f570 | |
parent | 6e4664525b1db28f8c4e1130957f70a94c19213e (diff) |
slab: correct pfmemalloc check
We checked pfmemalloc by slab unit, not page unit. You can see this
in is_slab_pfmemalloc(). So other pages don't need to be set/cleared
pfmemalloc.
And, therefore we should check pfmemalloc in page flag of first page,
but current implementation don't do that. virt_to_head_page(obj) just
return 'struct page' of that object, not one of first page, since the SLAB
don't use __GFP_COMP when CONFIG_MMU. To get 'struct page' of first page,
we first get a slab and try to get it via virt_to_head_page(slab->s_mem).
Acked-by: Andi Kleen <ak@linux.intel.com>
Signed-off-by: Joonsoo Kim <iamjoonsoo.kim@lge.com>
Signed-off-by: Pekka Enberg <penberg@iki.fi>
-rw-r--r-- | mm/slab.c | 8 |
1 files changed, 5 insertions, 3 deletions
@@ -930,7 +930,8 @@ static void *__ac_put_obj(struct kmem_cache *cachep, struct array_cache *ac, | |||
930 | { | 930 | { |
931 | if (unlikely(pfmemalloc_active)) { | 931 | if (unlikely(pfmemalloc_active)) { |
932 | /* Some pfmemalloc slabs exist, check if this is one */ | 932 | /* Some pfmemalloc slabs exist, check if this is one */ |
933 | struct page *page = virt_to_head_page(objp); | 933 | struct slab *slabp = virt_to_slab(objp); |
934 | struct page *page = virt_to_head_page(slabp->s_mem); | ||
934 | if (PageSlabPfmemalloc(page)) | 935 | if (PageSlabPfmemalloc(page)) |
935 | set_obj_pfmemalloc(&objp); | 936 | set_obj_pfmemalloc(&objp); |
936 | } | 937 | } |
@@ -1776,7 +1777,7 @@ static void *kmem_getpages(struct kmem_cache *cachep, gfp_t flags, int nodeid) | |||
1776 | __SetPageSlab(page + i); | 1777 | __SetPageSlab(page + i); |
1777 | 1778 | ||
1778 | if (page->pfmemalloc) | 1779 | if (page->pfmemalloc) |
1779 | SetPageSlabPfmemalloc(page + i); | 1780 | SetPageSlabPfmemalloc(page); |
1780 | } | 1781 | } |
1781 | memcg_bind_pages(cachep, cachep->gfporder); | 1782 | memcg_bind_pages(cachep, cachep->gfporder); |
1782 | 1783 | ||
@@ -1809,9 +1810,10 @@ static void kmem_freepages(struct kmem_cache *cachep, void *addr) | |||
1809 | else | 1810 | else |
1810 | sub_zone_page_state(page_zone(page), | 1811 | sub_zone_page_state(page_zone(page), |
1811 | NR_SLAB_UNRECLAIMABLE, nr_freed); | 1812 | NR_SLAB_UNRECLAIMABLE, nr_freed); |
1813 | |||
1814 | __ClearPageSlabPfmemalloc(page); | ||
1812 | while (i--) { | 1815 | while (i--) { |
1813 | BUG_ON(!PageSlab(page)); | 1816 | BUG_ON(!PageSlab(page)); |
1814 | __ClearPageSlabPfmemalloc(page); | ||
1815 | __ClearPageSlab(page); | 1817 | __ClearPageSlab(page); |
1816 | page++; | 1818 | page++; |
1817 | } | 1819 | } |