Print this page
3866 panic in idm module
3867 stmfCreateLu failed: GUID_IN_USE
3868 iscsi target not accepting any new connections
Reviewed by: Sebastien Roy <sebastien.roy@delphix.com>
Reviewed by: Jeremy Jones <jeremy@delphix.com>
Reviewed by: Eric Diven <eric.diven@delphix.com>
Reviewed by: Richard Lowe <richlowe@richlowe.net>
Reviewed by: T Nguyen <truongqnguien@gmail.com>
Approved by: Gordon Ross <gwr@nexenta.com>
3862 stmf + kstat = kernel panic
3863 stmf_itl_task_start() must check for ilu->ilu_kstat_io is non-null
3864 memory leak in the iSCSI code
Reviewed by: Adam Leventhal <ahl@delphix.com>
Reviewed by: Jeremy Jones <jeremy@delphix.com>
Reviewed by: Sebastien Roy <sebastien.roy@delphix.com>
Reviewed by: Dan McDonald <danmcd@nexenta.com>
Reviewed by: Garrett D'Amore <garrett@damore.org>
Reviewed by: Richard Elling <richard.elling@gmail.com>
Approved by: Gordon Ross <gwr@nexenta.com>
3621 ZFS LU stuck in the offlining state
Reviewed by: Sebastien Roy <sebastien.roy@delphix.com>
Reviewed by: Jeff Biseda <jeff.biseda@delphix.com>
Reviewed by: Dan McDonald <danmcd@nexenta.com>
Approved by: Christopher Siden <christopher.siden@delphix.com>

Split Close
Expand all
Collapse all
          --- old/usr/src/uts/common/io/comstar/stmf/stmf.c
          +++ new/usr/src/uts/common/io/comstar/stmf/stmf.c
↓ open down ↓ 15 lines elided ↑ open up ↑
  16   16   * fields enclosed by brackets "[]" replaced with your own identifying
  17   17   * information: Portions Copyright [yyyy] [name of copyright owner]
  18   18   *
  19   19   * CDDL HEADER END
  20   20   */
  21   21  /*
  22   22   * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
  23   23   */
  24   24  /*
  25   25   * Copyright 2012, Nexenta Systems, Inc. All rights reserved.
       26 + * Copyright (c) 2013 by Delphix. All rights reserved.
       27 + * Copyright (c) 2013 by Saso Kiselkov. All rights reserved.
  26   28   */
  27   29  
  28   30  #include <sys/conf.h>
  29   31  #include <sys/file.h>
  30   32  #include <sys/ddi.h>
  31   33  #include <sys/sunddi.h>
  32   34  #include <sys/modctl.h>
  33   35  #include <sys/scsi/scsi.h>
  34   36  #include <sys/scsi/generic/persist.h>
  35   37  #include <sys/scsi/impl/scsi_reset_notify.h>
↓ open down ↓ 22 lines elided ↑ open up ↑
  58   60   * stmf_state_lock --> ilport_lock/iss_lockp --> ilu_task_lock
  59   61   */
  60   62  
  61   63  static uint64_t stmf_session_counter = 0;
  62   64  static uint16_t stmf_rtpid_counter = 0;
  63   65  /* start messages at 1 */
  64   66  static uint64_t stmf_proxy_msg_id = 1;
  65   67  #define MSG_ID_TM_BIT   0x8000000000000000
  66   68  #define ALIGNED_TO_8BYTE_BOUNDARY(i)    (((i) + 7) & ~7)
  67   69  
       70 +/*
       71 + * When stmf_io_deadman_enabled is set to B_TRUE, we check that finishing up
       72 + * I/O operations on an offlining LU doesn't take longer than stmf_io_deadman
       73 + * seconds. If it does, we trigger a panic to inform the user of hung I/O
       74 + * blocking us for too long.
       75 + */
       76 +boolean_t stmf_io_deadman_enabled = B_TRUE;
       77 +int stmf_io_deadman = 1000;                     /* seconds */
       78 +
  68   79  struct stmf_svc_clocks;
  69   80  
  70   81  static int stmf_attach(dev_info_t *dip, ddi_attach_cmd_t cmd);
  71   82  static int stmf_detach(dev_info_t *dip, ddi_detach_cmd_t cmd);
  72   83  static int stmf_getinfo(dev_info_t *dip, ddi_info_cmd_t cmd, void *arg,
  73   84          void **result);
  74   85  static int stmf_open(dev_t *devp, int flag, int otype, cred_t *credp);
  75   86  static int stmf_close(dev_t dev, int flag, int otype, cred_t *credp);
  76   87  static int stmf_ioctl(dev_t dev, int cmd, intptr_t data, int mode,
  77   88          cred_t *credp, int *rval);
↓ open down ↓ 6 lines elided ↑ open up ↑
  84   95  
  85   96  static void stmf_task_audit(stmf_i_scsi_task_t *itask,
  86   97      task_audit_event_t te, uint32_t cmd_or_iof, stmf_data_buf_t *dbuf);
  87   98  
  88   99  static boolean_t stmf_base16_str_to_binary(char *c, int dplen, uint8_t *dp);
  89  100  static char stmf_ctoi(char c);
  90  101  stmf_xfer_data_t *stmf_prepare_tpgs_data(uint8_t ilu_alua);
  91  102  void stmf_svc_init();
  92  103  stmf_status_t stmf_svc_fini();
  93  104  void stmf_svc(void *arg);
      105 +static void stmf_wait_ilu_tasks_finish(stmf_i_lu_t *ilu);
  94  106  void stmf_svc_queue(int cmd, void *obj, stmf_state_change_info_t *info);
  95  107  static void stmf_svc_kill_obj_requests(void *obj);
  96  108  static void stmf_svc_timeout(struct stmf_svc_clocks *);
  97  109  void stmf_check_freetask();
  98  110  void stmf_abort_target_reset(scsi_task_t *task);
  99  111  stmf_status_t stmf_lun_reset_poll(stmf_lu_t *lu, struct scsi_task *task,
 100  112                                                          int target_reset);
 101  113  void stmf_target_reset_poll(struct scsi_task *task);
 102  114  void stmf_handle_lun_reset(scsi_task_t *task);
 103  115  void stmf_handle_target_reset(scsi_task_t *task);
↓ open down ↓ 52 lines elided ↑ open up ↑
 156  168  static int stmf_irport_compare(const void *void_irport1,
 157  169      const void *void_irport2);
 158  170  static stmf_i_remote_port_t *stmf_irport_create(scsi_devid_desc_t *rport_devid);
 159  171  static void stmf_irport_destroy(stmf_i_remote_port_t *irport);
 160  172  static stmf_i_remote_port_t *stmf_irport_register(
 161  173      scsi_devid_desc_t *rport_devid);
 162  174  static stmf_i_remote_port_t *stmf_irport_lookup_locked(
 163  175      scsi_devid_desc_t *rport_devid);
 164  176  static void stmf_irport_deregister(stmf_i_remote_port_t *irport);
 165  177  
 166      -static void stmf_teardown_itl_kstats(stmf_i_itl_kstat_t *ks);
 167      -static void stmf_delete_itl_kstat_by_lport(char *);
 168      -static void stmf_delete_itl_kstat_by_guid(char *);
 169      -static int stmf_itl_kstat_compare(const void*, const void*);
 170      -static stmf_i_itl_kstat_t *stmf_itl_kstat_lookup(char *kstat_nm);
 171      -static stmf_i_itl_kstat_t *stmf_itl_kstat_create(stmf_itl_data_t *itl,
 172      -    char *nm, scsi_devid_desc_t *lport, scsi_devid_desc_t *lun);
 173      -
 174  178  extern struct mod_ops mod_driverops;
 175  179  
 176  180  /* =====[ Tunables ]===== */
 177  181  /* Internal tracing */
 178  182  volatile int    stmf_trace_on = 1;
 179  183  volatile int    stmf_trace_buf_size = (1 * 1024 * 1024);
 180  184  /*
 181  185   * The reason default task timeout is 75 is because we want the
 182  186   * host to timeout 1st and mostly host timeout is 60 seconds.
 183  187   */
↓ open down ↓ 121 lines elided ↑ open up ↑
 305  309          mutex_init(&stmf_state.stmf_lock, NULL, MUTEX_DRIVER, NULL);
 306  310          cv_init(&stmf_state.stmf_cv, NULL, CV_DRIVER, NULL);
 307  311          stmf_session_counter = (uint64_t)ddi_get_lbolt();
 308  312          avl_create(&stmf_state.stmf_irportlist,
 309  313              stmf_irport_compare, sizeof (stmf_i_remote_port_t),
 310  314              offsetof(stmf_i_remote_port_t, irport_ln));
 311  315          stmf_state.stmf_ilport_inst_space =
 312  316              id_space_create("lport-instances", 0, MAX_ILPORT);
 313  317          stmf_state.stmf_irport_inst_space =
 314  318              id_space_create("rport-instances", 0, MAX_IRPORT);
 315      -        avl_create(&stmf_state.stmf_itl_kstat_list,
 316      -            stmf_itl_kstat_compare, sizeof (stmf_i_itl_kstat_t),
 317      -            offsetof(stmf_i_itl_kstat_t, iitl_kstat_ln));
 318  319          stmf_view_init();
 319  320          stmf_svc_init();
 320  321          stmf_dlun_init();
 321  322          return (ret);
 322  323  }
 323  324  
 324  325  int
 325  326  _fini(void)
 326  327  {
 327  328          int ret;
 328  329          stmf_i_remote_port_t    *irport;
 329      -        stmf_i_itl_kstat_t      *ks_itl;
 330  330          void                    *avl_dest_cookie = NULL;
 331  331  
 332  332          if (stmf_state.stmf_service_running)
 333  333                  return (EBUSY);
 334  334          if ((!stmf_allow_modunload) &&
 335  335              (stmf_state.stmf_config_state != STMF_CONFIG_NONE)) {
 336  336                  return (EBUSY);
 337  337          }
 338  338          if (stmf_state.stmf_nlps || stmf_state.stmf_npps) {
 339  339                  return (EBUSY);
↓ open down ↓ 20 lines elided ↑ open up ↑
 360  360  
 361  361          stmf_view_clear_config();
 362  362  
 363  363          while ((irport = avl_destroy_nodes(&stmf_state.stmf_irportlist,
 364  364              &avl_dest_cookie)) != NULL)
 365  365                  stmf_irport_destroy(irport);
 366  366          avl_destroy(&stmf_state.stmf_irportlist);
 367  367          id_space_destroy(stmf_state.stmf_ilport_inst_space);
 368  368          id_space_destroy(stmf_state.stmf_irport_inst_space);
 369  369  
 370      -        avl_dest_cookie = NULL;
 371      -        while ((ks_itl = avl_destroy_nodes(&stmf_state.stmf_itl_kstat_list,
 372      -            &avl_dest_cookie)) != NULL) {
 373      -                stmf_teardown_itl_kstats(ks_itl);
 374      -                kmem_free(ks_itl, sizeof (ks_itl));
 375      -        }
 376      -        avl_destroy(&stmf_state.stmf_itl_kstat_list);
 377      -
 378  370          kmem_free(stmf_trace_buf, stmf_trace_buf_size);
 379  371          mutex_destroy(&trace_buf_lock);
 380  372          mutex_destroy(&stmf_state.stmf_lock);
 381  373          cv_destroy(&stmf_state.stmf_cv);
 382  374          return (ret);
 383  375  }
 384  376  
 385  377  int
 386  378  _info(struct modinfo *modinfop)
 387  379  {
↓ open down ↓ 1197 lines elided ↑ open up ↑
1585 1577  static int
1586 1578  stmf_get_stmf_state(stmf_state_desc_t *std)
1587 1579  {
1588 1580          mutex_enter(&stmf_state.stmf_lock);
1589 1581          std->state = stmf_get_service_state();
1590 1582          std->config_state = stmf_state.stmf_config_state;
1591 1583          mutex_exit(&stmf_state.stmf_lock);
1592 1584  
1593 1585          return (0);
1594 1586  }
     1587 +
1595 1588  /*
1596 1589   * handles registration message from pppt for a logical unit
1597 1590   */
1598 1591  stmf_status_t
1599 1592  stmf_ic_lu_reg(stmf_ic_reg_dereg_lun_msg_t *msg, uint32_t type)
1600 1593  {
1601 1594          stmf_i_lu_provider_t    *ilp;
1602 1595          stmf_lu_provider_t      *lp;
1603 1596          mutex_enter(&stmf_state.stmf_lock);
1604 1597          for (ilp = stmf_state.stmf_ilplist; ilp != NULL; ilp = ilp->ilp_next) {
↓ open down ↓ 1447 lines elided ↑ open up ↑
3052 3045          if (ilu->ilu_next)
3053 3046                  ilu->ilu_next->ilu_prev = ilu;
3054 3047          stmf_state.stmf_ilulist = ilu;
3055 3048          stmf_state.stmf_nlus++;
3056 3049          if (lu->lu_lp) {
3057 3050                  ((stmf_i_lu_provider_t *)
3058 3051                      (lu->lu_lp->lp_stmf_private))->ilp_nlus++;
3059 3052          }
3060 3053          ilu->ilu_cur_task_cntr = &ilu->ilu_task_cntr1;
3061 3054          STMF_EVENT_ALLOC_HANDLE(ilu->ilu_event_hdl);
     3055 +        cv_init(&ilu->ilu_offline_pending_cv, NULL, CV_DRIVER, NULL);
3062 3056          stmf_create_kstat_lu(ilu);
3063 3057          /*
3064 3058           * register with proxy module if available and logical unit
3065 3059           * is in active state
3066 3060           */
3067 3061          if (stmf_state.stmf_alua_state == 1 &&
3068 3062              ilu->ilu_access == STMF_LU_ACTIVE) {
3069 3063                  stmf_ic_msg_status_t ic_ret = STMF_IC_MSG_SUCCESS;
3070 3064                  stmf_ic_msg_t *ic_reg_lun;
3071 3065                  if (lu->lu_lp && lu->lu_lp->lp_lpif_rev == LPIF_REV_2 &&
↓ open down ↓ 117 lines elided ↑ open up ↑
3189 3183          }
3190 3184          if (ilu->ilu_kstat_info) {
3191 3185                  kmem_free(ilu->ilu_kstat_info->ks_data,
3192 3186                      ilu->ilu_kstat_info->ks_data_size);
3193 3187                  kstat_delete(ilu->ilu_kstat_info);
3194 3188          }
3195 3189          if (ilu->ilu_kstat_io) {
3196 3190                  kstat_delete(ilu->ilu_kstat_io);
3197 3191                  mutex_destroy(&ilu->ilu_kstat_lock);
3198 3192          }
3199      -        stmf_delete_itl_kstat_by_guid(ilu->ilu_ascii_hex_guid);
     3193 +        cv_destroy(&ilu->ilu_offline_pending_cv);
3200 3194          mutex_exit(&stmf_state.stmf_lock);
3201 3195          return (STMF_SUCCESS);
3202 3196  }
3203 3197  
3204 3198  void
3205 3199  stmf_set_port_standby(stmf_local_port_t *lport, uint16_t rtpid)
3206 3200  {
3207 3201          stmf_i_local_port_t *ilport =
3208 3202              (stmf_i_local_port_t *)lport->lport_stmf_private;
3209 3203          ilport->ilport_rtpid = rtpid;
↓ open down ↓ 157 lines elided ↑ open up ↑
3367 3361          }
3368 3362          if (ilport->ilport_kstat_info) {
3369 3363                  kmem_free(ilport->ilport_kstat_info->ks_data,
3370 3364                      ilport->ilport_kstat_info->ks_data_size);
3371 3365                  kstat_delete(ilport->ilport_kstat_info);
3372 3366          }
3373 3367          if (ilport->ilport_kstat_io) {
3374 3368                  kstat_delete(ilport->ilport_kstat_io);
3375 3369                  mutex_destroy(&ilport->ilport_kstat_lock);
3376 3370          }
3377      -        stmf_delete_itl_kstat_by_lport(ilport->ilport_kstat_tgt_name);
3378 3371          mutex_exit(&stmf_state.stmf_lock);
3379 3372          return (STMF_SUCCESS);
3380 3373  }
3381 3374  
3382 3375  /*
3383 3376   * Rport id/instance mappings remain valid until STMF is unloaded
3384 3377   */
3385 3378  static int
3386 3379  stmf_irport_compare(const void *void_irport1, const void *void_irport2)
3387 3380  {
↓ open down ↓ 308 lines elided ↑ open up ↑
3696 3689                                  mutex_exit(&stmf_state.stmf_lock);
3697 3690                                  return (iss);
3698 3691                          }
3699 3692                  }
3700 3693                  rw_exit(&ilport->ilport_lock);
3701 3694          }
3702 3695          mutex_exit(&stmf_state.stmf_lock);
3703 3696          return (NULL);
3704 3697  }
3705 3698  
3706      -#define MAX_ALIAS               128
3707      -
3708      -static int
3709      -stmf_itl_kstat_compare(const void *itl_kstat_1, const void *itl_kstat_2)
3710      -{
3711      -        const   stmf_i_itl_kstat_t      *kstat_nm1 = itl_kstat_1;
3712      -        const   stmf_i_itl_kstat_t      *kstat_nm2 = itl_kstat_2;
3713      -        int     ret;
3714      -
3715      -        ret = strcmp(kstat_nm1->iitl_kstat_nm, kstat_nm2->iitl_kstat_nm);
3716      -        if (ret < 0) {
3717      -                return (-1);
3718      -        } else if (ret > 0) {
3719      -                return (1);
3720      -        }
3721      -        return (0);
3722      -}
3723      -
3724      -static stmf_i_itl_kstat_t *
3725      -stmf_itl_kstat_lookup(char *kstat_nm)
3726      -{
3727      -        stmf_i_itl_kstat_t      tmp;
3728      -        stmf_i_itl_kstat_t      *itl_kstat;
3729      -
3730      -        ASSERT(mutex_owned(&stmf_state.stmf_lock));
3731      -        (void) strcpy(tmp.iitl_kstat_nm, kstat_nm);
3732      -        itl_kstat = avl_find(&stmf_state.stmf_itl_kstat_list, &tmp, NULL);
3733      -        return (itl_kstat);
3734      -}
3735      -
3736      -static void
3737      -stmf_delete_itl_kstat_by_lport(char *tgt)
3738      -{
3739      -        stmf_i_itl_kstat_t      *ks_itl, *next;
3740      -
3741      -        ASSERT(mutex_owned(&stmf_state.stmf_lock));
3742      -        ks_itl = avl_first(&stmf_state.stmf_itl_kstat_list);
3743      -        for (; ks_itl != NULL; ks_itl = next) {
3744      -                next = AVL_NEXT(&stmf_state.stmf_itl_kstat_list, ks_itl);
3745      -                if (strcmp(ks_itl->iitl_kstat_lport, tgt) == 0) {
3746      -                        stmf_teardown_itl_kstats(ks_itl);
3747      -                        avl_remove(&stmf_state.stmf_itl_kstat_list, ks_itl);
3748      -                        kmem_free(ks_itl, sizeof (stmf_i_itl_kstat_t));
3749      -                }
3750      -        }
3751      -}
3752      -
3753      -static void
3754      -stmf_delete_itl_kstat_by_guid(char *guid)
3755      -{
3756      -        stmf_i_itl_kstat_t      *ks_itl, *next;
3757      -
3758      -        ASSERT(mutex_owned(&stmf_state.stmf_lock));
3759      -        ks_itl = avl_first(&stmf_state.stmf_itl_kstat_list);
3760      -        for (; ks_itl != NULL; ks_itl = next) {
3761      -                next = AVL_NEXT(&stmf_state.stmf_itl_kstat_list, ks_itl);
3762      -                if (strcmp(ks_itl->iitl_kstat_guid, guid) == 0) {
3763      -                        stmf_teardown_itl_kstats(ks_itl);
3764      -                        avl_remove(&stmf_state.stmf_itl_kstat_list, ks_itl);
3765      -                        kmem_free(ks_itl, sizeof (stmf_i_itl_kstat_t));
3766      -                }
3767      -        }
3768      -}
3769      -
3770      -static stmf_i_itl_kstat_t *
3771      -stmf_itl_kstat_create(stmf_itl_data_t *itl, char *nm,
3772      -    scsi_devid_desc_t *lport, scsi_devid_desc_t *lun)
3773      -{
3774      -        stmf_i_itl_kstat_t      *ks_itl;
3775      -        int                     i, len;
3776      -
3777      -        ASSERT(mutex_owned(&stmf_state.stmf_lock));
3778      -        if ((ks_itl = stmf_itl_kstat_lookup(nm)) != NULL)
3779      -                return (ks_itl);
3780      -
3781      -        len = sizeof (stmf_i_itl_kstat_t);
3782      -        ks_itl = kmem_zalloc(len, KM_NOSLEEP);
3783      -        if (ks_itl == NULL)
3784      -                return (NULL);
3785      -
3786      -        (void) strcpy(ks_itl->iitl_kstat_nm, nm);
3787      -        bcopy(lport->ident, ks_itl->iitl_kstat_lport, lport->ident_length);
3788      -        ks_itl->iitl_kstat_lport[lport->ident_length] = '\0';
3789      -        for (i = 0; i < STMF_GUID_INPUT / 2; i++) {
3790      -                (void) sprintf(&ks_itl->iitl_kstat_guid[i * 2], "%02x",
3791      -                    lun->ident[i]);
3792      -        }
3793      -        ks_itl->iitl_kstat_strbuf = itl->itl_kstat_strbuf;
3794      -        ks_itl->iitl_kstat_strbuflen = itl->itl_kstat_strbuflen;
3795      -        ks_itl->iitl_kstat_info = itl->itl_kstat_info;
3796      -        ks_itl->iitl_kstat_taskq = itl->itl_kstat_taskq;
3797      -        ks_itl->iitl_kstat_lu_xfer = itl->itl_kstat_lu_xfer;
3798      -        ks_itl->iitl_kstat_lport_xfer = itl->itl_kstat_lport_xfer;
3799      -        avl_add(&stmf_state.stmf_itl_kstat_list, ks_itl);
3800      -
3801      -        return (ks_itl);
3802      -}
3803      -
3804      -stmf_status_t
3805      -stmf_setup_itl_kstats(stmf_itl_data_t *itl)
3806      -{
3807      -        char                            ks_itl_id[32];
3808      -        char                            ks_nm[KSTAT_STRLEN];
3809      -        char                            ks_itl_nm[KSTAT_STRLEN];
3810      -        stmf_kstat_itl_info_t           *ks_itl;
3811      -        stmf_scsi_session_t             *ss;
3812      -        stmf_i_scsi_session_t           *iss;
3813      -        stmf_i_local_port_t             *ilport;
3814      -        char                            *strbuf;
3815      -        int                             id, len, i;
3816      -        char                            *rport_alias;
3817      -        char                            *lport_alias;
3818      -        char                            *lu_alias;
3819      -        stmf_i_itl_kstat_t              *tmp_kstat;
3820      -
3821      -        /*
3822      -         * Allocate enough memory in the ITL to hold the relevant
3823      -         * identifiers.
3824      -         * rport and lport identifiers come from the stmf_scsi_session_t.
3825      -         * ident might not be null terminated.
3826      -         */
3827      -        ss = itl->itl_session->iss_ss;
3828      -        iss = ss->ss_stmf_private;
3829      -        ilport = ss->ss_lport->lport_stmf_private;
3830      -        (void) snprintf(ks_itl_id, 32, "%d.%d.%d",
3831      -            iss->iss_irport->irport_instance, ilport->ilport_instance,
3832      -            itl->itl_lun);
3833      -
3834      -        (void) snprintf(ks_itl_nm, KSTAT_STRLEN, "itl_%s", ks_itl_id);
3835      -        /*
3836      -         * let's verify this itl_kstat already exist
3837      -         */
3838      -        if ((tmp_kstat = stmf_itl_kstat_lookup(ks_itl_nm)) != NULL) {
3839      -                itl->itl_kstat_strbuf = tmp_kstat->iitl_kstat_strbuf;
3840      -                itl->itl_kstat_strbuflen = tmp_kstat->iitl_kstat_strbuflen;
3841      -                itl->itl_kstat_info = tmp_kstat->iitl_kstat_info;
3842      -                itl->itl_kstat_taskq = tmp_kstat->iitl_kstat_taskq;
3843      -                itl->itl_kstat_lu_xfer = tmp_kstat->iitl_kstat_lu_xfer;
3844      -                itl->itl_kstat_lport_xfer = tmp_kstat->iitl_kstat_lport_xfer;
3845      -                return (STMF_SUCCESS);
3846      -        }
3847      -
3848      -        /* New itl_kstat */
3849      -        rport_alias = (ss->ss_rport_alias == NULL) ?
3850      -            "" : ss->ss_rport_alias;
3851      -        lport_alias = (ss->ss_lport->lport_alias == NULL) ?
3852      -            "" : ss->ss_lport->lport_alias;
3853      -        lu_alias = (itl->itl_ilu->ilu_lu->lu_alias == NULL) ?
3854      -            "" : itl->itl_ilu->ilu_lu->lu_alias;
3855      -
3856      -        itl->itl_kstat_strbuflen = (ss->ss_rport_id->ident_length + 1) +
3857      -            (strnlen(rport_alias, MAX_ALIAS) + 1) +
3858      -            (ss->ss_lport->lport_id->ident_length + 1) +
3859      -            (strnlen(lport_alias, MAX_ALIAS) + 1) +
3860      -            (STMF_GUID_INPUT + 1) +
3861      -            (strnlen(lu_alias, MAX_ALIAS) + 1) +
3862      -            MAX_PROTO_STR_LEN;
3863      -        itl->itl_kstat_strbuf = kmem_zalloc(itl->itl_kstat_strbuflen,
3864      -            KM_NOSLEEP);
3865      -        if (itl->itl_kstat_strbuf == NULL) {
3866      -                return (STMF_ALLOC_FAILURE);
3867      -        }
3868      -
3869      -        ks_itl = (stmf_kstat_itl_info_t *)kmem_zalloc(sizeof (*ks_itl),
3870      -            KM_NOSLEEP);
3871      -        if (ks_itl == NULL) {
3872      -                kmem_free(itl->itl_kstat_strbuf, itl->itl_kstat_strbuflen);
3873      -                return (STMF_ALLOC_FAILURE);
3874      -        }
3875      -
3876      -        if ((itl->itl_kstat_info = kstat_create(STMF_MODULE_NAME,
3877      -            0, ks_itl_nm, "misc", KSTAT_TYPE_NAMED,
3878      -            sizeof (stmf_kstat_itl_info_t) / sizeof (kstat_named_t),
3879      -            KSTAT_FLAG_VIRTUAL)) == NULL) {
3880      -                goto itl_kstat_cleanup;
3881      -        }
3882      -
3883      -        itl->itl_kstat_info->ks_data_size += itl->itl_kstat_strbuflen;
3884      -        itl->itl_kstat_info->ks_data = ks_itl;
3885      -
3886      -        kstat_named_init(&ks_itl->i_rport_name, "rport-name",
3887      -            KSTAT_DATA_STRING);
3888      -        kstat_named_init(&ks_itl->i_rport_alias, "rport-alias",
3889      -            KSTAT_DATA_STRING);
3890      -        kstat_named_init(&ks_itl->i_lport_name, "lport-name",
3891      -            KSTAT_DATA_STRING);
3892      -        kstat_named_init(&ks_itl->i_lport_alias, "lport-alias",
3893      -            KSTAT_DATA_STRING);
3894      -        kstat_named_init(&ks_itl->i_protocol, "protocol",
3895      -            KSTAT_DATA_STRING);
3896      -        kstat_named_init(&ks_itl->i_lu_guid, "lu-guid",
3897      -            KSTAT_DATA_STRING);
3898      -        kstat_named_init(&ks_itl->i_lu_alias, "lu-alias",
3899      -            KSTAT_DATA_STRING);
3900      -        kstat_named_init(&ks_itl->i_lu_number, "lu-number",
3901      -            KSTAT_DATA_UINT64);
3902      -        kstat_named_init(&ks_itl->i_task_waitq_elapsed, "task-waitq-elapsed",
3903      -            KSTAT_DATA_UINT64);
3904      -        kstat_named_init(&ks_itl->i_task_read_elapsed, "task-read-elapsed",
3905      -            KSTAT_DATA_UINT64);
3906      -        kstat_named_init(&ks_itl->i_task_write_elapsed, "task-write-elapsed",
3907      -            KSTAT_DATA_UINT64);
3908      -        kstat_named_init(&ks_itl->i_lu_read_elapsed, "lu-read-elapsed",
3909      -            KSTAT_DATA_UINT64);
3910      -        kstat_named_init(&ks_itl->i_lu_write_elapsed, "lu-write-elapsed",
3911      -            KSTAT_DATA_UINT64);
3912      -        kstat_named_init(&ks_itl->i_lport_read_elapsed, "lport-read-elapsed",
3913      -            KSTAT_DATA_UINT64);
3914      -        kstat_named_init(&ks_itl->i_lport_write_elapsed, "lport-write-elapsed",
3915      -            KSTAT_DATA_UINT64);
3916      -
3917      -        strbuf = itl->itl_kstat_strbuf;
3918      -
3919      -        /* Rport */
3920      -        len = ss->ss_rport_id->ident_length;
3921      -        bcopy(ss->ss_rport_id->ident, strbuf, len);
3922      -        strbuf += len;
3923      -        *strbuf = '\0';
3924      -        kstat_named_setstr(&ks_itl->i_rport_name, strbuf - len);
3925      -        strbuf++;
3926      -
3927      -        len = strnlen(rport_alias, MAX_ALIAS);
3928      -        (void) strncpy(strbuf, rport_alias, len + 1);
3929      -        kstat_named_setstr(&ks_itl->i_rport_alias, strbuf);
3930      -        strbuf += len + 1;
3931      -
3932      -        /* Lport */
3933      -        len = ss->ss_lport->lport_id->ident_length;
3934      -        bcopy(ss->ss_lport->lport_id->ident, strbuf, len);
3935      -        strbuf += len;
3936      -        *strbuf = '\0';
3937      -        kstat_named_setstr(&ks_itl->i_lport_name, strbuf - len);
3938      -        strbuf++;
3939      -
3940      -        len = strnlen(lport_alias, MAX_ALIAS);
3941      -        (void) strncpy(strbuf, lport_alias, len + 1);
3942      -        kstat_named_setstr(&ks_itl->i_lport_alias, strbuf);
3943      -        strbuf += len + 1;
3944      -
3945      -        id = (ss->ss_lport->lport_id->protocol_id > PROTOCOL_ANY) ?
3946      -            PROTOCOL_ANY : ss->ss_lport->lport_id->protocol_id;
3947      -        kstat_named_setstr(&ks_itl->i_protocol, protocol_ident[id]);
3948      -
3949      -        /* LU */
3950      -        for (i = 0; i < STMF_GUID_INPUT / 2; i++) {
3951      -                (void) sprintf(&strbuf[i * 2], "%02x",
3952      -                    itl->itl_ilu->ilu_lu->lu_id->ident[i]);
3953      -        }
3954      -        kstat_named_setstr(&ks_itl->i_lu_guid, strbuf);
3955      -        strbuf += STMF_GUID_INPUT + 1;
3956      -
3957      -        len = strnlen(lu_alias, MAX_ALIAS);
3958      -        (void) strncpy(strbuf, lu_alias, len + 1);
3959      -        kstat_named_setstr(&ks_itl->i_lu_alias, strbuf);
3960      -        strbuf += len + 1;
3961      -
3962      -        ks_itl->i_lu_number.value.ui64 = itl->itl_lun;
3963      -
3964      -        /* Now create the I/O kstats */
3965      -        (void) snprintf(ks_nm, KSTAT_STRLEN, "itl_tasks_%s",  ks_itl_id);
3966      -        if ((itl->itl_kstat_taskq = kstat_create(STMF_MODULE_NAME, 0,
3967      -            ks_nm, "io", KSTAT_TYPE_IO, 1, 0)) == NULL) {
3968      -                goto itl_kstat_cleanup;
3969      -        }
3970      -
3971      -        (void) snprintf(ks_nm, KSTAT_STRLEN, "itl_lu_%s",  ks_itl_id);
3972      -        if ((itl->itl_kstat_lu_xfer = kstat_create(STMF_MODULE_NAME, 0,
3973      -            ks_nm, "io", KSTAT_TYPE_IO, 1, 0)) == NULL) {
3974      -                goto itl_kstat_cleanup;
3975      -        }
3976      -
3977      -        (void) snprintf(ks_nm, KSTAT_STRLEN, "itl_lport_%s",  ks_itl_id);
3978      -        if ((itl->itl_kstat_lport_xfer = kstat_create(STMF_MODULE_NAME, 0,
3979      -            ks_nm, "io", KSTAT_TYPE_IO, 1, 0)) == NULL) {
3980      -                goto itl_kstat_cleanup;
3981      -        }
3982      -
3983      -        /* Install all the kstats */
3984      -        kstat_install(itl->itl_kstat_info);
3985      -        kstat_install(itl->itl_kstat_taskq);
3986      -        kstat_install(itl->itl_kstat_lu_xfer);
3987      -        kstat_install(itl->itl_kstat_lport_xfer);
3988      -
3989      -        /* Add new itl_kstat to stmf_itl_kstat_list */
3990      -        if (stmf_itl_kstat_create(itl, ks_itl_nm, ss->ss_lport->lport_id,
3991      -            itl->itl_ilu->ilu_lu->lu_id) != NULL)
3992      -                return (STMF_SUCCESS);
3993      -
3994      -itl_kstat_cleanup:
3995      -        if (itl->itl_kstat_taskq)
3996      -                kstat_delete(itl->itl_kstat_taskq);
3997      -        if (itl->itl_kstat_lu_xfer)
3998      -                kstat_delete(itl->itl_kstat_lu_xfer);
3999      -        if (itl->itl_kstat_lport_xfer)
4000      -                kstat_delete(itl->itl_kstat_lport_xfer);
4001      -        if (itl->itl_kstat_info)
4002      -                kstat_delete(itl->itl_kstat_info);
4003      -        kmem_free(ks_itl, sizeof (*ks_itl));
4004      -        kmem_free(itl->itl_kstat_strbuf, itl->itl_kstat_strbuflen);
4005      -        cmn_err(CE_WARN, "STMF: kstat_create itl failed");
4006      -        return (STMF_ALLOC_FAILURE);
4007      -}
4008      -
4009      -static void
4010      -stmf_teardown_itl_kstats(stmf_i_itl_kstat_t *ks)
4011      -{
4012      -        kstat_delete(ks->iitl_kstat_lport_xfer);
4013      -        kstat_delete(ks->iitl_kstat_lu_xfer);
4014      -        kstat_delete(ks->iitl_kstat_taskq);
4015      -        kmem_free(ks->iitl_kstat_info->ks_data, sizeof (stmf_kstat_itl_info_t));
4016      -        kstat_delete(ks->iitl_kstat_info);
4017      -        kmem_free(ks->iitl_kstat_strbuf, ks->iitl_kstat_strbuflen);
4018      -}
4019      -
4020 3699  void
4021 3700  stmf_release_itl_handle(stmf_lu_t *lu, stmf_itl_data_t *itl)
4022 3701  {
4023 3702          stmf_itl_data_t **itlpp;
4024 3703          stmf_i_lu_t *ilu;
4025 3704  
4026 3705          ASSERT(itl->itl_flags & STMF_ITL_BEING_TERMINATED);
4027 3706  
4028 3707          ilu = (stmf_i_lu_t *)lu->lu_stmf_private;
4029 3708          mutex_enter(&ilu->ilu_task_lock);
↓ open down ↓ 23 lines elided ↑ open up ↑
4053 3732  
4054 3733          ilu = (stmf_i_lu_t *)lu->lu_stmf_private;
4055 3734          if (ss == NULL) {
4056 3735                  iss = stmf_session_id_to_issptr(session_id, 1);
4057 3736                  if (iss == NULL)
4058 3737                          return (STMF_NOT_FOUND);
4059 3738          } else {
4060 3739                  iss = (stmf_i_scsi_session_t *)ss->ss_stmf_private;
4061 3740          }
4062 3741  
4063      -        /*
4064      -         * Acquire stmf_lock for stmf_itl_kstat_lookup.
4065      -         */
4066 3742          mutex_enter(&stmf_state.stmf_lock);
4067 3743          rw_enter(iss->iss_lockp, RW_WRITER);
4068 3744          n = ((uint16_t)lun[1] | (((uint16_t)(lun[0] & 0x3F)) << 8));
4069 3745          lun_map_ent = (stmf_lun_map_ent_t *)
4070 3746              stmf_get_ent_from_map(iss->iss_sm, n);
4071 3747          if ((lun_map_ent == NULL) || (lun_map_ent->ent_lu != lu)) {
4072 3748                  rw_exit(iss->iss_lockp);
4073 3749                  mutex_exit(&stmf_state.stmf_lock);
4074 3750                  return (STMF_NOT_FOUND);
4075 3751          }
↓ open down ↓ 9 lines elided ↑ open up ↑
4085 3761                  mutex_exit(&stmf_state.stmf_lock);
4086 3762                  return (STMF_ALLOC_FAILURE);
4087 3763          }
4088 3764  
4089 3765          itl->itl_ilu = ilu;
4090 3766          itl->itl_session = iss;
4091 3767          itl->itl_counter = 1;
4092 3768          itl->itl_lun = n;
4093 3769          itl->itl_handle = itl_handle;
4094 3770  
4095      -        if (stmf_setup_itl_kstats(itl) != STMF_SUCCESS) {
4096      -                kmem_free(itl, sizeof (*itl));
4097      -                rw_exit(iss->iss_lockp);
4098      -                mutex_exit(&stmf_state.stmf_lock);
4099      -                return (STMF_ALLOC_FAILURE);
4100      -        }
4101      -
4102 3771          mutex_enter(&ilu->ilu_task_lock);
4103 3772          itl->itl_next = ilu->ilu_itl_list;
4104 3773          ilu->ilu_itl_list = itl;
4105 3774          mutex_exit(&ilu->ilu_task_lock);
4106 3775          lun_map_ent->ent_itl_datap = itl;
4107 3776          rw_exit(iss->iss_lockp);
4108 3777          mutex_exit(&stmf_state.stmf_lock);
4109 3778  
4110 3779          return (STMF_SUCCESS);
4111 3780  }
↓ open down ↓ 9 lines elided ↑ open up ↑
4121 3790                          return;
4122 3791                  new |= STMF_ITL_BEING_TERMINATED;
4123 3792          } while (atomic_cas_8(&itl->itl_flags, old, new) != old);
4124 3793          itl->itl_hdlrm_reason = hdlrm_reason;
4125 3794  
4126 3795          ASSERT(itl->itl_counter);
4127 3796  
4128 3797          if (atomic_add_32_nv(&itl->itl_counter, -1))
4129 3798                  return;
4130 3799  
4131      -        drv_usecwait(10);
4132      -        if (itl->itl_counter)
4133      -                return;
4134      -
4135 3800          stmf_release_itl_handle(lu, itl);
4136 3801  }
4137 3802  
4138 3803  stmf_status_t
4139 3804  stmf_deregister_all_lu_itl_handles(stmf_lu_t *lu)
4140 3805  {
4141 3806          stmf_i_lu_t *ilu;
4142 3807          stmf_i_local_port_t *ilport;
4143 3808          stmf_i_scsi_session_t *iss;
4144 3809          stmf_lun_map_t *lm;
↓ open down ↓ 50 lines elided ↑ open up ↑
4195 3860          for (i = 0; i < nu; i++) {
4196 3861                  stmf_do_itl_dereg(lu, itl_list[i],
4197 3862                      STMF_ITL_REASON_DEREG_REQUEST);
4198 3863          }
4199 3864          kmem_free(itl_list, nmaps * sizeof (stmf_itl_data_t *));
4200 3865  
4201 3866          return (STMF_SUCCESS);
4202 3867  }
4203 3868  
4204 3869  stmf_status_t
4205      -stmf_deregister_itl_handle(stmf_lu_t *lu, uint8_t *lun,
4206      -    stmf_scsi_session_t *ss, uint64_t session_id, void *itl_handle)
4207      -{
4208      -        stmf_i_scsi_session_t *iss;
4209      -        stmf_itl_data_t *itl;
4210      -        stmf_lun_map_ent_t *ent;
4211      -        stmf_lun_map_t *lm;
4212      -        int i;
4213      -        uint16_t n;
4214      -
4215      -        if (ss == NULL) {
4216      -                if (session_id == STMF_SESSION_ID_NONE)
4217      -                        return (STMF_INVALID_ARG);
4218      -                iss = stmf_session_id_to_issptr(session_id, 1);
4219      -                if (iss == NULL)
4220      -                        return (STMF_NOT_FOUND);
4221      -        } else {
4222      -                iss = (stmf_i_scsi_session_t *)ss->ss_stmf_private;
4223      -                rw_enter(iss->iss_lockp, RW_WRITER);
4224      -        }
4225      -        lm = iss->iss_sm;
4226      -        if (lm == NULL) {
4227      -                rw_exit(iss->iss_lockp);
4228      -                return (STMF_NOT_FOUND);
4229      -        }
4230      -
4231      -        if (lun) {
4232      -                n = ((uint16_t)lun[1] | (((uint16_t)(lun[0] & 0x3F)) << 8));
4233      -                ent = (stmf_lun_map_ent_t *)
4234      -                    stmf_get_ent_from_map(iss->iss_sm, n);
4235      -        } else {
4236      -                if (itl_handle == NULL) {
4237      -                        rw_exit(iss->iss_lockp);
4238      -                        return (STMF_INVALID_ARG);
4239      -                }
4240      -                ent = NULL;
4241      -                for (i = 0; i < lm->lm_nentries; i++) {
4242      -                        if (lm->lm_plus[i] == NULL)
4243      -                                continue;
4244      -                        ent = (stmf_lun_map_ent_t *)lm->lm_plus[i];
4245      -                        if (ent->ent_itl_datap &&
4246      -                            (ent->ent_itl_datap->itl_handle == itl_handle)) {
4247      -                                break;
4248      -                        }
4249      -                }
4250      -        }
4251      -        if ((ent == NULL) || (ent->ent_lu != lu) ||
4252      -            (ent->ent_itl_datap == NULL)) {
4253      -                rw_exit(iss->iss_lockp);
4254      -                return (STMF_NOT_FOUND);
4255      -        }
4256      -        itl = ent->ent_itl_datap;
4257      -        ent->ent_itl_datap = NULL;
4258      -        rw_exit(iss->iss_lockp);
4259      -        stmf_do_itl_dereg(lu, itl, STMF_ITL_REASON_DEREG_REQUEST);
4260      -
4261      -        return (STMF_SUCCESS);
4262      -}
4263      -
4264      -stmf_status_t
4265 3870  stmf_get_itl_handle(stmf_lu_t *lu, uint8_t *lun, stmf_scsi_session_t *ss,
4266 3871      uint64_t session_id, void **itl_handle_retp)
4267 3872  {
4268 3873          stmf_i_scsi_session_t *iss;
4269 3874          stmf_lun_map_ent_t *ent;
4270 3875          stmf_lun_map_t *lm;
4271 3876          stmf_status_t ret;
4272 3877          int i;
4273 3878          uint16_t n;
4274 3879  
↓ open down ↓ 165 lines elided ↑ open up ↑
4440 4045          if (!lun_map_ent) {
4441 4046                  lu = dlun0;
4442 4047          } else {
4443 4048                  lu = lun_map_ent->ent_lu;
4444 4049          }
4445 4050          ilu = lu->lu_stmf_private;
4446 4051          if (ilu->ilu_flags & ILU_RESET_ACTIVE) {
4447 4052                  rw_exit(iss->iss_lockp);
4448 4053                  return (NULL);
4449 4054          }
     4055 +        ASSERT(lu == dlun0 || (ilu->ilu_state != STMF_STATE_OFFLINING &&
     4056 +            ilu->ilu_state != STMF_STATE_OFFLINE));
4450 4057          do {
4451 4058                  if (ilu->ilu_free_tasks == NULL) {
4452 4059                          new_task = 1;
4453 4060                          break;
4454 4061                  }
4455 4062                  mutex_enter(&ilu->ilu_task_lock);
4456 4063                  for (ppitask = &ilu->ilu_free_tasks; (*ppitask != NULL) &&
4457 4064                      ((*ppitask)->itask_cdb_buf_size < cdb_length);
4458 4065                      ppitask = &((*ppitask)->itask_lu_free_next))
4459 4066                          ;
↓ open down ↓ 108 lines elided ↑ open up ↑
4568 4175              (stmf_i_scsi_task_t *)task->task_stmf_private;
4569 4176          stmf_i_lu_t *ilu = (stmf_i_lu_t *)task->task_lu->lu_stmf_private;
4570 4177  
4571 4178          ASSERT(rw_lock_held(iss->iss_lockp));
4572 4179          itask->itask_flags = ITASK_IN_FREE_LIST;
4573 4180          itask->itask_proxy_msg_id = 0;
4574 4181          mutex_enter(&ilu->ilu_task_lock);
4575 4182          itask->itask_lu_free_next = ilu->ilu_free_tasks;
4576 4183          ilu->ilu_free_tasks = itask;
4577 4184          ilu->ilu_ntasks_free++;
     4185 +        if (ilu->ilu_ntasks == ilu->ilu_ntasks_free)
     4186 +                cv_signal(&ilu->ilu_offline_pending_cv);
4578 4187          mutex_exit(&ilu->ilu_task_lock);
4579 4188          atomic_add_32(itask->itask_ilu_task_cntr, -1);
4580 4189  }
4581 4190  
4582 4191  void
4583 4192  stmf_task_lu_check_freelist(stmf_i_lu_t *ilu)
4584 4193  {
4585 4194          uint32_t        num_to_release, ndx;
4586 4195          stmf_i_scsi_task_t *itask;
4587 4196          stmf_lu_t       *lu = ilu->ilu_lu;
↓ open down ↓ 1496 lines elided ↑ open up ↑
6084 5693  stmf_status_t
6085 5694  stmf_scsilib_uniq_lu_id2(uint32_t company_id, uint32_t host_id,
6086 5695      scsi_devid_desc_t *lu_id)
6087 5696  {
6088 5697          uint8_t *p;
6089 5698          struct timeval32 timestamp32;
6090 5699          uint32_t *t = (uint32_t *)&timestamp32;
6091 5700          struct ether_addr mac;
6092 5701          uint8_t *e = (uint8_t *)&mac;
6093 5702          int hid = (int)host_id;
     5703 +        uint16_t gen_number;
6094 5704  
6095 5705          if (company_id == COMPANY_ID_NONE)
6096 5706                  company_id = COMPANY_ID_SUN;
6097 5707  
6098 5708          if (lu_id->ident_length != 0x10)
6099 5709                  return (STMF_INVALID_ARG);
6100 5710  
6101 5711          p = (uint8_t *)lu_id;
6102 5712  
6103      -        atomic_add_16(&stmf_lu_id_gen_number, 1);
     5713 +        gen_number = atomic_add_16_nv(&stmf_lu_id_gen_number, 1);
6104 5714  
6105 5715          p[0] = 0xf1; p[1] = 3; p[2] = 0; p[3] = 0x10;
6106 5716          p[4] = ((company_id >> 20) & 0xf) | 0x60;
6107 5717          p[5] = (company_id >> 12) & 0xff;
6108 5718          p[6] = (company_id >> 4) & 0xff;
6109 5719          p[7] = (company_id << 4) & 0xf0;
6110 5720          if (hid == 0 && !localetheraddr((struct ether_addr *)NULL, &mac)) {
6111 5721                  hid = BE_32((int)zone_get_hostid(NULL));
6112 5722          }
6113 5723          if (hid != 0) {
6114 5724                  e[0] = (hid >> 24) & 0xff;
6115 5725                  e[1] = (hid >> 16) & 0xff;
6116 5726                  e[2] = (hid >> 8) & 0xff;
6117 5727                  e[3] = hid & 0xff;
6118 5728                  e[4] = e[5] = 0;
6119 5729          }
6120 5730          bcopy(e, p+8, 6);
6121 5731          uniqtime32(&timestamp32);
6122 5732          *t = BE_32(*t);
6123 5733          bcopy(t, p+14, 4);
6124      -        p[18] = (stmf_lu_id_gen_number >> 8) & 0xff;
6125      -        p[19] = stmf_lu_id_gen_number & 0xff;
     5734 +        p[18] = (gen_number >> 8) & 0xff;
     5735 +        p[19] = gen_number & 0xff;
6126 5736  
6127 5737          return (STMF_SUCCESS);
6128 5738  }
6129 5739  
6130 5740  /*
6131 5741   * saa is sense key, ASC, ASCQ
6132 5742   */
6133 5743  void
6134 5744  stmf_scsilib_send_status(scsi_task_t *task, uint8_t st, uint32_t saa)
6135 5745  {
↓ open down ↓ 1401 lines elided ↑ open up ↑
7537 7147  void
7538 7148  stmf_itl_task_start(stmf_i_scsi_task_t *itask)
7539 7149  {
7540 7150          stmf_itl_data_t *itl = itask->itask_itl_datap;
7541 7151          scsi_task_t     *task = itask->itask_task;
7542 7152          stmf_i_lu_t     *ilu;
7543 7153  
7544 7154          if (itl == NULL || task->task_lu == dlun0)
7545 7155                  return;
7546 7156          ilu = (stmf_i_lu_t *)task->task_lu->lu_stmf_private;
7547      -        mutex_enter(ilu->ilu_kstat_io->ks_lock);
7548 7157          itask->itask_start_timestamp = gethrtime();
7549      -        kstat_waitq_enter(KSTAT_IO_PTR(itl->itl_kstat_taskq));
7550      -        stmf_update_kstat_lu_q(itask->itask_task, kstat_waitq_enter);
7551      -        mutex_exit(ilu->ilu_kstat_io->ks_lock);
     7158 +        if (ilu->ilu_kstat_io != NULL) {
     7159 +                mutex_enter(ilu->ilu_kstat_io->ks_lock);
     7160 +                stmf_update_kstat_lu_q(itask->itask_task, kstat_waitq_enter);
     7161 +                mutex_exit(ilu->ilu_kstat_io->ks_lock);
     7162 +        }
7552 7163  
7553 7164          stmf_update_kstat_lport_q(itask->itask_task, kstat_waitq_enter);
7554 7165  }
7555 7166  
7556 7167  void
7557 7168  stmf_itl_lu_new_task(stmf_i_scsi_task_t *itask)
7558 7169  {
7559 7170          stmf_itl_data_t *itl = itask->itask_itl_datap;
7560 7171          scsi_task_t     *task = itask->itask_task;
7561 7172          stmf_i_lu_t     *ilu;
7562 7173  
7563 7174          if (itl == NULL || task->task_lu == dlun0)
7564 7175                  return;
7565 7176          ilu = (stmf_i_lu_t *)task->task_lu->lu_stmf_private;
7566      -        mutex_enter(ilu->ilu_kstat_io->ks_lock);
7567      -        kstat_waitq_to_runq(KSTAT_IO_PTR(itl->itl_kstat_taskq));
7568      -        stmf_update_kstat_lu_q(itask->itask_task, kstat_waitq_to_runq);
7569      -        mutex_exit(ilu->ilu_kstat_io->ks_lock);
     7177 +        if (ilu->ilu_kstat_io != NULL) {
     7178 +                mutex_enter(ilu->ilu_kstat_io->ks_lock);
     7179 +                stmf_update_kstat_lu_q(itask->itask_task, kstat_waitq_to_runq);
     7180 +                mutex_exit(ilu->ilu_kstat_io->ks_lock);
     7181 +        }
7570 7182  
7571 7183          stmf_update_kstat_lport_q(itask->itask_task, kstat_waitq_to_runq);
7572 7184  }
7573 7185  
7574 7186  void
7575 7187  stmf_itl_task_done(stmf_i_scsi_task_t *itask)
7576 7188  {
7577 7189          stmf_itl_data_t         *itl = itask->itask_itl_datap;
7578 7190          scsi_task_t             *task = itask->itask_task;
7579      -        kstat_io_t              *kip;
7580      -        hrtime_t                elapsed_time;
7581      -        stmf_kstat_itl_info_t   *itli;
7582 7191          stmf_i_lu_t     *ilu;
7583 7192  
     7193 +        itask->itask_done_timestamp = gethrtime();
     7194 +
7584 7195          if (itl == NULL || task->task_lu == dlun0)
7585 7196                  return;
7586 7197          ilu = (stmf_i_lu_t *)task->task_lu->lu_stmf_private;
7587 7198  
     7199 +        if (ilu->ilu_kstat_io == NULL)
     7200 +                return;
     7201 +
7588 7202          mutex_enter(ilu->ilu_kstat_io->ks_lock);
7589      -        itli = (stmf_kstat_itl_info_t *)KSTAT_NAMED_PTR(itl->itl_kstat_info);
7590      -        kip = KSTAT_IO_PTR(itl->itl_kstat_taskq);
7591 7203  
7592      -        itli->i_task_waitq_elapsed.value.ui64 += itask->itask_waitq_time;
7593      -
7594      -        itask->itask_done_timestamp = gethrtime();
7595      -        elapsed_time =
7596      -            itask->itask_done_timestamp - itask->itask_start_timestamp;
7597      -
7598      -        if (task->task_flags & TF_READ_DATA) {
7599      -                kip->reads++;
7600      -                kip->nread += itask->itask_read_xfer;
7601      -                itli->i_task_read_elapsed.value.ui64 += elapsed_time;
7602      -                itli->i_lu_read_elapsed.value.ui64 +=
7603      -                    itask->itask_lu_read_time;
7604      -                itli->i_lport_read_elapsed.value.ui64 +=
7605      -                    itask->itask_lport_read_time;
7606      -        }
7607      -
7608      -        if (task->task_flags & TF_WRITE_DATA) {
7609      -                kip->writes++;
7610      -                kip->nwritten += itask->itask_write_xfer;
7611      -                itli->i_task_write_elapsed.value.ui64 += elapsed_time;
7612      -                itli->i_lu_write_elapsed.value.ui64 +=
7613      -                    itask->itask_lu_write_time;
7614      -                itli->i_lport_write_elapsed.value.ui64 +=
7615      -                    itask->itask_lport_write_time;
7616      -        }
7617      -
7618 7204          if (itask->itask_flags & ITASK_KSTAT_IN_RUNQ) {
7619      -                kstat_runq_exit(kip);
7620 7205                  stmf_update_kstat_lu_q(task, kstat_runq_exit);
7621 7206                  mutex_exit(ilu->ilu_kstat_io->ks_lock);
7622 7207                  stmf_update_kstat_lport_q(task, kstat_runq_exit);
7623 7208          } else {
7624      -                kstat_waitq_exit(kip);
7625 7209                  stmf_update_kstat_lu_q(task, kstat_waitq_exit);
7626 7210                  mutex_exit(ilu->ilu_kstat_io->ks_lock);
7627 7211                  stmf_update_kstat_lport_q(task, kstat_waitq_exit);
7628 7212          }
7629 7213  }
7630 7214  
7631      -void
7632      -stmf_lu_xfer_start(scsi_task_t *task)
7633      -{
7634      -        stmf_i_scsi_task_t *itask = task->task_stmf_private;
7635      -        stmf_itl_data_t *itl = itask->itask_itl_datap;
7636      -        stmf_i_lu_t     *ilu = (stmf_i_lu_t *)task->task_lu->lu_stmf_private;
7637      -        kstat_io_t              *kip;
7638      -
7639      -        if (itl == NULL || task->task_lu == dlun0)
7640      -                return;
7641      -
7642      -        kip = KSTAT_IO_PTR(itl->itl_kstat_lu_xfer);
7643      -        mutex_enter(ilu->ilu_kstat_io->ks_lock);
7644      -        kstat_runq_enter(kip);
7645      -        mutex_exit(ilu->ilu_kstat_io->ks_lock);
7646      -}
7647      -
7648      -void
7649      -stmf_lu_xfer_done(scsi_task_t *task, boolean_t read, uint64_t xfer_bytes,
7650      -    hrtime_t elapsed_time)
7651      -{
7652      -        stmf_i_scsi_task_t      *itask = task->task_stmf_private;
7653      -        stmf_itl_data_t         *itl = itask->itask_itl_datap;
7654      -        stmf_i_lu_t     *ilu = (stmf_i_lu_t *)task->task_lu->lu_stmf_private;
7655      -        kstat_io_t              *kip;
7656      -
7657      -        if (itl == NULL || task->task_lu == dlun0)
7658      -                return;
7659      -
7660      -        if (read) {
7661      -                atomic_add_64((uint64_t *)&itask->itask_lu_read_time,
7662      -                    elapsed_time);
7663      -        } else {
7664      -                atomic_add_64((uint64_t *)&itask->itask_lu_write_time,
7665      -                    elapsed_time);
7666      -        }
7667      -
7668      -        kip = KSTAT_IO_PTR(itl->itl_kstat_lu_xfer);
7669      -        mutex_enter(ilu->ilu_kstat_io->ks_lock);
7670      -        kstat_runq_exit(kip);
7671      -        if (read) {
7672      -                kip->reads++;
7673      -                kip->nread += xfer_bytes;
7674      -        } else {
7675      -                kip->writes++;
7676      -                kip->nwritten += xfer_bytes;
7677      -        }
7678      -        mutex_exit(ilu->ilu_kstat_io->ks_lock);
7679      -}
7680      -
7681 7215  static void
7682 7216  stmf_lport_xfer_start(stmf_i_scsi_task_t *itask, stmf_data_buf_t *dbuf)
7683 7217  {
7684 7218          stmf_itl_data_t         *itl = itask->itask_itl_datap;
7685 7219  
7686 7220          if (itl == NULL)
7687 7221                  return;
7688 7222  
7689 7223          DTRACE_PROBE2(scsi__xfer__start, scsi_task_t *, itask->itask_task,
7690 7224              stmf_data_buf_t *, dbuf);
7691 7225  
7692 7226          dbuf->db_xfer_start_timestamp = gethrtime();
7693 7227  }
7694 7228  
7695 7229  static void
7696 7230  stmf_lport_xfer_done(stmf_i_scsi_task_t *itask, stmf_data_buf_t *dbuf)
7697 7231  {
7698 7232          stmf_itl_data_t         *itl = itask->itask_itl_datap;
7699      -        scsi_task_t             *task;
7700      -        stmf_i_local_port_t     *ilp;
7701      -        kstat_io_t              *kip;
7702 7233          hrtime_t                elapsed_time;
7703 7234          uint64_t                xfer_size;
7704 7235  
7705 7236          if (itl == NULL)
7706 7237                  return;
7707 7238  
7708      -        task = (scsi_task_t *)itask->itask_task;
7709      -        ilp = (stmf_i_local_port_t *)task->task_lport->lport_stmf_private;
7710 7239          xfer_size = (dbuf->db_xfer_status == STMF_SUCCESS) ?
7711 7240              dbuf->db_data_size : 0;
7712 7241  
7713 7242          elapsed_time = gethrtime() - dbuf->db_xfer_start_timestamp;
7714 7243          if (dbuf->db_flags & DB_DIRECTION_TO_RPORT) {
7715 7244                  atomic_add_64((uint64_t *)&itask->itask_lport_read_time,
7716 7245                      elapsed_time);
7717 7246                  atomic_add_64((uint64_t *)&itask->itask_read_xfer,
7718 7247                      xfer_size);
7719 7248          } else {
7720 7249                  atomic_add_64((uint64_t *)&itask->itask_lport_write_time,
7721 7250                      elapsed_time);
7722 7251                  atomic_add_64((uint64_t *)&itask->itask_write_xfer,
7723 7252                      xfer_size);
7724 7253          }
7725 7254  
7726 7255          DTRACE_PROBE3(scsi__xfer__end, scsi_task_t *, itask->itask_task,
7727 7256              stmf_data_buf_t *, dbuf, hrtime_t, elapsed_time);
7728 7257  
7729      -        kip = KSTAT_IO_PTR(itl->itl_kstat_lport_xfer);
7730      -        mutex_enter(ilp->ilport_kstat_io->ks_lock);
7731      -        if (dbuf->db_flags & DB_DIRECTION_TO_RPORT) {
7732      -                kip->reads++;
7733      -                kip->nread += xfer_size;
7734      -        } else {
7735      -                kip->writes++;
7736      -                kip->nwritten += xfer_size;
7737      -        }
7738      -        mutex_exit(ilp->ilport_kstat_io->ks_lock);
7739      -
7740 7258          dbuf->db_xfer_start_timestamp = 0;
7741 7259  }
7742 7260  
7743 7261  void
7744 7262  stmf_svc_init()
7745 7263  {
7746 7264          if (stmf_state.stmf_svc_flags & STMF_SVC_STARTED)
7747 7265                  return;
7748 7266          stmf_state.stmf_svc_tailp = &stmf_state.stmf_svc_active;
7749 7267          stmf_state.stmf_svc_taskq = ddi_taskq_create(0, "STMF_SVC_TASKQ", 1,
↓ open down ↓ 81 lines elided ↑ open up ↑
7831 7349                          break;
7832 7350                  case STMF_CMD_LU_OFFLINE:
7833 7351                          /* Remove all mappings of this LU */
7834 7352                          stmf_session_lu_unmapall((stmf_lu_t *)req->svc_obj);
7835 7353                          /* Kill all the pending I/Os for this LU */
7836 7354                          mutex_exit(&stmf_state.stmf_lock);
7837 7355                          stmf_task_lu_killall((stmf_lu_t *)req->svc_obj, NULL,
7838 7356                              STMF_ABORTED);
7839 7357                          lu = (stmf_lu_t *)req->svc_obj;
7840 7358                          ilu = (stmf_i_lu_t *)lu->lu_stmf_private;
7841      -                        if (ilu->ilu_ntasks != ilu->ilu_ntasks_free)
7842      -                                break;
     7359 +                        stmf_wait_ilu_tasks_finish(ilu);
7843 7360                          lu->lu_ctl(lu, req->svc_cmd, &req->svc_info);
7844 7361                          break;
7845 7362                  default:
7846 7363                          cmn_err(CE_PANIC, "stmf_svc: unknown cmd %d",
7847 7364                              req->svc_cmd);
7848 7365                  }
7849 7366  
     7367 +                kmem_free(req, req->svc_req_alloc_size);
7850 7368                  mutex_enter(&stmf_state.stmf_lock);
7851 7369          }
7852 7370  
7853 7371          stmf_state.stmf_svc_flags &= ~(STMF_SVC_STARTED | STMF_SVC_ACTIVE);
7854 7372          mutex_exit(&stmf_state.stmf_lock);
7855 7373  }
7856 7374  
7857 7375  static void
7858 7376  stmf_svc_timeout(struct stmf_svc_clocks *clks)
7859 7377  {
↓ open down ↓ 124 lines elided ↑ open up ↑
7984 7502                  if (stmf_level == 0)
7985 7503                          stmf_state.stmf_process_initial_luns = 0;
7986 7504          }
7987 7505  
7988 7506          stmf_state.stmf_svc_flags &= ~STMF_SVC_ACTIVE;
7989 7507          (void) cv_reltimedwait(&stmf_state.stmf_cv,
7990 7508              &stmf_state.stmf_lock, td, TR_CLOCK_TICK);
7991 7509          stmf_state.stmf_svc_flags |= STMF_SVC_ACTIVE;
7992 7510  }
7993 7511  
     7512 +/*
     7513 + * Waits for ongoing I/O tasks to finish on an LU in preparation for
     7514 + * the LU's offlining. The LU should already be in an Offlining state
     7515 + * (otherwise I/O to the LU might never end). There is an additional
     7516 + * enforcement of this via a deadman timer check.
     7517 + */
     7518 +static void
     7519 +stmf_wait_ilu_tasks_finish(stmf_i_lu_t *ilu)
     7520 +{
     7521 +        clock_t start, now, deadline;
     7522 +
     7523 +        start = now = ddi_get_lbolt();
     7524 +        deadline = start + drv_usectohz(stmf_io_deadman * 1000000llu);
     7525 +        mutex_enter(&ilu->ilu_task_lock);
     7526 +        while (ilu->ilu_ntasks != ilu->ilu_ntasks_free) {
     7527 +                (void) cv_timedwait(&ilu->ilu_offline_pending_cv,
     7528 +                    &ilu->ilu_task_lock, deadline);
     7529 +                now = ddi_get_lbolt();
     7530 +                if (now > deadline) {
     7531 +                        if (stmf_io_deadman_enabled) {
     7532 +                                cmn_err(CE_PANIC, "stmf_svc: I/O deadman hit "
     7533 +                                    "on STMF_CMD_LU_OFFLINE after %d seconds",
     7534 +                                    stmf_io_deadman);
     7535 +                        } else {
     7536 +                                /* keep on spinning */
     7537 +                                deadline = now + drv_usectohz(stmf_io_deadman *
     7538 +                                    1000000llu);
     7539 +                        }
     7540 +                }
     7541 +        }
     7542 +        mutex_exit(&ilu->ilu_task_lock);
     7543 +        DTRACE_PROBE1(deadman__timeout__wait, clock_t, now - start);
     7544 +}
     7545 +
7994 7546  void
7995 7547  stmf_svc_queue(int cmd, void *obj, stmf_state_change_info_t *info)
7996 7548  {
7997 7549          stmf_svc_req_t *req;
7998 7550          int s;
7999 7551  
8000 7552          ASSERT(!mutex_owned(&stmf_state.stmf_lock));
8001 7553          s = sizeof (stmf_svc_req_t);
8002 7554          if (info->st_additional_info) {
8003 7555                  s += strlen(info->st_additional_info) + 1;
↓ open down ↓ 441 lines elided ↑ open up ↑
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX