diff options
author | Keith M Wesolowski <wesolows@foobazco.org> | 2014-04-30 17:33:08 +0000 |
---|---|---|
committer | Keith M Wesolowski <wesolows@foobazco.org> | 2014-04-30 17:33:08 +0000 |
commit | e5eca69f4b721e7e2209d18b3358d79069be9024 (patch) | |
tree | 10281da4c59357b0ca0f9a89d716be080ed4c7ab /usr/src/uts/common | |
parent | e7a35eac19dab0d7a03157433255ec4d9ee9c60a (diff) | |
parent | 19449258028e6813f0b7a606b554b2fa37a390ec (diff) | |
download | illumos-joyent-e5eca69f4b721e7e2209d18b3358d79069be9024.tar.gz |
[illumos-gate merge]
commit 19449258028e6813f0b7a606b554b2fa37a390ec
4823 don't open-code NSEC2MSEC and MSEC2NSEC
commit cb3e7fb42f8104f779abb6856ccf6e5b8e6419d8
4819 fix mpt_sas command timeout handling
commit b59e2127f21675e88c58a4dd924bc55eeb83c7a6
4809 NANOSEC should be 'long long' to avoid integer overflow bugs
4810 spa_async_tasks_pending suffers from an integer overflow bug
4811 in.mpathd: tv2ns suffers from an integer overflow bug
Diffstat (limited to 'usr/src/uts/common')
-rw-r--r-- | usr/src/uts/common/dtrace/dtrace.c | 2 | ||||
-rw-r--r-- | usr/src/uts/common/inet/ip/ip.c | 8 | ||||
-rw-r--r-- | usr/src/uts/common/io/devpoll.c | 2 | ||||
-rw-r--r-- | usr/src/uts/common/io/power.c | 2 | ||||
-rw-r--r-- | usr/src/uts/common/io/scsi/adapters/mpt_sas/mptsas.c | 279 | ||||
-rw-r--r-- | usr/src/uts/common/sys/scsi/adapters/mpt_sas/mptsas_var.h | 16 | ||||
-rw-r--r-- | usr/src/uts/common/sys/time.h | 2 |
7 files changed, 167 insertions, 144 deletions
diff --git a/usr/src/uts/common/dtrace/dtrace.c b/usr/src/uts/common/dtrace/dtrace.c index 3ecd33e24e..e52b51315c 100644 --- a/usr/src/uts/common/dtrace/dtrace.c +++ b/usr/src/uts/common/dtrace/dtrace.c @@ -139,7 +139,7 @@ dtrace_optval_t dtrace_ustackframes_default = 20; dtrace_optval_t dtrace_jstackframes_default = 50; dtrace_optval_t dtrace_jstackstrsize_default = 512; int dtrace_msgdsize_max = 128; -hrtime_t dtrace_chill_max = 500 * (NANOSEC / MILLISEC); /* 500 ms */ +hrtime_t dtrace_chill_max = MSEC2NSEC(500); /* 500 ms */ hrtime_t dtrace_chill_interval = NANOSEC; /* 1000 ms */ int dtrace_devdepth_max = 32; int dtrace_err_verbose; diff --git a/usr/src/uts/common/inet/ip/ip.c b/usr/src/uts/common/inet/ip/ip.c index 313c6120ed..4b65ec8a6d 100644 --- a/usr/src/uts/common/inet/ip/ip.c +++ b/usr/src/uts/common/inet/ip/ip.c @@ -1498,7 +1498,7 @@ icmp_inbound_v4(mblk_t *mp, ip_recv_attr_t *ira) /* Compute # of milliseconds since midnight */ gethrestime(&now); ts = (now.tv_sec % (24 * 60 * 60)) * 1000 + - now.tv_nsec / (NANOSEC / MILLISEC); + NSEC2MSEC(now.tv_nsec); *tsp++ = htonl(ts); /* Lay in 'receive time' */ *tsp++ = htonl(ts); /* Lay in 'send time' */ BUMP_MIB(&ipst->ips_icmp_mib, icmpOutTimestampReps); @@ -9117,7 +9117,7 @@ ip_forward_options(mblk_t *mp, ipha_t *ipha, ill_t *dst_ill, /* Compute # of milliseconds since midnight */ gethrestime(&now); ts = (now.tv_sec % (24 * 60 * 60)) * 1000 + - now.tv_nsec / (NANOSEC / MILLISEC); + NSEC2MSEC(now.tv_nsec); bcopy(&ts, (char *)opt + off, IPOPT_TS_TIMELEN); opt[IPOPT_OFFSET] += IPOPT_TS_TIMELEN; break; @@ -9343,7 +9343,7 @@ ip_input_local_options(mblk_t *mp, ipha_t *ipha, ip_recv_attr_t *ira) /* Compute # of milliseconds since midnight */ gethrestime(&now); ts = (now.tv_sec % (24 * 60 * 60)) * 1000 + - now.tv_nsec / (NANOSEC / MILLISEC); + NSEC2MSEC(now.tv_nsec); bcopy(&ts, (char *)opt + off, IPOPT_TS_TIMELEN); opt[IPOPT_OFFSET] += IPOPT_TS_TIMELEN; break; @@ -12025,7 +12025,7 @@ ip_output_local_options(ipha_t *ipha, ip_stack_t *ipst) /* Compute # of milliseconds since midnight */ gethrestime(&now); ts = (now.tv_sec % (24 * 60 * 60)) * 1000 + - now.tv_nsec / (NANOSEC / MILLISEC); + NSEC2MSEC(now.tv_nsec); bcopy(&ts, (char *)opt + off, IPOPT_TS_TIMELEN); opt[IPOPT_OFFSET] += IPOPT_TS_TIMELEN; break; diff --git a/usr/src/uts/common/io/devpoll.c b/usr/src/uts/common/io/devpoll.c index 3c1e80eb01..db6d4881d4 100644 --- a/usr/src/uts/common/io/devpoll.c +++ b/usr/src/uts/common/io/devpoll.c @@ -960,7 +960,7 @@ dpioctl(dev_t dev, int cmd, intptr_t arg, int mode, cred_t *credp, int *rvalp) * to absolute nanoseconds. They must wait for at * least a tick. */ - deadline = deadline * NANOSEC / MILLISEC; + deadline = MSEC2NSEC(deadline); deadline = MAX(deadline, nsec_per_tick); deadline += now; } diff --git a/usr/src/uts/common/io/power.c b/usr/src/uts/common/io/power.c index 61e675ba77..aed53f5334 100644 --- a/usr/src/uts/common/io/power.c +++ b/usr/src/uts/common/io/power.c @@ -116,7 +116,7 @@ static char hasEPIC = B_FALSE; static void *power_state; static int power_inst = -1; -static hrtime_t power_button_debounce = NANOSEC/MILLISEC*10; +static hrtime_t power_button_debounce = MSEC2NSEC(10); static hrtime_t power_button_abort_interval = 1.5 * NANOSEC; static int power_button_abort_presses = 3; static int power_button_abort_enable = 1; diff --git a/usr/src/uts/common/io/scsi/adapters/mpt_sas/mptsas.c b/usr/src/uts/common/io/scsi/adapters/mpt_sas/mptsas.c index a21e8c820f..e7ad12761c 100644 --- a/usr/src/uts/common/io/scsi/adapters/mpt_sas/mptsas.c +++ b/usr/src/uts/common/io/scsi/adapters/mpt_sas/mptsas.c @@ -21,7 +21,7 @@ /* * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved. - * Copyright 2012 Nexenta Systems, Inc. All rights reserved. + * Copyright 2014 Nexenta Systems, Inc. All rights reserved. * Copyright (c) 2014, Joyent, Inc. All rights reserved. * Copyright 2014 OmniTI Computer Consulting, Inc. All rights reserved. */ @@ -240,7 +240,7 @@ static void mptsas_sge_setup(mptsas_t *mpt, mptsas_cmd_t *cmd, static void mptsas_watch(void *arg); static void mptsas_watchsubr(mptsas_t *mpt); -static void mptsas_cmd_timeout(mptsas_t *mpt, uint16_t devhdl); +static void mptsas_cmd_timeout(mptsas_t *mpt, mptsas_target_t *ptgt); static void mptsas_start_passthru(mptsas_t *mpt, mptsas_cmd_t *cmd); static int mptsas_do_passthru(mptsas_t *mpt, uint8_t *request, uint8_t *reply, @@ -3379,17 +3379,17 @@ mptsas_save_cmd(mptsas_t *mpt, mptsas_cmd_t *cmd) * event acknoledgment) */ if ((cmd->cmd_flags & CFLAG_CMDIOC) == 0) { + /* + * Expiration time is set in mptsas_start_cmd + */ ptgt->m_t_ncmds++; - } - cmd->cmd_active_timeout = cmd->cmd_pkt->pkt_time; - - /* - * If initial timout is less than or equal to one tick, bump - * the timeout by a tick so that command doesn't timeout before - * its allotted time. - */ - if (cmd->cmd_active_timeout <= mptsas_scsi_watchdog_tick) { - cmd->cmd_active_timeout += mptsas_scsi_watchdog_tick; + cmd->cmd_active_expiration = 0; + } else { + /* + * Initialize expiration time for passthrough commands, + */ + cmd->cmd_active_expiration = gethrtime() + + (hrtime_t)cmd->cmd_pkt->pkt_time * NANOSEC; } return (TRUE); } @@ -4853,9 +4853,8 @@ mptsas_handle_address_reply(mptsas_t *mpt, "reply in slot %d", SMID); return; } - if ((cmd->cmd_flags & CFLAG_PASSTHRU) || - (cmd->cmd_flags & CFLAG_CONFIG) || - (cmd->cmd_flags & CFLAG_FW_DIAG)) { + if ((cmd->cmd_flags & + (CFLAG_PASSTHRU | CFLAG_CONFIG | CFLAG_FW_DIAG))) { cmd->cmd_rfm = reply_addr; cmd->cmd_flags |= CFLAG_FINISHED; cv_broadcast(&mpt->m_passthru_cv); @@ -5022,6 +5021,9 @@ mptsas_check_scsi_io_error(mptsas_t *mpt, pMpi2SCSIIOReply_t reply, struct buf *bp; mptsas_target_t *ptgt = cmd->cmd_tgt_addr; uint8_t *sensedata = NULL; + uint64_t sas_wwn; + uint8_t phy; + char wwn_str[MPTSAS_WWN_STRLEN]; if ((cmd->cmd_flags & (CFLAG_SCBEXTERN | CFLAG_EXTARQBUFVALID)) == (CFLAG_SCBEXTERN | CFLAG_EXTARQBUFVALID)) { @@ -5039,12 +5041,19 @@ mptsas_check_scsi_io_error(mptsas_t *mpt, pMpi2SCSIIOReply_t reply, &reply->ResponseInfo); if (ioc_status & MPI2_IOCSTATUS_FLAG_LOG_INFO_AVAILABLE) { + sas_wwn = ptgt->m_addr.mta_wwn; + phy = ptgt->m_phynum; + if (sas_wwn == 0) { + (void) sprintf(wwn_str, "p%x", phy); + } else { + (void) sprintf(wwn_str, "w%016"PRIx64, sas_wwn); + } loginfo = ddi_get32(mpt->m_acc_reply_frame_hdl, &reply->IOCLogInfo); mptsas_log(mpt, CE_NOTE, - "?Log info 0x%x received for target %d.\n" + "?Log info 0x%x received for target %d %s.\n" "\tscsi_status=0x%x, ioc_status=0x%x, scsi_state=0x%x", - loginfo, Tgt(cmd), scsi_status, ioc_status, + loginfo, Tgt(cmd), wwn_str, scsi_status, ioc_status, scsi_state); } @@ -5199,8 +5208,18 @@ mptsas_check_scsi_io_error(mptsas_t *mpt, pMpi2SCSIIOReply_t reply, } break; case MPI2_IOCSTATUS_SCSI_TASK_TERMINATED: - mptsas_set_pkt_reason(mpt, - cmd, CMD_RESET, STAT_BUS_RESET); + if (cmd->cmd_active_expiration <= gethrtime()) { + /* + * When timeout requested, propagate + * proper reason and statistics to + * target drivers. + */ + mptsas_set_pkt_reason(mpt, cmd, CMD_TIMEOUT, + STAT_BUS_RESET | STAT_TIMEOUT); + } else { + mptsas_set_pkt_reason(mpt, cmd, CMD_RESET, + STAT_BUS_RESET); + } break; case MPI2_IOCSTATUS_SCSI_IOC_TERMINATED: case MPI2_IOCSTATUS_SCSI_EXT_TERMINATED: @@ -7660,7 +7679,6 @@ mptsas_remove_cmd(mptsas_t *mpt, mptsas_cmd_t *cmd) { int slot; mptsas_slots_t *slots = mpt->m_active; - int t; mptsas_target_t *ptgt = cmd->cmd_tgt_addr; ASSERT(cmd != NULL); @@ -7674,7 +7692,6 @@ mptsas_remove_cmd(mptsas_t *mpt, mptsas_cmd_t *cmd) return; } - t = Tgt(cmd); slot = cmd->cmd_slot; /* @@ -7699,8 +7716,16 @@ mptsas_remove_cmd(mptsas_t *mpt, mptsas_cmd_t *cmd) ((cmd->cmd_pkt_flags & FLAG_TAGMASK) == 0)) { mptsas_set_throttle(mpt, ptgt, MAX_THROTTLE); } - } + /* + * Remove this command from the active queue. + */ + if (cmd->cmd_active_expiration != 0) { + TAILQ_REMOVE(&ptgt->m_active_cmdq, cmd, + cmd_active_link); + cmd->cmd_active_expiration = 0; + } + } } /* @@ -7711,50 +7736,6 @@ mptsas_remove_cmd(mptsas_t *mpt, mptsas_cmd_t *cmd) return; } - /* - * Figure out what to set tag Q timeout for... - * - * Optimize: If we have duplicate's of same timeout - * we're using, then we'll use it again until we run - * out of duplicates. This should be the normal case - * for block and raw I/O. - * If no duplicates, we have to scan through tag que and - * find the longest timeout value and use it. This is - * going to take a while... - * Add 1 to m_n_normal to account for TM request. - */ - if (cmd->cmd_pkt->pkt_time == ptgt->m_timebase) { - if (--(ptgt->m_dups) == 0) { - if (ptgt->m_t_ncmds) { - mptsas_cmd_t *ssp; - uint_t n = 0; - ushort_t nslots = (slots->m_n_normal + 1); - ushort_t i; - /* - * This crude check assumes we don't do - * this too often which seems reasonable - * for block and raw I/O. - */ - for (i = 0; i < nslots; i++) { - ssp = slots->m_slot[i]; - if (ssp && (Tgt(ssp) == t) && - (ssp->cmd_pkt->pkt_time > n)) { - n = ssp->cmd_pkt->pkt_time; - ptgt->m_dups = 1; - } else if (ssp && (Tgt(ssp) == t) && - (ssp->cmd_pkt->pkt_time == n)) { - ptgt->m_dups++; - } - } - ptgt->m_timebase = n; - } else { - ptgt->m_dups = 0; - ptgt->m_timebase = 0; - } - } - } - ptgt->m_timeout = ptgt->m_timebase; - ASSERT(cmd != slots->m_slot[cmd->cmd_slot]); } @@ -7909,7 +7890,6 @@ mptsas_start_cmd(mptsas_t *mpt, mptsas_cmd_t *cmd) { struct scsi_pkt *pkt = CMD2PKT(cmd); uint32_t control = 0; - int n; caddr_t mem; pMpi2SCSIIORequest_t io_request; ddi_dma_handle_t dma_hdl = mpt->m_dma_req_frame_hdl; @@ -7917,6 +7897,7 @@ mptsas_start_cmd(mptsas_t *mpt, mptsas_cmd_t *cmd) mptsas_target_t *ptgt = cmd->cmd_tgt_addr; uint16_t SMID, io_flags = 0; uint32_t request_desc_low, request_desc_high; + mptsas_cmd_t *c; NDBG1(("mptsas_start_cmd: cmd=0x%p", (void *)cmd)); @@ -8046,37 +8027,44 @@ mptsas_start_cmd(mptsas_t *mpt, mptsas_cmd_t *cmd) /* * Start timeout. */ + cmd->cmd_active_expiration = + gethrtime() + (hrtime_t)pkt->pkt_time * NANOSEC; #ifdef MPTSAS_TEST /* - * Temporarily set timebase = 0; needed for - * timeout torture test. + * Force timeouts to happen immediately. */ - if (mptsas_test_timeouts) { - ptgt->m_timebase = 0; - } + if (mptsas_test_timeouts) + cmd->cmd_active_expiration = gethrtime(); #endif - n = pkt->pkt_time - ptgt->m_timebase; - - if (n == 0) { - (ptgt->m_dups)++; - ptgt->m_timeout = ptgt->m_timebase; - } else if (n > 0) { - ptgt->m_timeout = - ptgt->m_timebase = pkt->pkt_time; - ptgt->m_dups = 1; - } else if (n < 0) { - ptgt->m_timeout = ptgt->m_timebase; - } -#ifdef MPTSAS_TEST - /* - * Set back to a number higher than - * mptsas_scsi_watchdog_tick - * so timeouts will happen in mptsas_watchsubr - */ - if (mptsas_test_timeouts) { - ptgt->m_timebase = 60; + c = TAILQ_FIRST(&ptgt->m_active_cmdq); + if (c == NULL || + c->cmd_active_expiration < cmd->cmd_active_expiration) { + /* + * Common case is that this is the last pending expiration + * (or queue is empty). Insert at head of the queue. + */ + TAILQ_INSERT_HEAD(&ptgt->m_active_cmdq, cmd, cmd_active_link); + } else { + /* + * Queue is not empty and first element expires later than + * this command. Search for element expiring sooner. + */ + while ((c = TAILQ_NEXT(c, cmd_active_link)) != NULL) { + if (c->cmd_active_expiration < + cmd->cmd_active_expiration) { + TAILQ_INSERT_BEFORE(c, cmd, cmd_active_link); + break; + } + } + if (c == NULL) { + /* + * No element found expiring sooner, append to + * non-empty queue. + */ + TAILQ_INSERT_TAIL(&ptgt->m_active_cmdq, cmd, + cmd_active_link); + } } -#endif if ((mptsas_check_dma_handle(dma_hdl) != DDI_SUCCESS) || (mptsas_check_acc_handle(acc_hdl) != DDI_SUCCESS)) { @@ -8590,9 +8578,12 @@ mptsas_flush_target(mptsas_t *mpt, ushort_t target, int lun, uint8_t tasktype) int slot; uchar_t reason; uint_t stat; + hrtime_t timestamp; NDBG25(("mptsas_flush_target: target=%d lun=%d", target, lun)); + timestamp = gethrtime(); + /* * Make sure the I/O Controller has flushed all cmds * that are associated with this target for a target reset @@ -8607,6 +8598,15 @@ mptsas_flush_target(mptsas_t *mpt, ushort_t target, int lun, uint8_t tasktype) switch (tasktype) { case MPI2_SCSITASKMGMT_TASKTYPE_TARGET_RESET: if (Tgt(cmd) == target) { + if (cmd->cmd_active_expiration <= timestamp) { + /* + * When timeout requested, propagate + * proper reason and statistics to + * target drivers. + */ + reason = CMD_TIMEOUT; + stat |= STAT_TIMEOUT; + } NDBG25(("mptsas_flush_target discovered non-" "NULL cmd in slot %d, tasktype 0x%x", slot, tasktype)); @@ -8746,9 +8746,8 @@ mptsas_flush_hba(mptsas_t *mpt) */ mptsas_set_pkt_reason(mpt, cmd, CMD_RESET, STAT_BUS_RESET); - if ((cmd->cmd_flags & CFLAG_PASSTHRU) || - (cmd->cmd_flags & CFLAG_CONFIG) || - (cmd->cmd_flags & CFLAG_FW_DIAG)) { + if ((cmd->cmd_flags & + (CFLAG_PASSTHRU | CFLAG_CONFIG | CFLAG_FW_DIAG))) { cmd->cmd_flags |= CFLAG_FINISHED; cv_broadcast(&mpt->m_passthru_cv); cv_broadcast(&mpt->m_config_cv); @@ -9390,6 +9389,7 @@ mptsas_watchsubr(mptsas_t *mpt) int i; mptsas_cmd_t *cmd; mptsas_target_t *ptgt = NULL; + hrtime_t timestamp = gethrtime(); ASSERT(MUTEX_HELD(&mpt->m_mutex)); @@ -9407,10 +9407,8 @@ mptsas_watchsubr(mptsas_t *mpt) */ for (i = 0; i <= mpt->m_active->m_n_normal; i++) { if ((cmd = mpt->m_active->m_slot[i]) != NULL) { - if ((cmd->cmd_flags & CFLAG_CMDIOC) == 0) { - cmd->cmd_active_timeout -= - mptsas_scsi_watchdog_tick; - if (cmd->cmd_active_timeout <= 0) { + if (cmd->cmd_active_expiration <= timestamp) { + if ((cmd->cmd_flags & CFLAG_CMDIOC) == 0) { /* * There seems to be a command stuck * in the active slot. Drain throttle. @@ -9418,14 +9416,9 @@ mptsas_watchsubr(mptsas_t *mpt) mptsas_set_throttle(mpt, cmd->cmd_tgt_addr, DRAIN_THROTTLE); - } - } - if ((cmd->cmd_flags & CFLAG_PASSTHRU) || - (cmd->cmd_flags & CFLAG_CONFIG) || - (cmd->cmd_flags & CFLAG_FW_DIAG)) { - cmd->cmd_active_timeout -= - mptsas_scsi_watchdog_tick; - if (cmd->cmd_active_timeout <= 0) { + } else if (cmd->cmd_flags & + (CFLAG_PASSTHRU | CFLAG_CONFIG | + CFLAG_FW_DIAG)) { /* * passthrough command timeout */ @@ -9452,29 +9445,42 @@ mptsas_watchsubr(mptsas_t *mpt) mptsas_restart_hba(mpt); } - if ((ptgt->m_t_ncmds > 0) && - (ptgt->m_timebase)) { - - if (ptgt->m_timebase <= - mptsas_scsi_watchdog_tick) { - ptgt->m_timebase += - mptsas_scsi_watchdog_tick; - continue; - } + cmd = TAILQ_LAST(&ptgt->m_active_cmdq, mptsas_active_cmdq); + if (cmd == NULL) + continue; - ptgt->m_timeout -= mptsas_scsi_watchdog_tick; + if (cmd->cmd_active_expiration <= timestamp) { + /* + * Earliest command timeout expired. Drain throttle. + */ + mptsas_set_throttle(mpt, ptgt, DRAIN_THROTTLE); - if (ptgt->m_timeout < 0) { - mptsas_cmd_timeout(mpt, ptgt->m_devhdl); + /* + * Check for remaining commands. + */ + cmd = TAILQ_FIRST(&ptgt->m_active_cmdq); + if (cmd->cmd_active_expiration > timestamp) { + /* + * Wait for remaining commands to complete or + * time out. + */ + NDBG23(("command timed out, pending drain")); continue; } - if ((ptgt->m_timeout) <= - mptsas_scsi_watchdog_tick) { - NDBG23(("pending timeout")); - mptsas_set_throttle(mpt, ptgt, - DRAIN_THROTTLE); - } + /* + * All command timeouts expired. + */ + mptsas_log(mpt, CE_NOTE, "Timeout of %d seconds " + "expired with %d commands on target %d lun %d.", + cmd->cmd_pkt->pkt_time, ptgt->m_t_ncmds, + ptgt->m_devhdl, Lun(cmd)); + + mptsas_cmd_timeout(mpt, ptgt); + } else if (cmd->cmd_active_expiration <= + timestamp + (hrtime_t)mptsas_scsi_watchdog_tick * NANOSEC) { + NDBG23(("pending timeout")); + mptsas_set_throttle(mpt, ptgt, DRAIN_THROTTLE); } } } @@ -9483,16 +9489,28 @@ mptsas_watchsubr(mptsas_t *mpt) * timeout recovery */ static void -mptsas_cmd_timeout(mptsas_t *mpt, uint16_t devhdl) +mptsas_cmd_timeout(mptsas_t *mpt, mptsas_target_t *ptgt) { + uint16_t devhdl; + uint64_t sas_wwn; + uint8_t phy; + char wwn_str[MPTSAS_WWN_STRLEN]; + + devhdl = ptgt->m_devhdl; + sas_wwn = ptgt->m_addr.mta_wwn; + phy = ptgt->m_phynum; + if (sas_wwn == 0) { + (void) sprintf(wwn_str, "p%x", phy); + } else { + (void) sprintf(wwn_str, "w%016"PRIx64, sas_wwn); + } NDBG29(("mptsas_cmd_timeout: target=%d", devhdl)); mptsas_log(mpt, CE_WARN, "Disconnected command timeout for " - "Target %d", devhdl); + "target %d %s.", devhdl, wwn_str); /* - * If the current target is not the target passed in, - * try to reset that target. + * Abort all outstanding commands on the device. */ NDBG29(("mptsas_cmd_timeout: device reset")); if (mptsas_do_scsi_reset(mpt, devhdl) != TRUE) { @@ -15268,6 +15286,7 @@ mptsas_tgt_alloc(mptsas_t *mpt, uint16_t devhdl, uint64_t wwid, tmp_tgt->m_qfull_retry_interval = drv_usectohz(QFULL_RETRY_INTERVAL * 1000); tmp_tgt->m_t_throttle = MAX_THROTTLE; + TAILQ_INIT(&tmp_tgt->m_active_cmdq); refhash_insert(mpt->m_targets, tmp_tgt); diff --git a/usr/src/uts/common/sys/scsi/adapters/mpt_sas/mptsas_var.h b/usr/src/uts/common/sys/scsi/adapters/mpt_sas/mptsas_var.h index 96b9b11464..4c5bd659eb 100644 --- a/usr/src/uts/common/sys/scsi/adapters/mpt_sas/mptsas_var.h +++ b/usr/src/uts/common/sys/scsi/adapters/mpt_sas/mptsas_var.h @@ -21,7 +21,7 @@ /* * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved. - * Copyright 2012 Nexenta Systems, Inc. All rights reserved. + * Copyright 2014 Nexenta Systems, Inc. All rights reserved. * Copyright (c) 2013, Joyent, Inc. All rights reserved. */ @@ -56,6 +56,7 @@ #define _SYS_SCSI_ADAPTERS_MPTVAR_H #include <sys/byteorder.h> +#include <sys/queue.h> #include <sys/isa_defs.h> #include <sys/sunmdi.h> #include <sys/mdi_impldefs.h> @@ -200,6 +201,9 @@ typedef struct mptsas_target_addr { mptsas_phymask_t mta_phymask; } mptsas_target_addr_t; +TAILQ_HEAD(mptsas_active_cmdq, mptsas_cmd); +typedef struct mptsas_active_cmdq mptsas_active_cmdq_t; + typedef struct mptsas_target { mptsas_target_addr_t m_addr; refhash_link_t m_link; @@ -208,8 +212,7 @@ typedef struct mptsas_target { uint32_t m_deviceinfo; uint8_t m_phynum; uint32_t m_dups; - int32_t m_timeout; - int32_t m_timebase; + mptsas_active_cmdq_t m_active_cmdq; int32_t m_t_throttle; int32_t m_t_ncmds; int32_t m_reset_delay; @@ -265,8 +268,9 @@ typedef struct mptsas_cmd { int cmd_pkt_flags; - /* timer for command in active slot */ - int cmd_active_timeout; + /* pending expiration time for command in active slot */ + hrtime_t cmd_active_expiration; + TAILQ_ENTRY(mptsas_cmd) cmd_active_link; struct scsi_pkt *cmd_pkt; struct scsi_arq_status cmd_scb; @@ -1169,7 +1173,7 @@ _NOTE(DATA_READABLE_WITHOUT_LOCK(mptsas::m_instance)) */ #define DEFAULT_SCSI_OPTIONS SCSI_OPTIONS_DR #define DEFAULT_TAG_AGE_LIMIT 2 -#define DEFAULT_WD_TICK 10 +#define DEFAULT_WD_TICK 1 /* * invalid hostid. diff --git a/usr/src/uts/common/sys/time.h b/usr/src/uts/common/sys/time.h index 9fc4704860..eba6cb5277 100644 --- a/usr/src/uts/common/sys/time.h +++ b/usr/src/uts/common/sys/time.h @@ -234,7 +234,7 @@ struct itimerval32 { #define SEC 1 #define MILLISEC 1000 #define MICROSEC 1000000 -#define NANOSEC 1000000000 +#define NANOSEC 1000000000LL #define MSEC2NSEC(m) ((hrtime_t)(m) * (NANOSEC / MILLISEC)) #define NSEC2MSEC(n) ((n) / (NANOSEC / MILLISEC)) |