[PATCH 3/7] s3c-hsudc: add a remove function
Russell King - ARM Linux
linux at arm.linux.org.uk
Sun Dec 18 14:45:18 EST 2011
On Sun, Dec 18, 2011 at 08:33:32PM +0100, Heiko Stübner wrote:
> Am Sonntag 18 Dezember 2011, 20:01:02 schrieben Sie:
> > On Sun, Dec 18, 2011 at 07:50:37PM +0100, Heiko Stübner wrote:
> > > I didn't get this far. With your patch the Oopses already happen during
> > > the startup of the system / the loading of the modules.
> >
> > > A bit of the message spew I got during testing with linux-next-20111216:
> > In some way, this is a good thing because it's showing that there's
> > problems with kobject lifetime rules.
> >
> > The #2 and further oops dumps are a result of corrupting the work
> > queues as a result of #1, so #2 onwards should be ignored.
> >
> > I suspect if you avoid loading the s3c_hsudc module these will go away.
>
> nope :-), same faults happen even if s3c-hsudc is not present at all.
> So it seems, this delayed cleanup poses problems for other drivers as well.
Okay, let's try to find out which one it is. Please use the attached
patch - it'll be a little more noisy, reporting which kobjects are
being released at the point when they're added to the workqueue.
Thanks.
diff --git a/include/linux/kobject.h b/include/linux/kobject.h
index ad81e1c..be1c97a 100644
--- a/include/linux/kobject.h
+++ b/include/linux/kobject.h
@@ -26,6 +26,9 @@
#include <linux/kernel.h>
#include <linux/wait.h>
#include <linux/atomic.h>
+#include <linux/workqueue.h>
+
+#define KOBJECT_DEBUG_RELEASE
#define UEVENT_HELPER_PATH_LEN 256
#define UEVENT_NUM_ENVP 32 /* number of env pointers */
@@ -65,6 +68,9 @@ struct kobject {
struct kobj_type *ktype;
struct sysfs_dirent *sd;
struct kref kref;
+#ifdef KOBJECT_DEBUG_RELEASE
+ struct delayed_work release;
+#endif
unsigned int state_initialized:1;
unsigned int state_in_sysfs:1;
unsigned int state_add_uevent_sent:1;
diff --git a/lib/kobject.c b/lib/kobject.c
index 640bd98..5c01a78 100644
--- a/lib/kobject.c
+++ b/lib/kobject.c
@@ -540,7 +540,7 @@ static void kobject_cleanup(struct kobject *kobj)
struct kobj_type *t = get_ktype(kobj);
const char *name = kobj->name;
- pr_debug("kobject: '%s' (%p): %s\n",
+ pr_info("kobject: '%s' (%p): %s\n",
kobject_name(kobj), kobj, __func__);
if (t && !t->release)
@@ -575,9 +575,25 @@ static void kobject_cleanup(struct kobject *kobj)
}
}
+#ifdef KOBJECT_DEBUG_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 KOBJECT_DEBUG_RELEASE
+ pr_info("kobject: '%s' (%p): %s\n",
+ kobject_name(kobj), kobj, __func__);
+ INIT_DELAYED_WORK(&kobj->release, kobject_delayed_cleanup);
+ schedule_delayed_work(&kobj->release, HZ);
+#else
+ kobject_cleanup(kobj);
+#endif
}
/**
More information about the linux-arm-kernel
mailing list