aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKay Sievers <kay.sievers@vrfy.org>2007-12-18 19:40:42 -0500
committerGreg Kroah-Hartman <gregkh@suse.de>2008-01-24 23:40:39 -0500
commit0f4dafc0563c6c49e17fe14b3f5f356e4c4b8806 (patch)
treef4ded2831853cb6ea328d15d72871db6f8c22610
parent12e339ac6e31a34fe42396aec8fb1c0b43caf61e (diff)
Kobject: auto-cleanup on final unref
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>
-rw-r--r--drivers/base/core.c32
-rw-r--r--include/linux/kobject.h5
-rw-r--r--lib/kobject.c170
-rw-r--r--lib/kobject_uevent.c11
4 files changed, 119 insertions, 99 deletions
diff --git a/drivers/base/core.c b/drivers/base/core.c
index 675a719dcdd2..d5d542db96fd 100644
--- a/drivers/base/core.c
+++ b/drivers/base/core.c
@@ -576,8 +576,8 @@ static struct kobject *get_device_parent(struct device *dev,
576 576
577 /* 577 /*
578 * If we have no parent, we live in "virtual". 578 * If we have no parent, we live in "virtual".
579 * Class-devices with a bus-device as parent, live 579 * Class-devices with a non class-device as parent, live
580 * in a class-directory to prevent namespace collisions. 580 * in a "glue" directory to prevent namespace collisions.
581 */ 581 */
582 if (parent == NULL) 582 if (parent == NULL)
583 parent_kobj = virtual_device_parent(dev); 583 parent_kobj = virtual_device_parent(dev);
@@ -607,8 +607,7 @@ static struct kobject *get_device_parent(struct device *dev,
607 kobject_put(k); 607 kobject_put(k);
608 return NULL; 608 return NULL;
609 } 609 }
610 /* Do not emit a uevent, as it's not needed for this 610 /* do not emit an uevent for this simple "glue" directory */
611 * "class glue" directory. */
612 return k; 611 return k;
613 } 612 }
614 613
@@ -619,30 +618,13 @@ static struct kobject *get_device_parent(struct device *dev,
619 618
620static void cleanup_device_parent(struct device *dev) 619static void cleanup_device_parent(struct device *dev)
621{ 620{
622 struct device *d; 621 struct kobject *glue_dir = dev->kobj.parent;
623 int other = 0;
624 622
625 if (!dev->class) 623 /* see if we live in a "glue" directory */
626 return; 624 if (!dev->class || glue_dir->kset != &dev->class->class_dirs)
627
628 /* see if we live in a parent class directory */
629 if (dev->kobj.parent->kset != &dev->class->class_dirs)
630 return; 625 return;
631 626
632 /* if we are the last child of our class, delete the directory */ 627 kobject_put(glue_dir);
633 down(&dev->class->sem);
634 list_for_each_entry(d, &dev->class->devices, node) {
635 if (d == dev)
636 continue;
637 if (d->kobj.parent == dev->kobj.parent) {
638 other = 1;
639 break;
640 }
641 }
642 if (!other)
643 kobject_del(dev->kobj.parent);
644 kobject_put(dev->kobj.parent);
645 up(&dev->class->sem);
646} 628}
647#endif 629#endif
648 630
diff --git a/include/linux/kobject.h b/include/linux/kobject.h
index 63967da073af..be03ce83f9cc 100644
--- a/include/linux/kobject.h
+++ b/include/linux/kobject.h
@@ -68,6 +68,11 @@ struct kobject {
68 struct kset * kset; 68 struct kset * kset;
69 struct kobj_type * ktype; 69 struct kobj_type * ktype;
70 struct sysfs_dirent * sd; 70 struct sysfs_dirent * sd;
71 unsigned int state_initialized:1;
72 unsigned int state_name_set:1;
73 unsigned int state_in_sysfs:1;
74 unsigned int state_add_uevent_sent:1;
75 unsigned int state_remove_uevent_sent:1;
71}; 76};
72 77
73extern int kobject_set_name(struct kobject *, const char *, ...) 78extern int kobject_set_name(struct kobject *, const char *, ...)
diff --git a/lib/kobject.c b/lib/kobject.c
index c321f1910cc2..4fce5ca42c2e 100644
--- a/lib/kobject.c
+++ b/lib/kobject.c
@@ -124,85 +124,74 @@ char *kobject_get_path(struct kobject *kobj, gfp_t gfp_mask)
124} 124}
125EXPORT_SYMBOL_GPL(kobject_get_path); 125EXPORT_SYMBOL_GPL(kobject_get_path);
126 126
127static void kobject_init_internal(struct kobject * kobj) 127/* add the kobject to its kset's list */
128static void kobj_kset_join(struct kobject *kobj)
128{ 129{
129 if (!kobj) 130 if (!kobj->kset)
130 return; 131 return;
131 kref_init(&kobj->kref); 132
132 INIT_LIST_HEAD(&kobj->entry); 133 kset_get(kobj->kset);
134 spin_lock(&kobj->kset->list_lock);
135 list_add_tail(&kobj->entry, &kobj->kset->list);
136 spin_unlock(&kobj->kset->list_lock);
133} 137}
134 138
139/* remove the kobject from its kset's list */
140static void kobj_kset_leave(struct kobject *kobj)
141{
142 if (!kobj->kset)
143 return;
135 144
136/** 145 spin_lock(&kobj->kset->list_lock);
137 * unlink - remove kobject from kset list. 146 list_del_init(&kobj->entry);
138 * @kobj: kobject. 147 spin_unlock(&kobj->kset->list_lock);
139 * 148 kset_put(kobj->kset);
140 * Remove the kobject from the kset list and decrement 149}
141 * its parent's refcount.
142 * This is separated out, so we can use it in both
143 * kobject_del() and kobject_add_internal() on error.
144 */
145 150
146static void unlink(struct kobject * kobj) 151static void kobject_init_internal(struct kobject * kobj)
147{ 152{
148 struct kobject *parent = kobj->parent; 153 if (!kobj)
149 154 return;
150 if (kobj->kset) { 155 kref_init(&kobj->kref);
151 spin_lock(&kobj->kset->list_lock); 156 INIT_LIST_HEAD(&kobj->entry);
152 list_del_init(&kobj->entry);
153 spin_unlock(&kobj->kset->list_lock);
154 }
155 kobj->parent = NULL;
156 kobject_put(kobj);
157 kobject_put(parent);
158} 157}
159 158
159
160static int kobject_add_internal(struct kobject *kobj) 160static int kobject_add_internal(struct kobject *kobj)
161{ 161{
162 int error = 0; 162 int error = 0;
163 struct kobject * parent; 163 struct kobject * parent;
164 164
165 if (!(kobj = kobject_get(kobj))) 165 if (!kobj)
166 return -ENOENT; 166 return -ENOENT;
167 if (!kobj->k_name) 167
168 kobject_set_name(kobj, "NO_NAME"); 168 if (!kobj->k_name || !kobj->k_name[0]) {
169 if (!*kobj->k_name) { 169 pr_debug("kobject: (%p): attempted to be registered with empty "
170 pr_debug("kobject (%p) attempted to be registered with no "
171 "name!\n", kobj); 170 "name!\n", kobj);
172 WARN_ON(1); 171 WARN_ON(1);
173 kobject_put(kobj);
174 return -EINVAL; 172 return -EINVAL;
175 } 173 }
176 parent = kobject_get(kobj->parent);
177 174
178 pr_debug("kobject: '%s' (%p): %s: parent: '%s', set: '%s'\n", 175 parent = kobject_get(kobj->parent);
179 kobject_name(kobj), kobj, __FUNCTION__,
180 parent ? kobject_name(parent) : "<NULL>",
181 kobj->kset ? kobject_name(&kobj->kset->kobj) : "<NULL>" );
182 176
177 /* join kset if set, use it as parent if we do not already have one */
183 if (kobj->kset) { 178 if (kobj->kset) {
184 kobj->kset = kset_get(kobj->kset); 179 if (!parent)
185
186 if (!parent) {
187 parent = kobject_get(&kobj->kset->kobj); 180 parent = kobject_get(&kobj->kset->kobj);
188 /* 181 kobj_kset_join(kobj);
189 * If the kset is our parent, get a second
190 * reference, we drop both the kset and the
191 * parent ref on cleanup
192 */
193 kobject_get(parent);
194 }
195
196 spin_lock(&kobj->kset->list_lock);
197 list_add_tail(&kobj->entry, &kobj->kset->list);
198 spin_unlock(&kobj->kset->list_lock);
199 kobj->parent = parent; 182 kobj->parent = parent;
200 } 183 }
201 184
185 pr_debug("kobject: '%s' (%p): %s: parent: '%s', set: '%s'\n",
186 kobject_name(kobj), kobj, __FUNCTION__,
187 parent ? kobject_name(parent) : "<NULL>",
188 kobj->kset ? kobject_name(&kobj->kset->kobj) : "<NULL>" );
189
202 error = create_dir(kobj); 190 error = create_dir(kobj);
203 if (error) { 191 if (error) {
204 /* unlink does the kobject_put() for us */ 192 kobj_kset_leave(kobj);
205 unlink(kobj); 193 kobject_put(parent);
194 kobj->parent = NULL;
206 195
207 /* be noisy on error issues */ 196 /* be noisy on error issues */
208 if (error == -EEXIST) 197 if (error == -EEXIST)
@@ -214,7 +203,8 @@ static int kobject_add_internal(struct kobject *kobj)
214 printk(KERN_ERR "%s failed for %s (%d)\n", 203 printk(KERN_ERR "%s failed for %s (%d)\n",
215 __FUNCTION__, kobject_name(kobj), error); 204 __FUNCTION__, kobject_name(kobj), error);
216 dump_stack(); 205 dump_stack();
217 } 206 } else
207 kobj->state_in_sysfs = 1;
218 208
219 return error; 209 return error;
220} 210}
@@ -238,11 +228,13 @@ static int kobject_set_name_vargs(struct kobject *kobj, const char *fmt,
238 if (!name) 228 if (!name)
239 return -ENOMEM; 229 return -ENOMEM;
240 230
231
241 /* Free the old name, if necessary. */ 232 /* Free the old name, if necessary. */
242 kfree(kobj->k_name); 233 kfree(kobj->k_name);
243 234
244 /* Now, set the new name */ 235 /* Now, set the new name */
245 kobj->k_name = name; 236 kobj->k_name = name;
237 kobj->state_name_set = 1;
246 238
247 return 0; 239 return 0;
248} 240}
@@ -293,20 +285,25 @@ void kobject_init(struct kobject *kobj, struct kobj_type *ktype)
293 err_str = "must have a ktype to be initialized properly!\n"; 285 err_str = "must have a ktype to be initialized properly!\n";
294 goto error; 286 goto error;
295 } 287 }
296 if (atomic_read(&kobj->kref.refcount)) { 288 if (kobj->state_initialized) {
297 /* do not error out as sometimes we can recover */ 289 /* do not error out as sometimes we can recover */
298 printk(KERN_ERR "kobject: reference count is already set, " 290 printk(KERN_ERR "kobject (%p): tried to init an initialized "
299 "something is seriously wrong.\n"); 291 "object, something is seriously wrong.\n", kobj);
300 dump_stack(); 292 dump_stack();
301 } 293 }
302 294
303 kref_init(&kobj->kref); 295 kref_init(&kobj->kref);
304 INIT_LIST_HEAD(&kobj->entry); 296 INIT_LIST_HEAD(&kobj->entry);
305 kobj->ktype = ktype; 297 kobj->ktype = ktype;
298 kobj->state_name_set = 0;
299 kobj->state_in_sysfs = 0;
300 kobj->state_add_uevent_sent = 0;
301 kobj->state_remove_uevent_sent = 0;
302 kobj->state_initialized = 1;
306 return; 303 return;
307 304
308error: 305error:
309 printk(KERN_ERR "kobject: %s\n", err_str); 306 printk(KERN_ERR "kobject (%p): %s\n", kobj, err_str);
310 dump_stack(); 307 dump_stack();
311} 308}
312EXPORT_SYMBOL(kobject_init); 309EXPORT_SYMBOL(kobject_init);
@@ -345,17 +342,10 @@ static int kobject_add_varg(struct kobject *kobj, struct kobject *parent,
345 * 342 *
346 * If this function returns an error, kobject_put() must be called to 343 * If this function returns an error, kobject_put() must be called to
347 * properly clean up the memory associated with the object. 344 * properly clean up the memory associated with the object.
348 *
349 * If the function is successful, the only way to properly clean up the
350 * memory is with a call to kobject_del(), in which case, a call to
351 * kobject_put() is not necessary (kobject_del() does the final
352 * kobject_put() to call the release function in the ktype's release
353 * pointer.)
354 *
355 * Under no instance should the kobject that is passed to this function 345 * Under no instance should the kobject that is passed to this function
356 * be directly freed with a call to kfree(), that can leak memory. 346 * be directly freed with a call to kfree(), that can leak memory.
357 * 347 *
358 * Note, no uevent will be created with this call, the caller should set 348 * Note, no "add" uevent will be created with this call, the caller should set
359 * up all of the necessary sysfs files for the object and then call 349 * up all of the necessary sysfs files for the object and then call
360 * kobject_uevent() with the UEVENT_ADD parameter to ensure that 350 * kobject_uevent() with the UEVENT_ADD parameter to ensure that
361 * userspace is properly notified of this kobject's creation. 351 * userspace is properly notified of this kobject's creation.
@@ -369,6 +359,13 @@ int kobject_add(struct kobject *kobj, struct kobject *parent,
369 if (!kobj) 359 if (!kobj)
370 return -EINVAL; 360 return -EINVAL;
371 361
362 if (!kobj->state_initialized) {
363 printk(KERN_ERR "kobject '%s' (%p): tried to add an "
364 "uninitialized object, something is seriously wrong.\n",
365 kobject_name(kobj), kobj);
366 dump_stack();
367 return -EINVAL;
368 }
372 va_start(args, fmt); 369 va_start(args, fmt);
373 retval = kobject_add_varg(kobj, parent, fmt, args); 370 retval = kobject_add_varg(kobj, parent, fmt, args);
374 va_end(args); 371 va_end(args);
@@ -527,8 +524,12 @@ void kobject_del(struct kobject * kobj)
527{ 524{
528 if (!kobj) 525 if (!kobj)
529 return; 526 return;
527
530 sysfs_remove_dir(kobj); 528 sysfs_remove_dir(kobj);
531 unlink(kobj); 529 kobj->state_in_sysfs = 0;
530 kobj_kset_leave(kobj);
531 kobject_put(kobj->parent);
532 kobj->parent = NULL;
532} 533}
533 534
534/** 535/**
@@ -565,21 +566,43 @@ struct kobject * kobject_get(struct kobject * kobj)
565 */ 566 */
566static void kobject_cleanup(struct kobject *kobj) 567static void kobject_cleanup(struct kobject *kobj)
567{ 568{
568 struct kobj_type * t = get_ktype(kobj); 569 struct kobj_type *t = get_ktype(kobj);
569 struct kset * s = kobj->kset;
570 const char *name = kobj->k_name; 570 const char *name = kobj->k_name;
571 int name_set = kobj->state_name_set;
571 572
572 pr_debug("kobject: '%s' (%p): %s\n", 573 pr_debug("kobject: '%s' (%p): %s\n",
573 kobject_name(kobj), kobj, __FUNCTION__); 574 kobject_name(kobj), kobj, __FUNCTION__);
575
576 if (t && !t->release)
577 pr_debug("kobject: '%s' (%p): does not have a release() "
578 "function, it is broken and must be fixed.\n",
579 kobject_name(kobj), kobj);
580
581 /* send "remove" if the caller did not do it but sent "add" */
582 if (kobj->state_add_uevent_sent && !kobj->state_remove_uevent_sent) {
583 pr_debug("kobject: '%s' (%p): auto cleanup 'remove' event\n",
584 kobject_name(kobj), kobj);
585 kobject_uevent(kobj, KOBJ_REMOVE);
586 }
587
588 /* remove from sysfs if the caller did not do it */
589 if (kobj->state_in_sysfs) {
590 pr_debug("kobject: '%s' (%p): auto cleanup kobject_del\n",
591 kobject_name(kobj), kobj);
592 kobject_del(kobj);
593 }
594
574 if (t && t->release) { 595 if (t && t->release) {
596 pr_debug("kobject: '%s' (%p): calling ktype release\n",
597 kobject_name(kobj), kobj);
575 t->release(kobj); 598 t->release(kobj);
576 /* If we have a release function, we can guess that this was 599 }
577 * not a statically allocated kobject, so we should be safe to 600
578 * free the name */ 601 /* free name if we allocated it */
602 if (name_set && name) {
603 pr_debug("kobject: '%s': free name\n", name);
579 kfree(name); 604 kfree(name);
580 } 605 }
581 if (s)
582 kset_put(s);
583} 606}
584 607
585static void kobject_release(struct kref *kref) 608static void kobject_release(struct kref *kref)
@@ -601,8 +624,7 @@ void kobject_put(struct kobject * kobj)
601 624
602static void dynamic_kobj_release(struct kobject *kobj) 625static void dynamic_kobj_release(struct kobject *kobj)
603{ 626{
604 pr_debug("kobject: '%s' (%p): %s\n", 627 pr_debug("kobject: (%p): %s\n", kobj, __FUNCTION__);
605 kobject_name(kobj), kobj, __FUNCTION__);
606 kfree(kobj); 628 kfree(kobj);
607} 629}
608 630
diff --git a/lib/kobject_uevent.c b/lib/kobject_uevent.c
index 51dc4d287add..b021e67c4294 100644
--- a/lib/kobject_uevent.c
+++ b/lib/kobject_uevent.c
@@ -180,6 +180,17 @@ int kobject_uevent_env(struct kobject *kobj, enum kobject_action action,
180 } 180 }
181 } 181 }
182 182
183 /*
184 * Mark "add" and "remove" events in the object to ensure proper
185 * events to userspace during automatic cleanup. If the object did
186 * send an "add" event, "remove" will automatically generated by
187 * the core, if not already done by the caller.
188 */
189 if (action == KOBJ_ADD)
190 kobj->state_add_uevent_sent = 1;
191 else if (action == KOBJ_REMOVE)
192 kobj->state_remove_uevent_sent = 1;
193
183 /* we will send an event, so request a new sequence number */ 194 /* we will send an event, so request a new sequence number */
184 spin_lock(&sequence_lock); 195 spin_lock(&sequence_lock);
185 seq = ++uevent_seqnum; 196 seq = ++uevent_seqnum;