diff --git a/drivers/mtd/ubi/attach.c b/drivers/mtd/ubi/attach.c index ae5abe492b52..3694fd52c530 100644 --- a/drivers/mtd/ubi/attach.c +++ b/drivers/mtd/ubi/attach.c @@ -1447,6 +1447,7 @@ static int scan_all(struct ubi_device *ubi, struct ubi_attach_info *ai, return err; } +extern int g_inject; static struct ubi_attach_info *alloc_ai(void) { struct ubi_attach_info *ai; @@ -1461,9 +1462,11 @@ static struct ubi_attach_info *alloc_ai(void) INIT_LIST_HEAD(&ai->alien); INIT_LIST_HEAD(&ai->fastmap); ai->volumes = RB_ROOT; + g_inject = 1; ai->aeb_slab_cache = kmem_cache_create("ubi_aeb_slab_cache", sizeof(struct ubi_ainf_peb), 0, 0, NULL); + g_inject = 0; if (!ai->aeb_slab_cache) { kfree(ai); ai = NULL; diff --git a/lib/kobject.c b/lib/kobject.c index 59dbcbdb1c91..37da8b767557 100644 --- a/lib/kobject.c +++ b/lib/kobject.c @@ -204,7 +204,8 @@ static void kobject_init_internal(struct kobject *kobj) kobj->state_initialized = 1; } - +struct kobject *g_k; +int g_inject; static int kobject_add_internal(struct kobject *kobj) { int error = 0; @@ -235,6 +236,13 @@ static int kobject_add_internal(struct kobject *kobj) parent ? kobject_name(parent) : "", kobj->kset ? kobject_name(&kobj->kset->kobj) : ""); + if (g_inject) { + error = -ENOMEM; // Simulate failure in create_dir->sysfs_create_dir_ns->kernfs_create_dir_ns->kernfs_new_node->__kernfs_new_node-->kmem_cache_zalloc->slab_alloc_node->slab_pre_alloc_hook->should_failslab + g_k = kobj; + pr_err("inject failure, kobj ref %d\n", refcount_read(&kobj->kref.refcount)); + smp_wmb(); + } else + error = create_dir(kobj); if (error) { kobj_kset_leave(kobj); @@ -685,6 +693,12 @@ static void kobject_cleanup(struct kobject *kobj) kobject_name(kobj), kobj); } + smp_rmb(); + if (g_k == kobj) { + pr_err("free name %s\n", name); + dump_stack(); + } + /* free name if we allocated it */ if (name) { pr_debug("'%s': free name\n", name); diff --git a/mm/slab_common.c b/mm/slab_common.c index 238293b1dbe1..c76277004bd0 100644 --- a/mm/slab_common.c +++ b/mm/slab_common.c @@ -158,10 +158,12 @@ int slab_unmergeable(struct kmem_cache *s) return 0; } +extern int g_inject; struct kmem_cache *find_mergeable(unsigned int size, unsigned int align, slab_flags_t flags, const char *name, void (*ctor)(void *)) { struct kmem_cache *s; + static int enter = 0; if (slab_nomerge) return NULL; @@ -184,6 +186,11 @@ struct kmem_cache *find_mergeable(unsigned int size, unsigned int align, if (size > s->size) continue; + if (g_inject && !enter) { + enter = 1; + break; + } + if ((flags & SLAB_MERGE_SAME) != (s->flags & SLAB_MERGE_SAME)) continue; /*