* [PATCH 1/2] mm: kfence: fix missing objcg housekeeping for SLAB
@ 2022-03-27 5:18 Muchun Song
2022-03-27 5:18 ` [PATCH 2/2] mm: kfence: fix objcgs vector allocation Muchun Song
[not found] ` <CAHk-=wh-mVrp3auBiK2GSMpuqS10Bbq_7fRa6+=zt-0LiF7O2A@mail.gmail.com>
0 siblings, 2 replies; 9+ messages in thread
From: Muchun Song @ 2022-03-27 5:18 UTC (permalink / raw)
To: torvalds, glider, elver, dvyukov, akpm, cl, penberg, rientjes,
iamjoonsoo.kim, vbabka, roman.gushchin
Cc: kasan-dev, linux-mm, linux-kernel, Muchun Song,
syzbot+f8c45ccc7d5d45fc5965
The objcg is not cleared and put for kfence object when it is freed, which
could lead to memory leak for struct obj_cgroup and wrong statistics of
NR_SLAB_RECLAIMABLE_B or NR_SLAB_UNRECLAIMABLE_B. Since the last freed
object's objcg is not cleared, mem_cgroup_from_obj() could return the wrong
memcg when this kfence object, which is not charged to any objcgs, is
reallocated to other users. A real word issue [1] is caused by this bug.
[1] https://groups.google.com/g/syzkaller-bugs/c/BBQFy2QraoY/m/HtBd5gbyAQAJ
Reported-by: syzbot+f8c45ccc7d5d45fc5965@syzkaller.appspotmail.com
Fixes: d3fb45f370d9 ("mm, kfence: insert KFENCE hooks for SLAB")
Signed-off-by: Muchun Song <songmuchun@bytedance.com>
---
mm/slab.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/mm/slab.c b/mm/slab.c
index d9dec7a8fd79..b04e40078bdf 100644
--- a/mm/slab.c
+++ b/mm/slab.c
@@ -3422,6 +3422,7 @@ static __always_inline void __cache_free(struct kmem_cache *cachep, void *objp,
if (is_kfence_address(objp)) {
kmemleak_free_recursive(objp, cachep->flags);
+ memcg_slab_free_hook(cachep, &objp, 1);
__kfence_free(objp);
return;
}
--
2.11.0
^ permalink raw reply [flat|nested] 9+ messages in thread
* [PATCH 2/2] mm: kfence: fix objcgs vector allocation
2022-03-27 5:18 [PATCH 1/2] mm: kfence: fix missing objcg housekeeping for SLAB Muchun Song
@ 2022-03-27 5:18 ` Muchun Song
2022-03-27 5:43 ` Muchun Song
` (3 more replies)
[not found] ` <CAHk-=wh-mVrp3auBiK2GSMpuqS10Bbq_7fRa6+=zt-0LiF7O2A@mail.gmail.com>
1 sibling, 4 replies; 9+ messages in thread
From: Muchun Song @ 2022-03-27 5:18 UTC (permalink / raw)
To: torvalds, glider, elver, dvyukov, akpm, cl, penberg, rientjes,
iamjoonsoo.kim, vbabka, roman.gushchin
Cc: kasan-dev, linux-mm, linux-kernel, Muchun Song
If the kfence object is allocated to be used for objects vector, then
this slot of the pool eventually being occupied permanently since
the vector is never freed. The solutions could be 1) freeing vector
when the kfence object is freed or 2) allocating all vectors statically.
Since the memory consumption of object vectors is low, it is better to
chose 2) to fix the issue and it is also can reduce overhead of vectors
allocating in the future.
Fixes: d3fb45f370d9 ("mm, kfence: insert KFENCE hooks for SLAB")
Signed-off-by: Muchun Song <songmuchun@bytedance.com>
---
mm/kfence/core.c | 3 +++
mm/kfence/kfence.h | 1 +
2 files changed, 4 insertions(+)
diff --git a/mm/kfence/core.c b/mm/kfence/core.c
index 13128fa13062..9976b3f0d097 100644
--- a/mm/kfence/core.c
+++ b/mm/kfence/core.c
@@ -579,9 +579,11 @@ static bool __init kfence_init_pool(void)
}
for (i = 0; i < CONFIG_KFENCE_NUM_OBJECTS; i++) {
+ struct slab *slab = virt_to_slab(addr);
struct kfence_metadata *meta = &kfence_metadata[i];
/* Initialize metadata. */
+ slab->memcg_data = (unsigned long)&meta->objcg | MEMCG_DATA_OBJCGS;
INIT_LIST_HEAD(&meta->list);
raw_spin_lock_init(&meta->lock);
meta->state = KFENCE_OBJECT_UNUSED;
@@ -938,6 +940,7 @@ void __kfence_free(void *addr)
{
struct kfence_metadata *meta = addr_to_metadata((unsigned long)addr);
+ KFENCE_WARN_ON(meta->objcg);
/*
* If the objects of the cache are SLAB_TYPESAFE_BY_RCU, defer freeing
* the object, as the object page may be recycled for other-typed
diff --git a/mm/kfence/kfence.h b/mm/kfence/kfence.h
index 2a2d5de9d379..6f0e1aece3f8 100644
--- a/mm/kfence/kfence.h
+++ b/mm/kfence/kfence.h
@@ -89,6 +89,7 @@ struct kfence_metadata {
struct kfence_track free_track;
/* For updating alloc_covered on frees. */
u32 alloc_stack_hash;
+ struct obj_cgroup *objcg;
};
extern struct kfence_metadata kfence_metadata[CONFIG_KFENCE_NUM_OBJECTS];
--
2.11.0
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH 2/2] mm: kfence: fix objcgs vector allocation
2022-03-27 5:18 ` [PATCH 2/2] mm: kfence: fix objcgs vector allocation Muchun Song
@ 2022-03-27 5:43 ` Muchun Song
2022-03-27 8:07 ` kernel test robot
` (2 subsequent siblings)
3 siblings, 0 replies; 9+ messages in thread
From: Muchun Song @ 2022-03-27 5:43 UTC (permalink / raw)
To: Linus Torvalds, Alexander Potapenko, Marco Elver, Dmitry Vyukov,
Andrew Morton, Christoph Lameter, Pekka Enberg, David Rientjes,
Joonsoo Kim, Vlastimil Babka, Roman Gushchin
Cc: kasan-dev, Linux Memory Management List, LKML
On Sun, Mar 27, 2022 at 1:19 PM Muchun Song <songmuchun@bytedance.com> wrote:
>
> If the kfence object is allocated to be used for objects vector, then
> this slot of the pool eventually being occupied permanently since
> the vector is never freed. The solutions could be 1) freeing vector
> when the kfence object is freed or 2) allocating all vectors statically.
> Since the memory consumption of object vectors is low, it is better to
> chose 2) to fix the issue and it is also can reduce overhead of vectors
> allocating in the future.
>
> Fixes: d3fb45f370d9 ("mm, kfence: insert KFENCE hooks for SLAB")
> Signed-off-by: Muchun Song <songmuchun@bytedance.com>
Since it cannot be compiled successfully when !CONFIG_MEMCG
(The following patch should be applied), I'll update this in the next
version if anyone agrees with this change.
Thanks.
diff --git a/mm/kfence/core.c b/mm/kfence/core.c
index 9976b3f0d097..b5c4b62b5d2c 100644
--- a/mm/kfence/core.c
+++ b/mm/kfence/core.c
@@ -583,7 +583,9 @@ static bool __init kfence_init_pool(void)
struct kfence_metadata *meta = &kfence_metadata[i];
/* Initialize metadata. */
+#ifdef CONFIG_MEMCG
slab->memcg_data = (unsigned long)&meta->objcg |
MEMCG_DATA_OBJCGS;
+#endif
INIT_LIST_HEAD(&meta->list);
raw_spin_lock_init(&meta->lock);
meta->state = KFENCE_OBJECT_UNUSED;
@@ -940,7 +942,9 @@ void __kfence_free(void *addr)
{
struct kfence_metadata *meta = addr_to_metadata((unsigned long)addr);
+#ifdef CONFIG_MEMCG
KFENCE_WARN_ON(meta->objcg);
+#endif
/*
* If the objects of the cache are SLAB_TYPESAFE_BY_RCU, defer freeing
* the object, as the object page may be recycled for other-typed
diff --git a/mm/kfence/kfence.h b/mm/kfence/kfence.h
index 6f0e1aece3f8..9a6c4b1b12a8 100644
--- a/mm/kfence/kfence.h
+++ b/mm/kfence/kfence.h
@@ -89,7 +89,9 @@ struct kfence_metadata {
struct kfence_track free_track;
/* For updating alloc_covered on frees. */
u32 alloc_stack_hash;
+#ifdef CONFIG_MEMCG
struct obj_cgroup *objcg;
+#endif
};
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH 2/2] mm: kfence: fix objcgs vector allocation
2022-03-27 5:18 ` [PATCH 2/2] mm: kfence: fix objcgs vector allocation Muchun Song
2022-03-27 5:43 ` Muchun Song
@ 2022-03-27 8:07 ` kernel test robot
2022-03-27 8:07 ` kernel test robot
2022-03-27 17:31 ` Marco Elver
3 siblings, 0 replies; 9+ messages in thread
From: kernel test robot @ 2022-03-27 8:07 UTC (permalink / raw)
To: Muchun Song, torvalds, glider, elver, dvyukov, akpm, cl, penberg,
rientjes, iamjoonsoo.kim, vbabka, roman.gushchin
Cc: llvm, kbuild-all, kasan-dev, linux-mm, linux-kernel, Muchun Song
Hi Muchun,
Thank you for the patch! Perhaps something to improve:
[auto build test WARNING on hnaz-mm/master]
url: https://github.com/intel-lab-lkp/linux/commits/Muchun-Song/mm-kfence-fix-missing-objcg-housekeeping-for-SLAB/20220327-132038
base: https://github.com/hnaz/linux-mm master
config: x86_64-randconfig-a012 (https://download.01.org/0day-ci/archive/20220327/202203271634.QymsHESG-lkp@intel.com/config)
compiler: clang version 15.0.0 (https://github.com/llvm/llvm-project 0f6d9501cf49ce02937099350d08f20c4af86f3d)
reproduce (this is a W=1 build):
wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
chmod +x ~/bin/make.cross
# https://github.com/intel-lab-lkp/linux/commit/a33cf78311711db98d9f77541d0a4b50bc466875
git remote add linux-review https://github.com/intel-lab-lkp/linux
git fetch --no-tags linux-review Muchun-Song/mm-kfence-fix-missing-objcg-housekeeping-for-SLAB/20220327-132038
git checkout a33cf78311711db98d9f77541d0a4b50bc466875
# save the config file to linux build tree
mkdir build_dir
COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross W=1 O=build_dir ARCH=x86_64 SHELL=/bin/bash mm/kfence/
If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>
All warnings (new ones prefixed by >>):
>> mm/kfence/core.c:593:36: warning: incompatible integer to pointer conversion passing 'unsigned long' to parameter of type 'const void *' [-Wint-conversion]
struct slab *slab = virt_to_slab(addr);
^~~~
mm/kfence/../slab.h:173:53: note: passing argument to parameter 'addr' here
static inline struct slab *virt_to_slab(const void *addr)
^
mm/kfence/core.c:597:9: error: no member named 'memcg_data' in 'struct slab'
slab->memcg_data = (unsigned long)&meta->objcg | MEMCG_DATA_OBJCGS;
~~~~ ^
mm/kfence/core.c:597:52: error: use of undeclared identifier 'MEMCG_DATA_OBJCGS'
slab->memcg_data = (unsigned long)&meta->objcg | MEMCG_DATA_OBJCGS;
^
1 warning and 2 errors generated.
vim +593 mm/kfence/core.c
543
544 /*
545 * Initialization of the KFENCE pool after its allocation.
546 * Returns 0 on success; otherwise returns the address up to
547 * which partial initialization succeeded.
548 */
549 static unsigned long kfence_init_pool(void)
550 {
551 unsigned long addr = (unsigned long)__kfence_pool;
552 struct page *pages;
553 int i;
554
555 if (!arch_kfence_init_pool())
556 return addr;
557
558 pages = virt_to_page(addr);
559
560 /*
561 * Set up object pages: they must have PG_slab set, to avoid freeing
562 * these as real pages.
563 *
564 * We also want to avoid inserting kfence_free() in the kfree()
565 * fast-path in SLUB, and therefore need to ensure kfree() correctly
566 * enters __slab_free() slow-path.
567 */
568 for (i = 0; i < KFENCE_POOL_SIZE / PAGE_SIZE; i++) {
569 if (!i || (i % 2))
570 continue;
571
572 /* Verify we do not have a compound head page. */
573 if (WARN_ON(compound_head(&pages[i]) != &pages[i]))
574 return addr;
575
576 __SetPageSlab(&pages[i]);
577 }
578
579 /*
580 * Protect the first 2 pages. The first page is mostly unnecessary, and
581 * merely serves as an extended guard page. However, adding one
582 * additional page in the beginning gives us an even number of pages,
583 * which simplifies the mapping of address to metadata index.
584 */
585 for (i = 0; i < 2; i++) {
586 if (unlikely(!kfence_protect(addr)))
587 return addr;
588
589 addr += PAGE_SIZE;
590 }
591
592 for (i = 0; i < CONFIG_KFENCE_NUM_OBJECTS; i++) {
> 593 struct slab *slab = virt_to_slab(addr);
594 struct kfence_metadata *meta = &kfence_metadata[i];
595
596 /* Initialize metadata. */
597 slab->memcg_data = (unsigned long)&meta->objcg | MEMCG_DATA_OBJCGS;
598 INIT_LIST_HEAD(&meta->list);
599 raw_spin_lock_init(&meta->lock);
600 meta->state = KFENCE_OBJECT_UNUSED;
601 meta->addr = addr; /* Initialize for validation in metadata_to_pageaddr(). */
602 list_add_tail(&meta->list, &kfence_freelist);
603
604 /* Protect the right redzone. */
605 if (unlikely(!kfence_protect(addr + PAGE_SIZE)))
606 return addr;
607
608 addr += 2 * PAGE_SIZE;
609 }
610
611 /*
612 * The pool is live and will never be deallocated from this point on.
613 * Remove the pool object from the kmemleak object tree, as it would
614 * otherwise overlap with allocations returned by kfence_alloc(), which
615 * are registered with kmemleak through the slab post-alloc hook.
616 */
617 kmemleak_free(__kfence_pool);
618
619 return 0;
620 }
621
--
0-DAY CI Kernel Test Service
https://01.org/lkp
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH 2/2] mm: kfence: fix objcgs vector allocation
2022-03-27 5:18 ` [PATCH 2/2] mm: kfence: fix objcgs vector allocation Muchun Song
2022-03-27 5:43 ` Muchun Song
2022-03-27 8:07 ` kernel test robot
@ 2022-03-27 8:07 ` kernel test robot
2022-03-27 17:31 ` Marco Elver
3 siblings, 0 replies; 9+ messages in thread
From: kernel test robot @ 2022-03-27 8:07 UTC (permalink / raw)
To: Muchun Song, torvalds, glider, elver, dvyukov, akpm, cl, penberg,
rientjes, iamjoonsoo.kim, vbabka, roman.gushchin
Cc: kbuild-all, kasan-dev, linux-mm, linux-kernel, Muchun Song
Hi Muchun,
Thank you for the patch! Perhaps something to improve:
[auto build test WARNING on hnaz-mm/master]
url: https://github.com/intel-lab-lkp/linux/commits/Muchun-Song/mm-kfence-fix-missing-objcg-housekeeping-for-SLAB/20220327-132038
base: https://github.com/hnaz/linux-mm master
config: x86_64-randconfig-c022 (https://download.01.org/0day-ci/archive/20220327/202203271619.Ni4lY7Mc-lkp@intel.com/config)
compiler: gcc-9 (Ubuntu 9.4.0-1ubuntu1~20.04.1) 9.4.0
reproduce (this is a W=1 build):
# https://github.com/intel-lab-lkp/linux/commit/a33cf78311711db98d9f77541d0a4b50bc466875
git remote add linux-review https://github.com/intel-lab-lkp/linux
git fetch --no-tags linux-review Muchun-Song/mm-kfence-fix-missing-objcg-housekeeping-for-SLAB/20220327-132038
git checkout a33cf78311711db98d9f77541d0a4b50bc466875
# save the config file to linux build tree
mkdir build_dir
make W=1 O=build_dir ARCH=x86_64 SHELL=/bin/bash mm/kfence/
If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>
All warnings (new ones prefixed by >>):
mm/kfence/core.c: In function 'kfence_init_pool':
>> mm/kfence/core.c:593:36: warning: passing argument 1 of 'virt_to_slab' makes pointer from integer without a cast [-Wint-conversion]
593 | struct slab *slab = virt_to_slab(addr);
| ^~~~
| |
| long unsigned int
In file included from mm/kfence/kfence.h:17,
from mm/kfence/core.c:35:
mm/kfence/../slab.h:173:53: note: expected 'const void *' but argument is of type 'long unsigned int'
173 | static inline struct slab *virt_to_slab(const void *addr)
| ~~~~~~~~~~~~^~~~
mm/kfence/core.c:597:7: error: 'struct slab' has no member named 'memcg_data'
597 | slab->memcg_data = (unsigned long)&meta->objcg | MEMCG_DATA_OBJCGS;
| ^~
mm/kfence/core.c:597:52: error: 'MEMCG_DATA_OBJCGS' undeclared (first use in this function)
597 | slab->memcg_data = (unsigned long)&meta->objcg | MEMCG_DATA_OBJCGS;
| ^~~~~~~~~~~~~~~~~
mm/kfence/core.c:597:52: note: each undeclared identifier is reported only once for each function it appears in
vim +/virt_to_slab +593 mm/kfence/core.c
543
544 /*
545 * Initialization of the KFENCE pool after its allocation.
546 * Returns 0 on success; otherwise returns the address up to
547 * which partial initialization succeeded.
548 */
549 static unsigned long kfence_init_pool(void)
550 {
551 unsigned long addr = (unsigned long)__kfence_pool;
552 struct page *pages;
553 int i;
554
555 if (!arch_kfence_init_pool())
556 return addr;
557
558 pages = virt_to_page(addr);
559
560 /*
561 * Set up object pages: they must have PG_slab set, to avoid freeing
562 * these as real pages.
563 *
564 * We also want to avoid inserting kfence_free() in the kfree()
565 * fast-path in SLUB, and therefore need to ensure kfree() correctly
566 * enters __slab_free() slow-path.
567 */
568 for (i = 0; i < KFENCE_POOL_SIZE / PAGE_SIZE; i++) {
569 if (!i || (i % 2))
570 continue;
571
572 /* Verify we do not have a compound head page. */
573 if (WARN_ON(compound_head(&pages[i]) != &pages[i]))
574 return addr;
575
576 __SetPageSlab(&pages[i]);
577 }
578
579 /*
580 * Protect the first 2 pages. The first page is mostly unnecessary, and
581 * merely serves as an extended guard page. However, adding one
582 * additional page in the beginning gives us an even number of pages,
583 * which simplifies the mapping of address to metadata index.
584 */
585 for (i = 0; i < 2; i++) {
586 if (unlikely(!kfence_protect(addr)))
587 return addr;
588
589 addr += PAGE_SIZE;
590 }
591
592 for (i = 0; i < CONFIG_KFENCE_NUM_OBJECTS; i++) {
> 593 struct slab *slab = virt_to_slab(addr);
594 struct kfence_metadata *meta = &kfence_metadata[i];
595
596 /* Initialize metadata. */
597 slab->memcg_data = (unsigned long)&meta->objcg | MEMCG_DATA_OBJCGS;
598 INIT_LIST_HEAD(&meta->list);
599 raw_spin_lock_init(&meta->lock);
600 meta->state = KFENCE_OBJECT_UNUSED;
601 meta->addr = addr; /* Initialize for validation in metadata_to_pageaddr(). */
602 list_add_tail(&meta->list, &kfence_freelist);
603
604 /* Protect the right redzone. */
605 if (unlikely(!kfence_protect(addr + PAGE_SIZE)))
606 return addr;
607
608 addr += 2 * PAGE_SIZE;
609 }
610
611 /*
612 * The pool is live and will never be deallocated from this point on.
613 * Remove the pool object from the kmemleak object tree, as it would
614 * otherwise overlap with allocations returned by kfence_alloc(), which
615 * are registered with kmemleak through the slab post-alloc hook.
616 */
617 kmemleak_free(__kfence_pool);
618
619 return 0;
620 }
621
--
0-DAY CI Kernel Test Service
https://01.org/lkp
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH 2/2] mm: kfence: fix objcgs vector allocation
2022-03-27 5:18 ` [PATCH 2/2] mm: kfence: fix objcgs vector allocation Muchun Song
` (2 preceding siblings ...)
2022-03-27 8:07 ` kernel test robot
@ 2022-03-27 17:31 ` Marco Elver
2022-03-28 1:52 ` Muchun Song
3 siblings, 1 reply; 9+ messages in thread
From: Marco Elver @ 2022-03-27 17:31 UTC (permalink / raw)
To: Muchun Song
Cc: torvalds, glider, dvyukov, akpm, cl, penberg, rientjes,
iamjoonsoo.kim, vbabka, roman.gushchin, kasan-dev, linux-mm,
linux-kernel
On Sun, 27 Mar 2022 at 07:19, Muchun Song <songmuchun@bytedance.com> wrote:
>
> If the kfence object is allocated to be used for objects vector, then
> this slot of the pool eventually being occupied permanently since
> the vector is never freed. The solutions could be 1) freeing vector
> when the kfence object is freed or 2) allocating all vectors statically.
> Since the memory consumption of object vectors is low, it is better to
> chose 2) to fix the issue and it is also can reduce overhead of vectors
> allocating in the future.
>
> Fixes: d3fb45f370d9 ("mm, kfence: insert KFENCE hooks for SLAB")
> Signed-off-by: Muchun Song <songmuchun@bytedance.com>
> ---
> mm/kfence/core.c | 3 +++
> mm/kfence/kfence.h | 1 +
> 2 files changed, 4 insertions(+)
Thanks for this -- mostly looks good. Minor comments below + also
please fix what the test robot reported.
> diff --git a/mm/kfence/core.c b/mm/kfence/core.c
> index 13128fa13062..9976b3f0d097 100644
> --- a/mm/kfence/core.c
> +++ b/mm/kfence/core.c
> @@ -579,9 +579,11 @@ static bool __init kfence_init_pool(void)
> }
>
> for (i = 0; i < CONFIG_KFENCE_NUM_OBJECTS; i++) {
> + struct slab *slab = virt_to_slab(addr);
> struct kfence_metadata *meta = &kfence_metadata[i];
>
> /* Initialize metadata. */
> + slab->memcg_data = (unsigned long)&meta->objcg | MEMCG_DATA_OBJCGS;
Maybe just move it to kfence_guarded_alloc(), see "/* Set required
slab fields */", where similar initialization on slab is done.
> INIT_LIST_HEAD(&meta->list);
> raw_spin_lock_init(&meta->lock);
> meta->state = KFENCE_OBJECT_UNUSED;
> @@ -938,6 +940,7 @@ void __kfence_free(void *addr)
> {
> struct kfence_metadata *meta = addr_to_metadata((unsigned long)addr);
>
> + KFENCE_WARN_ON(meta->objcg);
This holds true for both SLAB and SLUB, right? (I think it does, but
just double-checking.)
> /*
> * If the objects of the cache are SLAB_TYPESAFE_BY_RCU, defer freeing
> * the object, as the object page may be recycled for other-typed
> diff --git a/mm/kfence/kfence.h b/mm/kfence/kfence.h
> index 2a2d5de9d379..6f0e1aece3f8 100644
> --- a/mm/kfence/kfence.h
> +++ b/mm/kfence/kfence.h
> @@ -89,6 +89,7 @@ struct kfence_metadata {
> struct kfence_track free_track;
> /* For updating alloc_covered on frees. */
> u32 alloc_stack_hash;
> + struct obj_cgroup *objcg;
> };
>
> extern struct kfence_metadata kfence_metadata[CONFIG_KFENCE_NUM_OBJECTS];
> --
> 2.11.0
>
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH 1/2] mm: kfence: fix missing objcg housekeeping for SLAB
[not found] ` <CAHk-=wh-mVrp3auBiK2GSMpuqS10Bbq_7fRa6+=zt-0LiF7O2A@mail.gmail.com>
@ 2022-03-28 1:36 ` Muchun Song
0 siblings, 0 replies; 9+ messages in thread
From: Muchun Song @ 2022-03-28 1:36 UTC (permalink / raw)
To: Linus Torvalds
Cc: Alexander Potapenko, Marco Elver, Dmitry Vyukov, Andrew Morton,
Christoph Lameter, Pekka Enberg, David Rientjes, Joonsoo Kim,
Vlastimil Babka, Roman Gushchin, kasan-dev, Linux-MM,
Linux Kernel Mailing List, syzbot
On Mon, Mar 28, 2022 at 5:08 AM Linus Torvalds
<torvalds@linux-foundation.org> wrote:
>
> On Sat, Mar 26, 2022 at 10:19 PM Muchun Song <songmuchun@bytedance.com> wrote:
> >
> > The objcg is not cleared and put for kfence object when it is freed, which
> > could lead to memory leak for struct obj_cgroup and wrong statistics of
> > NR_SLAB_RECLAIMABLE_B or NR_SLAB_UNRECLAIMABLE_B. Since the last freed
> > object's objcg is not cleared, mem_cgroup_from_obj() could return the wrong
> > memcg when this kfence object, which is not charged to any objcgs, is
> > reallocated to other users. A real word issue [1] is caused by this bug.
>
> Good that this looks sorted out.
>
> Patch 2/2 seems to still be up in the air. The patch not only causes
> build errors, but it looks really very odd to me.
>
> In particular, you do that loop with
>
> __SetPageSlab(&pages[i]);
>
> in kfence_init_pool(), but that is *not* where you set the
> MEMCG_DATA_OBJCGS, and instead do that virt_to_slab(addr) dance later.
>
> That looks very odd to me. I think the two should go hand-in-hand,
> since that __SetPageSlab() really is what makes it a slab thing, and I
> think it should go together with setting the slab state correctly.
Right. It is a little odd. I'll improve it in the next version.
>
> Finally, is there a syzbot report for that second problem?
No. The second bug does not trigger any oops, so it is hard to be seen.
It is just my code review.
>
> Anyway, should I apply this PATCH 1/2 now directly as the solution for
> the dentry issue, or should I wait for that second patch? They seem to
> be related only indirectly, in that the problems were both introduced
> by the same commit.
>
I think you could apply PATCH 1/2 now. PATCH 2/2 is another issue not
related to dentry issue.
Thanks.
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH 2/2] mm: kfence: fix objcgs vector allocation
2022-03-27 17:31 ` Marco Elver
@ 2022-03-28 1:52 ` Muchun Song
2022-03-28 7:01 ` Marco Elver
0 siblings, 1 reply; 9+ messages in thread
From: Muchun Song @ 2022-03-28 1:52 UTC (permalink / raw)
To: Marco Elver
Cc: Linus Torvalds, Alexander Potapenko, Dmitry Vyukov,
Andrew Morton, Christoph Lameter, Pekka Enberg, David Rientjes,
Joonsoo Kim, Vlastimil Babka, Roman Gushchin, kasan-dev,
Linux Memory Management List, LKML
On Mon, Mar 28, 2022 at 1:31 AM Marco Elver <elver@google.com> wrote:
>
> On Sun, 27 Mar 2022 at 07:19, Muchun Song <songmuchun@bytedance.com> wrote:
> >
> > If the kfence object is allocated to be used for objects vector, then
> > this slot of the pool eventually being occupied permanently since
> > the vector is never freed. The solutions could be 1) freeing vector
> > when the kfence object is freed or 2) allocating all vectors statically.
> > Since the memory consumption of object vectors is low, it is better to
> > chose 2) to fix the issue and it is also can reduce overhead of vectors
> > allocating in the future.
> >
> > Fixes: d3fb45f370d9 ("mm, kfence: insert KFENCE hooks for SLAB")
> > Signed-off-by: Muchun Song <songmuchun@bytedance.com>
> > ---
> > mm/kfence/core.c | 3 +++
> > mm/kfence/kfence.h | 1 +
> > 2 files changed, 4 insertions(+)
>
> Thanks for this -- mostly looks good. Minor comments below + also
> please fix what the test robot reported.
Will do.
>
> > diff --git a/mm/kfence/core.c b/mm/kfence/core.c
> > index 13128fa13062..9976b3f0d097 100644
> > --- a/mm/kfence/core.c
> > +++ b/mm/kfence/core.c
> > @@ -579,9 +579,11 @@ static bool __init kfence_init_pool(void)
> > }
> >
> > for (i = 0; i < CONFIG_KFENCE_NUM_OBJECTS; i++) {
> > + struct slab *slab = virt_to_slab(addr);
> > struct kfence_metadata *meta = &kfence_metadata[i];
> >
> > /* Initialize metadata. */
> > + slab->memcg_data = (unsigned long)&meta->objcg | MEMCG_DATA_OBJCGS;
>
> Maybe just move it to kfence_guarded_alloc(), see "/* Set required
> slab fields */", where similar initialization on slab is done.
But slab->memcg_data is special since it is only needed to be
initialized once. I think it is better move it to the place where
__SetPageSlab(&pages[i]) is. What do you think?
>
> > INIT_LIST_HEAD(&meta->list);
> > raw_spin_lock_init(&meta->lock);
> > meta->state = KFENCE_OBJECT_UNUSED;
> > @@ -938,6 +940,7 @@ void __kfence_free(void *addr)
> > {
> > struct kfence_metadata *meta = addr_to_metadata((unsigned long)addr);
> >
> > + KFENCE_WARN_ON(meta->objcg);
>
> This holds true for both SLAB and SLUB, right? (I think it does, but
> just double-checking.)
Right.
Thanks.
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH 2/2] mm: kfence: fix objcgs vector allocation
2022-03-28 1:52 ` Muchun Song
@ 2022-03-28 7:01 ` Marco Elver
0 siblings, 0 replies; 9+ messages in thread
From: Marco Elver @ 2022-03-28 7:01 UTC (permalink / raw)
To: Muchun Song
Cc: Linus Torvalds, Alexander Potapenko, Dmitry Vyukov,
Andrew Morton, Christoph Lameter, Pekka Enberg, David Rientjes,
Joonsoo Kim, Vlastimil Babka, Roman Gushchin, kasan-dev,
Linux Memory Management List, LKML
On Mon, 28 Mar 2022 at 03:53, Muchun Song <songmuchun@bytedance.com> wrote:
>
> On Mon, Mar 28, 2022 at 1:31 AM Marco Elver <elver@google.com> wrote:
> >
> > On Sun, 27 Mar 2022 at 07:19, Muchun Song <songmuchun@bytedance.com> wrote:
> > >
> > > If the kfence object is allocated to be used for objects vector, then
> > > this slot of the pool eventually being occupied permanently since
> > > the vector is never freed. The solutions could be 1) freeing vector
> > > when the kfence object is freed or 2) allocating all vectors statically.
> > > Since the memory consumption of object vectors is low, it is better to
> > > chose 2) to fix the issue and it is also can reduce overhead of vectors
> > > allocating in the future.
> > >
> > > Fixes: d3fb45f370d9 ("mm, kfence: insert KFENCE hooks for SLAB")
> > > Signed-off-by: Muchun Song <songmuchun@bytedance.com>
> > > ---
> > > mm/kfence/core.c | 3 +++
> > > mm/kfence/kfence.h | 1 +
> > > 2 files changed, 4 insertions(+)
> >
> > Thanks for this -- mostly looks good. Minor comments below + also
> > please fix what the test robot reported.
>
> Will do.
>
> >
> > > diff --git a/mm/kfence/core.c b/mm/kfence/core.c
> > > index 13128fa13062..9976b3f0d097 100644
> > > --- a/mm/kfence/core.c
> > > +++ b/mm/kfence/core.c
> > > @@ -579,9 +579,11 @@ static bool __init kfence_init_pool(void)
> > > }
> > >
> > > for (i = 0; i < CONFIG_KFENCE_NUM_OBJECTS; i++) {
> > > + struct slab *slab = virt_to_slab(addr);
> > > struct kfence_metadata *meta = &kfence_metadata[i];
> > >
> > > /* Initialize metadata. */
> > > + slab->memcg_data = (unsigned long)&meta->objcg | MEMCG_DATA_OBJCGS;
> >
> > Maybe just move it to kfence_guarded_alloc(), see "/* Set required
> > slab fields */", where similar initialization on slab is done.
>
> But slab->memcg_data is special since it is only needed to be
> initialized once. I think it is better move it to the place where
> __SetPageSlab(&pages[i]) is. What do you think?
That's fair.
^ permalink raw reply [flat|nested] 9+ messages in thread
end of thread, other threads:[~2022-03-28 7:02 UTC | newest]
Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-03-27 5:18 [PATCH 1/2] mm: kfence: fix missing objcg housekeeping for SLAB Muchun Song
2022-03-27 5:18 ` [PATCH 2/2] mm: kfence: fix objcgs vector allocation Muchun Song
2022-03-27 5:43 ` Muchun Song
2022-03-27 8:07 ` kernel test robot
2022-03-27 8:07 ` kernel test robot
2022-03-27 17:31 ` Marco Elver
2022-03-28 1:52 ` Muchun Song
2022-03-28 7:01 ` Marco Elver
[not found] ` <CAHk-=wh-mVrp3auBiK2GSMpuqS10Bbq_7fRa6+=zt-0LiF7O2A@mail.gmail.com>
2022-03-28 1:36 ` [PATCH 1/2] mm: kfence: fix missing objcg housekeeping for SLAB Muchun Song
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox