Message ID | 20200623140242.98864-1-maier@linux.ibm.com (mailing list archive) |
---|---|
State | Mainlined |
Commit | 936e6b85da0476dd2edac7c51c68072da9fb4ba2 |
Headers | show |
Series | zfcp: fix panic on ERP timeout for previously dismissed ERP action | expand |
On Tue, 23 Jun 2020 16:02:42 +0200, Steffen Maier wrote: > Suppose that, for unrelated reasons, FSF requests on behalf of recovery > are very slow and can run into the ERP timeout. > > In the case at hand, we did adapter recovery to a large degree. > However due to the slowness a LUN open is pending > so the corresponding fc_rport remains blocked. > After fast_io_fail_tmo we trigger close physical port recovery > for the port under which the LUN should have been opened. > The new higher order port recovery > dismisses the pending LUN open ERP action and > dismisses the pending LUN open FSF request. > Such dismissal decouples the ERP action from the pending corresponding > FSF request by setting zfcp_fsf_req->erp_action to NULL > (among other things) [zfcp_erp_strategy_check_fsfreq()]. > > [...] Applied to 5.8/scsi-fixes, thanks! [1/1] scsi: zfcp: Fix panic on ERP timeout for previously dismissed ERP action https://git.kernel.org/mkp/scsi/c/936e6b85da04
diff --git a/drivers/s390/scsi/zfcp_erp.c b/drivers/s390/scsi/zfcp_erp.c index db320dab1fee..79f6e8fb03ca 100644 --- a/drivers/s390/scsi/zfcp_erp.c +++ b/drivers/s390/scsi/zfcp_erp.c @@ -577,7 +577,10 @@ static void zfcp_erp_strategy_check_fsfreq(struct zfcp_erp_action *act) ZFCP_STATUS_ERP_TIMEDOUT)) { req->status |= ZFCP_STATUS_FSFREQ_DISMISSED; zfcp_dbf_rec_run("erscf_1", act); - req->erp_action = NULL; + /* lock-free concurrent access with + * zfcp_erp_timeout_handler() + */ + WRITE_ONCE(req->erp_action, NULL); } if (act->status & ZFCP_STATUS_ERP_TIMEDOUT) zfcp_dbf_rec_run("erscf_2", act); @@ -613,8 +616,14 @@ void zfcp_erp_notify(struct zfcp_erp_action *erp_action, unsigned long set_mask) void zfcp_erp_timeout_handler(struct timer_list *t) { struct zfcp_fsf_req *fsf_req = from_timer(fsf_req, t, timer); - struct zfcp_erp_action *act = fsf_req->erp_action; + struct zfcp_erp_action *act; + if (fsf_req->status & ZFCP_STATUS_FSFREQ_DISMISSED) + return; + /* lock-free concurrent access with zfcp_erp_strategy_check_fsfreq() */ + act = READ_ONCE(fsf_req->erp_action); + if (!act) + return; zfcp_erp_notify(act, ZFCP_STATUS_ERP_TIMEDOUT); }