diff options
author | Cornelia Huck <cornelia.huck@de.ibm.com> | 2008-04-17 01:45:59 -0400 |
---|---|---|
committer | Heiko Carstens <heiko.carstens@de.ibm.com> | 2008-04-17 01:46:57 -0400 |
commit | 22806dc1a8ffd88a7c7bdd070879e6e323db496a (patch) | |
tree | 45db4877914d6e0dbdb9de4b09f37d5ecce795b6 /drivers | |
parent | 374b8f45f1d5cb17f45ba1d7c74ce8cc9e2f1407 (diff) |
[S390] cio: Fix race for "fast" path gone/path back situations.
Make sure we wait for previous evaluations triggered by path state
changes to have settled before we manipulate path states again.
Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Signed-off-by: Heiko Carstens <heiko.carstens@de.ibm.com>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/s390/cio/chsc.c | 12 | ||||
-rw-r--r-- | drivers/s390/cio/css.c | 6 | ||||
-rw-r--r-- | drivers/s390/cio/css.h | 1 |
3 files changed, 17 insertions, 2 deletions
diff --git a/drivers/s390/cio/chsc.c b/drivers/s390/cio/chsc.c index 007aaeb4f532..b6a40c20780d 100644 --- a/drivers/s390/cio/chsc.c +++ b/drivers/s390/cio/chsc.c | |||
@@ -217,6 +217,8 @@ void chsc_chp_offline(struct chp_id chpid) | |||
217 | 217 | ||
218 | if (chp_get_status(chpid) <= 0) | 218 | if (chp_get_status(chpid) <= 0) |
219 | return; | 219 | return; |
220 | /* Wait until previous actions have settled. */ | ||
221 | css_wait_for_slow_path(); | ||
220 | for_each_subchannel_staged(s390_subchannel_remove_chpid, NULL, &chpid); | 222 | for_each_subchannel_staged(s390_subchannel_remove_chpid, NULL, &chpid); |
221 | } | 223 | } |
222 | 224 | ||
@@ -303,7 +305,8 @@ static void s390_process_res_acc (struct res_acc_data *res_data) | |||
303 | sprintf(dbf_txt, "fla%x", res_data->fla); | 305 | sprintf(dbf_txt, "fla%x", res_data->fla); |
304 | CIO_TRACE_EVENT( 2, dbf_txt); | 306 | CIO_TRACE_EVENT( 2, dbf_txt); |
305 | } | 307 | } |
306 | 308 | /* Wait until previous actions have settled. */ | |
309 | css_wait_for_slow_path(); | ||
307 | /* | 310 | /* |
308 | * I/O resources may have become accessible. | 311 | * I/O resources may have become accessible. |
309 | * Scan through all subchannels that may be concerned and | 312 | * Scan through all subchannels that may be concerned and |
@@ -561,9 +564,12 @@ void chsc_chp_online(struct chp_id chpid) | |||
561 | sprintf(dbf_txt, "cadd%x.%02x", chpid.cssid, chpid.id); | 564 | sprintf(dbf_txt, "cadd%x.%02x", chpid.cssid, chpid.id); |
562 | CIO_TRACE_EVENT(2, dbf_txt); | 565 | CIO_TRACE_EVENT(2, dbf_txt); |
563 | 566 | ||
564 | if (chp_get_status(chpid) != 0) | 567 | if (chp_get_status(chpid) != 0) { |
568 | /* Wait until previous actions have settled. */ | ||
569 | css_wait_for_slow_path(); | ||
565 | for_each_subchannel_staged(__chp_add, __chp_add_new_sch, | 570 | for_each_subchannel_staged(__chp_add, __chp_add_new_sch, |
566 | &chpid); | 571 | &chpid); |
572 | } | ||
567 | } | 573 | } |
568 | 574 | ||
569 | static void __s390_subchannel_vary_chpid(struct subchannel *sch, | 575 | static void __s390_subchannel_vary_chpid(struct subchannel *sch, |
@@ -650,6 +656,8 @@ __s390_vary_chpid_on(struct subchannel_id schid, void *data) | |||
650 | */ | 656 | */ |
651 | int chsc_chp_vary(struct chp_id chpid, int on) | 657 | int chsc_chp_vary(struct chp_id chpid, int on) |
652 | { | 658 | { |
659 | /* Wait until previous actions have settled. */ | ||
660 | css_wait_for_slow_path(); | ||
653 | /* | 661 | /* |
654 | * Redo PathVerification on the devices the chpid connects to | 662 | * Redo PathVerification on the devices the chpid connects to |
655 | */ | 663 | */ |
diff --git a/drivers/s390/cio/css.c b/drivers/s390/cio/css.c index 3b45bbe6cce0..3e829c827493 100644 --- a/drivers/s390/cio/css.c +++ b/drivers/s390/cio/css.c | |||
@@ -533,6 +533,12 @@ void css_schedule_eval_all(void) | |||
533 | spin_unlock_irqrestore(&slow_subchannel_lock, flags); | 533 | spin_unlock_irqrestore(&slow_subchannel_lock, flags); |
534 | } | 534 | } |
535 | 535 | ||
536 | void css_wait_for_slow_path(void) | ||
537 | { | ||
538 | flush_workqueue(ccw_device_notify_work); | ||
539 | flush_workqueue(slow_path_wq); | ||
540 | } | ||
541 | |||
536 | /* Reprobe subchannel if unregistered. */ | 542 | /* Reprobe subchannel if unregistered. */ |
537 | static int reprobe_subchannel(struct subchannel_id schid, void *data) | 543 | static int reprobe_subchannel(struct subchannel_id schid, void *data) |
538 | { | 544 | { |
diff --git a/drivers/s390/cio/css.h b/drivers/s390/cio/css.h index b70554523552..e1913518f354 100644 --- a/drivers/s390/cio/css.h +++ b/drivers/s390/cio/css.h | |||
@@ -144,6 +144,7 @@ struct schib; | |||
144 | int css_sch_is_valid(struct schib *); | 144 | int css_sch_is_valid(struct schib *); |
145 | 145 | ||
146 | extern struct workqueue_struct *slow_path_wq; | 146 | extern struct workqueue_struct *slow_path_wq; |
147 | void css_wait_for_slow_path(void); | ||
147 | 148 | ||
148 | extern struct attribute_group *subch_attr_groups[]; | 149 | extern struct attribute_group *subch_attr_groups[]; |
149 | #endif | 150 | #endif |