if (WARN_ON((unsigned long)addr & KASAN_GRANULE_MASK))
                return;
-       /*
-        * Explicitly initialize the memory with the precise object size to
-        * avoid overwriting the slab redzone. This disables initialization in
-        * the arch code and may thus lead to performance penalty. This penalty
-        * does not affect production builds, as slab redzones are not enabled
-        * there.
-        */
-       if (__slub_debug_enabled() &&
-           init && ((unsigned long)size & KASAN_GRANULE_MASK)) {
-               init = false;
-               memzero_explicit((void *)addr, size);
-       }
        size = round_up(size, KASAN_GRANULE_SIZE);
 
        hw_set_mem_tag_range((void *)addr, size, tag, init);
 
                                        unsigned int orig_size)
 {
        unsigned int zero_size = s->object_size;
+       bool kasan_init = init;
        size_t i;
 
        flags &= gfp_allowed_mask;
            (s->flags & SLAB_KMALLOC))
                zero_size = orig_size;
 
+       /*
+        * When slub_debug is enabled, avoid memory initialization integrated
+        * into KASAN and instead zero out the memory via the memset below with
+        * the proper size. Otherwise, KASAN might overwrite SLUB redzones and
+        * cause false-positive reports. This does not lead to a performance
+        * penalty on production builds, as slub_debug is not intended to be
+        * enabled there.
+        */
+       if (__slub_debug_enabled())
+               kasan_init = false;
+
        /*
         * As memory initialization might be integrated into KASAN,
         * kasan_slab_alloc and initialization memset must be
         * As p[i] might get tagged, memset and kmemleak hook come after KASAN.
         */
        for (i = 0; i < size; i++) {
-               p[i] = kasan_slab_alloc(s, p[i], flags, init);
-               if (p[i] && init && !kasan_has_integrated_init())
+               p[i] = kasan_slab_alloc(s, p[i], flags, kasan_init);
+               if (p[i] && init && (!kasan_init || !kasan_has_integrated_init()))
                        memset(p[i], 0, zero_size);
                kmemleak_alloc_recursive(p[i], s->object_size, 1,
                                         s->flags, flags);