scsi: qla2xxx: edif: Wait for app to ack on sess down
authorQuinn Tran <qutran@marvell.com>
Tue, 7 Jun 2022 04:46:19 +0000 (21:46 -0700)
committerMartin K. Petersen <martin.petersen@oracle.com>
Wed, 8 Jun 2022 01:50:10 +0000 (21:50 -0400)
On session deletion, wait for app to acknowledge before moving on. This
allows both app and driver to stay in sync. In addition, this gives a
chance for authentication app to do any type of cleanup before moving on.

Link: https://lore.kernel.org/r/20220607044627.19563-4-njavali@marvell.com
Fixes: dd30706e73b7 ("scsi: qla2xxx: edif: Add key update")
Signed-off-by: Quinn Tran <qutran@marvell.com>
Signed-off-by: Nilesh Javali <njavali@marvell.com>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
drivers/scsi/qla2xxx/qla_def.h
drivers/scsi/qla2xxx/qla_edif.c
drivers/scsi/qla2xxx/qla_init.c
drivers/scsi/qla2xxx/qla_target.c

index 510fbeb042561837f17a89611dce103d51d69a91..3e78bafa4011c678f74bc3f4750c9a3d075ea1e5 100644 (file)
@@ -2626,7 +2626,6 @@ typedef struct fc_port {
        struct {
                uint32_t        enable:1;       /* device is edif enabled/req'd */
                uint32_t        app_stop:2;
-               uint32_t        app_started:1;
                uint32_t        aes_gmac:1;
                uint32_t        app_sess_online:1;
                uint32_t        tx_sa_set:1;
@@ -2637,6 +2636,7 @@ typedef struct fc_port {
                uint32_t        rx_rekey_cnt;
                uint64_t        tx_bytes;
                uint64_t        rx_bytes;
+               uint8_t         sess_down_acked;
                uint8_t         auth_state;
                uint16_t        authok:1;
                uint16_t        rekey_cnt;
index 0a49834198ca39f095e36f542f18a9a699c29330..fffdf87d823aef38a3d0d2062a2841ba9d302bb0 100644 (file)
@@ -257,14 +257,8 @@ qla2x00_find_fcport_by_pid(scsi_qla_host_t *vha, port_id_t *id)
 
        f = NULL;
        list_for_each_entry_safe(f, tf, &vha->vp_fcports, list) {
-               if ((f->flags & FCF_FCSP_DEVICE)) {
-                       ql_dbg(ql_dbg_edif + ql_dbg_verbose, vha, 0x2058,
-                           "Found secure fcport - nn %8phN pn %8phN portid=0x%x, 0x%x.\n",
-                           f->node_name, f->port_name,
-                           f->d_id.b24, id->b24);
-                       if (f->d_id.b24 == id->b24)
-                               return f;
-               }
+               if (f->d_id.b24 == id->b24)
+                       return f;
        }
        return NULL;
 }
@@ -526,7 +520,6 @@ qla_edif_app_start(scsi_qla_host_t *vha, struct bsg_job *bsg_job)
 
                        fcport->edif.app_stop = 0;
                        fcport->edif.app_sess_online = 0;
-                       fcport->edif.app_started = 1;
 
                        if (fcport->scan_state != QLA_FCPORT_FOUND)
                                continue;
@@ -628,9 +621,6 @@ qla_edif_app_stop(scsi_qla_host_t *vha, struct bsg_job *bsg_job)
 
                        fcport->send_els_logo = 1;
                        qlt_schedule_sess_for_deletion(fcport);
-
-                       /* qla_edif_flush_sa_ctl_lists(fcport); */
-                       fcport->edif.app_started = 0;
                }
        }
 
@@ -1047,6 +1037,40 @@ qla_edif_app_getstats(scsi_qla_host_t *vha, struct bsg_job *bsg_job)
        return rval;
 }
 
+static int32_t
+qla_edif_ack(scsi_qla_host_t *vha, struct bsg_job *bsg_job)
+{
+       struct fc_port *fcport;
+       struct aen_complete_cmd ack;
+       struct fc_bsg_reply     *bsg_reply = bsg_job->reply;
+
+       sg_copy_to_buffer(bsg_job->request_payload.sg_list,
+                         bsg_job->request_payload.sg_cnt, &ack, sizeof(ack));
+
+       ql_dbg(ql_dbg_edif, vha, 0x70cf,
+              "%s: %06x event_code %x\n",
+              __func__, ack.port_id.b24, ack.event_code);
+
+       fcport = qla2x00_find_fcport_by_pid(vha, &ack.port_id);
+       SET_DID_STATUS(bsg_reply->result, DID_OK);
+
+       if (!fcport) {
+               ql_dbg(ql_dbg_edif, vha, 0x70cf,
+                      "%s: unable to find fcport %06x \n",
+                      __func__, ack.port_id.b24);
+               return 0;
+       }
+
+       switch (ack.event_code) {
+       case VND_CMD_AUTH_STATE_SESSION_SHUTDOWN:
+               fcport->edif.sess_down_acked = 1;
+               break;
+       default:
+               break;
+       }
+       return 0;
+}
+
 int32_t
 qla_edif_app_mgmt(struct bsg_job *bsg_job)
 {
@@ -1109,6 +1133,9 @@ qla_edif_app_mgmt(struct bsg_job *bsg_job)
        case QL_VND_SC_GET_STATS:
                rval = qla_edif_app_getstats(vha, bsg_job);
                break;
+       case QL_VND_SC_AEN_COMPLETE:
+               rval = qla_edif_ack(vha, bsg_job);
+               break;
        default:
                ql_dbg(ql_dbg_edif, vha, 0x911d, "%s unknown cmd=%x\n",
                    __func__,
@@ -3512,14 +3539,29 @@ done:
 
 void qla_edif_sess_down(struct scsi_qla_host *vha, struct fc_port *sess)
 {
+       u16 cnt = 0;
+
        if (sess->edif.app_sess_online && DBELL_ACTIVE(vha)) {
                ql_dbg(ql_dbg_disc, vha, 0xf09c,
                        "%s: sess %8phN send port_offline event\n",
                        __func__, sess->port_name);
                sess->edif.app_sess_online = 0;
+               sess->edif.sess_down_acked = 0;
                qla_edb_eventcreate(vha, VND_CMD_AUTH_STATE_SESSION_SHUTDOWN,
                    sess->d_id.b24, 0, sess);
                qla2x00_post_aen_work(vha, FCH_EVT_PORT_OFFLINE, sess->d_id.b24);
+
+               while (!READ_ONCE(sess->edif.sess_down_acked) &&
+                      !test_bit(VPORT_DELETE, &vha->dpc_flags)) {
+                       msleep(100);
+                       cnt++;
+                       if (cnt > 100)
+                               break;
+               }
+               sess->edif.sess_down_acked = 0;
+               ql_dbg(ql_dbg_disc, vha, 0xf09c,
+                      "%s: sess %8phN port_offline event completed\n",
+                      __func__, sess->port_name);
        }
 }
 
index 3f3417a3e89116743b98fc6da0e5c4bc1190c446..ec1722e86f10eb0f51aa5a1e78f6b01903085e14 100644 (file)
@@ -1480,7 +1480,6 @@ static int        qla_chk_secure_login(scsi_qla_host_t    *vha, fc_port_t *fcport,
                                ql_dbg(ql_dbg_disc, vha, 0x20ef,
                                    "%s %d %8phC EDIF: post DB_AUTH: AUTH needed\n",
                                    __func__, __LINE__, fcport->port_name);
-                               fcport->edif.app_started = 1;
                                fcport->edif.app_sess_online = 1;
 
                                qla_edb_eventcreate(vha, VND_CMD_AUTH_STATE_NEEDED,
@@ -5273,9 +5272,6 @@ qla2x00_alloc_fcport(scsi_qla_host_t *vha, gfp_t flags)
        INIT_LIST_HEAD(&fcport->edif.tx_sa_list);
        INIT_LIST_HEAD(&fcport->edif.rx_sa_list);
 
-       if (vha->e_dbell.db_flags == EDB_ACTIVE)
-               fcport->edif.app_started = 1;
-
        spin_lock_init(&fcport->edif.indx_list_lock);
        INIT_LIST_HEAD(&fcport->edif.edif_indx_list);
 
index cb97f625970d0cac62ed63dce2f68e5af794a6bd..2b2f682883752956f49281d0c91ae35c5fc97884 100644 (file)
@@ -981,22 +981,6 @@ void qlt_free_session_done(struct work_struct *work)
                sess->send_els_logo);
 
        if (!IS_SW_RESV_ADDR(sess->d_id)) {
-               if (ha->flags.edif_enabled &&
-                   (!own || own->iocb.u.isp24.status_subcode == ELS_PLOGI)) {
-                       sess->edif.authok = 0;
-                       if (!ha->flags.host_shutting_down) {
-                               ql_dbg(ql_dbg_edif, vha, 0x911e,
-                                       "%s wwpn %8phC calling qla2x00_release_all_sadb\n",
-                                       __func__, sess->port_name);
-                               qla2x00_release_all_sadb(vha, sess);
-                       } else {
-                               ql_dbg(ql_dbg_edif, vha, 0x911e,
-                                       "%s bypassing release_all_sadb\n",
-                                       __func__);
-                       }
-                       qla_edif_clear_appdata(vha, sess);
-                       qla_edif_sess_down(vha, sess);
-               }
                qla2x00_mark_device_lost(vha, sess, 0);
 
                if (sess->send_els_logo) {
@@ -1042,6 +1026,25 @@ void qlt_free_session_done(struct work_struct *work)
                        sess->nvme_flag |= NVME_FLAG_DELETING;
                        qla_nvme_unregister_remote_port(sess);
                }
+
+               if (ha->flags.edif_enabled &&
+                   (!own || (own &&
+                             own->iocb.u.isp24.status_subcode == ELS_PLOGI))) {
+                       sess->edif.authok = 0;
+                       if (!ha->flags.host_shutting_down) {
+                               ql_dbg(ql_dbg_edif, vha, 0x911e,
+                                      "%s wwpn %8phC calling qla2x00_release_all_sadb\n",
+                                      __func__, sess->port_name);
+                               qla2x00_release_all_sadb(vha, sess);
+                       } else {
+                               ql_dbg(ql_dbg_edif, vha, 0x911e,
+                                      "%s bypassing release_all_sadb\n",
+                                      __func__);
+                       }
+
+                       qla_edif_clear_appdata(vha, sess);
+                       qla_edif_sess_down(vha, sess);
+               }
        }
 
        /*