aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSebastian Ott <sebott@linux.vnet.ibm.com>2010-02-26 16:37:24 -0500
committerMartin Schwidefsky <sky@mschwide.boeblingen.de.ibm.com>2010-02-26 16:37:29 -0500
commitbe5d3823f29c09676abd2eeea4f9767bc4a1a531 (patch)
tree0a89be6c2b36e1db6f1118cf2b483c84d1ac8def
parent6f5d09a0e9731a39a4d52a5902daec72c1e43692 (diff)
[S390] cio: consolidate workqueues
We used to maintain 2 singlethreaded workqueues for synchronization and to trigger work from interrupt context. Since our latest cio changes we only use one of these workqueues. So get rid of the unused workqueue, rename the remaining one to "cio_work_q" and move its ownership to the channel subsystem driver. Signed-off-by: Sebastian Ott <sebott@linux.vnet.ibm.com> Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
-rw-r--r--drivers/s390/cio/css.c26
-rw-r--r--drivers/s390/cio/css.h2
-rw-r--r--drivers/s390/cio/device.c28
-rw-r--r--drivers/s390/cio/device.h1
4 files changed, 25 insertions, 32 deletions
diff --git a/drivers/s390/cio/css.c b/drivers/s390/cio/css.c
index 7679aee6fa14..99fcf9d0ea14 100644
--- a/drivers/s390/cio/css.c
+++ b/drivers/s390/cio/css.c
@@ -232,7 +232,7 @@ void css_sched_sch_todo(struct subchannel *sch, enum sch_todo todo)
232 if (!get_device(&sch->dev)) 232 if (!get_device(&sch->dev))
233 return; 233 return;
234 sch->todo = todo; 234 sch->todo = todo;
235 if (!queue_work(slow_path_wq, &sch->todo_work)) { 235 if (!queue_work(cio_work_q, &sch->todo_work)) {
236 /* Already queued, release workqueue ref. */ 236 /* Already queued, release workqueue ref. */
237 put_device(&sch->dev); 237 put_device(&sch->dev);
238 } 238 }
@@ -543,7 +543,7 @@ static void css_slow_path_func(struct work_struct *unused)
543} 543}
544 544
545static DECLARE_WORK(slow_path_work, css_slow_path_func); 545static DECLARE_WORK(slow_path_work, css_slow_path_func);
546struct workqueue_struct *slow_path_wq; 546struct workqueue_struct *cio_work_q;
547 547
548void css_schedule_eval(struct subchannel_id schid) 548void css_schedule_eval(struct subchannel_id schid)
549{ 549{
@@ -552,7 +552,7 @@ void css_schedule_eval(struct subchannel_id schid)
552 spin_lock_irqsave(&slow_subchannel_lock, flags); 552 spin_lock_irqsave(&slow_subchannel_lock, flags);
553 idset_sch_add(slow_subchannel_set, schid); 553 idset_sch_add(slow_subchannel_set, schid);
554 atomic_set(&css_eval_scheduled, 1); 554 atomic_set(&css_eval_scheduled, 1);
555 queue_work(slow_path_wq, &slow_path_work); 555 queue_work(cio_work_q, &slow_path_work);
556 spin_unlock_irqrestore(&slow_subchannel_lock, flags); 556 spin_unlock_irqrestore(&slow_subchannel_lock, flags);
557} 557}
558 558
@@ -563,7 +563,7 @@ void css_schedule_eval_all(void)
563 spin_lock_irqsave(&slow_subchannel_lock, flags); 563 spin_lock_irqsave(&slow_subchannel_lock, flags);
564 idset_fill(slow_subchannel_set); 564 idset_fill(slow_subchannel_set);
565 atomic_set(&css_eval_scheduled, 1); 565 atomic_set(&css_eval_scheduled, 1);
566 queue_work(slow_path_wq, &slow_path_work); 566 queue_work(cio_work_q, &slow_path_work);
567 spin_unlock_irqrestore(&slow_subchannel_lock, flags); 567 spin_unlock_irqrestore(&slow_subchannel_lock, flags);
568} 568}
569 569
@@ -594,14 +594,14 @@ void css_schedule_eval_all_unreg(void)
594 spin_lock_irqsave(&slow_subchannel_lock, flags); 594 spin_lock_irqsave(&slow_subchannel_lock, flags);
595 idset_add_set(slow_subchannel_set, unreg_set); 595 idset_add_set(slow_subchannel_set, unreg_set);
596 atomic_set(&css_eval_scheduled, 1); 596 atomic_set(&css_eval_scheduled, 1);
597 queue_work(slow_path_wq, &slow_path_work); 597 queue_work(cio_work_q, &slow_path_work);
598 spin_unlock_irqrestore(&slow_subchannel_lock, flags); 598 spin_unlock_irqrestore(&slow_subchannel_lock, flags);
599 idset_free(unreg_set); 599 idset_free(unreg_set);
600} 600}
601 601
602void css_wait_for_slow_path(void) 602void css_wait_for_slow_path(void)
603{ 603{
604 flush_workqueue(slow_path_wq); 604 flush_workqueue(cio_work_q);
605} 605}
606 606
607/* Schedule reprobing of all unregistered subchannels. */ 607/* Schedule reprobing of all unregistered subchannels. */
@@ -992,12 +992,21 @@ static int __init channel_subsystem_init(void)
992 ret = css_bus_init(); 992 ret = css_bus_init();
993 if (ret) 993 if (ret)
994 return ret; 994 return ret;
995 995 cio_work_q = create_singlethread_workqueue("cio");
996 if (!cio_work_q) {
997 ret = -ENOMEM;
998 goto out_bus;
999 }
996 ret = io_subchannel_init(); 1000 ret = io_subchannel_init();
997 if (ret) 1001 if (ret)
998 css_bus_cleanup(); 1002 goto out_wq;
999 1003
1000 return ret; 1004 return ret;
1005out_wq:
1006 destroy_workqueue(cio_work_q);
1007out_bus:
1008 css_bus_cleanup();
1009 return ret;
1001} 1010}
1002subsys_initcall(channel_subsystem_init); 1011subsys_initcall(channel_subsystem_init);
1003 1012
@@ -1020,6 +1029,7 @@ static int __init channel_subsystem_init_sync(void)
1020 css_schedule_eval_all(); 1029 css_schedule_eval_all();
1021 /* Wait for the evaluation of subchannels to finish. */ 1030 /* Wait for the evaluation of subchannels to finish. */
1022 wait_event(css_eval_wq, atomic_read(&css_eval_scheduled) == 0); 1031 wait_event(css_eval_wq, atomic_read(&css_eval_scheduled) == 0);
1032 flush_workqueue(cio_work_q);
1023 /* Wait for the subchannel type specific initialization to finish */ 1033 /* Wait for the subchannel type specific initialization to finish */
1024 return bus_for_each_drv(&css_bus_type, NULL, NULL, css_settle); 1034 return bus_for_each_drv(&css_bus_type, NULL, NULL, css_settle);
1025} 1035}
diff --git a/drivers/s390/cio/css.h b/drivers/s390/cio/css.h
index fe84b92cde60..e05525d53ea5 100644
--- a/drivers/s390/cio/css.h
+++ b/drivers/s390/cio/css.h
@@ -151,7 +151,7 @@ int sch_is_pseudo_sch(struct subchannel *);
151struct schib; 151struct schib;
152int css_sch_is_valid(struct schib *); 152int css_sch_is_valid(struct schib *);
153 153
154extern struct workqueue_struct *slow_path_wq; 154extern struct workqueue_struct *cio_work_q;
155void css_wait_for_slow_path(void); 155void css_wait_for_slow_path(void);
156void css_sched_sch_todo(struct subchannel *sch, enum sch_todo todo); 156void css_sched_sch_todo(struct subchannel *sch, enum sch_todo todo);
157#endif 157#endif
diff --git a/drivers/s390/cio/device.c b/drivers/s390/cio/device.c
index a6c7d5426fb2..9c9ea45141af 100644
--- a/drivers/s390/cio/device.c
+++ b/drivers/s390/cio/device.c
@@ -136,7 +136,6 @@ static int io_subchannel_sch_event(struct subchannel *, int);
136static int io_subchannel_chp_event(struct subchannel *, struct chp_link *, 136static int io_subchannel_chp_event(struct subchannel *, struct chp_link *,
137 int); 137 int);
138static void recovery_func(unsigned long data); 138static void recovery_func(unsigned long data);
139struct workqueue_struct *ccw_device_work;
140wait_queue_head_t ccw_device_init_wq; 139wait_queue_head_t ccw_device_init_wq;
141atomic_t ccw_device_init_count; 140atomic_t ccw_device_init_count;
142 141
@@ -163,7 +162,7 @@ static void io_subchannel_settle(void)
163{ 162{
164 wait_event(ccw_device_init_wq, 163 wait_event(ccw_device_init_wq,
165 atomic_read(&ccw_device_init_count) == 0); 164 atomic_read(&ccw_device_init_count) == 0);
166 flush_workqueue(ccw_device_work); 165 flush_workqueue(cio_work_q);
167} 166}
168 167
169static struct css_driver io_subchannel_driver = { 168static struct css_driver io_subchannel_driver = {
@@ -188,27 +187,13 @@ int __init io_subchannel_init(void)
188 atomic_set(&ccw_device_init_count, 0); 187 atomic_set(&ccw_device_init_count, 0);
189 setup_timer(&recovery_timer, recovery_func, 0); 188 setup_timer(&recovery_timer, recovery_func, 0);
190 189
191 ccw_device_work = create_singlethread_workqueue("cio"); 190 ret = bus_register(&ccw_bus_type);
192 if (!ccw_device_work) 191 if (ret)
193 return -ENOMEM; 192 return ret;
194 slow_path_wq = create_singlethread_workqueue("kslowcrw");
195 if (!slow_path_wq) {
196 ret = -ENOMEM;
197 goto out_err;
198 }
199 if ((ret = bus_register (&ccw_bus_type)))
200 goto out_err;
201
202 ret = css_driver_register(&io_subchannel_driver); 193 ret = css_driver_register(&io_subchannel_driver);
203 if (ret) 194 if (ret)
204 goto out_err; 195 bus_unregister(&ccw_bus_type);
205 196
206 return 0;
207out_err:
208 if (ccw_device_work)
209 destroy_workqueue(ccw_device_work);
210 if (slow_path_wq)
211 destroy_workqueue(slow_path_wq);
212 return ret; 197 return ret;
213} 198}
214 199
@@ -2028,7 +2013,7 @@ void ccw_device_sched_todo(struct ccw_device *cdev, enum cdev_todo todo)
2028 /* Get workqueue ref. */ 2013 /* Get workqueue ref. */
2029 if (!get_device(&cdev->dev)) 2014 if (!get_device(&cdev->dev))
2030 return; 2015 return;
2031 if (!queue_work(slow_path_wq, &cdev->private->todo_work)) { 2016 if (!queue_work(cio_work_q, &cdev->private->todo_work)) {
2032 /* Already queued, release workqueue ref. */ 2017 /* Already queued, release workqueue ref. */
2033 put_device(&cdev->dev); 2018 put_device(&cdev->dev);
2034 } 2019 }
@@ -2041,5 +2026,4 @@ EXPORT_SYMBOL(ccw_driver_register);
2041EXPORT_SYMBOL(ccw_driver_unregister); 2026EXPORT_SYMBOL(ccw_driver_unregister);
2042EXPORT_SYMBOL(get_ccwdev_by_busid); 2027EXPORT_SYMBOL(get_ccwdev_by_busid);
2043EXPORT_SYMBOL(ccw_bus_type); 2028EXPORT_SYMBOL(ccw_bus_type);
2044EXPORT_SYMBOL(ccw_device_work);
2045EXPORT_SYMBOL_GPL(ccw_device_get_subchannel_id); 2029EXPORT_SYMBOL_GPL(ccw_device_get_subchannel_id);
diff --git a/drivers/s390/cio/device.h b/drivers/s390/cio/device.h
index bcfe13e42638..ef60c8f5cd14 100644
--- a/drivers/s390/cio/device.h
+++ b/drivers/s390/cio/device.h
@@ -71,7 +71,6 @@ dev_fsm_final_state(struct ccw_device *cdev)
71 cdev->private->state == DEV_STATE_BOXED); 71 cdev->private->state == DEV_STATE_BOXED);
72} 72}
73 73
74extern struct workqueue_struct *ccw_device_work;
75extern wait_queue_head_t ccw_device_init_wq; 74extern wait_queue_head_t ccw_device_init_wq;
76extern atomic_t ccw_device_init_count; 75extern atomic_t ccw_device_init_count;
77int __init io_subchannel_init(void); 76int __init io_subchannel_init(void);