Author: ram
Date: Fri Jan 11 15:59:24 2019
New Revision: 342946
URL: https://svnweb.freebsd.org/changeset/base/342946

Log:
  Remove accessing remote node and domain objects while processing cam actions.
  Issue:
    ocs_fc(4) driver panics. It's induced by setting the port_state
  sysctl to offline, then online, then offline, then online, and so
  forth and so on in rapid succession.
  
  Reason:
    While we set the port_state to online fc discovery will start and OS
  is enumerating the target discs by calling ocs_action(),  then set the
  port state to "offline" which deletes domain/sport/nodes.
  
    In ocs_action()->XPT_GET_TRAN_SETTINGS we are accessing the remote
  node which can be invalid to get the wwpn, wwnn and port.
  
  Fix:
    Removed accessing of remote node and domain in some ocs_action() cases.
    Populated the required values from ocs_fcport.
    This removes the dependency of node and domain structures while
  processing XPT_PATH_INQ and XPT_GET_TRAN_SETTINGS.
     We will invalidate the target entries after the device lost
  timeout(30 seconds).
  
  Approved by: ken, mav
  MFC after: 3 weeks

Modified:
  head/sys/dev/ocs_fc/ocs.h
  head/sys/dev/ocs_fc/ocs_cam.c

Modified: head/sys/dev/ocs_fc/ocs.h
==============================================================================
--- head/sys/dev/ocs_fc/ocs.h   Fri Jan 11 15:52:09 2019        (r342945)
+++ head/sys/dev/ocs_fc/ocs.h   Fri Jan 11 15:59:24 2019        (r342946)
@@ -84,6 +84,7 @@ typedef struct ocs_fcport_s {
        struct cam_sim          *sim;
        struct cam_path         *path;
        uint32_t                role;
+       uint32_t                fc_id;
 
        ocs_fc_target_t tgt[OCS_MAX_TARGETS];
        int lost_device_time;

Modified: head/sys/dev/ocs_fc/ocs_cam.c
==============================================================================
--- head/sys/dev/ocs_fc/ocs_cam.c       Fri Jan 11 15:52:09 2019        
(r342945)
+++ head/sys/dev/ocs_fc/ocs_cam.c       Fri Jan 11 15:59:24 2019        
(r342946)
@@ -886,9 +886,11 @@ int32_t
 ocs_scsi_ini_new_sport(ocs_sport_t *sport)
 {
        ocs_t *ocs = sport->ocs;
+       ocs_fcport *fcp = FCPORT(ocs, 0);
 
-       if(!sport->is_vport) {
-               sport->tgt_data = FCPORT(ocs, 0);
+       if (!sport->is_vport) {
+               sport->tgt_data = fcp;
+               fcp->fc_id = sport->fc_id;      
        }
 
        return 0;
@@ -911,6 +913,12 @@ ocs_scsi_ini_new_sport(ocs_sport_t *sport)
 void
 ocs_scsi_ini_del_sport(ocs_sport_t *sport)
 {
+       ocs_t *ocs = sport->ocs;
+       ocs_fcport *fcp = FCPORT(ocs, 0);
+
+       if (!sport->is_vport) {
+               fcp->fc_id = 0; 
+       }
 }
 
 void 
@@ -1984,6 +1992,7 @@ ocs_action(struct cam_sim *sim, union ccb *ccb)
        {
                struct ccb_pathinq *cpi = &ccb->cpi;
                struct ccb_pathinq_settings_fc *fc = &cpi->xport_specific.fc;
+               ocs_fcport *fcp = FCPORT(ocs, bus);
 
                uint64_t wwn = 0;
                ocs_xport_stats_t value;
@@ -2011,9 +2020,7 @@ ocs_action(struct cam_sim *sim, union ccb *ccb)
                wwn = *((uint64_t *)ocs_scsi_get_property_ptr(ocs, 
OCS_SCSI_WWNN));
                fc->wwnn = be64toh(wwn);
 
-               if (ocs->domain && ocs->domain->attached) {
-                       fc->port = ocs->domain->sport->fc_id;
-               }
+               fc->port = fcp->fc_id;
 
                if (ocs->config_tgt) {
                        cpi->target_sprt =
@@ -2059,7 +2066,7 @@ ocs_action(struct cam_sim *sim, union ccb *ccb)
                struct ccb_trans_settings_fc *fc = &cts->xport_specific.fc;
                ocs_xport_stats_t value;
                ocs_fcport *fcp = FCPORT(ocs, bus);
-               ocs_node_t      *fnode = NULL;
+               ocs_fc_target_t *tgt = NULL;
 
                if (ocs->ocs_xport != OCS_XPORT_FC) {
                        ocs_set_ccb_status(ccb, CAM_REQ_INVALID);
@@ -2067,13 +2074,19 @@ ocs_action(struct cam_sim *sim, union ccb *ccb)
                        break;
                }
 
-               fnode = ocs_node_get_instance(ocs, 
fcp->tgt[cts->ccb_h.target_id].node_id);
-               if (fnode == NULL) {
+               if (cts->ccb_h.target_id > OCS_MAX_TARGETS) {
                        ocs_set_ccb_status(ccb, CAM_DEV_NOT_THERE);
                        xpt_done(ccb);
                        break;
                }
 
+               tgt = &fcp->tgt[cts->ccb_h.target_id];
+               if (tgt->state == OCS_TGT_STATE_NONE) { 
+                       ocs_set_ccb_status(ccb, CAM_DEV_NOT_THERE);
+                       xpt_done(ccb);
+                       break;
+               }
+
                cts->protocol = PROTO_SCSI;
                cts->protocol_version = SCSI_REV_SPC2;
                cts->transport = XPORT_FC;
@@ -2086,11 +2099,11 @@ ocs_action(struct cam_sim *sim, union ccb *ccb)
                ocs_xport_status(ocs->xport, OCS_XPORT_LINK_SPEED, &value);
                fc->bitrate = value.value * 100;
 
-               fc->wwpn = ocs_node_get_wwpn(fnode);
+               fc->wwpn = tgt->wwpn;
 
-               fc->wwnn = ocs_node_get_wwnn(fnode);
+               fc->wwnn = tgt->wwnn;
 
-               fc->port = fnode->rnode.fc_id;
+               fc->port = tgt->port_id;
 
                fc->valid = CTS_FC_VALID_SPEED |
                        CTS_FC_VALID_WWPN |
_______________________________________________
svn-src-head@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to