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().

Split Close
Expand all
Collapse all
          --- old/usr/src/uts/common/io/fibre-channel/ulp/fcp.c
          +++ new/usr/src/uts/common/io/fibre-channel/ulp/fcp.c
↓ open down ↓ 8205 lines elided ↑ open up ↑
8206 8206                  mdi_devi_enter(pptr->port_dip, &circ);
8207 8207          } else {
8208 8208                  ndi_devi_enter(pptr->port_dip, &circ);
8209 8209          }
8210 8210  
8211 8211          mutex_enter(&pptr->port_mutex);
8212 8212          mutex_enter(&plun->lun_mutex);
8213 8213  
8214 8214          if (online == FCP_ONLINE) {
8215 8215                  ccip = fcp_get_cip(plun, cip, lcount, tcount);
8216      -                if (ccip == NULL) {
8217      -                        goto fail;
8218      -                }
     8216 +                if (ccip == NULL)
     8217 +                        goto skip;
8219 8218          } else {
8220      -                if (fcp_is_child_present(plun, cip) != FC_SUCCESS) {
8221      -                        goto fail;
8222      -                }
     8219 +                if (fcp_is_child_present(plun, cip) != FC_SUCCESS)
     8220 +                        goto skip;
8223 8221                  ccip = cip;
8224 8222          }
8225 8223  
8226 8224          if (online == FCP_ONLINE) {
8227 8225                  rval = fcp_online_child(plun, ccip, lcount, tcount, flags,
8228 8226                      &circ);
8229      -                fc_ulp_log_device_event(pptr->port_fp_handle,
8230      -                    FC_ULP_DEVICE_ONLINE);
8231 8227          } else {
8232 8228                  rval = fcp_offline_child(plun, ccip, lcount, tcount, flags,
8233 8229                      &circ);
8234      -                fc_ulp_log_device_event(pptr->port_fp_handle,
8235      -                    FC_ULP_DEVICE_OFFLINE);
8236 8230          }
8237 8231  
8238      -fail:   mutex_exit(&plun->lun_mutex);
     8232 +skip:
     8233 +        mutex_exit(&plun->lun_mutex);
8239 8234          mutex_exit(&pptr->port_mutex);
8240 8235  
     8236 +        if (rval == NDI_SUCCESS) {
     8237 +                fc_ulp_log_device_event(pptr->port_fp_handle,
     8238 +                    online == FCP_ONLINE ?
     8239 +                    FC_ULP_DEVICE_ONLINE : FC_ULP_DEVICE_OFFLINE);
     8240 +        }
     8241 +
8241 8242          if (is_mpxio) {
8242 8243                  mdi_devi_exit(pptr->port_dip, circ);
8243 8244          } else {
8244 8245                  ndi_devi_exit(pptr->port_dip, circ);
8245 8246          }
8246 8247  
8247 8248          fc_ulp_idle_port(pptr->port_fp_handle);
8248 8249  
8249 8250          return (rval);
8250 8251  }
↓ open down ↓ 2786 lines elided ↑ open up ↑
11037 11038          int                     rval;
11038 11039  
11039 11040          /* ensure command isn't already issued */
11040 11041          ASSERT(cmd->cmd_state != FCP_PKT_ISSUED);
11041 11042  
11042 11043          FCP_DTRACE(fcp_logq, pptr->port_instbuf,
11043 11044              fcp_trace, FCP_BUF_LEVEL_9, 0,
11044 11045              "fcp_transport Invoked for %x", plun->lun_tgt->tgt_d_id);
11045 11046  
11046 11047          /*
11047      -         * It is strange that we enter the fcp_port mutex and the target
11048      -         * mutex to check the lun state (which has a mutex of its own).
11049      -         */
11050      -        mutex_enter(&pptr->port_mutex);
11051      -        mutex_enter(&ptgt->tgt_mutex);
11052      -
11053      -        /*
11054 11048           * If the device is offline and is not in the process of coming
11055 11049           * online, fail the request.
11056 11050           */
11057      -
     11051 +        mutex_enter(&plun->lun_mutex);
11058 11052          if ((plun->lun_state & FCP_LUN_OFFLINE) &&
11059 11053              !(plun->lun_state & FCP_LUN_ONLINING)) {
11060      -                mutex_exit(&ptgt->tgt_mutex);
11061      -                mutex_exit(&pptr->port_mutex);
11062      -
11063      -                if (cmd->cmd_fp_pkt->pkt_pd == NULL) {
     11054 +                mutex_exit(&plun->lun_mutex);
     11055 +                if (cmd->cmd_fp_pkt->pkt_pd == NULL)
11064 11056                          pkt->pkt_reason = CMD_DEV_GONE;
11065      -                }
11066      -
11067 11057                  return (TRAN_FATAL_ERROR);
11068 11058          }
     11059 +        mutex_exit(&plun->lun_mutex);
     11060 +
11069 11061          cmd->cmd_fp_pkt->pkt_timeout = pkt->pkt_time;
11070 11062  
11071 11063          /*
11072 11064           * If we are suspended, kernel is trying to dump, so don't
11073 11065           * block, fail or defer requests - send them down right away.
11074 11066           * NOTE: If we are in panic (i.e. trying to dump), we can't
11075 11067           * assume we have been suspended.  There is hardware such as
11076 11068           * the v880 that doesn't do PM.  Thus, the check for
11077 11069           * ddi_in_panic.
11078 11070           *
↓ open down ↓ 4 lines elided ↑ open up ↑
11083 11075           *
11084 11076           * If the pd in the target or the packet is NULL it's probably
11085 11077           * because the device has gone away, we allow the request to be
11086 11078           * put on the internal queue here in case the device comes back within
11087 11079           * the offline timeout. fctl will fix up the pd's if the tgt_pd_handle
11088 11080           * has gone NULL, while fcp deals cases where pkt_pd is NULL. pkt_pd
11089 11081           * could be NULL because the device was disappearing during or since
11090 11082           * packet initialization.
11091 11083           */
11092 11084  
     11085 +        mutex_enter(&pptr->port_mutex);
     11086 +        mutex_enter(&ptgt->tgt_mutex);
     11087 +
11093 11088          if (((plun->lun_state & FCP_LUN_BUSY) && (!(pptr->port_state &
11094 11089              FCP_STATE_SUSPENDED)) && !ddi_in_panic()) ||
11095 11090              (pptr->port_state & (FCP_STATE_ONLINING | FCP_STATE_IN_CB_DEVC)) ||
11096 11091              (ptgt->tgt_pd_handle == NULL) ||
11097 11092              (cmd->cmd_fp_pkt->pkt_pd == NULL)) {
11098 11093                  /*
11099 11094                   * If ((LUN is busy AND
11100 11095                   *      LUN not suspended AND
11101 11096                   *      The system is not in panic state) OR
11102 11097                   *      (The port is coming up))
↓ open down ↓ 5213 lines elided ↑ open up ↑
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX