Commit 22806dc1 authored by Cornelia Huck's avatar Cornelia Huck Committed by Heiko Carstens

[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: default avatarCornelia Huck <cornelia.huck@de.ibm.com>
Signed-off-by: default avatarMartin Schwidefsky <schwidefsky@de.ibm.com>
Signed-off-by: default avatarHeiko Carstens <heiko.carstens@de.ibm.com>
parent 374b8f45
...@@ -217,6 +217,8 @@ void chsc_chp_offline(struct chp_id chpid) ...@@ -217,6 +217,8 @@ void chsc_chp_offline(struct chp_id chpid)
if (chp_get_status(chpid) <= 0) if (chp_get_status(chpid) <= 0)
return; return;
/* Wait until previous actions have settled. */
css_wait_for_slow_path();
for_each_subchannel_staged(s390_subchannel_remove_chpid, NULL, &chpid); for_each_subchannel_staged(s390_subchannel_remove_chpid, NULL, &chpid);
} }
...@@ -303,7 +305,8 @@ static void s390_process_res_acc (struct res_acc_data *res_data) ...@@ -303,7 +305,8 @@ static void s390_process_res_acc (struct res_acc_data *res_data)
sprintf(dbf_txt, "fla%x", res_data->fla); sprintf(dbf_txt, "fla%x", res_data->fla);
CIO_TRACE_EVENT( 2, dbf_txt); CIO_TRACE_EVENT( 2, dbf_txt);
} }
/* Wait until previous actions have settled. */
css_wait_for_slow_path();
/* /*
* I/O resources may have become accessible. * I/O resources may have become accessible.
* Scan through all subchannels that may be concerned and * Scan through all subchannels that may be concerned and
...@@ -561,9 +564,12 @@ void chsc_chp_online(struct chp_id chpid) ...@@ -561,9 +564,12 @@ void chsc_chp_online(struct chp_id chpid)
sprintf(dbf_txt, "cadd%x.%02x", chpid.cssid, chpid.id); sprintf(dbf_txt, "cadd%x.%02x", chpid.cssid, chpid.id);
CIO_TRACE_EVENT(2, dbf_txt); CIO_TRACE_EVENT(2, dbf_txt);
if (chp_get_status(chpid) != 0) if (chp_get_status(chpid) != 0) {
/* Wait until previous actions have settled. */
css_wait_for_slow_path();
for_each_subchannel_staged(__chp_add, __chp_add_new_sch, for_each_subchannel_staged(__chp_add, __chp_add_new_sch,
&chpid); &chpid);
}
} }
static void __s390_subchannel_vary_chpid(struct subchannel *sch, static void __s390_subchannel_vary_chpid(struct subchannel *sch,
...@@ -650,6 +656,8 @@ __s390_vary_chpid_on(struct subchannel_id schid, void *data) ...@@ -650,6 +656,8 @@ __s390_vary_chpid_on(struct subchannel_id schid, void *data)
*/ */
int chsc_chp_vary(struct chp_id chpid, int on) int chsc_chp_vary(struct chp_id chpid, int on)
{ {
/* Wait until previous actions have settled. */
css_wait_for_slow_path();
/* /*
* Redo PathVerification on the devices the chpid connects to * Redo PathVerification on the devices the chpid connects to
*/ */
......
...@@ -533,6 +533,12 @@ void css_schedule_eval_all(void) ...@@ -533,6 +533,12 @@ void css_schedule_eval_all(void)
spin_unlock_irqrestore(&slow_subchannel_lock, flags); spin_unlock_irqrestore(&slow_subchannel_lock, flags);
} }
void css_wait_for_slow_path(void)
{
flush_workqueue(ccw_device_notify_work);
flush_workqueue(slow_path_wq);
}
/* Reprobe subchannel if unregistered. */ /* Reprobe subchannel if unregistered. */
static int reprobe_subchannel(struct subchannel_id schid, void *data) static int reprobe_subchannel(struct subchannel_id schid, void *data)
{ {
......
...@@ -144,6 +144,7 @@ struct schib; ...@@ -144,6 +144,7 @@ struct schib;
int css_sch_is_valid(struct schib *); int css_sch_is_valid(struct schib *);
extern struct workqueue_struct *slow_path_wq; extern struct workqueue_struct *slow_path_wq;
void css_wait_for_slow_path(void);
extern struct attribute_group *subch_attr_groups[]; extern struct attribute_group *subch_attr_groups[];
#endif #endif
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment