Commit 0f4dafc0563c6c49e17fe14b3f5f356e4c4b8806

Authored by Kay Sievers
Committed by Greg Kroah-Hartman
1 parent 12e339ac6e

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>

Showing 4 changed files with 119 additions and 99 deletions Side-by-side Diff

... ... @@ -576,8 +576,8 @@
576 576  
577 577 /*
578 578 * If we have no parent, we live in "virtual".
579   - * Class-devices with a bus-device as parent, live
580   - * in a class-directory to prevent namespace collisions.
  579 + * Class-devices with a non class-device as parent, live
  580 + * in a "glue" directory to prevent namespace collisions.
581 581 */
582 582 if (parent == NULL)
583 583 parent_kobj = virtual_device_parent(dev);
... ... @@ -607,8 +607,7 @@
607 607 kobject_put(k);
608 608 return NULL;
609 609 }
610   - /* Do not emit a uevent, as it's not needed for this
611   - * "class glue" directory. */
  610 + /* do not emit an uevent for this simple "glue" directory */
612 611 return k;
613 612 }
614 613  
615 614  
616 615  
... ... @@ -619,30 +618,13 @@
619 618  
620 619 static void cleanup_device_parent(struct device *dev)
621 620 {
622   - struct device *d;
623   - int other = 0;
  621 + struct kobject *glue_dir = dev->kobj.parent;
624 622  
625   - if (!dev->class)
  623 + /* see if we live in a "glue" directory */
  624 + if (!dev->class || glue_dir->kset != &dev->class->class_dirs)
626 625 return;
627 626  
628   - /* see if we live in a parent class directory */
629   - if (dev->kobj.parent->kset != &dev->class->class_dirs)
630   - return;
631   -
632   - /* if we are the last child of our class, delete the directory */
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);
  627 + kobject_put(glue_dir);
646 628 }
647 629 #endif
648 630  
include/linux/kobject.h
... ... @@ -68,6 +68,11 @@
68 68 struct kset * kset;
69 69 struct kobj_type * ktype;
70 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  
73 78 extern int kobject_set_name(struct kobject *, const char *, ...)
... ... @@ -124,85 +124,74 @@
124 124 }
125 125 EXPORT_SYMBOL_GPL(kobject_get_path);
126 126  
127   -static void kobject_init_internal(struct kobject * kobj)
  127 +/* add the kobject to its kset's list */
  128 +static void kobj_kset_join(struct kobject *kobj)
128 129 {
129   - if (!kobj)
  130 + if (!kobj->kset)
130 131 return;
131   - kref_init(&kobj->kref);
132   - INIT_LIST_HEAD(&kobj->entry);
  132 +
  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 */
  140 +static void kobj_kset_leave(struct kobject *kobj)
  141 +{
  142 + if (!kobj->kset)
  143 + return;
135 144  
136   -/**
137   - * unlink - remove kobject from kset list.
138   - * @kobj: kobject.
139   - *
140   - * Remove the kobject from the kset list and decrement
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 + spin_lock(&kobj->kset->list_lock);
  146 + list_del_init(&kobj->entry);
  147 + spin_unlock(&kobj->kset->list_lock);
  148 + kset_put(kobj->kset);
  149 +}
145 150  
146   -static void unlink(struct kobject * kobj)
  151 +static void kobject_init_internal(struct kobject * kobj)
147 152 {
148   - struct kobject *parent = kobj->parent;
149   -
150   - if (kobj->kset) {
151   - spin_lock(&kobj->kset->list_lock);
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);
  153 + if (!kobj)
  154 + return;
  155 + kref_init(&kobj->kref);
  156 + INIT_LIST_HEAD(&kobj->entry);
158 157 }
159 158  
  159 +
160 160 static int kobject_add_internal(struct kobject *kobj)
161 161 {
162 162 int error = 0;
163 163 struct kobject * parent;
164 164  
165   - if (!(kobj = kobject_get(kobj)))
  165 + if (!kobj)
166 166 return -ENOENT;
167   - if (!kobj->k_name)
168   - kobject_set_name(kobj, "NO_NAME");
169   - if (!*kobj->k_name) {
170   - pr_debug("kobject (%p) attempted to be registered with no "
  167 +
  168 + if (!kobj->k_name || !kobj->k_name[0]) {
  169 + pr_debug("kobject: (%p): attempted to be registered with empty "
171 170 "name!\n", kobj);
172 171 WARN_ON(1);
173   - kobject_put(kobj);
174 172 return -EINVAL;
175 173 }
  174 +
176 175 parent = kobject_get(kobj->parent);
177 176  
178   - pr_debug("kobject: '%s' (%p): %s: parent: '%s', set: '%s'\n",
179   - kobject_name(kobj), kobj, __FUNCTION__,
180   - parent ? kobject_name(parent) : "<NULL>",
181   - kobj->kset ? kobject_name(&kobj->kset->kobj) : "<NULL>" );
182   -
  177 + /* join kset if set, use it as parent if we do not already have one */
183 178 if (kobj->kset) {
184   - kobj->kset = kset_get(kobj->kset);
185   -
186   - if (!parent) {
  179 + if (!parent)
187 180 parent = kobject_get(&kobj->kset->kobj);
188   - /*
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);
  181 + kobj_kset_join(kobj);
199 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 190 error = create_dir(kobj);
203 191 if (error) {
204   - /* unlink does the kobject_put() for us */
205   - unlink(kobj);
  192 + kobj_kset_leave(kobj);
  193 + kobject_put(parent);
  194 + kobj->parent = NULL;
206 195  
207 196 /* be noisy on error issues */
208 197 if (error == -EEXIST)
... ... @@ -214,7 +203,8 @@
214 203 printk(KERN_ERR "%s failed for %s (%d)\n",
215 204 __FUNCTION__, kobject_name(kobj), error);
216 205 dump_stack();
217   - }
  206 + } else
  207 + kobj->state_in_sysfs = 1;
218 208  
219 209 return error;
220 210 }
221 211  
... ... @@ -238,11 +228,13 @@
238 228 if (!name)
239 229 return -ENOMEM;
240 230  
  231 +
241 232 /* Free the old name, if necessary. */
242 233 kfree(kobj->k_name);
243 234  
244 235 /* Now, set the new name */
245 236 kobj->k_name = name;
  237 + kobj->state_name_set = 1;
246 238  
247 239 return 0;
248 240 }
249 241  
250 242  
251 243  
... ... @@ -293,20 +285,25 @@
293 285 err_str = "must have a ktype to be initialized properly!\n";
294 286 goto error;
295 287 }
296   - if (atomic_read(&kobj->kref.refcount)) {
  288 + if (kobj->state_initialized) {
297 289 /* do not error out as sometimes we can recover */
298   - printk(KERN_ERR "kobject: reference count is already set, "
299   - "something is seriously wrong.\n");
  290 + printk(KERN_ERR "kobject (%p): tried to init an initialized "
  291 + "object, something is seriously wrong.\n", kobj);
300 292 dump_stack();
301 293 }
302 294  
303 295 kref_init(&kobj->kref);
304 296 INIT_LIST_HEAD(&kobj->entry);
305 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 303 return;
307 304  
308 305 error:
309   - printk(KERN_ERR "kobject: %s\n", err_str);
  306 + printk(KERN_ERR "kobject (%p): %s\n", kobj, err_str);
310 307 dump_stack();
311 308 }
312 309 EXPORT_SYMBOL(kobject_init);
313 310  
... ... @@ -345,17 +342,10 @@
345 342 *
346 343 * If this function returns an error, kobject_put() must be called to
347 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 345 * Under no instance should the kobject that is passed to this function
356 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 349 * up all of the necessary sysfs files for the object and then call
360 350 * kobject_uevent() with the UEVENT_ADD parameter to ensure that
361 351 * userspace is properly notified of this kobject's creation.
... ... @@ -369,6 +359,13 @@
369 359 if (!kobj)
370 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 369 va_start(args, fmt);
373 370 retval = kobject_add_varg(kobj, parent, fmt, args);
374 371 va_end(args);
375 372  
... ... @@ -527,8 +524,12 @@
527 524 {
528 525 if (!kobj)
529 526 return;
  527 +
530 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 /**
535 536  
536 537  
537 538  
538 539  
539 540  
... ... @@ -565,21 +566,43 @@
565 566 */
566 567 static void kobject_cleanup(struct kobject *kobj)
567 568 {
568   - struct kobj_type * t = get_ktype(kobj);
569   - struct kset * s = kobj->kset;
  569 + struct kobj_type *t = get_ktype(kobj);
570 570 const char *name = kobj->k_name;
  571 + int name_set = kobj->state_name_set;
571 572  
572 573 pr_debug("kobject: '%s' (%p): %s\n",
573 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 595 if (t && t->release) {
  596 + pr_debug("kobject: '%s' (%p): calling ktype release\n",
  597 + kobject_name(kobj), kobj);
575 598 t->release(kobj);
576   - /* If we have a release function, we can guess that this was
577   - * not a statically allocated kobject, so we should be safe to
578   - * free the name */
  599 + }
  600 +
  601 + /* free name if we allocated it */
  602 + if (name_set && name) {
  603 + pr_debug("kobject: '%s': free name\n", name);
579 604 kfree(name);
580 605 }
581   - if (s)
582   - kset_put(s);
583 606 }
584 607  
585 608 static void kobject_release(struct kref *kref)
... ... @@ -601,8 +624,7 @@
601 624  
602 625 static void dynamic_kobj_release(struct kobject *kobj)
603 626 {
604   - pr_debug("kobject: '%s' (%p): %s\n",
605   - kobject_name(kobj), kobj, __FUNCTION__);
  627 + pr_debug("kobject: (%p): %s\n", kobj, __FUNCTION__);
606 628 kfree(kobj);
607 629 }
608 630  
lib/kobject_uevent.c
... ... @@ -180,6 +180,17 @@
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 194 /* we will send an event, so request a new sequence number */
184 195 spin_lock(&sequence_lock);
185 196 seq = ++uevent_seqnum;