aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/w1/w1.c
diff options
context:
space:
mode:
authorDavid Fries <david@fries.net>2008-10-16 01:04:38 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2008-10-16 14:21:49 -0400
commitc30c9b15187e977ab5928f7276e9dfcd8d6f9460 (patch)
treed36d7513c5acf1d39f581625ffa5c1915ae5627f /drivers/w1/w1.c
parentdd78c9439fc1e031835bccb934d27b978c72c536 (diff)
W1: fix deadlocks and remove w1_control_thread
w1_control_thread was removed which would wake up every second and process newly registered family codes and complete some final cleanup for a removed master. Those routines were moved to the threads that were previously requesting those operations. A new function w1_reconnect_slaves takes care of reconnecting existing slave devices when a new family code is registered or removed. The removal case was missing and would cause a deadlock waiting for the family code reference count to decrease, which will now happen. A problem with registering a family code was fixed. A slave device would be unattached if it wasn't yet claimed, then attached at the end of the list, two unclaimed slaves would cause an infinite loop. The struct w1_bus_master.search now takes a pointer to the struct w1_master device to avoid searching for it, which would have caused a lock ordering deadlock with the removal of w1_control_thread. Signed-off-by: David Fries <david@fries.net> Signed-off-by: Evgeniy Polyakov <johnpol@2ka.mipt.ru> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'drivers/w1/w1.c')
-rw-r--r--drivers/w1/w1.c146
1 files changed, 34 insertions, 112 deletions
diff --git a/drivers/w1/w1.c b/drivers/w1/w1.c
index 7293c9b11f91..25640f681729 100644
--- a/drivers/w1/w1.c
+++ b/drivers/w1/w1.c
@@ -46,20 +46,16 @@ MODULE_AUTHOR("Evgeniy Polyakov <johnpol@2ka.mipt.ru>");
46MODULE_DESCRIPTION("Driver for 1-wire Dallas network protocol."); 46MODULE_DESCRIPTION("Driver for 1-wire Dallas network protocol.");
47 47
48static int w1_timeout = 10; 48static int w1_timeout = 10;
49static int w1_control_timeout = 1;
50int w1_max_slave_count = 10; 49int w1_max_slave_count = 10;
51int w1_max_slave_ttl = 10; 50int w1_max_slave_ttl = 10;
52 51
53module_param_named(timeout, w1_timeout, int, 0); 52module_param_named(timeout, w1_timeout, int, 0);
54module_param_named(control_timeout, w1_control_timeout, int, 0);
55module_param_named(max_slave_count, w1_max_slave_count, int, 0); 53module_param_named(max_slave_count, w1_max_slave_count, int, 0);
56module_param_named(slave_ttl, w1_max_slave_ttl, int, 0); 54module_param_named(slave_ttl, w1_max_slave_ttl, int, 0);
57 55
58DEFINE_MUTEX(w1_mlock); 56DEFINE_MUTEX(w1_mlock);
59LIST_HEAD(w1_masters); 57LIST_HEAD(w1_masters);
60 58
61static struct task_struct *w1_control_thread;
62
63static int w1_master_match(struct device *dev, struct device_driver *drv) 59static int w1_master_match(struct device *dev, struct device_driver *drv)
64{ 60{
65 return 1; 61 return 1;
@@ -390,7 +386,7 @@ int w1_create_master_attributes(struct w1_master *master)
390 return sysfs_create_group(&master->dev.kobj, &w1_master_defattr_group); 386 return sysfs_create_group(&master->dev.kobj, &w1_master_defattr_group);
391} 387}
392 388
393static void w1_destroy_master_attributes(struct w1_master *master) 389void w1_destroy_master_attributes(struct w1_master *master)
394{ 390{
395 sysfs_remove_group(&master->dev.kobj, &w1_master_defattr_group); 391 sysfs_remove_group(&master->dev.kobj, &w1_master_defattr_group);
396} 392}
@@ -567,7 +563,7 @@ static int w1_attach_slave_device(struct w1_master *dev, struct w1_reg_num *rn)
567 return 0; 563 return 0;
568} 564}
569 565
570static void w1_slave_detach(struct w1_slave *sl) 566void w1_slave_detach(struct w1_slave *sl)
571{ 567{
572 struct w1_netlink_msg msg; 568 struct w1_netlink_msg msg;
573 569
@@ -591,24 +587,6 @@ static void w1_slave_detach(struct w1_slave *sl)
591 kfree(sl); 587 kfree(sl);
592} 588}
593 589
594static struct w1_master *w1_search_master(void *data)
595{
596 struct w1_master *dev;
597 int found = 0;
598
599 mutex_lock(&w1_mlock);
600 list_for_each_entry(dev, &w1_masters, w1_master_entry) {
601 if (dev->bus_master->data == data) {
602 found = 1;
603 atomic_inc(&dev->refcnt);
604 break;
605 }
606 }
607 mutex_unlock(&w1_mlock);
608
609 return (found)?dev:NULL;
610}
611
612struct w1_master *w1_search_master_id(u32 id) 590struct w1_master *w1_search_master_id(u32 id)
613{ 591{
614 struct w1_master *dev; 592 struct w1_master *dev;
@@ -656,34 +634,49 @@ struct w1_slave *w1_search_slave(struct w1_reg_num *id)
656 return (found)?sl:NULL; 634 return (found)?sl:NULL;
657} 635}
658 636
659void w1_reconnect_slaves(struct w1_family *f) 637void w1_reconnect_slaves(struct w1_family *f, int attach)
660{ 638{
639 struct w1_slave *sl, *sln;
661 struct w1_master *dev; 640 struct w1_master *dev;
662 641
663 mutex_lock(&w1_mlock); 642 mutex_lock(&w1_mlock);
664 list_for_each_entry(dev, &w1_masters, w1_master_entry) { 643 list_for_each_entry(dev, &w1_masters, w1_master_entry) {
665 dev_dbg(&dev->dev, "Reconnecting slaves in %s into new family %02x.\n", 644 dev_dbg(&dev->dev, "Reconnecting slaves in device %s "
666 dev->name, f->fid); 645 "for family %02x.\n", dev->name, f->fid);
667 set_bit(W1_MASTER_NEED_RECONNECT, &dev->flags); 646 mutex_lock(&dev->mutex);
647 list_for_each_entry_safe(sl, sln, &dev->slist, w1_slave_entry) {
648 /* If it is a new family, slaves with the default
649 * family driver and are that family will be
650 * connected. If the family is going away, devices
651 * matching that family are reconneced.
652 */
653 if ((attach && sl->family->fid == W1_FAMILY_DEFAULT
654 && sl->reg_num.family == f->fid) ||
655 (!attach && sl->family->fid == f->fid)) {
656 struct w1_reg_num rn;
657
658 memcpy(&rn, &sl->reg_num, sizeof(rn));
659 w1_slave_detach(sl);
660
661 w1_attach_slave_device(dev, &rn);
662 }
663 }
664 dev_dbg(&dev->dev, "Reconnecting slaves in device %s "
665 "has been finished.\n", dev->name);
666 mutex_unlock(&dev->mutex);
668 } 667 }
669 mutex_unlock(&w1_mlock); 668 mutex_unlock(&w1_mlock);
670} 669}
671 670
672static void w1_slave_found(void *data, u64 rn) 671static void w1_slave_found(struct w1_master *dev, u64 rn)
673{ 672{
674 int slave_count; 673 int slave_count;
675 struct w1_slave *sl; 674 struct w1_slave *sl;
676 struct list_head *ent; 675 struct list_head *ent;
677 struct w1_reg_num *tmp; 676 struct w1_reg_num *tmp;
678 struct w1_master *dev;
679 u64 rn_le = cpu_to_le64(rn); 677 u64 rn_le = cpu_to_le64(rn);
680 678
681 dev = w1_search_master(data); 679 atomic_inc(&dev->refcnt);
682 if (!dev) {
683 printk(KERN_ERR "Failed to find w1 master device for data %p, "
684 "it is impossible.\n", data);
685 return;
686 }
687 680
688 tmp = (struct w1_reg_num *) &rn; 681 tmp = (struct w1_reg_num *) &rn;
689 682
@@ -785,76 +778,11 @@ void w1_search(struct w1_master *dev, u8 search_type, w1_slave_found_callback cb
785 if ( (desc_bit == last_zero) || (last_zero < 0)) 778 if ( (desc_bit == last_zero) || (last_zero < 0))
786 last_device = 1; 779 last_device = 1;
787 desc_bit = last_zero; 780 desc_bit = last_zero;
788 cb(dev->bus_master->data, rn); 781 cb(dev, rn);
789 } 782 }
790 } 783 }
791} 784}
792 785
793static int w1_control(void *data)
794{
795 struct w1_slave *sl, *sln;
796 struct w1_master *dev, *n;
797 int have_to_wait = 0;
798
799 set_freezable();
800 while (!kthread_should_stop() || have_to_wait) {
801 have_to_wait = 0;
802
803 try_to_freeze();
804 msleep_interruptible(w1_control_timeout * 1000);
805
806 list_for_each_entry_safe(dev, n, &w1_masters, w1_master_entry) {
807 if (!kthread_should_stop() && !dev->flags)
808 continue;
809 /*
810 * Little race: we can create thread but not set the flag.
811 * Get a chance for external process to set flag up.
812 */
813 if (!dev->initialized) {
814 have_to_wait = 1;
815 continue;
816 }
817
818 if (kthread_should_stop() || test_bit(W1_MASTER_NEED_EXIT, &dev->flags)) {
819 set_bit(W1_MASTER_NEED_EXIT, &dev->flags);
820
821 mutex_lock(&w1_mlock);
822 list_del(&dev->w1_master_entry);
823 mutex_unlock(&w1_mlock);
824
825 mutex_lock(&dev->mutex);
826 list_for_each_entry_safe(sl, sln, &dev->slist, w1_slave_entry) {
827 w1_slave_detach(sl);
828 }
829 w1_destroy_master_attributes(dev);
830 mutex_unlock(&dev->mutex);
831 atomic_dec(&dev->refcnt);
832 continue;
833 }
834
835 if (test_bit(W1_MASTER_NEED_RECONNECT, &dev->flags)) {
836 dev_dbg(&dev->dev, "Reconnecting slaves in device %s.\n", dev->name);
837 mutex_lock(&dev->mutex);
838 list_for_each_entry_safe(sl, sln, &dev->slist, w1_slave_entry) {
839 if (sl->family->fid == W1_FAMILY_DEFAULT) {
840 struct w1_reg_num rn;
841
842 memcpy(&rn, &sl->reg_num, sizeof(rn));
843 w1_slave_detach(sl);
844
845 w1_attach_slave_device(dev, &rn);
846 }
847 }
848 dev_dbg(&dev->dev, "Reconnecting slaves in device %s has been finished.\n", dev->name);
849 clear_bit(W1_MASTER_NEED_RECONNECT, &dev->flags);
850 mutex_unlock(&dev->mutex);
851 }
852 }
853 }
854
855 return 0;
856}
857
858void w1_search_process(struct w1_master *dev, u8 search_type) 786void w1_search_process(struct w1_master *dev, u8 search_type)
859{ 787{
860 struct w1_slave *sl, *sln; 788 struct w1_slave *sl, *sln;
@@ -932,18 +860,13 @@ static int w1_init(void)
932 goto err_out_master_unregister; 860 goto err_out_master_unregister;
933 } 861 }
934 862
935 w1_control_thread = kthread_run(w1_control, NULL, "w1_control");
936 if (IS_ERR(w1_control_thread)) {
937 retval = PTR_ERR(w1_control_thread);
938 printk(KERN_ERR "Failed to create control thread. err=%d\n",
939 retval);
940 goto err_out_slave_unregister;
941 }
942
943 return 0; 863 return 0;
944 864
865#if 0
866/* For undoing the slave register if there was a step after it. */
945err_out_slave_unregister: 867err_out_slave_unregister:
946 driver_unregister(&w1_slave_driver); 868 driver_unregister(&w1_slave_driver);
869#endif
947 870
948err_out_master_unregister: 871err_out_master_unregister:
949 driver_unregister(&w1_master_driver); 872 driver_unregister(&w1_master_driver);
@@ -959,13 +882,12 @@ static void w1_fini(void)
959{ 882{
960 struct w1_master *dev; 883 struct w1_master *dev;
961 884
885 /* Set netlink removal messages and some cleanup */
962 list_for_each_entry(dev, &w1_masters, w1_master_entry) 886 list_for_each_entry(dev, &w1_masters, w1_master_entry)
963 __w1_remove_master_device(dev); 887 __w1_remove_master_device(dev);
964 888
965 w1_fini_netlink(); 889 w1_fini_netlink();
966 890
967 kthread_stop(w1_control_thread);
968
969 driver_unregister(&w1_slave_driver); 891 driver_unregister(&w1_slave_driver);
970 driver_unregister(&w1_master_driver); 892 driver_unregister(&w1_master_driver);
971 bus_unregister(&w1_bus_type); 893 bus_unregister(&w1_bus_type);