Print this page
NEX-17866
Release lun_mutex/port_mutex before logging an online/offline event, and only
do logging if online/offline operation was successful.
While here, follow the comment suggestion and only hold lun_mutex while checking
its state in fcp_scsi_start().

@@ -8211,35 +8211,36 @@
         mutex_enter(&pptr->port_mutex);
         mutex_enter(&plun->lun_mutex);
 
         if (online == FCP_ONLINE) {
                 ccip = fcp_get_cip(plun, cip, lcount, tcount);
-                if (ccip == NULL) {
-                        goto fail;
-                }
+                if (ccip == NULL)
+                        goto skip;
         } else {
-                if (fcp_is_child_present(plun, cip) != FC_SUCCESS) {
-                        goto fail;
-                }
+                if (fcp_is_child_present(plun, cip) != FC_SUCCESS)
+                        goto skip;
                 ccip = cip;
         }
 
         if (online == FCP_ONLINE) {
                 rval = fcp_online_child(plun, ccip, lcount, tcount, flags,
                     &circ);
-                fc_ulp_log_device_event(pptr->port_fp_handle,
-                    FC_ULP_DEVICE_ONLINE);
         } else {
                 rval = fcp_offline_child(plun, ccip, lcount, tcount, flags,
                     &circ);
-                fc_ulp_log_device_event(pptr->port_fp_handle,
-                    FC_ULP_DEVICE_OFFLINE);
         }
 
-fail:   mutex_exit(&plun->lun_mutex);
+skip:
+        mutex_exit(&plun->lun_mutex);
         mutex_exit(&pptr->port_mutex);
 
+        if (rval == NDI_SUCCESS) {
+                fc_ulp_log_device_event(pptr->port_fp_handle,
+                    online == FCP_ONLINE ?
+                    FC_ULP_DEVICE_ONLINE : FC_ULP_DEVICE_OFFLINE);
+        }
+
         if (is_mpxio) {
                 mdi_devi_exit(pptr->port_dip, circ);
         } else {
                 ndi_devi_exit(pptr->port_dip, circ);
         }

@@ -11042,32 +11043,23 @@
         FCP_DTRACE(fcp_logq, pptr->port_instbuf,
             fcp_trace, FCP_BUF_LEVEL_9, 0,
             "fcp_transport Invoked for %x", plun->lun_tgt->tgt_d_id);
 
         /*
-         * It is strange that we enter the fcp_port mutex and the target
-         * mutex to check the lun state (which has a mutex of its own).
-         */
-        mutex_enter(&pptr->port_mutex);
-        mutex_enter(&ptgt->tgt_mutex);
-
-        /*
          * If the device is offline and is not in the process of coming
          * online, fail the request.
          */
-
+        mutex_enter(&plun->lun_mutex);
         if ((plun->lun_state & FCP_LUN_OFFLINE) &&
             !(plun->lun_state & FCP_LUN_ONLINING)) {
-                mutex_exit(&ptgt->tgt_mutex);
-                mutex_exit(&pptr->port_mutex);
-
-                if (cmd->cmd_fp_pkt->pkt_pd == NULL) {
+                mutex_exit(&plun->lun_mutex);
+                if (cmd->cmd_fp_pkt->pkt_pd == NULL)
                         pkt->pkt_reason = CMD_DEV_GONE;
-                }
-
                 return (TRAN_FATAL_ERROR);
         }
+        mutex_exit(&plun->lun_mutex);
+
         cmd->cmd_fp_pkt->pkt_timeout = pkt->pkt_time;
 
         /*
          * If we are suspended, kernel is trying to dump, so don't
          * block, fail or defer requests - send them down right away.

@@ -11088,10 +11080,13 @@
          * has gone NULL, while fcp deals cases where pkt_pd is NULL. pkt_pd
          * could be NULL because the device was disappearing during or since
          * packet initialization.
          */
 
+        mutex_enter(&pptr->port_mutex);
+        mutex_enter(&ptgt->tgt_mutex);
+
         if (((plun->lun_state & FCP_LUN_BUSY) && (!(pptr->port_state &
             FCP_STATE_SUSPENDED)) && !ddi_in_panic()) ||
             (pptr->port_state & (FCP_STATE_ONLINING | FCP_STATE_IN_CB_DEVC)) ||
             (ptgt->tgt_pd_handle == NULL) ||
             (cmd->cmd_fp_pkt->pkt_pd == NULL)) {