From owner-svn-src-all@freebsd.org Mon Feb 12 17:41:12 2018 Return-Path: Delivered-To: svn-src-all@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 0A63EF0BD27; Mon, 12 Feb 2018 17:41:12 +0000 (UTC) (envelope-from ian@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 B4A94810E2; Mon, 12 Feb 2018 17:41:11 +0000 (UTC) (envelope-from ian@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 AF93F150BD; Mon, 12 Feb 2018 17:41:11 +0000 (UTC) (envelope-from ian@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id w1CHfBlP069972; Mon, 12 Feb 2018 17:41:11 GMT (envelope-from ian@FreeBSD.org) Received: (from ian@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id w1CHfBWa069971; Mon, 12 Feb 2018 17:41:11 GMT (envelope-from ian@FreeBSD.org) Message-Id: <201802121741.w1CHfBWa069971@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: ian set sender to ian@FreeBSD.org using -f From: Ian Lepore Date: Mon, 12 Feb 2018 17:41:11 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r329173 - head/sys/kern X-SVN-Group: head X-SVN-Commit-Author: ian X-SVN-Commit-Paths: head/sys/kern X-SVN-Commit-Revision: 329173 X-SVN-Commit-Repository: base MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.25 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 12 Feb 2018 17:41:12 -0000 Author: ian Date: Mon Feb 12 17:41:11 2018 New Revision: 329173 URL: https://svnweb.freebsd.org/changeset/base/329173 Log: Add a new sysctl, debug.clock_do_io, to allow manully triggering a one-shot read or write of all registered realtime clocks. In the read case, the values read are simply discarded. For writes, there's no alternative but to actually write the current system time to the device. Modified: head/sys/kern/subr_rtc.c Modified: head/sys/kern/subr_rtc.c ============================================================================== --- head/sys/kern/subr_rtc.c Mon Feb 12 17:33:14 2018 (r329172) +++ head/sys/kern/subr_rtc.c Mon Feb 12 17:41:11 2018 (r329173) @@ -80,6 +80,11 @@ static int show_io; SYSCTL_INT(_debug, OID_AUTO, clock_show_io, CTLFLAG_RWTUN, &show_io, 0, "Enable debug printing of RTC clock I/O; 1=reads, 2=writes, 3=both."); +static int sysctl_clock_do_io(SYSCTL_HANDLER_ARGS); +SYSCTL_PROC(_debug, OID_AUTO, clock_do_io, CTLTYPE_INT | CTLFLAG_RW, + 0, 0, sysctl_clock_do_io, "I", + "Trigger one-time IO on RTC clocks; 1=read (and discard), 2=write"); + /* XXX: should be kern. now, it's no longer machdep. */ static int disable_rtc_set; SYSCTL_INT(_machdep, OID_AUTO, disable_rtc_set, CTLFLAG_RW, &disable_rtc_set, @@ -280,6 +285,36 @@ clock_schedule(device_t clockdev, u_int offsetns) sx_xunlock(&rtc_list_lock); } +static int +read_clocks(struct timespec *ts, bool debug_read) +{ + struct rtc_instance *rtc; + int error; + + error = ENXIO; + sx_xlock(&rtc_list_lock); + LIST_FOREACH(rtc, &rtc_list, rtc_entries) { + if ((error = CLOCK_GETTIME(rtc->clockdev, ts)) != 0) + continue; + if (ts->tv_sec < 0 || ts->tv_nsec < 0) { + error = EINVAL; + continue; + } + if (!(rtc->flags & CLOCKF_GETTIME_NO_ADJ)) { + timespecadd(ts, &rtc->resadj); + ts->tv_sec += utc_offset(); + } + if (!debug_read) { + if (bootverbose) + device_printf(rtc->clockdev, + "providing initial system time\n"); + break; + } + } + sx_xunlock(&rtc_list_lock); + return (error); +} + /* * Initialize the system time. Must be called from a context which does not * restrict any locking or sleeping that clock drivers may need to do. @@ -296,28 +331,9 @@ void inittodr(time_t base) { struct timespec ts; - struct rtc_instance *rtc; int error; - error = ENXIO; - sx_xlock(&rtc_list_lock); - LIST_FOREACH(rtc, &rtc_list, rtc_entries) { - if ((error = CLOCK_GETTIME(rtc->clockdev, &ts)) != 0) - continue; - if (ts.tv_sec < 0 || ts.tv_nsec < 0) { - error = EINVAL; - continue; - } - if (!(rtc->flags & CLOCKF_GETTIME_NO_ADJ)) { - timespecadd(&ts, &rtc->resadj); - ts.tv_sec += utc_offset(); - } - if (bootverbose) - device_printf(rtc->clockdev, - "providing initial system time\n"); - break; - } - sx_xunlock(&rtc_list_lock); + error = read_clocks(&ts, false); /* * Do not report errors from each clock; it is expected that some clocks @@ -379,4 +395,30 @@ resettodr(void) &rtc->stask, -sbt, 0, C_PREL(31)); } sx_xunlock(&rtc_list_lock); +} + +static int +sysctl_clock_do_io(SYSCTL_HANDLER_ARGS) +{ + struct timespec ts_discard; + int error, value; + + value = 0; + error = sysctl_handle_int(oidp, &value, 0, req); + if (error != 0 || req->newptr == NULL) + return (error); + + switch (value) { + case CLOCK_DBG_READ: + if (read_clocks(&ts_discard, true) == ENXIO) + printf("No registered RTC clocks\n"); + break; + case CLOCK_DBG_WRITE: + resettodr(); + break; + default: + return (EINVAL); + } + + return (0); }