aboutsummaryrefslogtreecommitdiffstats
path: root/driver
diff options
authorGreg Kroah-Hartman <gregkh@suse.de>2007-12-19 11:35:35 -0800
committerGreg Kroah-Hartman <gregkh@suse.de>2007-12-19 11:35:35 -0800
commite30d51d7cb7a0c13fe80c8f82328d4cad79207a5 (patch)
treebd263af98ff6c1f98e33e594b47faa607999b410 /driver
parentac5bb415ab5d05ade598b44367d040526ef4967c (diff)
downloadpatches-e30d51d7cb7a0c13fe80c8f82328d4cad79207a5.tar.gz
more kobject fun...
Diffstat (limited to 'driver')
-rw-r--r--driver/kobject-auto-cleanup-on-final-unref.patch408
-rw-r--r--driver/kobject-change-arch-x86-kernel-cpu-mcheck-mce_amd_64.c-to-use-kobject_create_and_add.patch85
-rw-r--r--driver/kobject-change-arch-x86-kernel-cpu-mcheck-mce_amd_64.c-to-use-kobject_init_and_add.patch42
-rw-r--r--driver/kobject-remove-kobject_register.patch62
-rw-r--r--driver/kobject-warn.patch28
-rw-r--r--driver/warn-when-statically-allocated-kobjects-are-used.patch19
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);