| From 55bca1fbc5303c635a3c4ffbf7688f03a9d622bd Mon Sep 17 00:00:00 2001 |
| From: Steffen Maier <maier@linux.ibm.com> |
| Date: Thu, 12 Mar 2020 18:44:56 +0100 |
| Subject: [PATCH] scsi: zfcp: fix missing erp_lock in port recovery trigger for |
| point-to-point |
| |
| commit 819732be9fea728623e1ed84eba28def7384ad1f upstream. |
| |
| v2.6.27 commit cc8c282963bd ("[SCSI] zfcp: Automatically attach remote |
| ports") introduced zfcp automatic port scan. |
| |
| Before that, the user had to use the sysfs attribute "port_add" of an FCP |
| device (adapter) to add and open remote (target) ports, even for the remote |
| peer port in point-to-point topology. That code path did a proper port open |
| recovery trigger taking the erp_lock. |
| |
| Since above commit, a new helper function zfcp_erp_open_ptp_port() |
| performed an UNlocked port open recovery trigger. This can race with other |
| parallel recovery triggers. In zfcp_erp_action_enqueue() this could corrupt |
| e.g. adapter->erp_total_count or adapter->erp_ready_head. |
| |
| As already found for fabric topology in v4.17 commit fa89adba1941 ("scsi: |
| zfcp: fix infinite iteration on ERP ready list"), there was an endless loop |
| during tracing of rport (un)block. A subsequent v4.18 commit 9e156c54ace3 |
| ("scsi: zfcp: assert that the ERP lock is held when tracing a recovery |
| trigger") introduced a lockdep assertion for that case. |
| |
| As a side effect, that lockdep assertion now uncovered the unlocked code |
| path for PtP. It is from within an adapter ERP action: |
| |
| zfcp_erp_strategy[1479] intentionally DROPs erp lock around |
| zfcp_erp_strategy_do_action() |
| zfcp_erp_strategy_do_action[1441] NO erp lock |
| zfcp_erp_adapter_strategy[876] NO erp lock |
| zfcp_erp_adapter_strategy_open[855] NO erp lock |
| zfcp_erp_adapter_strategy_open_fsf[806]NO erp lock |
| zfcp_erp_adapter_strat_fsf_xconf[772] erp lock only around |
| zfcp_erp_action_to_running(), |
| BUT *_not_* around |
| zfcp_erp_enqueue_ptp_port() |
| zfcp_erp_enqueue_ptp_port[728] BUG: *_not_* taking erp lock |
| _zfcp_erp_port_reopen[432] assumes to be called with erp lock |
| zfcp_erp_action_enqueue[314] assumes to be called with erp lock |
| zfcp_dbf_rec_trig[288] _checks_ to be called with erp lock: |
| lockdep_assert_held(&adapter->erp_lock); |
| |
| It causes the following lockdep warning: |
| |
| WARNING: CPU: 2 PID: 775 at drivers/s390/scsi/zfcp_dbf.c:288 |
| zfcp_dbf_rec_trig+0x16a/0x188 |
| no locks held by zfcperp0.0.17c0/775. |
| |
| Fix this by using the proper locked recovery trigger helper function. |
| |
| Link: https://lore.kernel.org/r/20200312174505.51294-2-maier@linux.ibm.com |
| Fixes: cc8c282963bd ("[SCSI] zfcp: Automatically attach remote ports") |
| Cc: <stable@vger.kernel.org> #v2.6.27+ |
| Reviewed-by: Jens Remus <jremus@linux.ibm.com> |
| Reviewed-by: Benjamin Block <bblock@linux.ibm.com> |
| Signed-off-by: Steffen Maier <maier@linux.ibm.com> |
| Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com> |
| Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com> |
| |
| diff --git a/drivers/s390/scsi/zfcp_erp.c b/drivers/s390/scsi/zfcp_erp.c |
| index 96f0d34e9459..cb84125ab80d 100644 |
| --- a/drivers/s390/scsi/zfcp_erp.c |
| +++ b/drivers/s390/scsi/zfcp_erp.c |
| @@ -725,7 +725,7 @@ static void zfcp_erp_enqueue_ptp_port(struct zfcp_adapter *adapter) |
| adapter->peer_d_id); |
| if (IS_ERR(port)) /* error or port already attached */ |
| return; |
| - _zfcp_erp_port_reopen(port, 0, "ereptp1"); |
| + zfcp_erp_port_reopen(port, 0, "ereptp1"); |
| } |
| |
| static enum zfcp_erp_act_result zfcp_erp_adapter_strat_fsf_xconf( |
| -- |
| 2.7.4 |
| |