diff options
author | Evgeniy Polyakov <johnpol@2ka.mipt.ru> | 2006-02-20 03:15:37 -0500 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2006-03-23 20:28:13 -0500 |
commit | 674a396c6d2ba0341ebdd7c1c9950f32f018e2dd (patch) | |
tree | b1263e0a926d9cbdc7aa58260099392ad49a72fe | |
parent | f73b5e7949945486a649e40821cd351e2f60bf02 (diff) |
[PATCH] w1: use kthread api.
This patch removes old-style kernel thread initialization
and changes w1 to use kthread api.
It is based on Christoph Hellwig <hch@lst.de> work.
Signed-off-by: Evgeniy Polyakov <johnpol@2ka.mipt.ru>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
-rw-r--r-- | drivers/w1/w1.c | 56 | ||||
-rw-r--r-- | drivers/w1/w1.h | 3 | ||||
-rw-r--r-- | drivers/w1/w1_int.c | 34 |
3 files changed, 28 insertions, 65 deletions
diff --git a/drivers/w1/w1.c b/drivers/w1/w1.c index d640c1e1f8cd..a698b517e863 100644 --- a/drivers/w1/w1.c +++ b/drivers/w1/w1.c | |||
@@ -30,6 +30,7 @@ | |||
30 | #include <linux/device.h> | 30 | #include <linux/device.h> |
31 | #include <linux/slab.h> | 31 | #include <linux/slab.h> |
32 | #include <linux/sched.h> | 32 | #include <linux/sched.h> |
33 | #include <linux/kthread.h> | ||
33 | 34 | ||
34 | #include <asm/atomic.h> | 35 | #include <asm/atomic.h> |
35 | 36 | ||
@@ -57,9 +58,7 @@ module_param_named(slave_ttl, w1_max_slave_ttl, int, 0); | |||
57 | DEFINE_SPINLOCK(w1_mlock); | 58 | DEFINE_SPINLOCK(w1_mlock); |
58 | LIST_HEAD(w1_masters); | 59 | LIST_HEAD(w1_masters); |
59 | 60 | ||
60 | static pid_t control_thread; | 61 | static struct task_struct *w1_control_thread; |
61 | static int control_needs_exit; | ||
62 | static DECLARE_COMPLETION(w1_control_complete); | ||
63 | 62 | ||
64 | static int w1_master_match(struct device *dev, struct device_driver *drv) | 63 | static int w1_master_match(struct device *dev, struct device_driver *drv) |
65 | { | 64 | { |
@@ -717,22 +716,16 @@ static int w1_control(void *data) | |||
717 | { | 716 | { |
718 | struct w1_slave *sl, *sln; | 717 | struct w1_slave *sl, *sln; |
719 | struct w1_master *dev, *n; | 718 | struct w1_master *dev, *n; |
720 | int err, have_to_wait = 0; | 719 | int have_to_wait = 0; |
721 | 720 | ||
722 | daemonize("w1_control"); | 721 | while (!kthread_should_stop() || have_to_wait) { |
723 | allow_signal(SIGTERM); | ||
724 | |||
725 | while (!control_needs_exit || have_to_wait) { | ||
726 | have_to_wait = 0; | 722 | have_to_wait = 0; |
727 | 723 | ||
728 | try_to_freeze(); | 724 | try_to_freeze(); |
729 | msleep_interruptible(w1_control_timeout * 1000); | 725 | msleep_interruptible(w1_control_timeout * 1000); |
730 | 726 | ||
731 | if (signal_pending(current)) | ||
732 | flush_signals(current); | ||
733 | |||
734 | list_for_each_entry_safe(dev, n, &w1_masters, w1_master_entry) { | 727 | list_for_each_entry_safe(dev, n, &w1_masters, w1_master_entry) { |
735 | if (!control_needs_exit && !dev->flags) | 728 | if (!kthread_should_stop() && !dev->flags) |
736 | continue; | 729 | continue; |
737 | /* | 730 | /* |
738 | * Little race: we can create thread but not set the flag. | 731 | * Little race: we can create thread but not set the flag. |
@@ -743,21 +736,12 @@ static int w1_control(void *data) | |||
743 | continue; | 736 | continue; |
744 | } | 737 | } |
745 | 738 | ||
746 | if (control_needs_exit) { | 739 | if (kthread_should_stop() || test_bit(W1_MASTER_NEED_EXIT, &dev->flags)) { |
747 | set_bit(W1_MASTER_NEED_EXIT, &dev->flags); | 740 | set_bit(W1_MASTER_NEED_EXIT, &dev->flags); |
748 | 741 | ||
749 | err = kill_proc(dev->kpid, SIGTERM, 1); | 742 | spin_lock(&w1_mlock); |
750 | if (err) | ||
751 | dev_err(&dev->dev, | ||
752 | "Failed to send signal to w1 kernel thread %d.\n", | ||
753 | dev->kpid); | ||
754 | } | ||
755 | |||
756 | if (test_bit(W1_MASTER_NEED_EXIT, &dev->flags)) { | ||
757 | wait_for_completion(&dev->dev_exited); | ||
758 | spin_lock_bh(&w1_mlock); | ||
759 | list_del(&dev->w1_master_entry); | 743 | list_del(&dev->w1_master_entry); |
760 | spin_unlock_bh(&w1_mlock); | 744 | spin_unlock(&w1_mlock); |
761 | 745 | ||
762 | down(&dev->mutex); | 746 | down(&dev->mutex); |
763 | list_for_each_entry_safe(sl, sln, &dev->slist, w1_slave_entry) { | 747 | list_for_each_entry_safe(sl, sln, &dev->slist, w1_slave_entry) { |
@@ -789,7 +773,7 @@ static int w1_control(void *data) | |||
789 | } | 773 | } |
790 | } | 774 | } |
791 | 775 | ||
792 | complete_and_exit(&w1_control_complete, 0); | 776 | return 0; |
793 | } | 777 | } |
794 | 778 | ||
795 | int w1_process(void *data) | 779 | int w1_process(void *data) |
@@ -797,17 +781,11 @@ int w1_process(void *data) | |||
797 | struct w1_master *dev = (struct w1_master *) data; | 781 | struct w1_master *dev = (struct w1_master *) data; |
798 | struct w1_slave *sl, *sln; | 782 | struct w1_slave *sl, *sln; |
799 | 783 | ||
800 | daemonize("%s", dev->name); | 784 | while (!kthread_should_stop() && !test_bit(W1_MASTER_NEED_EXIT, &dev->flags)) { |
801 | allow_signal(SIGTERM); | ||
802 | |||
803 | while (!test_bit(W1_MASTER_NEED_EXIT, &dev->flags)) { | ||
804 | try_to_freeze(); | 785 | try_to_freeze(); |
805 | msleep_interruptible(w1_timeout * 1000); | 786 | msleep_interruptible(w1_timeout * 1000); |
806 | 787 | ||
807 | if (signal_pending(current)) | 788 | if (kthread_should_stop() || test_bit(W1_MASTER_NEED_EXIT, &dev->flags)) |
808 | flush_signals(current); | ||
809 | |||
810 | if (test_bit(W1_MASTER_NEED_EXIT, &dev->flags)) | ||
811 | break; | 789 | break; |
812 | 790 | ||
813 | if (!dev->initialized) | 791 | if (!dev->initialized) |
@@ -840,7 +818,6 @@ int w1_process(void *data) | |||
840 | } | 818 | } |
841 | 819 | ||
842 | atomic_dec(&dev->refcnt); | 820 | atomic_dec(&dev->refcnt); |
843 | complete_and_exit(&dev->dev_exited, 0); | ||
844 | 821 | ||
845 | return 0; | 822 | return 0; |
846 | } | 823 | } |
@@ -873,11 +850,11 @@ static int w1_init(void) | |||
873 | goto err_out_master_unregister; | 850 | goto err_out_master_unregister; |
874 | } | 851 | } |
875 | 852 | ||
876 | control_thread = kernel_thread(&w1_control, NULL, 0); | 853 | w1_control_thread = kthread_run(w1_control, NULL, "w1_control"); |
877 | if (control_thread < 0) { | 854 | if (IS_ERR(w1_control_thread)) { |
855 | retval = PTR_ERR(w1_control_thread); | ||
878 | printk(KERN_ERR "Failed to create control thread. err=%d\n", | 856 | printk(KERN_ERR "Failed to create control thread. err=%d\n", |
879 | control_thread); | 857 | retval); |
880 | retval = control_thread; | ||
881 | goto err_out_slave_unregister; | 858 | goto err_out_slave_unregister; |
882 | } | 859 | } |
883 | 860 | ||
@@ -903,8 +880,7 @@ static void w1_fini(void) | |||
903 | list_for_each_entry(dev, &w1_masters, w1_master_entry) | 880 | list_for_each_entry(dev, &w1_masters, w1_master_entry) |
904 | __w1_remove_master_device(dev); | 881 | __w1_remove_master_device(dev); |
905 | 882 | ||
906 | control_needs_exit = 1; | 883 | kthread_stop(w1_control_thread); |
907 | wait_for_completion(&w1_control_complete); | ||
908 | 884 | ||
909 | driver_unregister(&w1_slave_driver); | 885 | driver_unregister(&w1_slave_driver); |
910 | driver_unregister(&w1_master_driver); | 886 | driver_unregister(&w1_master_driver); |
diff --git a/drivers/w1/w1.h b/drivers/w1/w1.h index 5f09213512bf..56980505e6c4 100644 --- a/drivers/w1/w1.h +++ b/drivers/w1/w1.h | |||
@@ -172,12 +172,11 @@ struct w1_master | |||
172 | 172 | ||
173 | long flags; | 173 | long flags; |
174 | 174 | ||
175 | pid_t kpid; | 175 | struct task_struct *thread; |
176 | struct semaphore mutex; | 176 | struct semaphore mutex; |
177 | 177 | ||
178 | struct device_driver *driver; | 178 | struct device_driver *driver; |
179 | struct device dev; | 179 | struct device dev; |
180 | struct completion dev_exited; | ||
181 | 180 | ||
182 | struct w1_bus_master *bus_master; | 181 | struct w1_bus_master *bus_master; |
183 | 182 | ||
diff --git a/drivers/w1/w1_int.c b/drivers/w1/w1_int.c index a2f9065e1928..68565aacec7b 100644 --- a/drivers/w1/w1_int.c +++ b/drivers/w1/w1_int.c | |||
@@ -22,6 +22,7 @@ | |||
22 | #include <linux/kernel.h> | 22 | #include <linux/kernel.h> |
23 | #include <linux/list.h> | 23 | #include <linux/list.h> |
24 | #include <linux/delay.h> | 24 | #include <linux/delay.h> |
25 | #include <linux/kthread.h> | ||
25 | 26 | ||
26 | #include "w1.h" | 27 | #include "w1.h" |
27 | #include "w1_log.h" | 28 | #include "w1_log.h" |
@@ -56,7 +57,6 @@ static struct w1_master * w1_alloc_dev(u32 id, int slave_count, int slave_ttl, | |||
56 | dev->max_slave_count = slave_count; | 57 | dev->max_slave_count = slave_count; |
57 | dev->slave_count = 0; | 58 | dev->slave_count = 0; |
58 | dev->attempts = 0; | 59 | dev->attempts = 0; |
59 | dev->kpid = -1; | ||
60 | dev->initialized = 0; | 60 | dev->initialized = 0; |
61 | dev->id = id; | 61 | dev->id = id; |
62 | dev->slave_ttl = slave_ttl; | 62 | dev->slave_ttl = slave_ttl; |
@@ -67,8 +67,6 @@ static struct w1_master * w1_alloc_dev(u32 id, int slave_count, int slave_ttl, | |||
67 | INIT_LIST_HEAD(&dev->slist); | 67 | INIT_LIST_HEAD(&dev->slist); |
68 | init_MUTEX(&dev->mutex); | 68 | init_MUTEX(&dev->mutex); |
69 | 69 | ||
70 | init_completion(&dev->dev_exited); | ||
71 | |||
72 | memcpy(&dev->dev, device, sizeof(struct device)); | 70 | memcpy(&dev->dev, device, sizeof(struct device)); |
73 | snprintf(dev->dev.bus_id, sizeof(dev->dev.bus_id), | 71 | snprintf(dev->dev.bus_id, sizeof(dev->dev.bus_id), |
74 | "w1_bus_master%u", dev->id); | 72 | "w1_bus_master%u", dev->id); |
@@ -116,12 +114,12 @@ int w1_add_master_device(struct w1_bus_master *master) | |||
116 | if (!dev) | 114 | if (!dev) |
117 | return -ENOMEM; | 115 | return -ENOMEM; |
118 | 116 | ||
119 | dev->kpid = kernel_thread(&w1_process, dev, 0); | 117 | dev->thread = kthread_run(&w1_process, dev, "%s", dev->name); |
120 | if (dev->kpid < 0) { | 118 | if (IS_ERR(dev->thread)) { |
119 | retval = PTR_ERR(dev->thread); | ||
121 | dev_err(&dev->dev, | 120 | dev_err(&dev->dev, |
122 | "Failed to create new kernel thread. err=%d\n", | 121 | "Failed to create new kernel thread. err=%d\n", |
123 | dev->kpid); | 122 | retval); |
124 | retval = dev->kpid; | ||
125 | goto err_out_free_dev; | 123 | goto err_out_free_dev; |
126 | } | 124 | } |
127 | 125 | ||
@@ -138,20 +136,14 @@ int w1_add_master_device(struct w1_bus_master *master) | |||
138 | spin_unlock(&w1_mlock); | 136 | spin_unlock(&w1_mlock); |
139 | 137 | ||
140 | msg.id.mst.id = dev->id; | 138 | msg.id.mst.id = dev->id; |
141 | msg.id.mst.pid = dev->kpid; | 139 | msg.id.mst.pid = dev->thread->pid; |
142 | msg.type = W1_MASTER_ADD; | 140 | msg.type = W1_MASTER_ADD; |
143 | w1_netlink_send(dev, &msg); | 141 | w1_netlink_send(dev, &msg); |
144 | 142 | ||
145 | return 0; | 143 | return 0; |
146 | 144 | ||
147 | err_out_kill_thread: | 145 | err_out_kill_thread: |
148 | set_bit(W1_MASTER_NEED_EXIT, &dev->flags); | 146 | kthread_stop(dev->thread); |
149 | if (kill_proc(dev->kpid, SIGTERM, 1)) | ||
150 | dev_err(&dev->dev, | ||
151 | "Failed to send signal to w1 kernel thread %d.\n", | ||
152 | dev->kpid); | ||
153 | wait_for_completion(&dev->dev_exited); | ||
154 | |||
155 | err_out_free_dev: | 147 | err_out_free_dev: |
156 | w1_free_dev(dev); | 148 | w1_free_dev(dev); |
157 | 149 | ||
@@ -160,18 +152,14 @@ err_out_free_dev: | |||
160 | 152 | ||
161 | void __w1_remove_master_device(struct w1_master *dev) | 153 | void __w1_remove_master_device(struct w1_master *dev) |
162 | { | 154 | { |
163 | int err; | ||
164 | struct w1_netlink_msg msg; | 155 | struct w1_netlink_msg msg; |
156 | pid_t pid = dev->thread->pid; | ||
165 | 157 | ||
166 | set_bit(W1_MASTER_NEED_EXIT, &dev->flags); | 158 | set_bit(W1_MASTER_NEED_EXIT, &dev->flags); |
167 | err = kill_proc(dev->kpid, SIGTERM, 1); | 159 | kthread_stop(dev->thread); |
168 | if (err) | ||
169 | dev_err(&dev->dev, | ||
170 | "%s: Failed to send signal to w1 kernel thread %d.\n", | ||
171 | __func__, dev->kpid); | ||
172 | 160 | ||
173 | while (atomic_read(&dev->refcnt)) { | 161 | while (atomic_read(&dev->refcnt)) { |
174 | dev_dbg(&dev->dev, "Waiting for %s to become free: refcnt=%d.\n", | 162 | dev_info(&dev->dev, "Waiting for %s to become free: refcnt=%d.\n", |
175 | dev->name, atomic_read(&dev->refcnt)); | 163 | dev->name, atomic_read(&dev->refcnt)); |
176 | 164 | ||
177 | if (msleep_interruptible(1000)) | 165 | if (msleep_interruptible(1000)) |
@@ -179,7 +167,7 @@ void __w1_remove_master_device(struct w1_master *dev) | |||
179 | } | 167 | } |
180 | 168 | ||
181 | msg.id.mst.id = dev->id; | 169 | msg.id.mst.id = dev->id; |
182 | msg.id.mst.pid = dev->kpid; | 170 | msg.id.mst.pid = pid; |
183 | msg.type = W1_MASTER_REMOVE; | 171 | msg.type = W1_MASTER_REMOVE; |
184 | w1_netlink_send(dev, &msg); | 172 | w1_netlink_send(dev, &msg); |
185 | 173 | ||