diff options
| author | Greg Kroah-Hartman <gregkh@suse.de> | 2007-12-19 11:35:35 -0800 |
|---|---|---|
| committer | Greg Kroah-Hartman <gregkh@suse.de> | 2007-12-19 11:35:35 -0800 |
| commit | e30d51d7cb7a0c13fe80c8f82328d4cad79207a5 (patch) | |
| tree | bd263af98ff6c1f98e33e594b47faa607999b410 /driver | |
| parent | ac5bb415ab5d05ade598b44367d040526ef4967c (diff) | |
| download | patches-e30d51d7cb7a0c13fe80c8f82328d4cad79207a5.tar.gz | |
more kobject fun...
Diffstat (limited to 'driver')
6 files changed, 607 insertions, 37 deletions
diff --git a/driver/kobject-auto-cleanup-on-final-unref.patch b/driver/kobject-auto-cleanup-on-final-unref.patch new file mode 100644 index 00000000000000..90dee5443b1bf5 --- /dev/null +++ b/driver/kobject-auto-cleanup-on-final-unref.patch @@ -0,0 +1,408 @@ +From kay.sievers@vrfy.org Tue Dec 18 13:41:53 2007 +From: Kay Sievers <kay.sievers@vrfy.org> +Date: Wed, 19 Dec 2007 01:40:42 +0100 +Subject: Kobject: auto-cleanup on final unref +Message-ID: <1197993016.2798.1.camel@lov.site> + + +We save the current state in the object itself, so we can do proper +cleanup when the last reference is dropped. + +If the initial reference is dropped, the object will be removed from +sysfs if needed, if an "add" event was sent, "remove" will be send, and +the allocated resources are released. + +This allows us to clean up some driver core usage as well as allowing us +to do other such changes to the rest of the kernel. + +Signed-off-by: Kay Sievers <kay.sievers@vrfy.org> +Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> + +--- + drivers/base/core.c | 32 +-------- + include/linux/kobject.h | 5 + + lib/kobject.c | 169 ++++++++++++++++++++++++++---------------------- + lib/kobject_uevent.c | 11 +++ + 4 files changed, 118 insertions(+), 99 deletions(-) + +--- a/drivers/base/core.c ++++ b/drivers/base/core.c +@@ -576,8 +576,8 @@ static struct kobject *get_device_parent + + /* + * If we have no parent, we live in "virtual". +- * Class-devices with a bus-device as parent, live +- * in a class-directory to prevent namespace collisions. ++ * Class-devices with a non class-device as parent, live ++ * in a "glue" directory to prevent namespace collisions. + */ + if (parent == NULL) + parent_kobj = virtual_device_parent(dev); +@@ -607,8 +607,7 @@ static struct kobject *get_device_parent + kobject_put(k); + return NULL; + } +- /* Do not emit a uevent, as it's not needed for this +- * "class glue" directory. */ ++ /* do not emit an uevent for this simple "glue" directory */ + return k; + } + +@@ -619,30 +618,13 @@ static struct kobject *get_device_parent + + static void cleanup_device_parent(struct device *dev) + { +- struct device *d; +- int other = 0; ++ struct kobject *glue_dir = dev->kobj.parent; + +- if (!dev->class) +- return; +- +- /* see if we live in a parent class directory */ +- if (dev->kobj.parent->kset != &dev->class->class_dirs) ++ /* see if we live in a "glue" directory */ ++ if (!dev->class || glue_dir->kset != &dev->class->class_dirs) + return; + +- /* if we are the last child of our class, delete the directory */ +- down(&dev->class->sem); +- list_for_each_entry(d, &dev->class->devices, node) { +- if (d == dev) +- continue; +- if (d->kobj.parent == dev->kobj.parent) { +- other = 1; +- break; +- } +- } +- if (!other) +- kobject_del(dev->kobj.parent); +- kobject_put(dev->kobj.parent); +- up(&dev->class->sem); ++ kobject_put(glue_dir); + } + #endif + +--- a/include/linux/kobject.h ++++ b/include/linux/kobject.h +@@ -68,6 +68,11 @@ struct kobject { + struct kset * kset; + struct kobj_type * ktype; + struct sysfs_dirent * sd; ++ unsigned int state_initialized:1; ++ unsigned int state_name_set:1; ++ unsigned int state_in_sysfs:1; ++ unsigned int state_add_uevent_sent:1; ++ unsigned int state_remove_uevent_sent:1; + }; + + extern int kobject_set_name(struct kobject *, const char *, ...) +--- a/lib/kobject.c ++++ b/lib/kobject.c +@@ -124,85 +124,74 @@ char *kobject_get_path(struct kobject *k + } + EXPORT_SYMBOL_GPL(kobject_get_path); + +-static void kobject_init_internal(struct kobject * kobj) ++/* add the kobject to its kset's list */ ++static void kobj_kset_join(struct kobject *kobj) + { +- if (!kobj) ++ if (!kobj->kset) + return; +- kref_init(&kobj->kref); +- INIT_LIST_HEAD(&kobj->entry); ++ ++ kset_get(kobj->kset); ++ spin_lock(&kobj->kset->list_lock); ++ list_add_tail(&kobj->entry, &kobj->kset->list); ++ spin_unlock(&kobj->kset->list_lock); + } + ++/* remove the kobject from its kset's list */ ++static void kobj_kset_leave(struct kobject *kobj) ++{ ++ if (!kobj->kset) ++ return; + +-/** +- * unlink - remove kobject from kset list. +- * @kobj: kobject. +- * +- * Remove the kobject from the kset list and decrement +- * its parent's refcount. +- * This is separated out, so we can use it in both +- * kobject_del() and kobject_add_internal() on error. +- */ ++ spin_lock(&kobj->kset->list_lock); ++ list_del_init(&kobj->entry); ++ spin_unlock(&kobj->kset->list_lock); ++ kset_put(kobj->kset); ++} + +-static void unlink(struct kobject * kobj) ++static void kobject_init_internal(struct kobject * kobj) + { +- struct kobject *parent = kobj->parent; +- +- if (kobj->kset) { +- spin_lock(&kobj->kset->list_lock); +- list_del_init(&kobj->entry); +- spin_unlock(&kobj->kset->list_lock); +- } +- kobj->parent = NULL; +- kobject_put(kobj); +- kobject_put(parent); ++ if (!kobj) ++ return; ++ kref_init(&kobj->kref); ++ INIT_LIST_HEAD(&kobj->entry); + } + ++ + static int kobject_add_internal(struct kobject *kobj) + { + int error = 0; + struct kobject * parent; + +- if (!(kobj = kobject_get(kobj))) ++ if (!kobj) + return -ENOENT; +- if (!kobj->k_name) +- kobject_set_name(kobj, "NO_NAME"); +- if (!*kobj->k_name) { +- pr_debug("kobject (%p) attempted to be registered with no " ++ ++ if (!kobj->k_name || !kobj->k_name[0]) { ++ pr_debug("kobject (%p) attempted to be registered with empty " + "name!\n", kobj); + WARN_ON(1); +- kobject_put(kobj); + return -EINVAL; + } +- parent = kobject_get(kobj->parent); + +- pr_debug("kobject: '%s' (%p): %s: parent: '%s', set: '%s'\n", +- kobject_name(kobj), kobj, __FUNCTION__, +- parent ? kobject_name(parent) : "<NULL>", +- kobj->kset ? kobject_name(&kobj->kset->kobj) : "<NULL>" ); ++ parent = kobject_get(kobj->parent); + ++ /* join kset if set, use it as parent if we do not already have one */ + if (kobj->kset) { +- kobj->kset = kset_get(kobj->kset); +- +- if (!parent) { ++ if (!parent) + parent = kobject_get(&kobj->kset->kobj); +- /* +- * If the kset is our parent, get a second +- * reference, we drop both the kset and the +- * parent ref on cleanup +- */ +- kobject_get(parent); +- } +- +- spin_lock(&kobj->kset->list_lock); +- list_add_tail(&kobj->entry, &kobj->kset->list); +- spin_unlock(&kobj->kset->list_lock); ++ kobj_kset_join(kobj); + kobj->parent = parent; + } + ++ pr_debug("kobject: '%s' (%p): %s: parent: '%s', set: '%s'\n", ++ kobject_name(kobj), kobj, __FUNCTION__, ++ parent ? kobject_name(parent) : "<NULL>", ++ kobj->kset ? kobject_name(&kobj->kset->kobj) : "<NULL>" ); ++ + error = create_dir(kobj); + if (error) { +- /* unlink does the kobject_put() for us */ +- unlink(kobj); ++ kobj_kset_leave(kobj); ++ kobject_put(parent); ++ kobj->parent = NULL; + + /* be noisy on error issues */ + if (error == -EEXIST) +@@ -214,7 +203,8 @@ static int kobject_add_internal(struct k + printk(KERN_ERR "%s failed for %s (%d)\n", + __FUNCTION__, kobject_name(kobj), error); + dump_stack(); +- } ++ } else ++ kobj->state_in_sysfs = 1; + + return error; + } +@@ -238,11 +228,13 @@ static int kobject_set_name_vargs(struct + if (!name) + return -ENOMEM; + ++ + /* Free the old name, if necessary. */ + kfree(kobj->k_name); + + /* Now, set the new name */ + kobj->k_name = name; ++ kobj->state_name_set = 1; + + return 0; + } +@@ -293,20 +285,25 @@ void kobject_init(struct kobject *kobj, + err_str = "must have a ktype to be initialized properly!\n"; + goto error; + } +- if (atomic_read(&kobj->kref.refcount)) { ++ if (kobj->state_initialized) { + /* do not error out as sometimes we can recover */ +- printk(KERN_ERR "kobject: reference count is already set, " +- "something is seriously wrong.\n"); ++ printk(KERN_ERR "kobject (%p): tried to init an initialized " ++ "object, something is seriously wrong.\n", kobj); + dump_stack(); + } + + kref_init(&kobj->kref); + INIT_LIST_HEAD(&kobj->entry); + kobj->ktype = ktype; ++ kobj->state_name_set = 0; ++ kobj->state_in_sysfs = 0; ++ kobj->state_add_uevent_sent = 0; ++ kobj->state_remove_uevent_sent = 0; ++ kobj->state_initialized = 1; + return; + + error: +- printk(KERN_ERR "kobject: %s\n", err_str); ++ printk(KERN_ERR "kobject (%p): %s\n", kobj, err_str); + dump_stack(); + } + EXPORT_SYMBOL(kobject_init); +@@ -345,17 +342,10 @@ static int kobject_add_varg(struct kobje + * + * If this function returns an error, kobject_put() must be called to + * properly clean up the memory associated with the object. +- * +- * If the function is successful, the only way to properly clean up the +- * memory is with a call to kobject_del(), in which case, a call to +- * kobject_put() is not necessary (kobject_del() does the final +- * kobject_put() to call the release function in the ktype's release +- * pointer.) +- * + * Under no instance should the kobject that is passed to this function + * be directly freed with a call to kfree(), that can leak memory. + * +- * Note, no uevent will be created with this call, the caller should set ++ * Note, no "add" uevent will be created with this call, the caller should set + * up all of the necessary sysfs files for the object and then call + * kobject_uevent() with the UEVENT_ADD parameter to ensure that + * userspace is properly notified of this kobject's creation. +@@ -369,6 +359,13 @@ int kobject_add(struct kobject *kobj, st + if (!kobj) + return -EINVAL; + ++ if (!kobj->state_initialized) { ++ printk(KERN_ERR "kobject '%s' (%p): tried to add an " ++ "uninitialized object, something is seriously wrong.\n", ++ kobject_name(kobj), kobj); ++ dump_stack(); ++ return -EINVAL; ++ } + va_start(args, fmt); + retval = kobject_add_varg(kobj, parent, fmt, args); + va_end(args); +@@ -527,8 +524,12 @@ void kobject_del(struct kobject * kobj) + { + if (!kobj) + return; ++ + sysfs_remove_dir(kobj); +- unlink(kobj); ++ kobj->state_in_sysfs = 0; ++ kobj_kset_leave(kobj); ++ kobject_put(kobj->parent); ++ kobj->parent = NULL; + } + + /** +@@ -565,21 +566,42 @@ struct kobject * kobject_get(struct kobj + */ + static void kobject_cleanup(struct kobject *kobj) + { +- struct kobj_type * t = get_ktype(kobj); +- struct kset * s = kobj->kset; ++ struct kobj_type *t = get_ktype(kobj); + const char *name = kobj->k_name; ++ int name_set = kobj->state_name_set; + + pr_debug("kobject: '%s' (%p): %s\n", + kobject_name(kobj), kobj, __FUNCTION__); ++ ++ if (t && !t->release) ++ pr_debug("kobject: '%s' (%p) does not have a release() " ++ "function, it is broken and must be fixed.\n", ++ kobject_name(kobj), kobj); ++ ++ /* send "remove" if the caller did not do it but sent "add" */ ++ if (kobj->state_add_uevent_sent && !kobj->state_remove_uevent_sent) { ++ pr_debug("kobject: '%s' (%p) auto cleanup 'remove' event", ++ kobject_name(kobj), kobj); ++ kobject_uevent(kobj, KOBJ_REMOVE); ++ } ++ ++ /* remove from sysfs if the caller did not do it */ ++ if (kobj->state_in_sysfs) { ++ pr_debug("kobject: '%s' (%p) auto cleanup kobject_del\n", ++ kobject_name(kobj), kobj); ++ kobject_del(kobj); ++ } ++ + if (t && t->release) { ++ pr_debug("kobject: (%p) calling ktype release\n", kobj); + t->release(kobj); +- /* If we have a release function, we can guess that this was +- * not a statically allocated kobject, so we should be safe to +- * free the name */ ++ } ++ ++ /* free name if we allocated it */ ++ if (name_set && name) { ++ pr_debug("kobject: '%s' free name\n", name); + kfree(name); + } +- if (s) +- kset_put(s); + } + + static void kobject_release(struct kref *kref) +@@ -601,8 +623,7 @@ void kobject_put(struct kobject * kobj) + + static void dynamic_kobj_release(struct kobject *kobj) + { +- pr_debug("kobject: '%s' (%p): %s\n", +- kobject_name(kobj), kobj, __FUNCTION__); ++ pr_debug("kobject: (%p): %s\n", kobj, __FUNCTION__); + kfree(kobj); + } + +--- a/lib/kobject_uevent.c ++++ b/lib/kobject_uevent.c +@@ -180,6 +180,17 @@ int kobject_uevent_env(struct kobject *k + } + } + ++ /* ++ * Mark "add" and "remove" events in the object to ensure proper ++ * events to userspace during automatic cleanup. If the object did ++ * send an "add" event, "remove" will automatically generated by ++ * the core, if not already done by the caller. ++ */ ++ if (action == KOBJ_ADD) ++ kobj->state_add_uevent_sent = 1; ++ else if (action == KOBJ_REMOVE) ++ kobj->state_remove_uevent_sent = 1; ++ + /* we will send an event, so request a new sequence number */ + spin_lock(&sequence_lock); + seq = ++uevent_seqnum; diff --git a/driver/kobject-change-arch-x86-kernel-cpu-mcheck-mce_amd_64.c-to-use-kobject_create_and_add.patch b/driver/kobject-change-arch-x86-kernel-cpu-mcheck-mce_amd_64.c-to-use-kobject_create_and_add.patch new file mode 100644 index 00000000000000..301d720cd8cd19 --- /dev/null +++ b/driver/kobject-change-arch-x86-kernel-cpu-mcheck-mce_amd_64.c-to-use-kobject_create_and_add.patch @@ -0,0 +1,85 @@ +From foo@baz Tue Apr 9 12:12:43 2002 +Date: Wed, 19 Dec 2007 09:23:20 -0800 +To: Greg KH <greg@kroah.com> +From: Greg Kroah-Hartman <gregkh@suse.de> +Subject: Kobject: change arch/x86/kernel/cpu/mcheck/mce_amd_64.c to use kobject_create_and_add + +Make this kobject dynamic and convert it to not use kobject_register, +which is going away. + +Cc: Jacob Shin <jacob.shin@amd.com> +Cc: Kay Sievers <kay.sievers@vrfy.org> +Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> + +--- + arch/x86/kernel/cpu/mcheck/mce_amd_64.c | 19 +++++++++---------- + 1 file changed, 9 insertions(+), 10 deletions(-) + +--- a/arch/x86/kernel/cpu/mcheck/mce_amd_64.c ++++ b/arch/x86/kernel/cpu/mcheck/mce_amd_64.c +@@ -65,7 +65,7 @@ static struct threshold_block threshold_ + }; + + struct threshold_bank { +- struct kobject kobj; ++ struct kobject *kobj; + struct threshold_block *blocks; + cpumask_t cpus; + }; +@@ -433,7 +433,7 @@ static __cpuinit int allocate_threshold_ + per_cpu(threshold_banks, cpu)[bank]->blocks = b; + + kobject_set_name(&b->kobj, "misc%i", block); +- b->kobj.parent = &per_cpu(threshold_banks, cpu)[bank]->kobj; ++ b->kobj.parent = per_cpu(threshold_banks, cpu)[bank]->kobj; + b->kobj.ktype = &threshold_ktype; + err = kobject_register(&b->kobj); + if (err) +@@ -489,7 +489,7 @@ static __cpuinit int threshold_create_ba + goto out; + + err = sysfs_create_link(&per_cpu(device_mce, cpu).kobj, +- &b->kobj, name); ++ b->kobj, name); + if (err) + goto out; + +@@ -505,16 +505,15 @@ static __cpuinit int threshold_create_ba + goto out; + } + +- kobject_set_name(&b->kobj, "threshold_bank%i", bank); +- b->kobj.parent = &per_cpu(device_mce, cpu).kobj; ++ b->kobj = kobject_create_and_add(name, &per_cpu(device_mce, cpu).kobj); ++ if (!b->kobj) ++ goto out_free; ++ + #ifndef CONFIG_SMP + b->cpus = CPU_MASK_ALL; + #else + b->cpus = per_cpu(cpu_core_map, cpu); + #endif +- err = kobject_register(&b->kobj); +- if (err) +- goto out_free; + + per_cpu(threshold_banks, cpu)[bank] = b; + +@@ -531,7 +530,7 @@ static __cpuinit int threshold_create_ba + continue; + + err = sysfs_create_link(&per_cpu(device_mce, i).kobj, +- &b->kobj, name); ++ b->kobj, name); + if (err) + goto out; + +@@ -627,7 +626,7 @@ static void threshold_remove_bank(unsign + deallocate_threshold_block(cpu, bank); + + free_out: +- kobject_unregister(&b->kobj); ++ kobject_unregister(b->kobj); + kfree(b); + per_cpu(threshold_banks, cpu)[bank] = NULL; + } diff --git a/driver/kobject-change-arch-x86-kernel-cpu-mcheck-mce_amd_64.c-to-use-kobject_init_and_add.patch b/driver/kobject-change-arch-x86-kernel-cpu-mcheck-mce_amd_64.c-to-use-kobject_init_and_add.patch new file mode 100644 index 00000000000000..b15a78d790ae97 --- /dev/null +++ b/driver/kobject-change-arch-x86-kernel-cpu-mcheck-mce_amd_64.c-to-use-kobject_init_and_add.patch @@ -0,0 +1,42 @@ +From foo@baz Tue Apr 9 12:12:43 2002 +Date: Wed, 19 Dec 2007 09:23:20 -0800 +To: Greg KH <greg@kroah.com> +From: Greg Kroah-Hartman <gregkh@suse.de> +Subject: Kobject: change arch/x86/kernel/cpu/mcheck/mce_amd_64.c to use kobject_init_and_add + +Stop using kobject_register, as this way we can control the sending of +the uevent properly, after everything is properly initialized. + +Cc: Jacob Shin <jacob.shin@amd.com> +Cc: Kay Sievers <kay.sievers@vrfy.org> +Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> + +--- + arch/x86/kernel/cpu/mcheck/mce_amd_64.c | 9 +++++---- + 1 file changed, 5 insertions(+), 4 deletions(-) + +--- a/arch/x86/kernel/cpu/mcheck/mce_amd_64.c ++++ b/arch/x86/kernel/cpu/mcheck/mce_amd_64.c +@@ -432,10 +432,9 @@ static __cpuinit int allocate_threshold_ + else + per_cpu(threshold_banks, cpu)[bank]->blocks = b; + +- kobject_set_name(&b->kobj, "misc%i", block); +- b->kobj.parent = per_cpu(threshold_banks, cpu)[bank]->kobj; +- b->kobj.ktype = &threshold_ktype; +- err = kobject_register(&b->kobj); ++ err = kobject_init_and_add(&b->kobj, &threshold_ktype, ++ per_cpu(threshold_banks, cpu)[bank]->kobj, ++ "misc%i", block); + if (err) + goto out_free; + recurse: +@@ -451,6 +450,8 @@ recurse: + if (err) + goto out_free; + ++ kobject_uevent(&b->kobj, KOBJ_ADD); ++ + return err; + + out_free: diff --git a/driver/kobject-remove-kobject_register.patch b/driver/kobject-remove-kobject_register.patch new file mode 100644 index 00000000000000..92ea4cdd9857b8 --- /dev/null +++ b/driver/kobject-remove-kobject_register.patch @@ -0,0 +1,62 @@ +From foo@baz Tue Apr 9 12:12:43 2002 +Date: Wed, 19 Dec 2007 11:26:50 -0800 +To: Greg KH <greg@kroah.com> +From: Greg Kroah-Hartman <gregkh@suse.de> +Subject: Kobject: remove kobject_register() + +The function is no longer used by anyone in the kernel, and it prevents +the proper sending of the kobject uevent after the needed files are set +up by the caller. kobject_init_and_add() can be used in its place. + +Cc: Kay Sievers <kay.sievers@vrfy.org> +Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> + +--- + include/linux/kobject.h | 1 - + lib/kobject.c | 18 ------------------ + 2 files changed, 19 deletions(-) + +--- a/include/linux/kobject.h ++++ b/include/linux/kobject.h +@@ -96,7 +96,6 @@ extern struct kobject * __must_check kob + extern int __must_check kobject_rename(struct kobject *, const char *new_name); + extern int __must_check kobject_move(struct kobject *, struct kobject *); + +-extern int __must_check kobject_register(struct kobject *); + extern void kobject_unregister(struct kobject *); + + extern struct kobject * kobject_get(struct kobject *); +--- a/lib/kobject.c ++++ b/lib/kobject.c +@@ -220,23 +220,6 @@ static int kobject_add_internal(struct k + } + + /** +- * kobject_register - initialize and add an object. +- * @kobj: object in question. +- */ +- +-int kobject_register(struct kobject * kobj) +-{ +- int error = -EINVAL; +- if (kobj) { +- kobject_init_internal(kobj); +- error = kobject_add(kobj); +- if (!error) +- kobject_uevent(kobj, KOBJ_ADD); +- } +- return error; +-} +- +-/** + * kobject_set_name_vargs - Set the name of an kobject + * @kobj: struct kobject to set the name of + * @fmt: format string used to build the name +@@ -883,7 +866,6 @@ struct kset *kset_create_and_add(const c + } + EXPORT_SYMBOL_GPL(kset_create_and_add); + +-EXPORT_SYMBOL(kobject_register); + EXPORT_SYMBOL(kobject_unregister); + EXPORT_SYMBOL(kobject_get); + EXPORT_SYMBOL(kobject_put); diff --git a/driver/kobject-warn.patch b/driver/kobject-warn.patch index 638e437cb885be..292674bd5da69d 100644 --- a/driver/kobject-warn.patch +++ b/driver/kobject-warn.patch @@ -1,31 +1,20 @@ From: gregkh@suse.de Subject: kobject warning stuff -Good for development, don't push it to mainline as there are too many -false positives. - -There are 2 changes in this patch. - First one is to ensure that the kobject is properly initialized _before_ kobject_init() is called. Yeah, seems funny, right? Turns out this has caught a lot of issues where kobject_init() is called twice on the same object, not a good thing at all. -The second change in that patch tries to enforce the "everything needs a -release() function" rule for kobjects, but it turns out, a lot of static -kobjects trigger this inproperly (struct bus and friends), so that can't -go to mainline, and it only shows up if you enable CONFIG_KOBJECT_DEBUG. - - Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> --- - lib/kobject.c | 5 +++++ - 1 file changed, 5 insertions(+) + lib/kobject.c | 1 + + 1 file changed, 1 insertion(+) --- a/lib/kobject.c +++ b/lib/kobject.c -@@ -128,6 +128,7 @@ static void kobject_init_internal(struct +@@ -152,6 +152,7 @@ static void kobject_init_internal(struct { if (!kobj) return; @@ -33,14 +22,3 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> kref_init(&kobj->kref); INIT_LIST_HEAD(&kobj->entry); } -@@ -594,6 +595,10 @@ static void kobject_cleanup(struct kobje - * not a statically allocated kobject, so we should be safe to - * free the name */ - kfree(name); -+ } else { -+ pr_debug("kobject: '%s' (%p) does not have a release() " -+ "function, if this is not a directory kobject, it " -+ "is broken and must be fixed.\n", name, kobj); - } - if (s) - kset_put(s); diff --git a/driver/warn-when-statically-allocated-kobjects-are-used.patch b/driver/warn-when-statically-allocated-kobjects-are-used.patch index 8a355f25a04893..d8b3fd42c270ed 100644 --- a/driver/warn-when-statically-allocated-kobjects-are-used.patch +++ b/driver/warn-when-statically-allocated-kobjects-are-used.patch @@ -32,8 +32,8 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> --- include/linux/init.h | 1 init/main.c | 9 ++++++++ - lib/kobject.c | 56 ++++++++++++++++++++++++++++++++++++++++++++++++++- - 3 files changed, 65 insertions(+), 1 deletion(-) + lib/kobject.c | 55 +++++++++++++++++++++++++++++++++++++++++++++++++++ + 3 files changed, 65 insertions(+) --- a/include/linux/init.h +++ b/include/linux/init.h @@ -80,9 +80,9 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> /** * populate_dir - populate directory with attributes. -@@ -124,16 +126,67 @@ char *kobject_get_path(struct kobject *k +@@ -148,11 +150,63 @@ static void kobj_kset_leave(struct kobje + kset_put(kobj->kset); } - EXPORT_SYMBOL_GPL(kobject_get_path); +#ifdef CONFIG_X86_32 +static int ptr_in_range(void *ptr, void *start, void *end) @@ -140,17 +140,12 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> if (!kobj) return; WARN_ON(atomic_read(&kobj->kref.refcount)); - kref_init(&kobj->kref); + verify_dynamic_kobject_allocation(kobj); + kref_init(&kobj->kref); INIT_LIST_HEAD(&kobj->entry); } - -- - /** - * unlink - remove kobject from kset list. - * @kobj: kobject. -@@ -317,6 +370,7 @@ void kobject_init(struct kobject *kobj, - "something is seriously wrong.\n"); +@@ -292,6 +346,7 @@ void kobject_init(struct kobject *kobj, + "object, something is seriously wrong.\n", kobj); dump_stack(); } + verify_dynamic_kobject_allocation(kobj); |
