diff mbox series

[2/3] scsi: efct: fix nport free

Message ID 20210914105539.6942-3-d.bogdanov@yadro.com
State New
Headers show
Series efct fixes & improvements | expand

Commit Message

Dmitry Bogdanov Sept. 14, 2021, 10:55 a.m. UTC
nport_free for an empty nport hangs the state machine waiting for mbox
completion if nport is not yet attached thinking that it is attaching
right now.
Add a check for nport attaching state and complete nport free.

Signed-off-by: Dmitry Bogdanov <d.bogdanov@yadro.com>
---
 drivers/scsi/elx/libefc/efc_cmds.c | 7 ++++++-
 drivers/scsi/elx/libefc/efclib.h   | 1 +
 2 files changed, 7 insertions(+), 1 deletion(-)

Comments

Ram Kishore Vegesna Sept. 15, 2021, 12:51 p.m. UTC | #1
On Tue, Sep 14, 2021 at 4:25 PM Dmitry Bogdanov <d.bogdanov@yadro.com> wrote:
>
> nport_free for an empty nport hangs the state machine waiting for mbox
> completion if nport is not yet attached thinking that it is attaching
> right now.
> Add a check for nport attaching state and complete nport free.
>
> Signed-off-by: Dmitry Bogdanov <d.bogdanov@yadro.com>
> ---
>  drivers/scsi/elx/libefc/efc_cmds.c | 7 ++++++-
>  drivers/scsi/elx/libefc/efclib.h   | 1 +
>  2 files changed, 7 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/scsi/elx/libefc/efc_cmds.c b/drivers/scsi/elx/libefc/efc_cmds.c
> index 37e6697d86b8..f8665d48904a 100644
> --- a/drivers/scsi/elx/libefc/efc_cmds.c
> +++ b/drivers/scsi/elx/libefc/efc_cmds.c
> @@ -249,6 +249,7 @@ efc_nport_attach_reg_vpi_cb(struct efc *efc, int status, u8 *mqe,
>  {
>         struct efc_nport *nport = arg;
>
> +       nport->attaching = false;
>         if (efc_nport_get_mbox_status(nport, mqe, status)) {
>                 efc_nport_free_resources(nport, EFC_EVT_NPORT_ATTACH_FAIL, mqe);
>                 return -EIO;
> @@ -286,6 +287,8 @@ efc_cmd_nport_attach(struct efc *efc, struct efc_nport *nport, u32 fc_id)
>         if (rc) {
>                 efc_log_err(efc, "REG_VPI command failure\n");
>                 efc_nport_free_resources(nport, EFC_EVT_NPORT_ATTACH_FAIL, buf);
> +       } else {
> +               nport->attaching = true;
>         }
>
>         return rc;
> @@ -302,8 +305,10 @@ efc_cmd_nport_free(struct efc *efc, struct efc_nport *nport)
>         /* Issue the UNREG_VPI command to free the assigned VPI context */
>         if (nport->attached)
>                 efc_nport_free_unreg_vpi(nport);
> -       else
> +       else if (nport->attaching)
>                 nport->free_req_pending = true;
> +       else
> +               efc_sm_post_event(&nport->sm, EFC_EVT_NPORT_FREE_OK, NULL);
>
>         return 0;
>  }
> diff --git a/drivers/scsi/elx/libefc/efclib.h b/drivers/scsi/elx/libefc/efclib.h
> index ee291cabf7e0..dde20891c2dd 100644
> --- a/drivers/scsi/elx/libefc/efclib.h
> +++ b/drivers/scsi/elx/libefc/efclib.h
> @@ -142,6 +142,7 @@ struct efc_nport {
>         bool                    is_vport;
>         bool                    free_req_pending;
>         bool                    attached;
> +       bool                    attaching;
>         bool                    p2p_winner;
>         struct efc_domain       *domain;
>         u64                     wwpn;
> --
> 2.25.1
>
Looks good. Thanks.

Reviewed-by: Ram Vegesna <ram.vegesna@broadcom.com>
diff mbox series

Patch

diff --git a/drivers/scsi/elx/libefc/efc_cmds.c b/drivers/scsi/elx/libefc/efc_cmds.c
index 37e6697d86b8..f8665d48904a 100644
--- a/drivers/scsi/elx/libefc/efc_cmds.c
+++ b/drivers/scsi/elx/libefc/efc_cmds.c
@@ -249,6 +249,7 @@  efc_nport_attach_reg_vpi_cb(struct efc *efc, int status, u8 *mqe,
 {
 	struct efc_nport *nport = arg;
 
+	nport->attaching = false;
 	if (efc_nport_get_mbox_status(nport, mqe, status)) {
 		efc_nport_free_resources(nport, EFC_EVT_NPORT_ATTACH_FAIL, mqe);
 		return -EIO;
@@ -286,6 +287,8 @@  efc_cmd_nport_attach(struct efc *efc, struct efc_nport *nport, u32 fc_id)
 	if (rc) {
 		efc_log_err(efc, "REG_VPI command failure\n");
 		efc_nport_free_resources(nport, EFC_EVT_NPORT_ATTACH_FAIL, buf);
+	} else {
+		nport->attaching = true;
 	}
 
 	return rc;
@@ -302,8 +305,10 @@  efc_cmd_nport_free(struct efc *efc, struct efc_nport *nport)
 	/* Issue the UNREG_VPI command to free the assigned VPI context */
 	if (nport->attached)
 		efc_nport_free_unreg_vpi(nport);
-	else
+	else if (nport->attaching)
 		nport->free_req_pending = true;
+	else
+		efc_sm_post_event(&nport->sm, EFC_EVT_NPORT_FREE_OK, NULL);
 
 	return 0;
 }
diff --git a/drivers/scsi/elx/libefc/efclib.h b/drivers/scsi/elx/libefc/efclib.h
index ee291cabf7e0..dde20891c2dd 100644
--- a/drivers/scsi/elx/libefc/efclib.h
+++ b/drivers/scsi/elx/libefc/efclib.h
@@ -142,6 +142,7 @@  struct efc_nport {
 	bool			is_vport;
 	bool			free_req_pending;
 	bool			attached;
+	bool			attaching;
 	bool			p2p_winner;
 	struct efc_domain	*domain;
 	u64			wwpn;