From: Sebastian Herbszt <herbszt@gmx.de>
To: James Smart <james.smart@avagotech.com>
Cc: linux-scsi@vger.kernel.org, Sebastian Herbszt <herbszt@gmx.de>
Subject: Re: [PATCH v2 12/15] lpfc: Fix rport leak.
Date: Sun, 24 May 2015 13:56:36 +0200 [thread overview]
Message-ID: <20150524135636.00000f81@localhost> (raw)
In-Reply-To: <555e1c10.+P+E84TfJG4E7Wsc%james.smart@avagotech.com>
James Smart wrote:
>
> Fix rport leak.
>
> Correct locking and refcounting in tracking our rports
>
> Signed-off-by: Dick Kennedy <dick.kennedy@avagotech.com>
> Signed-off-by: James Smart <james.smart@avagotech.com>
> ---
> drivers/scsi/lpfc/lpfc_disc.h | 4 +-
> drivers/scsi/lpfc/lpfc_els.c | 12 +++-
> drivers/scsi/lpfc/lpfc_hbadisc.c | 145 +++++++++++++++++++--------------------
> 3 files changed, 79 insertions(+), 82 deletions(-)
snip
> diff --git a/drivers/scsi/lpfc/lpfc_hbadisc.c b/drivers/scsi/lpfc/lpfc_hbadisc.c
> index 0dfa566..88af258 100644
> --- a/drivers/scsi/lpfc/lpfc_hbadisc.c
> +++ b/drivers/scsi/lpfc/lpfc_hbadisc.c
> @@ -106,6 +106,7 @@ lpfc_dev_loss_tmo_callbk(struct fc_rport *rport)
> struct lpfc_rport_data *rdata;
> struct lpfc_nodelist * ndlp;
> struct lpfc_vport *vport;
> + struct Scsi_Host *shost;
> struct lpfc_hba *phba;
> struct lpfc_work_evt *evtp;
> int put_node;
> @@ -146,49 +147,32 @@ lpfc_dev_loss_tmo_callbk(struct fc_rport *rport)
> if (ndlp->nlp_state == NLP_STE_MAPPED_NODE)
> return;
>
> - if (ndlp->nlp_type & NLP_FABRIC) {
> -
> - /* If the WWPN of the rport and ndlp don't match, ignore it */
> - if (rport->port_name != wwn_to_u64(ndlp->nlp_portname.u.wwn)) {
> - lpfc_printf_vlog(vport, KERN_ERR, LOG_NODE,
> - "6789 rport name %lx != node port name %lx",
> - (unsigned long)rport->port_name,
> - (unsigned long)wwn_to_u64(
> - ndlp->nlp_portname.u.wwn));
> - put_node = rdata->pnode != NULL;
> - put_rport = ndlp->rport != NULL;
> - rdata->pnode = NULL;
> - ndlp->rport = NULL;
> - if (put_node)
> - lpfc_nlp_put(ndlp);
> - if (put_rport)
> - put_device(&rport->dev);
> - return;
> - }
> -
> - put_node = rdata->pnode != NULL;
> - put_rport = ndlp->rport != NULL;
> - rdata->pnode = NULL;
> - ndlp->rport = NULL;
> - if (put_node)
> - lpfc_nlp_put(ndlp);
> - if (put_rport)
> - put_device(&rport->dev);
> - return;
> - }
> + if (rport->port_name != wwn_to_u64(ndlp->nlp_portname.u.wwn))
> + lpfc_printf_vlog(vport, KERN_ERR, LOG_NODE,
> + "6789 rport name %llx != node port name %llx",
> + rport->port_name,
> + wwn_to_u64(ndlp->nlp_portname.u.wwn));
>
> evtp = &ndlp->dev_loss_evt;
>
> - if (!list_empty(&evtp->evt_listp))
> + if (!list_empty(&evtp->evt_listp)) {
> + lpfc_printf_vlog(vport, KERN_ERR, LOG_NODE,
> + "6790 rport name %llx dev_loss_evt pending",
> + rport->port_name);
> return;
> + }
>
> - evtp->evt_arg1 = lpfc_nlp_get(ndlp);
> - ndlp->nlp_add_flag |= NLP_IN_DEV_LOSS;
> + shost = lpfc_shost_from_vport(vport);
> + spin_lock_irq(shost->host_lock);
> + ndlp->nlp_flag |= NLP_IN_DEV_LOSS;
> + spin_unlock_irq(shost->host_lock);
>
> - spin_lock_irq(&phba->hbalock);
> /* We need to hold the node by incrementing the reference
> * count until this queued work is done
> */
> + evtp->evt_arg1 = lpfc_nlp_get(ndlp);
Additional space here
> +
> + spin_lock_irq(&phba->hbalock);
> if (evtp->evt_arg1) {
> evtp->evt = LPFC_EVT_DEV_LOSS;
> list_add_tail(&evtp->evt_listp, &phba->work_list);
snip
> @@ -4799,14 +4782,24 @@ lpfc_nlp_remove(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp)
> lpfc_cleanup_node(vport, ndlp);
>
> /*
> - * We can get here with a non-NULL ndlp->rport because when we
> - * unregister a rport we don't break the rport/node linkage. So if we
> - * do, make sure we don't leaving any dangling pointers behind.
> + * ndlp->rport must be set to NULL before it reaches here
> + * i.e. break rport/node link before doing lpfc_nlp_put for
> + * registered rport and then drop the reference of rport.
> */
> if (ndlp->rport) {
> - rdata = ndlp->rport->dd_data;
> + /*
> + * extra lpfc_nlp_put dropped the reference of ndlp
> + * for registered rport so need to cleanup rport
> + */
> + lpfc_printf_vlog(vport, KERN_WARNING, LOG_NODE,
> + "0940 removed node x%p DID x%x "
> + " rport not null %p\n",
> + ndlp, ndlp->nlp_DID, ndlp->rport);
checkpatch suggests to not split this user-visible string.
> + rport = ndlp->rport;
> + rdata = rport->dd_data;
> rdata->pnode = NULL;
> ndlp->rport = NULL;
> + put_device(&rport->dev);
> }
> }
>
Sebastian
next prev parent reply other threads:[~2015-05-24 11:56 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-05-21 17:55 [PATCH v2 12/15] lpfc: Fix rport leak James Smart
2015-05-24 11:56 ` Sebastian Herbszt [this message]
2015-05-26 13:30 ` James Smart
2015-05-26 14:31 ` James Bottomley
2015-05-27 21:32 ` Sebastian Herbszt
2015-05-29 14:08 ` James Smart
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20150524135636.00000f81@localhost \
--to=herbszt@gmx.de \
--cc=james.smart@avagotech.com \
--cc=linux-scsi@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).