Skip to content

Commit 3f6f32b

Browse files
Hyesoo Yutehcaster
authored andcommitted
mm: slub: call WARN() when detecting a slab corruption
If a slab object is corrupted or an error occurs in its internal validation, continuing after restoration may cause other side effects. At this point, it is difficult to debug because the problem occurred in the past. It is useful to use WARN() to catch errors at the point of issue because WARN() could trigger panic for system debugging when panic_on_warn is enabled. WARN() is added where to detect the error on slab_err and object_err. It makes sense to only do the WARN() after printing the logs. slab_err is splited to __slab_err that calls the WARN() and it is called after printing logs. Signed-off-by: Hyesoo Yu <[email protected]> Reviewed-by: Harry Yoo <[email protected]> Signed-off-by: Vlastimil Babka <[email protected]>
1 parent ed5ec2e commit 3f6f32b

File tree

1 file changed

+29
-18
lines changed

1 file changed

+29
-18
lines changed

mm/slub.c

Lines changed: 29 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1026,7 +1026,7 @@ static void slab_bug(struct kmem_cache *s, char *fmt, ...)
10261026
vaf.fmt = fmt;
10271027
vaf.va = &args;
10281028
pr_err("=============================================================================\n");
1029-
pr_err("BUG %s (%s): %pV\n", s->name, print_tainted(), &vaf);
1029+
pr_err("BUG %s (%s): %pV\n", s ? s->name : "<unknown>", print_tainted(), &vaf);
10301030
pr_err("-----------------------------------------------------------------------------\n\n");
10311031
va_end(args);
10321032
}
@@ -1085,8 +1085,6 @@ static void print_trailer(struct kmem_cache *s, struct slab *slab, u8 *p)
10851085
/* Beginning of the filler is the free pointer */
10861086
print_section(KERN_ERR, "Padding ", p + off,
10871087
size_from_object(s) - off);
1088-
1089-
dump_stack();
10901088
}
10911089

10921090
static void object_err(struct kmem_cache *s, struct slab *slab,
@@ -1098,6 +1096,8 @@ static void object_err(struct kmem_cache *s, struct slab *slab,
10981096
slab_bug(s, "%s", reason);
10991097
print_trailer(s, slab, object);
11001098
add_taint(TAINT_BAD_PAGE, LOCKDEP_NOW_UNRELIABLE);
1099+
1100+
WARN_ON(1);
11011101
}
11021102

11031103
static bool freelist_corrupted(struct kmem_cache *s, struct slab *slab,
@@ -1114,6 +1114,17 @@ static bool freelist_corrupted(struct kmem_cache *s, struct slab *slab,
11141114
return false;
11151115
}
11161116

1117+
static void __slab_err(struct slab *slab)
1118+
{
1119+
if (slab_in_kunit_test())
1120+
return;
1121+
1122+
print_slab_info(slab);
1123+
add_taint(TAINT_BAD_PAGE, LOCKDEP_NOW_UNRELIABLE);
1124+
1125+
WARN_ON(1);
1126+
}
1127+
11171128
static __printf(3, 4) void slab_err(struct kmem_cache *s, struct slab *slab,
11181129
const char *fmt, ...)
11191130
{
@@ -1127,9 +1138,7 @@ static __printf(3, 4) void slab_err(struct kmem_cache *s, struct slab *slab,
11271138
vsnprintf(buf, sizeof(buf), fmt, args);
11281139
va_end(args);
11291140
slab_bug(s, "%s", buf);
1130-
print_slab_info(slab);
1131-
dump_stack();
1132-
add_taint(TAINT_BAD_PAGE, LOCKDEP_NOW_UNRELIABLE);
1141+
__slab_err(slab);
11331142
}
11341143

11351144
static void init_object(struct kmem_cache *s, void *object, u8 val)
@@ -1302,9 +1311,10 @@ slab_pad_check(struct kmem_cache *s, struct slab *slab)
13021311
while (end > fault && end[-1] == POISON_INUSE)
13031312
end--;
13041313

1305-
slab_err(s, slab, "Padding overwritten. 0x%p-0x%p @offset=%tu",
1306-
fault, end - 1, fault - start);
1314+
slab_bug(s, "Padding overwritten. 0x%p-0x%p @offset=%tu",
1315+
fault, end - 1, fault - start);
13071316
print_section(KERN_ERR, "Padding ", pad, remainder);
1317+
__slab_err(slab);
13081318

13091319
restore_bytes(s, "slab padding", POISON_INUSE, fault, end);
13101320
}
@@ -1620,12 +1630,12 @@ static inline int free_consistency_checks(struct kmem_cache *s,
16201630
slab_err(s, slab, "Attempt to free object(0x%p) outside of slab",
16211631
object);
16221632
} else if (!slab->slab_cache) {
1623-
pr_err("SLUB <none>: no slab for object 0x%p.\n",
1624-
object);
1625-
dump_stack();
1626-
} else
1633+
slab_err(NULL, slab, "No slab cache for object 0x%p",
1634+
object);
1635+
} else {
16271636
object_err(s, slab, object,
1628-
"page slab pointer corrupt.");
1637+
"page slab pointer corrupt.");
1638+
}
16291639
return 0;
16301640
}
16311641
return 1;
@@ -5728,14 +5738,14 @@ static int calculate_sizes(struct kmem_cache_args *args, struct kmem_cache *s)
57285738
return !!oo_objects(s->oo);
57295739
}
57305740

5731-
static void list_slab_objects(struct kmem_cache *s, struct slab *slab,
5732-
const char *text)
5741+
static void list_slab_objects(struct kmem_cache *s, struct slab *slab)
57335742
{
57345743
#ifdef CONFIG_SLUB_DEBUG
57355744
void *addr = slab_address(slab);
57365745
void *p;
57375746

5738-
slab_err(s, slab, text, s->name);
5747+
if (!slab_add_kunit_errors())
5748+
slab_bug(s, "Objects remaining on __kmem_cache_shutdown()");
57395749

57405750
spin_lock(&object_map_lock);
57415751
__fill_map(object_map, s, slab);
@@ -5750,6 +5760,8 @@ static void list_slab_objects(struct kmem_cache *s, struct slab *slab,
57505760
}
57515761
}
57525762
spin_unlock(&object_map_lock);
5763+
5764+
__slab_err(slab);
57535765
#endif
57545766
}
57555767

@@ -5770,8 +5782,7 @@ static void free_partial(struct kmem_cache *s, struct kmem_cache_node *n)
57705782
remove_partial(n, slab);
57715783
list_add(&slab->slab_list, &discard);
57725784
} else {
5773-
list_slab_objects(s, slab,
5774-
"Objects remaining in %s on __kmem_cache_shutdown()");
5785+
list_slab_objects(s, slab);
57755786
}
57765787
}
57775788
spin_unlock_irq(&n->list_lock);

0 commit comments

Comments
 (0)