diff options
| author | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2013-08-08 15:01:03 -0700 |
|---|---|---|
| committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2013-08-08 15:01:03 -0700 |
| commit | e8c73558c4456417be58d1d60e94bd6c4bdd4989 (patch) | |
| tree | fb0bdbcb9113e2137ed0bc7d36320ce8d8b91187 | |
| parent | 6866d52ad99a8c2c5301c7371fce365d25b2d0be (diff) | |
| download | patches-e8c73558c4456417be58d1d60e94bd6c4bdd4989.tar.gz | |
kobject patch
| -rw-r--r-- | kobject-delayed-kobject-release-help-find-buggy-drivers.patch | 125 | ||||
| -rw-r--r-- | series | 1 |
2 files changed, 126 insertions, 0 deletions
diff --git a/kobject-delayed-kobject-release-help-find-buggy-drivers.patch b/kobject-delayed-kobject-release-help-find-buggy-drivers.patch new file mode 100644 index 00000000000000..cdae1a841c82e6 --- /dev/null +++ b/kobject-delayed-kobject-release-help-find-buggy-drivers.patch @@ -0,0 +1,125 @@ +From rmk+greg=kroah.com@arm.linux.org.uk Thu Jun 27 07:06:26 2013 +From: Russell King <rmk@arm.linux.org.uk> +Date: Thu, 27 Jun 2013 15:06:14 +0100 +Subject: kobject: delayed kobject release: help find buggy drivers +To: Greg KH <greg@kroah.com> +Cc: Linux Kernel List <linux-kernel@vger.kernel.org>, Linus Torvalds <torvalds@linux-foundation.org>, Andrew Morton <akpm@linux-foundation.org> +Message-ID: <20130627140613.GB12530@flint.arm.linux.org.uk> + + +From: Russell King <rmk+kernel@arm.linux.org.uk> + +Implement debugging for kobject release functions. kobjects are +reference counted, so the drop of the last reference to them is not +predictable. However, the common case is for the last reference to be +the kobject's removal from a subsystem, which results in the release +function being immediately called. + +This can hide subtle bugs, which can occur when another thread holds a +reference to the kobject at the same time that a kobject is removed. +This results in the release method being delayed. + +In order to make these kinds of problems more visible, the following +patch implements a delayed release; this has the effect that the +release function will be out of order with respect to the removal of +the kobject in the same manner that it would be if a reference was +being held. + +This provides us with an easy way to allow driver writers to debug +their drivers and fix otherwise hidden problems. + +Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk> +--- + include/linux/kobject.h | 4 ++++ + lib/Kconfig.debug | 19 +++++++++++++++++++ + lib/kobject.c | 22 +++++++++++++++++++--- + 3 files changed, 42 insertions(+), 3 deletions(-) + +--- a/include/linux/kobject.h ++++ b/include/linux/kobject.h +@@ -26,6 +26,7 @@ + #include <linux/kernel.h> + #include <linux/wait.h> + #include <linux/atomic.h> ++#include <linux/workqueue.h> + + #define UEVENT_HELPER_PATH_LEN 256 + #define UEVENT_NUM_ENVP 32 /* number of env pointers */ +@@ -65,6 +66,9 @@ struct kobject { + struct kobj_type *ktype; + struct sysfs_dirent *sd; + struct kref kref; ++#ifdef CONFIG_DEBUG_KOBJECT_RELEASE ++ struct delayed_work release; ++#endif + unsigned int state_initialized:1; + unsigned int state_in_sysfs:1; + unsigned int state_add_uevent_sent:1; +--- a/lib/Kconfig.debug ++++ b/lib/Kconfig.debug +@@ -981,6 +981,25 @@ config DEBUG_KOBJECT + If you say Y here, some extra kobject debugging messages will be sent + to the syslog. + ++config DEBUG_KOBJECT_RELEASE ++ bool "kobject release debugging" ++ depends on DEBUG_KERNEL ++ help ++ kobjects are reference counted objects. This means that their ++ last reference count put is not predictable, and the kobject can ++ live on past the point at which a driver decides to drop it's ++ initial reference to the kobject gained on allocation. An ++ example of this would be a struct device which has just been ++ unregistered. ++ ++ However, some buggy drivers assume that after such an operation, ++ the memory backing the kobject can be immediately freed. This ++ goes completely against the principles of a refcounted object. ++ ++ If you say Y here, the kernel will delay the release of kobjects ++ on the last reference count to improve the visibility of this ++ kind of kobject release bug. ++ + config HAVE_DEBUG_BUGVERBOSE + bool + +--- a/lib/kobject.c ++++ b/lib/kobject.c +@@ -545,8 +545,8 @@ static void kobject_cleanup(struct kobje + struct kobj_type *t = get_ktype(kobj); + const char *name = kobj->name; + +- pr_debug("kobject: '%s' (%p): %s\n", +- kobject_name(kobj), kobj, __func__); ++ pr_debug("kobject: '%s' (%p): %s, parent %p\n", ++ kobject_name(kobj), kobj, __func__, kobj->parent); + + if (t && !t->release) + pr_debug("kobject: '%s' (%p): does not have a release() " +@@ -580,9 +580,25 @@ static void kobject_cleanup(struct kobje + } + } + ++#ifdef CONFIG_DEBUG_KOBJECT_RELEASE ++static void kobject_delayed_cleanup(struct work_struct *work) ++{ ++ kobject_cleanup(container_of(to_delayed_work(work), ++ struct kobject, release)); ++} ++#endif ++ + static void kobject_release(struct kref *kref) + { +- kobject_cleanup(container_of(kref, struct kobject, kref)); ++ struct kobject *kobj = container_of(kref, struct kobject, kref); ++#ifdef CONFIG_DEBUG_KOBJECT_RELEASE ++ pr_debug("kobject: '%s' (%p): %s, parent %p (delayed)\n", ++ kobject_name(kobj), kobj, __func__, kobj->parent); ++ INIT_DELAYED_WORK(&kobj->release, kobject_delayed_cleanup); ++ schedule_delayed_work(&kobj->release, HZ); ++#else ++ kobject_cleanup(kobj); ++#endif + } + + /** @@ -1,4 +1,5 @@ # patches already in my git trees, but still here so I don't loose them. +kobject-delayed-kobject-release-help-find-buggy-drivers.patch applied/misc-c2port-use-dev_bin_attrs-instead-of-hand-coding-it.patch # usb DEBUG cleanups |
