Message ID | 20240125094815.2041933-2-elver@google.com (mailing list archive) |
---|---|
State | New |
Headers | show |
Series | [1/2] stackdepot: use variable size records for non-evictable entries | expand |
On Thu, Jan 25, 2024 at 10:48 AM Marco Elver <elver@google.com> wrote: > > This partially reverts commits cc478e0b6bdf, 63b85ac56a64, 08d7c94d9635, > a414d4286f34, and 773688a6cb24 to make use of variable-sized stack depot > records, since eviction of stack entries from stack depot forces fixed- > sized stack records. Care was taken to retain the code cleanups by the > above commits. > > Eviction was added to generic KASAN as a response to alleviating the > additional memory usage from fixed-sized stack records, but this still > uses more memory than previously. > > With the re-introduction of variable-sized records for stack depot, we > can just switch back to non-evictable stack records again, and return > back to the previous performance and memory usage baseline. > > Before (observed after a KASAN kernel boot): > > pools: 597 > allocations: 29657 > frees: 6425 > in_use: 23232 > freelist_size: 3493 > > After: > > pools: 315 > allocations: 28964 > frees: 0 > in_use: 28964 > freelist_size: 0 > > As can be seen from the number of "frees", with a generic KASAN config, > evictions are no longer used but due to using variable-sized records, I > observe a reduction of 282 stack depot pools (saving 4512 KiB) with my > test setup. > > Fixes: cc478e0b6bdf ("kasan: avoid resetting aux_lock") > Fixes: 63b85ac56a64 ("kasan: stop leaking stack trace handles") > Fixes: 08d7c94d9635 ("kasan: memset free track in qlink_free") > Fixes: a414d4286f34 ("kasan: handle concurrent kasan_record_aux_stack calls") > Fixes: 773688a6cb24 ("kasan: use stack_depot_put for Generic mode") > Signed-off-by: Marco Elver <elver@google.com> > Cc: Alexander Potapenko <glider@google.com> > Cc: Andrey Konovalov <andreyknvl@gmail.com> > Cc: Dmitry Vyukov <dvyukov@google.com> > --- > mm/kasan/common.c | 3 +-- > mm/kasan/generic.c | 54 ++++++---------------------------------------- > mm/kasan/kasan.h | 8 ------- > 3 files changed, 8 insertions(+), 57 deletions(-) > > diff --git a/mm/kasan/common.c b/mm/kasan/common.c > index 610efae91220..ad32803e34e9 100644 > --- a/mm/kasan/common.c > +++ b/mm/kasan/common.c > @@ -65,8 +65,7 @@ void kasan_save_track(struct kasan_track *track, gfp_t flags) > { > depot_stack_handle_t stack; > > - stack = kasan_save_stack(flags, > - STACK_DEPOT_FLAG_CAN_ALLOC | STACK_DEPOT_FLAG_GET); > + stack = kasan_save_stack(flags, STACK_DEPOT_FLAG_CAN_ALLOC); > kasan_set_track(track, stack); > } > > diff --git a/mm/kasan/generic.c b/mm/kasan/generic.c > index df6627f62402..8bfb52b28c22 100644 > --- a/mm/kasan/generic.c > +++ b/mm/kasan/generic.c > @@ -485,16 +485,6 @@ void kasan_init_object_meta(struct kmem_cache *cache, const void *object) > if (alloc_meta) { > /* Zero out alloc meta to mark it as invalid. */ > __memset(alloc_meta, 0, sizeof(*alloc_meta)); > - > - /* > - * Prepare the lock for saving auxiliary stack traces. > - * Temporarily disable KASAN bug reporting to allow instrumented > - * raw_spin_lock_init to access aux_lock, which resides inside > - * of a redzone. > - */ > - kasan_disable_current(); > - raw_spin_lock_init(&alloc_meta->aux_lock); > - kasan_enable_current(); > } > > /* > @@ -506,18 +496,8 @@ void kasan_init_object_meta(struct kmem_cache *cache, const void *object) > > static void release_alloc_meta(struct kasan_alloc_meta *meta) > { > - /* Evict the stack traces from stack depot. */ > - stack_depot_put(meta->alloc_track.stack); > - stack_depot_put(meta->aux_stack[0]); > - stack_depot_put(meta->aux_stack[1]); > - > - /* > - * Zero out alloc meta to mark it as invalid but keep aux_lock > - * initialized to avoid having to reinitialize it when another object > - * is allocated in the same slot. > - */ > - __memset(&meta->alloc_track, 0, sizeof(meta->alloc_track)); > - __memset(meta->aux_stack, 0, sizeof(meta->aux_stack)); > + /* Zero out alloc meta to mark it as invalid. */ > + __memset(meta, 0, sizeof(*meta)); > } > > static void release_free_meta(const void *object, struct kasan_free_meta *meta) > @@ -526,9 +506,6 @@ static void release_free_meta(const void *object, struct kasan_free_meta *meta) > if (*(u8 *)kasan_mem_to_shadow(object) != KASAN_SLAB_FREE_META) > return; > > - /* Evict the stack trace from the stack depot. */ > - stack_depot_put(meta->free_track.stack); > - > /* Mark free meta as invalid. */ > *(u8 *)kasan_mem_to_shadow(object) = KASAN_SLAB_FREE; > } > @@ -571,8 +548,6 @@ static void __kasan_record_aux_stack(void *addr, depot_flags_t depot_flags) > struct kmem_cache *cache; > struct kasan_alloc_meta *alloc_meta; > void *object; > - depot_stack_handle_t new_handle, old_handle; > - unsigned long flags; > > if (is_kfence_address(addr) || !slab) > return; > @@ -583,33 +558,18 @@ static void __kasan_record_aux_stack(void *addr, depot_flags_t depot_flags) > if (!alloc_meta) > return; > > - new_handle = kasan_save_stack(0, depot_flags); > - > - /* > - * Temporarily disable KASAN bug reporting to allow instrumented > - * spinlock functions to access aux_lock, which resides inside of a > - * redzone. > - */ > - kasan_disable_current(); > - raw_spin_lock_irqsave(&alloc_meta->aux_lock, flags); > - old_handle = alloc_meta->aux_stack[1]; > alloc_meta->aux_stack[1] = alloc_meta->aux_stack[0]; > - alloc_meta->aux_stack[0] = new_handle; > - raw_spin_unlock_irqrestore(&alloc_meta->aux_lock, flags); > - kasan_enable_current(); > - > - stack_depot_put(old_handle); > + alloc_meta->aux_stack[0] = kasan_save_stack(0, depot_flags); > } > > void kasan_record_aux_stack(void *addr) > { > - return __kasan_record_aux_stack(addr, > - STACK_DEPOT_FLAG_CAN_ALLOC | STACK_DEPOT_FLAG_GET); > + return __kasan_record_aux_stack(addr, STACK_DEPOT_FLAG_CAN_ALLOC); > } > > void kasan_record_aux_stack_noalloc(void *addr) > { > - return __kasan_record_aux_stack(addr, STACK_DEPOT_FLAG_GET); > + return __kasan_record_aux_stack(addr, 0); > } > > void kasan_save_alloc_info(struct kmem_cache *cache, void *object, gfp_t flags) > @@ -620,7 +580,7 @@ void kasan_save_alloc_info(struct kmem_cache *cache, void *object, gfp_t flags) > if (!alloc_meta) > return; > > - /* Evict previous stack traces (might exist for krealloc or mempool). */ > + /* Invalidate previous stack traces (might exist for krealloc or mempool). */ > release_alloc_meta(alloc_meta); > > kasan_save_track(&alloc_meta->alloc_track, flags); > @@ -634,7 +594,7 @@ void kasan_save_free_info(struct kmem_cache *cache, void *object) > if (!free_meta) > return; > > - /* Evict previous stack trace (might exist for mempool). */ > + /* Invalidate previous stack trace (might exist for mempool). */ > release_free_meta(object, free_meta); > > kasan_save_track(&free_meta->free_track, 0); > diff --git a/mm/kasan/kasan.h b/mm/kasan/kasan.h > index d0f172f2b978..216ae0ef1e4b 100644 > --- a/mm/kasan/kasan.h > +++ b/mm/kasan/kasan.h > @@ -6,7 +6,6 @@ > #include <linux/kasan.h> > #include <linux/kasan-tags.h> > #include <linux/kfence.h> > -#include <linux/spinlock.h> > #include <linux/stackdepot.h> > > #if defined(CONFIG_KASAN_SW_TAGS) || defined(CONFIG_KASAN_HW_TAGS) > @@ -265,13 +264,6 @@ struct kasan_global { > struct kasan_alloc_meta { > struct kasan_track alloc_track; > /* Free track is stored in kasan_free_meta. */ > - /* > - * aux_lock protects aux_stack from accesses from concurrent > - * kasan_record_aux_stack calls. It is a raw spinlock to avoid sleeping > - * on RT kernels, as kasan_record_aux_stack_noalloc can be called from > - * non-sleepable contexts. > - */ > - raw_spinlock_t aux_lock; > depot_stack_handle_t aux_stack[2]; > }; > > -- > 2.43.0.429.g432eaa2c6b-goog > Reviewed-by: Andrey Konovalov <andreyknvl@gmail.com> But I'm wondering if we should also stop resetting metadata when the object is fully freed (from quarantine or bypassing quarantine). With stack_depot_put, I had to put the stack handles on free, as otherwise we would leak the stack depot references. And I also chose to memset meta at that point, as its gets invalid anyway. But without stack_depot_put, this is not required. Before the stack depot-related changes, the code was inconsistent in this regard AFAICS: for quarantine, free meta was marked as invalid via KASAN_SLAB_FREE but alloc meta was kept; for no quarantine, both alloc and free meta were kept. So perhaps we can just keep both metas on full free. I.e. drop both kasan_release_object_meta calls. This will go back to the old behavior + keeping free meta for the quarantine case (I think there's no harm in that). This will give better reporting for uaf-before-realloc bugs. WDYT?
On Thu, Jan 25, 2024 at 11:36PM +0100, Andrey Konovalov wrote: [...] > > Reviewed-by: Andrey Konovalov <andreyknvl@gmail.com> > > But I'm wondering if we should also stop resetting metadata when the > object is fully freed (from quarantine or bypassing quarantine). > > With stack_depot_put, I had to put the stack handles on free, as > otherwise we would leak the stack depot references. And I also chose > to memset meta at that point, as its gets invalid anyway. But without > stack_depot_put, this is not required. > > Before the stack depot-related changes, the code was inconsistent in > this regard AFAICS: for quarantine, free meta was marked as invalid > via KASAN_SLAB_FREE but alloc meta was kept; for no quarantine, both > alloc and free meta were kept. > > So perhaps we can just keep both metas on full free. I.e. drop both > kasan_release_object_meta calls. This will go back to the old behavior > + keeping free meta for the quarantine case (I think there's no harm > in that). This will give better reporting for uaf-before-realloc bugs. > > WDYT? Yes, that makes sense. You mean this on top? diff --git a/mm/kasan/common.c b/mm/kasan/common.c index ad32803e34e9..0577db1d2c62 100644 --- a/mm/kasan/common.c +++ b/mm/kasan/common.c @@ -264,12 +264,6 @@ bool __kasan_slab_free(struct kmem_cache *cache, void *object, if (kasan_quarantine_put(cache, object)) return true; - /* - * If the object is not put into quarantine, it will likely be quickly - * reallocated. Thus, release its metadata now. - */ - kasan_release_object_meta(cache, object); - /* Let slab put the object onto the freelist. */ return false; } diff --git a/mm/kasan/generic.c b/mm/kasan/generic.c index 8bfb52b28c22..fc9cf1860efb 100644 --- a/mm/kasan/generic.c +++ b/mm/kasan/generic.c @@ -510,20 +510,6 @@ static void release_free_meta(const void *object, struct kasan_free_meta *meta) *(u8 *)kasan_mem_to_shadow(object) = KASAN_SLAB_FREE; } -void kasan_release_object_meta(struct kmem_cache *cache, const void *object) -{ - struct kasan_alloc_meta *alloc_meta; - struct kasan_free_meta *free_meta; - - alloc_meta = kasan_get_alloc_meta(cache, object); - if (alloc_meta) - release_alloc_meta(alloc_meta); - - free_meta = kasan_get_free_meta(cache, object); - if (free_meta) - release_free_meta(object, free_meta); -} - size_t kasan_metadata_size(struct kmem_cache *cache, bool in_object) { struct kasan_cache *info = &cache->kasan_info; diff --git a/mm/kasan/kasan.h b/mm/kasan/kasan.h index 216ae0ef1e4b..fb2b9ac0659a 100644 --- a/mm/kasan/kasan.h +++ b/mm/kasan/kasan.h @@ -390,10 +390,8 @@ struct kasan_alloc_meta *kasan_get_alloc_meta(struct kmem_cache *cache, struct kasan_free_meta *kasan_get_free_meta(struct kmem_cache *cache, const void *object); void kasan_init_object_meta(struct kmem_cache *cache, const void *object); -void kasan_release_object_meta(struct kmem_cache *cache, const void *object); #else static inline void kasan_init_object_meta(struct kmem_cache *cache, const void *object) { } -static inline void kasan_release_object_meta(struct kmem_cache *cache, const void *object) { } #endif depot_stack_handle_t kasan_save_stack(gfp_t flags, depot_flags_t depot_flags); diff --git a/mm/kasan/quarantine.c b/mm/kasan/quarantine.c index 3ba02efb952a..a758c2e10703 100644 --- a/mm/kasan/quarantine.c +++ b/mm/kasan/quarantine.c @@ -145,8 +145,6 @@ static void qlink_free(struct qlist_node *qlink, struct kmem_cache *cache) void *object = qlink_to_object(qlink, cache); struct kasan_free_meta *free_meta = kasan_get_free_meta(cache, object); - kasan_release_object_meta(cache, object); - /* * If init_on_free is enabled and KASAN's free metadata is stored in * the object, zero the metadata. Otherwise, the object's memory will
On Fri, Jan 26, 2024 at 3:44 PM Marco Elver <elver@google.com> wrote: > > On Thu, Jan 25, 2024 at 11:36PM +0100, Andrey Konovalov wrote: > [...] > > > > Reviewed-by: Andrey Konovalov <andreyknvl@gmail.com> > > > > But I'm wondering if we should also stop resetting metadata when the > > object is fully freed (from quarantine or bypassing quarantine). > > > > With stack_depot_put, I had to put the stack handles on free, as > > otherwise we would leak the stack depot references. And I also chose > > to memset meta at that point, as its gets invalid anyway. But without > > stack_depot_put, this is not required. > > > > Before the stack depot-related changes, the code was inconsistent in > > this regard AFAICS: for quarantine, free meta was marked as invalid > > via KASAN_SLAB_FREE but alloc meta was kept; for no quarantine, both > > alloc and free meta were kept. > > > > So perhaps we can just keep both metas on full free. I.e. drop both > > kasan_release_object_meta calls. This will go back to the old behavior > > + keeping free meta for the quarantine case (I think there's no harm > > in that). This will give better reporting for uaf-before-realloc bugs. > > > > WDYT? > > Yes, that makes sense. > > You mean this on top? > > diff --git a/mm/kasan/common.c b/mm/kasan/common.c > index ad32803e34e9..0577db1d2c62 100644 > --- a/mm/kasan/common.c > +++ b/mm/kasan/common.c > @@ -264,12 +264,6 @@ bool __kasan_slab_free(struct kmem_cache *cache, void *object, > if (kasan_quarantine_put(cache, object)) > return true; > > - /* > - * If the object is not put into quarantine, it will likely be quickly > - * reallocated. Thus, release its metadata now. > - */ > - kasan_release_object_meta(cache, object); > - > /* Let slab put the object onto the freelist. */ > return false; > } > diff --git a/mm/kasan/generic.c b/mm/kasan/generic.c > index 8bfb52b28c22..fc9cf1860efb 100644 > --- a/mm/kasan/generic.c > +++ b/mm/kasan/generic.c > @@ -510,20 +510,6 @@ static void release_free_meta(const void *object, struct kasan_free_meta *meta) > *(u8 *)kasan_mem_to_shadow(object) = KASAN_SLAB_FREE; > } > > -void kasan_release_object_meta(struct kmem_cache *cache, const void *object) > -{ > - struct kasan_alloc_meta *alloc_meta; > - struct kasan_free_meta *free_meta; > - > - alloc_meta = kasan_get_alloc_meta(cache, object); > - if (alloc_meta) > - release_alloc_meta(alloc_meta); > - > - free_meta = kasan_get_free_meta(cache, object); > - if (free_meta) > - release_free_meta(object, free_meta); > -} > - > size_t kasan_metadata_size(struct kmem_cache *cache, bool in_object) > { > struct kasan_cache *info = &cache->kasan_info; > diff --git a/mm/kasan/kasan.h b/mm/kasan/kasan.h > index 216ae0ef1e4b..fb2b9ac0659a 100644 > --- a/mm/kasan/kasan.h > +++ b/mm/kasan/kasan.h > @@ -390,10 +390,8 @@ struct kasan_alloc_meta *kasan_get_alloc_meta(struct kmem_cache *cache, > struct kasan_free_meta *kasan_get_free_meta(struct kmem_cache *cache, > const void *object); > void kasan_init_object_meta(struct kmem_cache *cache, const void *object); > -void kasan_release_object_meta(struct kmem_cache *cache, const void *object); > #else > static inline void kasan_init_object_meta(struct kmem_cache *cache, const void *object) { } > -static inline void kasan_release_object_meta(struct kmem_cache *cache, const void *object) { } > #endif > > depot_stack_handle_t kasan_save_stack(gfp_t flags, depot_flags_t depot_flags); > diff --git a/mm/kasan/quarantine.c b/mm/kasan/quarantine.c > index 3ba02efb952a..a758c2e10703 100644 > --- a/mm/kasan/quarantine.c > +++ b/mm/kasan/quarantine.c > @@ -145,8 +145,6 @@ static void qlink_free(struct qlist_node *qlink, struct kmem_cache *cache) > void *object = qlink_to_object(qlink, cache); > struct kasan_free_meta *free_meta = kasan_get_free_meta(cache, object); > > - kasan_release_object_meta(cache, object); > - > /* > * If init_on_free is enabled and KASAN's free metadata is stored in > * the object, zero the metadata. Otherwise, the object's memory will Please also add a comment saying something like "Keep per-object metadata to allow KASAN print stack traces for use-after-free-before-realloc bugs." to the places where you removed kasan_release_object_meta. Otherwise, looks good to me.
diff --git a/mm/kasan/common.c b/mm/kasan/common.c index 610efae91220..ad32803e34e9 100644 --- a/mm/kasan/common.c +++ b/mm/kasan/common.c @@ -65,8 +65,7 @@ void kasan_save_track(struct kasan_track *track, gfp_t flags) { depot_stack_handle_t stack; - stack = kasan_save_stack(flags, - STACK_DEPOT_FLAG_CAN_ALLOC | STACK_DEPOT_FLAG_GET); + stack = kasan_save_stack(flags, STACK_DEPOT_FLAG_CAN_ALLOC); kasan_set_track(track, stack); } diff --git a/mm/kasan/generic.c b/mm/kasan/generic.c index df6627f62402..8bfb52b28c22 100644 --- a/mm/kasan/generic.c +++ b/mm/kasan/generic.c @@ -485,16 +485,6 @@ void kasan_init_object_meta(struct kmem_cache *cache, const void *object) if (alloc_meta) { /* Zero out alloc meta to mark it as invalid. */ __memset(alloc_meta, 0, sizeof(*alloc_meta)); - - /* - * Prepare the lock for saving auxiliary stack traces. - * Temporarily disable KASAN bug reporting to allow instrumented - * raw_spin_lock_init to access aux_lock, which resides inside - * of a redzone. - */ - kasan_disable_current(); - raw_spin_lock_init(&alloc_meta->aux_lock); - kasan_enable_current(); } /* @@ -506,18 +496,8 @@ void kasan_init_object_meta(struct kmem_cache *cache, const void *object) static void release_alloc_meta(struct kasan_alloc_meta *meta) { - /* Evict the stack traces from stack depot. */ - stack_depot_put(meta->alloc_track.stack); - stack_depot_put(meta->aux_stack[0]); - stack_depot_put(meta->aux_stack[1]); - - /* - * Zero out alloc meta to mark it as invalid but keep aux_lock - * initialized to avoid having to reinitialize it when another object - * is allocated in the same slot. - */ - __memset(&meta->alloc_track, 0, sizeof(meta->alloc_track)); - __memset(meta->aux_stack, 0, sizeof(meta->aux_stack)); + /* Zero out alloc meta to mark it as invalid. */ + __memset(meta, 0, sizeof(*meta)); } static void release_free_meta(const void *object, struct kasan_free_meta *meta) @@ -526,9 +506,6 @@ static void release_free_meta(const void *object, struct kasan_free_meta *meta) if (*(u8 *)kasan_mem_to_shadow(object) != KASAN_SLAB_FREE_META) return; - /* Evict the stack trace from the stack depot. */ - stack_depot_put(meta->free_track.stack); - /* Mark free meta as invalid. */ *(u8 *)kasan_mem_to_shadow(object) = KASAN_SLAB_FREE; } @@ -571,8 +548,6 @@ static void __kasan_record_aux_stack(void *addr, depot_flags_t depot_flags) struct kmem_cache *cache; struct kasan_alloc_meta *alloc_meta; void *object; - depot_stack_handle_t new_handle, old_handle; - unsigned long flags; if (is_kfence_address(addr) || !slab) return; @@ -583,33 +558,18 @@ static void __kasan_record_aux_stack(void *addr, depot_flags_t depot_flags) if (!alloc_meta) return; - new_handle = kasan_save_stack(0, depot_flags); - - /* - * Temporarily disable KASAN bug reporting to allow instrumented - * spinlock functions to access aux_lock, which resides inside of a - * redzone. - */ - kasan_disable_current(); - raw_spin_lock_irqsave(&alloc_meta->aux_lock, flags); - old_handle = alloc_meta->aux_stack[1]; alloc_meta->aux_stack[1] = alloc_meta->aux_stack[0]; - alloc_meta->aux_stack[0] = new_handle; - raw_spin_unlock_irqrestore(&alloc_meta->aux_lock, flags); - kasan_enable_current(); - - stack_depot_put(old_handle); + alloc_meta->aux_stack[0] = kasan_save_stack(0, depot_flags); } void kasan_record_aux_stack(void *addr) { - return __kasan_record_aux_stack(addr, - STACK_DEPOT_FLAG_CAN_ALLOC | STACK_DEPOT_FLAG_GET); + return __kasan_record_aux_stack(addr, STACK_DEPOT_FLAG_CAN_ALLOC); } void kasan_record_aux_stack_noalloc(void *addr) { - return __kasan_record_aux_stack(addr, STACK_DEPOT_FLAG_GET); + return __kasan_record_aux_stack(addr, 0); } void kasan_save_alloc_info(struct kmem_cache *cache, void *object, gfp_t flags) @@ -620,7 +580,7 @@ void kasan_save_alloc_info(struct kmem_cache *cache, void *object, gfp_t flags) if (!alloc_meta) return; - /* Evict previous stack traces (might exist for krealloc or mempool). */ + /* Invalidate previous stack traces (might exist for krealloc or mempool). */ release_alloc_meta(alloc_meta); kasan_save_track(&alloc_meta->alloc_track, flags); @@ -634,7 +594,7 @@ void kasan_save_free_info(struct kmem_cache *cache, void *object) if (!free_meta) return; - /* Evict previous stack trace (might exist for mempool). */ + /* Invalidate previous stack trace (might exist for mempool). */ release_free_meta(object, free_meta); kasan_save_track(&free_meta->free_track, 0); diff --git a/mm/kasan/kasan.h b/mm/kasan/kasan.h index d0f172f2b978..216ae0ef1e4b 100644 --- a/mm/kasan/kasan.h +++ b/mm/kasan/kasan.h @@ -6,7 +6,6 @@ #include <linux/kasan.h> #include <linux/kasan-tags.h> #include <linux/kfence.h> -#include <linux/spinlock.h> #include <linux/stackdepot.h> #if defined(CONFIG_KASAN_SW_TAGS) || defined(CONFIG_KASAN_HW_TAGS) @@ -265,13 +264,6 @@ struct kasan_global { struct kasan_alloc_meta { struct kasan_track alloc_track; /* Free track is stored in kasan_free_meta. */ - /* - * aux_lock protects aux_stack from accesses from concurrent - * kasan_record_aux_stack calls. It is a raw spinlock to avoid sleeping - * on RT kernels, as kasan_record_aux_stack_noalloc can be called from - * non-sleepable contexts. - */ - raw_spinlock_t aux_lock; depot_stack_handle_t aux_stack[2]; };
This partially reverts commits cc478e0b6bdf, 63b85ac56a64, 08d7c94d9635, a414d4286f34, and 773688a6cb24 to make use of variable-sized stack depot records, since eviction of stack entries from stack depot forces fixed- sized stack records. Care was taken to retain the code cleanups by the above commits. Eviction was added to generic KASAN as a response to alleviating the additional memory usage from fixed-sized stack records, but this still uses more memory than previously. With the re-introduction of variable-sized records for stack depot, we can just switch back to non-evictable stack records again, and return back to the previous performance and memory usage baseline. Before (observed after a KASAN kernel boot): pools: 597 allocations: 29657 frees: 6425 in_use: 23232 freelist_size: 3493 After: pools: 315 allocations: 28964 frees: 0 in_use: 28964 freelist_size: 0 As can be seen from the number of "frees", with a generic KASAN config, evictions are no longer used but due to using variable-sized records, I observe a reduction of 282 stack depot pools (saving 4512 KiB) with my test setup. Fixes: cc478e0b6bdf ("kasan: avoid resetting aux_lock") Fixes: 63b85ac56a64 ("kasan: stop leaking stack trace handles") Fixes: 08d7c94d9635 ("kasan: memset free track in qlink_free") Fixes: a414d4286f34 ("kasan: handle concurrent kasan_record_aux_stack calls") Fixes: 773688a6cb24 ("kasan: use stack_depot_put for Generic mode") Signed-off-by: Marco Elver <elver@google.com> Cc: Alexander Potapenko <glider@google.com> Cc: Andrey Konovalov <andreyknvl@gmail.com> Cc: Dmitry Vyukov <dvyukov@google.com> --- mm/kasan/common.c | 3 +-- mm/kasan/generic.c | 54 ++++++---------------------------------------- mm/kasan/kasan.h | 8 ------- 3 files changed, 8 insertions(+), 57 deletions(-)