From owner-svn-src-head@freebsd.org Thu Nov 15 16:02:48 2018 Return-Path: Delivered-To: svn-src-head@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 5EE111101CD5; Thu, 15 Nov 2018 16:02:48 +0000 (UTC) (envelope-from imp@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client CN "mxrelay.nyi.freebsd.org", Issuer "Let's Encrypt Authority X3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id C5595726E5; Thu, 15 Nov 2018 16:02:47 +0000 (UTC) (envelope-from imp@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 3688E10A87; Thu, 15 Nov 2018 16:02:46 +0000 (UTC) (envelope-from imp@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id wAFG2kMk041031; Thu, 15 Nov 2018 16:02:46 GMT (envelope-from imp@FreeBSD.org) Received: (from imp@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id wAFG2jjU041028; Thu, 15 Nov 2018 16:02:45 GMT (envelope-from imp@FreeBSD.org) Message-Id: <201811151602.wAFG2jjU041028@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: imp set sender to imp@FreeBSD.org using -f From: Warner Losh Date: Thu, 15 Nov 2018 16:02:45 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r340453 - head/sys/cam X-SVN-Group: head X-SVN-Commit-Author: imp X-SVN-Commit-Paths: head/sys/cam X-SVN-Commit-Revision: 340453 X-SVN-Commit-Repository: base MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-Rspamd-Queue-Id: C5595726E5 X-Spamd-Result: default: False [-106.88 / 200.00]; ARC_NA(0.00)[]; NEURAL_HAM_MEDIUM(-1.00)[-1.000,0]; ALLOW_DOMAIN_WHITELIST(-100.00)[FreeBSD.org]; FROM_HAS_DN(0.00)[]; RCPT_COUNT_THREE(0.00)[3]; TO_MATCH_ENVRCPT_ALL(0.00)[]; NEURAL_HAM_LONG(-1.00)[-1.000,0]; MIME_GOOD(-0.10)[text/plain]; TO_DN_NONE(0.00)[]; HAS_XAW(0.00)[]; R_SPF_SOFTFAIL(0.00)[~all]; DMARC_NA(0.00)[FreeBSD.org]; RCVD_COUNT_THREE(0.00)[4]; MX_GOOD(-0.01)[cached: mx1.FreeBSD.org]; NEURAL_HAM_SHORT(-1.00)[-1.000,0]; FROM_EQ_ENVFROM(0.00)[]; R_DKIM_NA(0.00)[]; RCVD_TLS_LAST(0.00)[]; ASN(0.00)[asn:11403, ipnet:2610:1c1:1::/48, country:US]; IP_SCORE(-3.77)[ip: (-9.91), ipnet: 2610:1c1:1::/48(-4.93), asn: 11403(-3.91), country: US(-0.10)] X-Rspamd-Server: mx1.freebsd.org X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 15 Nov 2018 16:02:48 -0000 Author: imp Date: Thu Nov 15 16:02:45 2018 New Revision: 340453 URL: https://svnweb.freebsd.org/changeset/base/340453 Log: Add cam_iosched_set_latfcn to set a latency callback for high latency. It's often useful to have a callback when an I/O takes more than a threshold amount of time. This adds the infrastructure for periph devices to register one. One use-case is as a debugging aide when you need a semi-realtime indication of an I/O outlier so you can trigger bus capture gear for vendor analysis. Sponsored by: Netflix, Inc Modified: head/sys/cam/cam_iosched.c head/sys/cam/cam_iosched.h Modified: head/sys/cam/cam_iosched.c ============================================================================== --- head/sys/cam/cam_iosched.c Thu Nov 15 16:02:34 2018 (r340452) +++ head/sys/cam/cam_iosched.c Thu Nov 15 16:02:45 2018 (r340453) @@ -294,6 +294,9 @@ struct cam_iosched_softc { uint32_t this_frac; /* Fraction of a second (1024ths) for this tick */ sbintime_t last_time; /* Last time we ticked */ struct control_loop cl; + sbintime_t max_lat; /* when != 0, if iop latency > max_lat, call max_lat_fcn */ + cam_iosched_latfcn_t latfcn; + void *latarg; #endif }; @@ -1171,9 +1174,24 @@ void cam_iosched_sysctl_init(struct cam_iosched_softc OID_AUTO, "load", CTLFLAG_RD, &isc->load, 0, "scaled load average / 100"); + + SYSCTL_ADD_U64(ctx, n, + OID_AUTO, "latency_trigger", CTLFLAG_RW, + &isc->max_lat, 0, + "Latency treshold to trigger callbacks"); #endif } +void +cam_iosched_set_latfcn(struct cam_iosched_softc *isc, + cam_iosched_latfcn_t fnp, void *argp) +{ +#ifdef CAM_IOSCHED_DYNAMIC + isc->latfcn = fnp; + isc->latarg = argp; +#endif +} + /* * Flush outstanding I/O. Consumers of this library don't know all the * queues we may keep, so this allows all I/O to be flushed in one @@ -1510,10 +1528,21 @@ cam_iosched_bio_complete(struct cam_iosched_softc *isc printf("Completing command with bio_cmd == %#x\n", bp->bio_cmd); } - if (!(bp->bio_flags & BIO_ERROR) && done_ccb != NULL) - cam_iosched_io_metric_update(isc, - cam_iosched_sbintime_t(done_ccb->ccb_h.qos.periph_data), + if (!(bp->bio_flags & BIO_ERROR) && done_ccb != NULL) { + sbintime_t sim_latency; + + sim_latency = cam_iosched_sbintime_t(done_ccb->ccb_h.qos.periph_data); + + cam_iosched_io_metric_update(isc, sim_latency, bp->bio_cmd, bp->bio_bcount); + /* + * Debugging code: allow callbacks to the periph driver when latency max + * is exceeded. This can be useful for triggering external debugging actions. + */ + if (isc->latfcn && isc->max_lat != 0 && sim_latency > isc->max_lat) + isc->latfcn(isc->latarg, sim_latency, bp); + } + #endif return retval; } Modified: head/sys/cam/cam_iosched.h ============================================================================== --- head/sys/cam/cam_iosched.h Thu Nov 15 16:02:34 2018 (r340452) +++ head/sys/cam/cam_iosched.h Thu Nov 15 16:02:45 2018 (r340453) @@ -80,6 +80,8 @@ cam_iosched_sbintime_t(uintptr_t delta) return (sbintime_t)((uint64_t)delta << CAM_IOSCHED_TIME_SHIFT); } +typedef void (*cam_iosched_latfcn_t)(void *, sbintime_t, struct bio *); + int cam_iosched_init(struct cam_iosched_softc **, struct cam_periph *periph); void cam_iosched_fini(struct cam_iosched_softc *); void cam_iosched_sysctl_init(struct cam_iosched_softc *, struct sysctl_ctx_list *, struct sysctl_oid *); @@ -98,6 +100,7 @@ void cam_iosched_set_work_flags(struct cam_iosched_sof void cam_iosched_clr_work_flags(struct cam_iosched_softc *isc, uint32_t flags); void cam_iosched_trim_done(struct cam_iosched_softc *isc); int cam_iosched_bio_complete(struct cam_iosched_softc *isc, struct bio *bp, union ccb *done_ccb); +void cam_iosched_set_latfcn(struct cam_iosched_softc *isc, cam_iosched_latfcn_t, void *); #endif #endif