diff mbox series

[v2,1/2] mm: memcg/slab: Properly set up gfp flags for objcg pointer array

Message ID 20210504132350.4693-2-longman@redhat.com (mailing list archive)
State New, archived
Headers show
Series mm: memcg/slab: Fix objcg pointer array handling problem | expand

Commit Message

Waiman Long May 4, 2021, 1:23 p.m. UTC
Since the merging of the new slab memory controller in v5.9, the page
structure may store a pointer to obj_cgroup pointer array for slab pages.
Currently, only the __GFP_ACCOUNT bit is masked off. However, the array
is not readily reclaimable and doesn't need to come from the DMA buffer.
So those GFP bits should be masked off as well.

Do the flag bit clearing at memcg_alloc_page_obj_cgroups() to make sure
that it is consistently applied no matter where it is called.

Fixes: 286e04b8ed7a ("mm: memcg/slab: allocate obj_cgroups for non-root slab pages")
Signed-off-by: Waiman Long <longman@redhat.com>
---
 mm/memcontrol.c | 8 ++++++++
 mm/slab.h       | 1 -
 2 files changed, 8 insertions(+), 1 deletion(-)

Comments

Shakeel Butt May 4, 2021, 7:37 p.m. UTC | #1
On Tue, May 4, 2021 at 6:24 AM Waiman Long <longman@redhat.com> wrote:
>
> Since the merging of the new slab memory controller in v5.9, the page
> structure may store a pointer to obj_cgroup pointer array for slab pages.
> Currently, only the __GFP_ACCOUNT bit is masked off. However, the array
> is not readily reclaimable and doesn't need to come from the DMA buffer.
> So those GFP bits should be masked off as well.
>
> Do the flag bit clearing at memcg_alloc_page_obj_cgroups() to make sure
> that it is consistently applied no matter where it is called.
>
> Fixes: 286e04b8ed7a ("mm: memcg/slab: allocate obj_cgroups for non-root slab pages")
> Signed-off-by: Waiman Long <longman@redhat.com>
> ---
>  mm/memcontrol.c | 8 ++++++++
>  mm/slab.h       | 1 -
>  2 files changed, 8 insertions(+), 1 deletion(-)
>
> diff --git a/mm/memcontrol.c b/mm/memcontrol.c
> index c100265dc393..5e3b4f23b830 100644
> --- a/mm/memcontrol.c
> +++ b/mm/memcontrol.c
> @@ -2863,6 +2863,13 @@ static struct mem_cgroup *get_mem_cgroup_from_objcg(struct obj_cgroup *objcg)
>  }
>
>  #ifdef CONFIG_MEMCG_KMEM
> +/*
> + * The allocated objcg pointers array is not accounted directly.
> + * Moreover, it should not come from DMA buffer and is not readily
> + * reclaimable. So those GFP bits should be masked off.
> + */
> +#define OBJCGS_CLEAR_MASK      (__GFP_DMA | __GFP_RECLAIMABLE | __GFP_ACCOUNT)

What about __GFP_DMA32? Does it matter? It seems like DMA32 requests
go to normal caches.

> +
>  int memcg_alloc_page_obj_cgroups(struct page *page, struct kmem_cache *s,
>                                  gfp_t gfp, bool new_page)
>  {
> @@ -2870,6 +2877,7 @@ int memcg_alloc_page_obj_cgroups(struct page *page, struct kmem_cache *s,
>         unsigned long memcg_data;
>         void *vec;
>
> +       gfp &= ~OBJCGS_CLEAR_MASK;
>         vec = kcalloc_node(objects, sizeof(struct obj_cgroup *), gfp,
>                            page_to_nid(page));
>         if (!vec)
> diff --git a/mm/slab.h b/mm/slab.h
> index 18c1927cd196..b3294712a686 100644
> --- a/mm/slab.h
> +++ b/mm/slab.h
> @@ -309,7 +309,6 @@ static inline void memcg_slab_post_alloc_hook(struct kmem_cache *s,
>         if (!memcg_kmem_enabled() || !objcg)
>                 return;
>
> -       flags &= ~__GFP_ACCOUNT;
>         for (i = 0; i < size; i++) {
>                 if (likely(p[i])) {
>                         page = virt_to_head_page(p[i]);
> --
> 2.18.1
>
Waiman Long May 4, 2021, 8:02 p.m. UTC | #2
On 5/4/21 3:37 PM, Shakeel Butt wrote:
> On Tue, May 4, 2021 at 6:24 AM Waiman Long <longman@redhat.com> wrote:
>> Since the merging of the new slab memory controller in v5.9, the page
>> structure may store a pointer to obj_cgroup pointer array for slab pages.
>> Currently, only the __GFP_ACCOUNT bit is masked off. However, the array
>> is not readily reclaimable and doesn't need to come from the DMA buffer.
>> So those GFP bits should be masked off as well.
>>
>> Do the flag bit clearing at memcg_alloc_page_obj_cgroups() to make sure
>> that it is consistently applied no matter where it is called.
>>
>> Fixes: 286e04b8ed7a ("mm: memcg/slab: allocate obj_cgroups for non-root slab pages")
>> Signed-off-by: Waiman Long <longman@redhat.com>
>> ---
>>   mm/memcontrol.c | 8 ++++++++
>>   mm/slab.h       | 1 -
>>   2 files changed, 8 insertions(+), 1 deletion(-)
>>
>> diff --git a/mm/memcontrol.c b/mm/memcontrol.c
>> index c100265dc393..5e3b4f23b830 100644
>> --- a/mm/memcontrol.c
>> +++ b/mm/memcontrol.c
>> @@ -2863,6 +2863,13 @@ static struct mem_cgroup *get_mem_cgroup_from_objcg(struct obj_cgroup *objcg)
>>   }
>>
>>   #ifdef CONFIG_MEMCG_KMEM
>> +/*
>> + * The allocated objcg pointers array is not accounted directly.
>> + * Moreover, it should not come from DMA buffer and is not readily
>> + * reclaimable. So those GFP bits should be masked off.
>> + */
>> +#define OBJCGS_CLEAR_MASK      (__GFP_DMA | __GFP_RECLAIMABLE | __GFP_ACCOUNT)
> What about __GFP_DMA32? Does it matter? It seems like DMA32 requests
> go to normal caches.

I included __GFP_DMA32 in my first draft patch. However, __GFP_DMA32 is 
not considered in determining the right kmalloc_type() (patch 2), so I 
took it out to make it consistent. I can certainly add it back.

Cheers,
Longman
Shakeel Butt May 4, 2021, 8:06 p.m. UTC | #3
On Tue, May 4, 2021 at 1:02 PM Waiman Long <llong@redhat.com> wrote:
>
> On 5/4/21 3:37 PM, Shakeel Butt wrote:
> > On Tue, May 4, 2021 at 6:24 AM Waiman Long <longman@redhat.com> wrote:
> >> Since the merging of the new slab memory controller in v5.9, the page
> >> structure may store a pointer to obj_cgroup pointer array for slab pages.
> >> Currently, only the __GFP_ACCOUNT bit is masked off. However, the array
> >> is not readily reclaimable and doesn't need to come from the DMA buffer.
> >> So those GFP bits should be masked off as well.
> >>
> >> Do the flag bit clearing at memcg_alloc_page_obj_cgroups() to make sure
> >> that it is consistently applied no matter where it is called.
> >>
> >> Fixes: 286e04b8ed7a ("mm: memcg/slab: allocate obj_cgroups for non-root slab pages")
> >> Signed-off-by: Waiman Long <longman@redhat.com>
> >> ---
> >>   mm/memcontrol.c | 8 ++++++++
> >>   mm/slab.h       | 1 -
> >>   2 files changed, 8 insertions(+), 1 deletion(-)
> >>
> >> diff --git a/mm/memcontrol.c b/mm/memcontrol.c
> >> index c100265dc393..5e3b4f23b830 100644
> >> --- a/mm/memcontrol.c
> >> +++ b/mm/memcontrol.c
> >> @@ -2863,6 +2863,13 @@ static struct mem_cgroup *get_mem_cgroup_from_objcg(struct obj_cgroup *objcg)
> >>   }
> >>
> >>   #ifdef CONFIG_MEMCG_KMEM
> >> +/*
> >> + * The allocated objcg pointers array is not accounted directly.
> >> + * Moreover, it should not come from DMA buffer and is not readily
> >> + * reclaimable. So those GFP bits should be masked off.
> >> + */
> >> +#define OBJCGS_CLEAR_MASK      (__GFP_DMA | __GFP_RECLAIMABLE | __GFP_ACCOUNT)
> > What about __GFP_DMA32? Does it matter? It seems like DMA32 requests
> > go to normal caches.
>
> I included __GFP_DMA32 in my first draft patch. However, __GFP_DMA32 is
> not considered in determining the right kmalloc_type() (patch 2), so I
> took it out to make it consistent. I can certainly add it back.
>

No this is fine and DMA32 question is unrelated to this patch series.
Vlastimil Babka May 5, 2021, 11:32 a.m. UTC | #4
On 5/4/21 10:06 PM, Shakeel Butt wrote:
> On Tue, May 4, 2021 at 1:02 PM Waiman Long <llong@redhat.com> wrote:
>>
>> On 5/4/21 3:37 PM, Shakeel Butt wrote:
>> > On Tue, May 4, 2021 at 6:24 AM Waiman Long <longman@redhat.com> wrote:
>> >> Since the merging of the new slab memory controller in v5.9, the page
>> >> structure may store a pointer to obj_cgroup pointer array for slab pages.
>> >> Currently, only the __GFP_ACCOUNT bit is masked off. However, the array
>> >> is not readily reclaimable and doesn't need to come from the DMA buffer.
>> >> So those GFP bits should be masked off as well.
>> >>
>> >> Do the flag bit clearing at memcg_alloc_page_obj_cgroups() to make sure
>> >> that it is consistently applied no matter where it is called.
>> >>
>> >> Fixes: 286e04b8ed7a ("mm: memcg/slab: allocate obj_cgroups for non-root slab pages")
>> >> Signed-off-by: Waiman Long <longman@redhat.com>
>> >> ---
>> >>   mm/memcontrol.c | 8 ++++++++
>> >>   mm/slab.h       | 1 -
>> >>   2 files changed, 8 insertions(+), 1 deletion(-)
>> >>
>> >> diff --git a/mm/memcontrol.c b/mm/memcontrol.c
>> >> index c100265dc393..5e3b4f23b830 100644
>> >> --- a/mm/memcontrol.c
>> >> +++ b/mm/memcontrol.c
>> >> @@ -2863,6 +2863,13 @@ static struct mem_cgroup *get_mem_cgroup_from_objcg(struct obj_cgroup *objcg)
>> >>   }
>> >>
>> >>   #ifdef CONFIG_MEMCG_KMEM
>> >> +/*
>> >> + * The allocated objcg pointers array is not accounted directly.
>> >> + * Moreover, it should not come from DMA buffer and is not readily
>> >> + * reclaimable. So those GFP bits should be masked off.
>> >> + */
>> >> +#define OBJCGS_CLEAR_MASK      (__GFP_DMA | __GFP_RECLAIMABLE | __GFP_ACCOUNT)
>> > What about __GFP_DMA32? Does it matter? It seems like DMA32 requests
>> > go to normal caches.
>>
>> I included __GFP_DMA32 in my first draft patch. However, __GFP_DMA32 is
>> not considered in determining the right kmalloc_type() (patch 2), so I
>> took it out to make it consistent. I can certainly add it back.
>>
> 
> No this is fine and DMA32 question is unrelated to this patch series.

We never supported them in kmalloc(), only explicit caches with SLAB_CACHE_DMA32
flag.
diff mbox series

Patch

diff --git a/mm/memcontrol.c b/mm/memcontrol.c
index c100265dc393..5e3b4f23b830 100644
--- a/mm/memcontrol.c
+++ b/mm/memcontrol.c
@@ -2863,6 +2863,13 @@  static struct mem_cgroup *get_mem_cgroup_from_objcg(struct obj_cgroup *objcg)
 }
 
 #ifdef CONFIG_MEMCG_KMEM
+/*
+ * The allocated objcg pointers array is not accounted directly.
+ * Moreover, it should not come from DMA buffer and is not readily
+ * reclaimable. So those GFP bits should be masked off.
+ */
+#define OBJCGS_CLEAR_MASK	(__GFP_DMA | __GFP_RECLAIMABLE | __GFP_ACCOUNT)
+
 int memcg_alloc_page_obj_cgroups(struct page *page, struct kmem_cache *s,
 				 gfp_t gfp, bool new_page)
 {
@@ -2870,6 +2877,7 @@  int memcg_alloc_page_obj_cgroups(struct page *page, struct kmem_cache *s,
 	unsigned long memcg_data;
 	void *vec;
 
+	gfp &= ~OBJCGS_CLEAR_MASK;
 	vec = kcalloc_node(objects, sizeof(struct obj_cgroup *), gfp,
 			   page_to_nid(page));
 	if (!vec)
diff --git a/mm/slab.h b/mm/slab.h
index 18c1927cd196..b3294712a686 100644
--- a/mm/slab.h
+++ b/mm/slab.h
@@ -309,7 +309,6 @@  static inline void memcg_slab_post_alloc_hook(struct kmem_cache *s,
 	if (!memcg_kmem_enabled() || !objcg)
 		return;
 
-	flags &= ~__GFP_ACCOUNT;
 	for (i = 0; i < size; i++) {
 		if (likely(p[i])) {
 			page = virt_to_head_page(p[i]);