|
@@ -545,8 +545,8 @@ 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",
|
|
|
- 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 kobject *kobj)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+#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
|
|
|
}
|
|
|
|
|
|
/**
|