• Steffen Maier's avatar
    scsi: zfcp: fix missing erp_lock in port recovery trigger for point-to-point · 819732be
    Steffen Maier authored
    v2.6.27 commit cc8c2829 ("[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 fa89adba ("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 9e156c54
    ("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: cc8c2829 ("[SCSI] zfcp: Automatically attach remote ports")
    Cc: <stable@vger.kernel.org> #v2.6.27+
    Reviewed-by: default avatarJens Remus <jremus@linux.ibm.com>
    Reviewed-by: default avatarBenjamin Block <bblock@linux.ibm.com>
    Signed-off-by: default avatarSteffen Maier <maier@linux.ibm.com>
    Signed-off-by: default avatarMartin K. Petersen <martin.petersen@oracle.com>
    819732be
zfcp_erp.c 49.6 KB