Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

class: change internal semaphore to a mutex

Now that the lockdep infrastructure in the class core is in place, we
should be able to properly change the internal class semaphore to be a
mutex.

David wrote the original patch, and Greg fixed it up to apply properly
due to all of the recent changes in this area.

From: Dave Young <hidave.darkstar@gmail.com>
Cc: Matthew Wilcox <matthew@wil.cx>
Cc: Kay Sievers <kay.sievers@vrfy.org>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: James Bottomley <James.Bottomley@HansenPartnership.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>

authored by

Dave Young and committed by
Greg Kroah-Hartman
f75b1c60 d2a3b914

+19 -17
+2 -2
drivers/base/base.h
··· 44 44 * @class_devices - list of devices associated with this class 45 45 * @class_interfaces - list of class_interfaces associated with this class 46 46 * @class_dirs - "glue" directory for virtual devices associated with this class 47 - * @class_sem - semaphore to protect the children, devices, and interfaces lists. 47 + * @class_mutex - mutex to protect the children, devices, and interfaces lists. 48 48 * @class - pointer back to the struct class that this structure is associated 49 49 * with. 50 50 * ··· 57 57 struct list_head class_devices; 58 58 struct list_head class_interfaces; 59 59 struct kset class_dirs; 60 - struct semaphore class_sem; 60 + struct mutex class_mutex; 61 61 struct class *class; 62 62 }; 63 63 #define to_class(obj) \
+12 -11
drivers/base/class.c
··· 18 18 #include <linux/err.h> 19 19 #include <linux/slab.h> 20 20 #include <linux/genhd.h> 21 + #include <linux/mutex.h> 21 22 #include "base.h" 22 23 23 24 #define to_class_attr(_attr) container_of(_attr, struct class_attribute, attr) ··· 148 147 INIT_LIST_HEAD(&cp->class_devices); 149 148 INIT_LIST_HEAD(&cp->class_interfaces); 150 149 kset_init(&cp->class_dirs); 151 - init_MUTEX(&cp->class_sem); 150 + __mutex_init(&cp->class_mutex, "struct class mutex", key); 152 151 error = kobject_set_name(&cp->class_subsys.kobj, "%s", cls->name); 153 152 if (error) { 154 153 kfree(cp); ··· 282 281 * We check the return of @fn each time. If it returns anything 283 282 * other than 0, we break out and return that value. 284 283 * 285 - * Note, we hold class->class_sem in this function, so it can not be 284 + * Note, we hold class->class_mutex in this function, so it can not be 286 285 * re-acquired in @fn, otherwise it will self-deadlocking. For 287 286 * example, calls to add or remove class members would be verboten. 288 287 */ ··· 294 293 295 294 if (!class) 296 295 return -EINVAL; 297 - down(&class->p->class_sem); 296 + mutex_lock(&class->p->class_mutex); 298 297 list_for_each_entry(dev, &class->p->class_devices, node) { 299 298 if (start) { 300 299 if (start == dev) ··· 307 306 if (error) 308 307 break; 309 308 } 310 - up(&class->p->class_sem); 309 + mutex_unlock(&class->p->class_mutex); 311 310 312 311 return error; 313 312 } ··· 330 329 * 331 330 * Note, you will need to drop the reference with put_device() after use. 332 331 * 333 - * We hold class->class_sem in this function, so it can not be 332 + * We hold class->class_mutex in this function, so it can not be 334 333 * re-acquired in @match, otherwise it will self-deadlocking. For 335 334 * example, calls to add or remove class members would be verboten. 336 335 */ ··· 344 343 if (!class) 345 344 return NULL; 346 345 347 - down(&class->p->class_sem); 346 + mutex_lock(&class->p->class_mutex); 348 347 list_for_each_entry(dev, &class->p->class_devices, node) { 349 348 if (start) { 350 349 if (start == dev) ··· 358 357 } else 359 358 put_device(dev); 360 359 } 361 - up(&class->p->class_sem); 360 + mutex_unlock(&class->p->class_mutex); 362 361 363 362 return found ? dev : NULL; 364 363 } ··· 376 375 if (!parent) 377 376 return -EINVAL; 378 377 379 - down(&parent->p->class_sem); 378 + mutex_lock(&parent->p->class_mutex); 380 379 list_add_tail(&class_intf->node, &parent->p->class_interfaces); 381 380 if (class_intf->add_dev) { 382 381 list_for_each_entry(dev, &parent->p->class_devices, node) 383 382 class_intf->add_dev(dev, class_intf); 384 383 } 385 - up(&parent->p->class_sem); 384 + mutex_unlock(&parent->p->class_mutex); 386 385 387 386 return 0; 388 387 } ··· 395 394 if (!parent) 396 395 return; 397 396 398 - down(&parent->p->class_sem); 397 + mutex_lock(&parent->p->class_mutex); 399 398 list_del_init(&class_intf->node); 400 399 if (class_intf->remove_dev) { 401 400 list_for_each_entry(dev, &parent->p->class_devices, node) 402 401 class_intf->remove_dev(dev, class_intf); 403 402 } 404 - up(&parent->p->class_sem); 403 + mutex_unlock(&parent->p->class_mutex); 405 404 406 405 class_put(parent); 407 406 }
+5 -4
drivers/base/core.c
··· 21 21 #include <linux/genhd.h> 22 22 #include <linux/kallsyms.h> 23 23 #include <linux/semaphore.h> 24 + #include <linux/mutex.h> 24 25 25 26 #include "base.h" 26 27 #include "power/power.h" ··· 908 907 klist_add_tail(&dev->knode_parent, &parent->klist_children); 909 908 910 909 if (dev->class) { 911 - down(&dev->class->p->class_sem); 910 + mutex_lock(&dev->class->p->class_mutex); 912 911 /* tie the class to the device */ 913 912 list_add_tail(&dev->node, &dev->class->p->class_devices); 914 913 ··· 917 916 &dev->class->p->class_interfaces, node) 918 917 if (class_intf->add_dev) 919 918 class_intf->add_dev(dev, class_intf); 920 - up(&dev->class->p->class_sem); 919 + mutex_unlock(&dev->class->p->class_mutex); 921 920 } 922 921 Done: 923 922 put_device(dev); ··· 1018 1017 if (dev->class) { 1019 1018 device_remove_class_symlinks(dev); 1020 1019 1021 - down(&dev->class->p->class_sem); 1020 + mutex_lock(&dev->class->p->class_mutex); 1022 1021 /* notify any interfaces that the device is now gone */ 1023 1022 list_for_each_entry(class_intf, 1024 1023 &dev->class->p->class_interfaces, node) ··· 1026 1025 class_intf->remove_dev(dev, class_intf); 1027 1026 /* remove the device from the class list */ 1028 1027 list_del_init(&dev->node); 1029 - up(&dev->class->p->class_sem); 1028 + mutex_unlock(&dev->class->p->class_mutex); 1030 1029 } 1031 1030 device_remove_file(dev, &uevent_attr); 1032 1031 device_remove_attrs(dev);