lkml.org 
[lkml]   [2019]   [Jun]   [4]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH AUTOSEL 5.1 19/60] scsi: lpfc: correct rcu unlock issue in lpfc_nvme_info_show
    Date
    From: James Smart <jsmart2021@gmail.com>

    [ Upstream commit 79080d349f7f58a2e86c56043a3d04184d5f294a ]

    Many of the exit cases were not releasing the rcu read lock. Corrected the
    exit paths.

    Signed-off-by: Dick Kennedy <dick.kennedy@broadcom.com>
    Signed-off-by: James Smart <jsmart2021@gmail.com>
    Tested-by: Bart Van Assche <bvanassche@acm.org>
    Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
    Signed-off-by: Sasha Levin <sashal@kernel.org>
    ---
    drivers/scsi/lpfc/lpfc_attr.c | 32 +++++++++++++++++++-------------
    1 file changed, 19 insertions(+), 13 deletions(-)

    diff --git a/drivers/scsi/lpfc/lpfc_attr.c b/drivers/scsi/lpfc/lpfc_attr.c
    index f30cb0fb9a82..26a22e41204e 100644
    --- a/drivers/scsi/lpfc/lpfc_attr.c
    +++ b/drivers/scsi/lpfc/lpfc_attr.c
    @@ -338,7 +338,7 @@ lpfc_nvme_info_show(struct device *dev, struct device_attribute *attr,
    phba->sli4_hba.io_xri_max,
    lpfc_sli4_get_els_iocb_cnt(phba));
    if (strlcat(buf, tmp, PAGE_SIZE) >= PAGE_SIZE)
    - goto buffer_done;
    + goto rcu_unlock_buf_done;

    /* Port state is only one of two values for now. */
    if (localport->port_id)
    @@ -354,7 +354,7 @@ lpfc_nvme_info_show(struct device *dev, struct device_attribute *attr,
    wwn_to_u64(vport->fc_nodename.u.wwn),
    localport->port_id, statep);
    if (strlcat(buf, tmp, PAGE_SIZE) >= PAGE_SIZE)
    - goto buffer_done;
    + goto rcu_unlock_buf_done;

    list_for_each_entry(ndlp, &vport->fc_nodes, nlp_listp) {
    nrport = NULL;
    @@ -381,39 +381,39 @@ lpfc_nvme_info_show(struct device *dev, struct device_attribute *attr,

    /* Tab in to show lport ownership. */
    if (strlcat(buf, "NVME RPORT ", PAGE_SIZE) >= PAGE_SIZE)
    - goto buffer_done;
    + goto rcu_unlock_buf_done;
    if (phba->brd_no >= 10) {
    if (strlcat(buf, " ", PAGE_SIZE) >= PAGE_SIZE)
    - goto buffer_done;
    + goto rcu_unlock_buf_done;
    }

    scnprintf(tmp, sizeof(tmp), "WWPN x%llx ",
    nrport->port_name);
    if (strlcat(buf, tmp, PAGE_SIZE) >= PAGE_SIZE)
    - goto buffer_done;
    + goto rcu_unlock_buf_done;

    scnprintf(tmp, sizeof(tmp), "WWNN x%llx ",
    nrport->node_name);
    if (strlcat(buf, tmp, PAGE_SIZE) >= PAGE_SIZE)
    - goto buffer_done;
    + goto rcu_unlock_buf_done;

    scnprintf(tmp, sizeof(tmp), "DID x%06x ",
    nrport->port_id);
    if (strlcat(buf, tmp, PAGE_SIZE) >= PAGE_SIZE)
    - goto buffer_done;
    + goto rcu_unlock_buf_done;

    /* An NVME rport can have multiple roles. */
    if (nrport->port_role & FC_PORT_ROLE_NVME_INITIATOR) {
    if (strlcat(buf, "INITIATOR ", PAGE_SIZE) >= PAGE_SIZE)
    - goto buffer_done;
    + goto rcu_unlock_buf_done;
    }
    if (nrport->port_role & FC_PORT_ROLE_NVME_TARGET) {
    if (strlcat(buf, "TARGET ", PAGE_SIZE) >= PAGE_SIZE)
    - goto buffer_done;
    + goto rcu_unlock_buf_done;
    }
    if (nrport->port_role & FC_PORT_ROLE_NVME_DISCOVERY) {
    if (strlcat(buf, "DISCSRVC ", PAGE_SIZE) >= PAGE_SIZE)
    - goto buffer_done;
    + goto rcu_unlock_buf_done;
    }
    if (nrport->port_role & ~(FC_PORT_ROLE_NVME_INITIATOR |
    FC_PORT_ROLE_NVME_TARGET |
    @@ -421,12 +421,12 @@ lpfc_nvme_info_show(struct device *dev, struct device_attribute *attr,
    scnprintf(tmp, sizeof(tmp), "UNKNOWN ROLE x%x",
    nrport->port_role);
    if (strlcat(buf, tmp, PAGE_SIZE) >= PAGE_SIZE)
    - goto buffer_done;
    + goto rcu_unlock_buf_done;
    }

    scnprintf(tmp, sizeof(tmp), "%s\n", statep);
    if (strlcat(buf, tmp, PAGE_SIZE) >= PAGE_SIZE)
    - goto buffer_done;
    + goto rcu_unlock_buf_done;
    }
    rcu_read_unlock();

    @@ -488,7 +488,13 @@ lpfc_nvme_info_show(struct device *dev, struct device_attribute *attr,
    atomic_read(&lport->cmpl_fcp_err));
    strlcat(buf, tmp, PAGE_SIZE);

    -buffer_done:
    + /* RCU is already unlocked. */
    + goto buffer_done;
    +
    + rcu_unlock_buf_done:
    + rcu_read_unlock();
    +
    + buffer_done:
    len = strnlen(buf, PAGE_SIZE);

    if (unlikely(len >= (PAGE_SIZE - 1))) {
    --
    2.20.1
    \
     
     \ /
      Last update: 2019-06-05 01:23    [W:5.126 / U:0.884 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site