Skip to content

Commit 94a046f

Browse files
gilanljmo
authored andcommitted
OS-62 slow io error detector is needed.
1 parent 505fdfe commit 94a046f

10 files changed

Lines changed: 243 additions & 8 deletions

File tree

usr/src/cmd/fm/modules/common/Makefile

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@
2121
#
2222
# Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved.
2323
#
24+
# Copyright 2013 Nexenta Systems, Inc. All rights reserved.
25+
#
2426

2527
SUBDIRS = cpumem-retire \
2628
disk-lights \
@@ -34,6 +36,7 @@ SUBDIRS = cpumem-retire \
3436
ip-transport \
3537
sensor-transport \
3638
ses-log-transport \
39+
slow-io-de \
3740
sw-diag-response \
3841
sp-monitor \
3942
syslog-msgs \
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
#
2+
# This file and its contents are supplied under the terms of the
3+
# Common Development and Distribution License ("CDDL"), version 1.0.
4+
# You may only use this file in accordance with the terms of version
5+
# 1.0 of the CDDL.
6+
#
7+
# A full copy of the text of the CDDL should have accompanied this
8+
# source. A copy of the CDDL is also available via the Internet at
9+
# http://www.illumos.org/license/CDDL.
10+
11+
#
12+
# Copyright 2013 Nexenta Systems, Inc. All rights reserved.
13+
#
14+
15+
MODULE = slow-io-de
16+
CLASS = common
17+
SRCS = slow-io-de.c
18+
19+
include ../../Makefile.plugin
20+
21+
LINTFLAGS += -L$(ROOT)/usr/lib/fm
22+
#LDLIBS += -ltopo
23+
LDFLAGS += -L$(ROOT)/usr/lib/fm -R/usr/lib/fm
Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
/*
2+
* This file and its contents are supplied under the terms of the
3+
* Common Development and Distribution License ("CDDL"), version 1.0.
4+
* You may only use this file in accordance with the terms of version
5+
* 1.0 of the CDDL.
6+
*
7+
* A full copy of the text of the CDDL should have accompanied this
8+
* source. A copy of the CDDL is also available via the Internet at
9+
* http://www.illumos.org/license/CDDL.
10+
*/
11+
12+
/*
13+
* Copyright 2013 Nexenta Systems, Inc. All rights reserved.
14+
*/
15+
16+
#include <fm/fmd_api.h>
17+
18+
typedef struct slow_io_stat {
19+
fmd_stat_t bad_fmri;
20+
fmd_stat_t bad_scheme;
21+
} slow_io_stat_t;
22+
23+
slow_io_stat_t slow_io_stats = {
24+
{ "bad_FMRI", FMD_TYPE_UINT64,
25+
"event FMRI is missing or invalid" },
26+
{ "bad_scheme", FMD_TYPE_UINT64,
27+
"event does not contain a valid detector"},
28+
};
29+
30+
static const fmd_prop_t fmd_props [] = {
31+
{ "io_N", FMD_TYPE_INT32, "10" },
32+
{ "io_T", FMD_TYPE_TIME, "10min"},
33+
{ NULL, 0, NULL }
34+
};
35+
36+
void
37+
slow_io_close(fmd_hdl_t *hdl, fmd_case_t *c)
38+
{
39+
char *devid = fmd_case_getspecific(hdl, c);
40+
fmd_hdl_debug(hdl, "Destroying serd: %s", devid);
41+
fmd_serd_destroy(hdl, devid);
42+
}
43+
44+
void
45+
slow_io_recv(fmd_hdl_t *hdl, fmd_event_t *event, nvlist_t *nvl,
46+
const char *class)
47+
{
48+
nvlist_t *detector = NULL;
49+
char *devid = NULL;
50+
51+
if (nvlist_lookup_nvlist(nvl, "detector", &detector) != 0) {
52+
slow_io_stats.bad_scheme.fmds_value.ui64++;
53+
return;
54+
}
55+
56+
if (nvlist_lookup_string(detector, "devid", &devid) != 0) {
57+
slow_io_stats.bad_fmri.fmds_value.ui64++;
58+
return;
59+
}
60+
61+
if (fmd_serd_exists(hdl, devid) == 0) {
62+
fmd_serd_create(hdl, devid, fmd_prop_get_int32(hdl, "io_N"),
63+
fmd_prop_get_int64(hdl, "io_T"));
64+
(void) fmd_serd_record(hdl, devid, event);
65+
return;
66+
}
67+
68+
if (fmd_serd_record(hdl, devid, event) == FMD_B_TRUE) {
69+
fmd_case_t *c = fmd_case_open(hdl, NULL);
70+
nvlist_t *fault = fmd_nvl_create_fault(hdl,
71+
"fault.io.disk.predictive-failure", 100,
72+
detector, NULL, detector);
73+
fmd_case_add_serd(hdl, c, devid);
74+
fmd_case_add_suspect(hdl, c, fault);
75+
fmd_case_setspecific(hdl, c, devid);
76+
fmd_case_solve(hdl, c);
77+
}
78+
}
79+
80+
static const fmd_hdl_ops_t fmd_ops = {
81+
slow_io_recv,
82+
NULL,
83+
slow_io_close,
84+
NULL,
85+
NULL,
86+
};
87+
88+
static const fmd_hdl_info_t fmd_info = {
89+
"slow-io-de", "0.1", &fmd_ops, fmd_props
90+
};
91+
92+
void
93+
_fmd_init(fmd_hdl_t *hdl)
94+
{
95+
if (fmd_hdl_register(hdl, FMD_API_VERSION, &fmd_info) != 0) {
96+
fmd_hdl_debug(hdl, "Internal error\n");
97+
return;
98+
}
99+
100+
fmd_stat_create(hdl, FMD_STAT_NOALLOC, sizeof (slow_io_stats) /
101+
sizeof (fmd_stat_t), (fmd_stat_t *)&slow_io_stats);
102+
}
103+
104+
void
105+
_fmd_fini(fmd_hdl_t *hdl)
106+
{
107+
108+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
#
2+
# This file and its contents are supplied under the terms of the
3+
# Common Development and Distribution License ("CDDL"), version 1.0.
4+
# You may only use this file in accordance with the terms of version
5+
# 1.0 of the CDDL.
6+
#
7+
# A full copy of the text of the CDDL should have accompanied this
8+
# source. A copy of the CDDL is also available via the Internet at
9+
# http://www.illumos.org/license/CDDL.
10+
11+
#
12+
# Copyright 2013 Nexenta Systems, Inc. All rights reserved.
13+
#
14+
15+
#
16+
# fmd configuration file for the slow-io diagnosis
17+
#
18+
19+
subscribe ereport.io.disk.slow-io

usr/src/pkg/manifests/service-fault-management.mf

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
# See the License for the specific language governing permissions
1111
# and limitations under the License.
1212
#
13+
#
1314
# When distributing Covered Code, include this CDDL HEADER in each
1415
# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
1516
# If applicable, add the following below this CDDL HEADER, with the
@@ -22,7 +23,7 @@
2223
#
2324
# Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
2425
#
25-
26+
# Copyright 2013 Nexenta Systems, Inc. All rights reserved.
2627
#
2728
# The default for payload-bearing actions in this package is to appear in the
2829
# global zone only. See the include file for greater detail, as well as
@@ -450,6 +451,8 @@ file path=usr/lib/fm/fmd/plugins/sensor-transport.conf
450451
file path=usr/lib/fm/fmd/plugins/sensor-transport.so mode=0555
451452
file path=usr/lib/fm/fmd/plugins/ses-log-transport.conf
452453
file path=usr/lib/fm/fmd/plugins/ses-log-transport.so mode=0555
454+
file path=usr/lib/fm/fmd/plugins/slow-io-de.conf
455+
file path=usr/lib/fm/fmd/plugins/slow-io-de.so mode=0555
453456
file path=usr/lib/fm/fmd/plugins/software-diagnosis.conf \
454457
variant.opensolaris.zone=__NODEFAULT
455458
file path=usr/lib/fm/fmd/plugins/software-diagnosis.so mode=0555 \
@@ -470,6 +473,8 @@ file path=usr/lib/fm/fmd/plugins/zfs-monitor.conf
470473
file path=usr/lib/fm/fmd/plugins/zfs-monitor.so mode=0555
471474
file path=usr/lib/fm/fmd/plugins/zfs-retire.conf
472475
file path=usr/lib/fm/fmd/plugins/zfs-retire.so mode=0555
476+
477+
473478
#
474479
# fmri scheme support: all are common to both global and non-global zones
475480
#

usr/src/uts/common/io/scsi/adapters/mpt_sas/mptsas.c

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3464,6 +3464,8 @@ mptsas_scsi_init_pkt(struct scsi_address *ap, struct scsi_pkt *pkt,
34643464

34653465
} else {
34663466
cmd = PKT2CMD(pkt);
3467+
pkt->pkt_start = 0;
3468+
pkt->pkt_stop = 0;
34673469
new_cmd = NULL;
34683470
}
34693471

@@ -4666,6 +4668,9 @@ mptsas_handle_scsi_io_success(mptsas_t *mpt,
46664668
}
46674669

46684670
pkt = CMD2PKT(cmd);
4671+
ASSERT(pkt->pkt_start != 0);
4672+
ASSERT(pkt->pkt_stop == 0);
4673+
pkt->pkt_stop = gethrtime();
46694674
pkt->pkt_state |= (STATE_GOT_BUS | STATE_GOT_TARGET | STATE_SENT_CMD |
46704675
STATE_GOT_STATUS);
46714676
if (cmd->cmd_flags & CFLAG_DMAVALID) {
@@ -4976,6 +4981,9 @@ mptsas_check_scsi_io_error(mptsas_t *mpt, pMpi2SCSIIOReply_t reply,
49764981
scsi_status, ioc_status, scsi_state));
49774982

49784983
pkt = CMD2PKT(cmd);
4984+
ASSERT(pkt->pkt_start != 0);
4985+
ASSERT(pkt->pkt_stop == 0);
4986+
pkt->pkt_stop = gethrtime();
49794987
*(pkt->pkt_scbp) = scsi_status;
49804988

49814989
if (loginfo == 0x31170000) {
@@ -7936,7 +7944,7 @@ mptsas_start_cmd(mptsas_t *mpt, mptsas_cmd_t *cmd)
79367944
(void *)(uintptr_t)mpt->m_req_frame_dma_addr, (void *)cmd));
79377945

79387946
(void) ddi_dma_sync(dma_hdl, 0, 0, DDI_DMA_SYNC_FORDEV);
7939-
7947+
pkt->pkt_start = gethrtime();
79407948
/*
79417949
* Build request descriptor and write it to the request desc post reg.
79427950
*/
@@ -7947,8 +7955,10 @@ mptsas_start_cmd(mptsas_t *mpt, mptsas_cmd_t *cmd)
79477955
/*
79487956
* Start timeout.
79497957
*/
7950-
cmd->cmd_active_expiration =
7951-
gethrtime() + (hrtime_t)pkt->pkt_time * NANOSEC;
7958+
7959+
cmd->cmd_active_expiration = pkt->pkt_start +
7960+
(hrtime_t)pkt->pkt_time * (hrtime_t)NANOSEC;
7961+
79527962
#ifdef MPTSAS_TEST
79537963
/*
79547964
* Force timeouts to happen immediately.

usr/src/uts/common/io/scsi/adapters/scsi_vhci/scsi_vhci.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3189,6 +3189,8 @@ vhci_intr(struct scsi_pkt *pkt)
31893189
tpkt->pkt_state = pkt->pkt_state;
31903190
tpkt->pkt_statistics = pkt->pkt_statistics;
31913191
tpkt->pkt_reason = pkt->pkt_reason;
3192+
tpkt->pkt_start = pkt->pkt_start;
3193+
tpkt->pkt_stop = pkt->pkt_stop;
31923194

31933195
/* Return path_instance information back to the target driver. */
31943196
if (scsi_pkt_allocated_correctly(tpkt)) {

usr/src/uts/common/io/scsi/targets/sd.c

Lines changed: 63 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,14 +21,15 @@
2121

2222
/*
2323
* Copyright (c) 1990, 2010, Oracle and/or its affiliates. All rights reserved.
24-
*/
25-
/*
24+
*
25+
*
2626
* Copyright (c) 2011 Bayard G. Bell. All rights reserved.
2727
* Copyright (c) 2012 by Delphix. All rights reserved.
2828
* Copyright 2013 Nexenta Systems, Inc. All rights reserved.
29-
*/
30-
/*
29+
*
30+
*
3131
* Copyright 2011 cyril.galibern@opensvc.com
32+
*
3233
*/
3334

3435
/*
@@ -241,6 +242,14 @@ int sd_qfull_throttle_enable = TRUE;
241242

242243
int sd_retry_on_reservation_conflict = 1;
243244
int sd_reinstate_resv_delay = SD_REINSTATE_RESV_DELAY;
245+
246+
/*
247+
* Default safe I/O delay threshold of 2s for all devices.
248+
* Can be overriden for vendor/device id in sd.conf
249+
*/
250+
251+
hrtime_t sd_g_slow_io_threshold = 2 * NANOSEC;
252+
244253
_NOTE(SCHEME_PROTECTS_DATA("safe sharing", sd_reinstate_resv_delay))
245254

246255
static int sd_dtype_optical_bind = -1;
@@ -4231,6 +4240,23 @@ sd_set_properties(struct sd_lun *un, char *name, char *value)
42314240
"physical block size set to %d\n", un->un_phy_blocksize);
42324241
}
42334242

4243+
if (strcasecmp(name, "slow-io-threshold") == 0) {
4244+
if (ddi_strtol(value, &endptr, 0, &val) == 0) {
4245+
un->un_slow_io_threshold = (hrtime_t)val * NANOSEC;
4246+
} else {
4247+
un->un_slow_io_threshold =
4248+
(hrtime_t)sd_g_slow_io_threshold;
4249+
goto value_invalid;
4250+
}
4251+
SD_INFO(SD_LOG_ATTACH_DETACH, un, "sd_set_properties: "
4252+
"slow IO threshold set to %llu\n",
4253+
un->un_slow_io_threshold);
4254+
#ifdef SDDEBUG
4255+
cmn_err(CE_NOTE, "slow IO set to %llu",
4256+
un->un_slow_io_threshold);
4257+
#endif
4258+
}
4259+
42344260
if (strcasecmp(name, "retries-victim") == 0) {
42354261
if (ddi_strtol(value, &endptr, 0, &val) == 0) {
42364262
un->un_victim_retry_count = val;
@@ -7534,6 +7560,8 @@ sd_unit_attach(dev_info_t *devi)
75347560
*/
75357561
un->un_reserve_release_time = 5;
75367562

7563+
un->un_slow_io_threshold = sd_g_slow_io_threshold;
7564+
75377565
/*
75387566
* Set up the default maximum transfer size. Note that this may
75397567
* get updated later in the attach, when setting up default wide
@@ -16825,6 +16853,29 @@ sdrunout(caddr_t arg)
1682516853
return (1);
1682616854
}
1682716855

16856+
static void
16857+
sd_slow_io_ereport(struct scsi_pkt *pktp)
16858+
{
16859+
struct buf *bp;
16860+
struct sd_lun *un;
16861+
char *devid;
16862+
16863+
ASSERT(pktp != NULL);
16864+
bp = (struct buf *)pktp->pkt_private;
16865+
ASSERT(bp != NULL);
16866+
un = SD_GET_UN(bp);
16867+
ASSERT(un != NULL);
16868+
16869+
devid = DEVI(un->un_sd->sd_dev)->devi_devid_str;
16870+
scsi_fm_ereport_post(un->un_sd, 0, NULL, "cmd.disk.slow-io",
16871+
fm_ena_generate(0, FM_ENA_FMT1), devid, NULL, DDI_NOSLEEP, NULL,
16872+
FM_VERSION, DATA_TYPE_UINT8, FM_EREPORT_VERS0,
16873+
"start", DATA_TYPE_UINT64, pktp->pkt_start,
16874+
"stop", DATA_TYPE_UINT64, pktp->pkt_stop,
16875+
"delta", DATA_TYPE_UINT64, pktp->pkt_stop - pktp->pkt_start,
16876+
"threshold", DATA_TYPE_UINT64, un->un_slow_io_threshold,
16877+
NULL);
16878+
}
1682816879

1682916880
/*
1683016881
* Function: sdintr
@@ -16879,6 +16930,14 @@ sdintr(struct scsi_pkt *pktp)
1687916930
un->un_in_callback++;
1688016931

1688116932
SD_UPDATE_KSTATS(un, kstat_runq_exit, bp);
16933+
if ((pktp->pkt_stop - pktp->pkt_start) > un->un_slow_io_threshold) {
16934+
sd_slow_io_ereport(pktp);
16935+
#ifdef SDDEBUG
16936+
cmn_err(CE_WARN, "Slow IO detected SD: 0x%p delta in nsec: %llu",
16937+
un, pktp->pkt_stop - pktp->pkt_start);
16938+
#endif
16939+
}
16940+
1688216941

1688316942
#ifdef SDDEBUG
1688416943
if (bp == un->un_retry_bp) {

usr/src/uts/common/sys/scsi/scsi_pkt.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@
2121
/*
2222
* Copyright 2009 Sun Microsystems, Inc. All rights reserved.
2323
* Use is subject to license terms.
24+
*
25+
* Copyright 2013 Nexenta Systems, Inc. All rights reserved.
2426
*/
2527

2628
#ifndef _SYS_SCSI_SCSI_PKT_H
@@ -106,6 +108,8 @@ struct scsi_pkt {
106108

107109
/* stage-temporary: iff scsi_pkt_allocated_correctly() */
108110
void *pkt_stmp; /* temporary for current pkt stage */
111+
hrtime_t pkt_start;
112+
hrtime_t pkt_stop;
109113

110114
#ifdef SCSI_SIZE_CLEAN_VERIFY
111115
/*

0 commit comments

Comments
 (0)