From owner-svn-src-all@FreeBSD.ORG Mon Nov 21 01:26:11 2011 Return-Path: Delivered-To: svn-src-all@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 50BAC106564A; Mon, 21 Nov 2011 01:26:11 +0000 (UTC) (envelope-from lstewart@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 3D1408FC0A; Mon, 21 Nov 2011 01:26:11 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.4/8.14.4) with ESMTP id pAL1QBO5017947; Mon, 21 Nov 2011 01:26:11 GMT (envelope-from lstewart@svn.freebsd.org) Received: (from lstewart@localhost) by svn.freebsd.org (8.14.4/8.14.4/Submit) id pAL1QAkg017923; Mon, 21 Nov 2011 01:26:10 GMT (envelope-from lstewart@svn.freebsd.org) Message-Id: <201111210126.pAL1QAkg017923@svn.freebsd.org> From: Lawrence Stewart Date: Mon, 21 Nov 2011 01:26:10 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r227776 - in head: lib/libc/sys sys/amd64/linux32 sys/compat/freebsd32 sys/conf sys/i386/linux sys/kern sys/sys X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.5 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, 21 Nov 2011 01:26:11 -0000 Author: lstewart Date: Mon Nov 21 01:26:10 2011 New Revision: 227776 URL: http://svn.freebsd.org/changeset/base/227776 Log: - Add the ffclock_getcounter(), ffclock_getestimate() and ffclock_setestimate() system calls to provide feed-forward clock management capabilities to userspace processes. ffclock_getcounter() returns the current value of the kernel's feed-forward clock counter. ffclock_getestimate() returns the current feed-forward clock parameter estimates and ffclock_setestimate() updates the feed-forward clock parameter estimates. - Document the syscalls in the ffclock.2 man page. - Regenerate the script-derived syscall related files. Committed on behalf of Julien Ridoux and Darryl Veitch from the University of Melbourne, Australia, as part of the FreeBSD Foundation funded "Feed-Forward Clock Synchronization Algorithms" project. For more information, see http://www.synclab.org/radclock/ Submitted by: Julien Ridoux (jridoux at unimelb edu au) Added: head/lib/libc/sys/ffclock.2 (contents, props changed) Modified: head/lib/libc/sys/Makefile.inc head/lib/libc/sys/Symbol.map head/sys/amd64/linux32/linux32_proto.h head/sys/compat/freebsd32/freebsd32_proto.h head/sys/compat/freebsd32/freebsd32_syscall.h head/sys/compat/freebsd32/freebsd32_syscalls.c head/sys/compat/freebsd32/freebsd32_sysent.c head/sys/compat/freebsd32/freebsd32_systrace_args.c head/sys/compat/freebsd32/syscalls.master head/sys/conf/files head/sys/i386/linux/linux_proto.h head/sys/kern/init_sysent.c head/sys/kern/kern_ffclock.c head/sys/kern/makesyscalls.sh head/sys/kern/syscalls.c head/sys/kern/syscalls.master head/sys/kern/systrace_args.c head/sys/sys/syscall.h head/sys/sys/syscall.mk head/sys/sys/sysproto.h head/sys/sys/timeffc.h Modified: head/lib/libc/sys/Makefile.inc ============================================================================== --- head/lib/libc/sys/Makefile.inc Mon Nov 21 00:49:46 2011 (r227775) +++ head/lib/libc/sys/Makefile.inc Mon Nov 21 01:26:10 2011 (r227776) @@ -80,7 +80,7 @@ MAN+= abort2.2 accept.2 access.2 acct.2 bind.2 brk.2 cap_enter.2 cap_new.2 chdir.2 chflags.2 \ chmod.2 chown.2 chroot.2 clock_gettime.2 close.2 closefrom.2 \ connect.2 cpuset.2 cpuset_getaffinity.2 dup.2 execve.2 _exit.2 \ - extattr_get_file.2 fcntl.2 fhopen.2 flock.2 fork.2 fsync.2 \ + extattr_get_file.2 fcntl.2 ffclock.2 fhopen.2 flock.2 fork.2 fsync.2 \ getdirentries.2 getdtablesize.2 \ getfh.2 getfsstat.2 getgid.2 getgroups.2 getitimer.2 getlogin.2 \ getloginclass.2 getpeername.2 getpgrp.2 getpid.2 getpriority.2 \ @@ -142,6 +142,8 @@ MLINKS+=extattr_get_file.2 extattr.2 \ extattr_get_file.2 extattr_set_fd.2 \ extattr_get_file.2 extattr_set_file.2 \ extattr_get_file.2 extattr_set_link.2 +MLINKS+=ffclock.2 ffclock_getcounter.2 ffclock.2 ffclock_getestimate.2 \ + ffclock.2 ffclock_setestimate.2 MLINKS+=fhopen.2 fhstat.2 fhopen.2 fhstatfs.2 MLINKS+=getdirentries.2 getdents.2 MLINKS+=getfh.2 lgetfh.2 Modified: head/lib/libc/sys/Symbol.map ============================================================================== --- head/lib/libc/sys/Symbol.map Mon Nov 21 00:49:46 2011 (r227775) +++ head/lib/libc/sys/Symbol.map Mon Nov 21 01:26:10 2011 (r227776) @@ -365,6 +365,9 @@ FBSD_1.2 { cap_getmode; cap_new; cap_getrights; + ffclock_getcounter; + ffclock_getestimate; + ffclock_setestimate; getloginclass; pdfork; pdgetpid; Added: head/lib/libc/sys/ffclock.2 ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ head/lib/libc/sys/ffclock.2 Mon Nov 21 01:26:10 2011 (r227776) @@ -0,0 +1,177 @@ +.\" Copyright (c) 2011 The University of Melbourne +.\" All rights reserved. +.\" +.\" This documentation was written by Julien Ridoux at the University of +.\" Melbourne under sponsorship from the FreeBSD Foundation. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" $FreeBSD$ +.\" +.Dd November 21, 2011 +.Dt FFCLOCK 2 +.Os +.Sh NAME +.Nm ffclock_getcounter , +.Nm ffclock_getestimate , +.Nm ffclock_setestimate +.Nd Retrieve feed-forward counter, get and set feed-forward clock estimates. +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In sys/timeffc.h +.Ft int +.Fn ffclock_getcounter "ffcounter *ffcount" +.Ft int +.Fn ffclock_getestimate "struct ffclock_estimate *cest" +.Ft int +.Fn ffclock_setestimate "struct ffclock_estimate *cest" +.Sh DESCRIPTION +The ffclock is an alternative method to synchronise the system clock. +The ffclock implements a feed-forward paradigm and decouples the timestamping +and timekeeping kernel functions. +This ensures that past clock errors do not affect current timekeeping, an +approach radically different from the feedback alternative implemented by the +ntpd daemon when adjusting the system clock. +The feed-forward approach has demonstrated better performance and higher +robustness than a feedback approach when synchronising over the network. +.Pp +In the feed-forward context, a +.Em timestamp +is a cumulative value of the ticks of the timecounter, which can be converted +into seconds by using the feed-forward +.Em clock estimates. +.Pp +The +.Fn ffclock_getcounter +system call allows the calling process to retrieve the current value of the +feed-forward counter maintained by the kernel. +.Pp +The +.Fn ffclock_getestimate +and +.Fn ffclock_setestimate +system calls allow the caller to get and set the kernel's feed-forward clock +parameter estimates respectively. +The +.Fn ffclock_setestimate +system call should be invoked by a single instance of a feed-forward +synchronisation daemon. +The +.Fn ffclock_getestimate +system call can be called by any process to retrieve the feed-forward clock +estimates. +.Pp +The feed-forward approach does not require that the clock estimates be retrieved +every time a timestamp is to be converted into seconds. +The number of system calls can therefore be greatly reduced if the calling +process retrieves the clock estimates from the clock synchronisation daemon +instead. +The +.Fn ffclock_getestimate +must be used when the feed-forward synchronisation daemon is not running +.Po see +.Sx USAGE +below +.Pc . +.Pp +The clock parameter estimates structure pointed to by +.Fa cest +is defined in +.In sys/timeffc.h +as: +.Bd -literal +struct ffclock_estimate { + struct bintime update_time; /* Time of last estimates update. */ + ffcounter update_ffcount; /* Counter value at last update. */ + ffcounter leapsec_next; /* Counter value of next leap second. */ + uint64_t period; /* Estimate of counter period. */ + uint32_t errb_abs; /* Bound on absolute clock error [ns]. */ + uint32_t errb_rate; /* Bound on counter rate error [ps/s]. */ + uint32_t status; /* Clock status. */ + int16_t leapsec_total; /* All leap seconds seen so far. */ + int8_t leapsec; /* Next leap second (in {-1,0,1}). */ +}; +.Ed +.Pp +Only the super-user may set the feed-forward clock estimates. +.Sh RETURN VALUES +.Rv -std +.Sh ERRORS +The following error codes may be set in +.Va errno : +.Bl -tag -width Er +.It Bq Er EFAULT +The +.Fa ffcount +or +.Fa cest +pointer referenced invalid memory. +.It Bq Er EPERM +A user other than the super-user attempted to set the feed-forward clock +parameter estimates. +.El +.Sh USAGE +The feed-forward paradigm enables the definition of specialised clock functions. +.Pp +In its simplest form, +.Fn ffclock_getcounter +can be used to establish strict order between events or to measure small time +intervals very accurately with a minimum performance cost. +.Pp +Different methods exist to access absolute time +.Po or +.Qq wall-clock time +.Pc tracked by the ffclock. +The simplest method uses the ffclock sysctl interface +.Va kern.ffclock +to make the system clock return the ffclock time. +The +.Xr clock_gettime 2 +system call can then be used to retrieve the current time seen by the +feed-forward clock. +Note that this setting affects the entire system and that a feed-forward +synchronisation daemon should be running. +.Pp +A less automated method consists of retrieving the feed-forward counter +timestamp from the kernel and using the feed-forward clock parameter estimates +to convert the timestamp into seconds. +The feed-forward clock parameter estimates can be retrieved from the kernel or +from the synchronisation daemon directly (preferred). +This method allows converting timestamps using different clock models as needed +by the application, while collecting meaningful upper bounds on current clock +error. +.Sh SEE ALSO +.Xr date 1 , +.Xr adjtime 2 , +.Xr clock_gettime 2 , +.Xr ctime 3 +.Sh HISTORY +Feed-forward clock support first appeared in +.Fx 10.0 . +.Sh AUTHORS +.An -nosplit +The feed-forward clock support was written by +.An Julien Ridoux Aq jridoux@unimelb.edu.au +in collaboration with +.An Darryl Veitch Aq dveitch@unimelb.edu.au +at the University of Melbourne under sponsorship from the FreeBSD Foundation. Modified: head/sys/amd64/linux32/linux32_proto.h ============================================================================== --- head/sys/amd64/linux32/linux32_proto.h Mon Nov 21 00:49:46 2011 (r227775) +++ head/sys/amd64/linux32/linux32_proto.h Mon Nov 21 01:26:10 2011 (r227776) @@ -12,6 +12,7 @@ #include #include #include +#include #include #include Modified: head/sys/compat/freebsd32/freebsd32_proto.h ============================================================================== --- head/sys/compat/freebsd32/freebsd32_proto.h Mon Nov 21 00:49:46 2011 (r227775) +++ head/sys/compat/freebsd32/freebsd32_proto.h Mon Nov 21 01:26:10 2011 (r227776) @@ -12,6 +12,7 @@ #include #include #include +#include #include #include Modified: head/sys/compat/freebsd32/freebsd32_syscall.h ============================================================================== --- head/sys/compat/freebsd32/freebsd32_syscall.h Mon Nov 21 00:49:46 2011 (r227775) +++ head/sys/compat/freebsd32/freebsd32_syscall.h Mon Nov 21 01:26:10 2011 (r227776) @@ -207,6 +207,9 @@ #define FREEBSD32_SYS_freebsd32_clock_settime 233 #define FREEBSD32_SYS_freebsd32_clock_getres 234 #define FREEBSD32_SYS_freebsd32_nanosleep 240 +#define FREEBSD32_SYS_ffclock_getcounter 241 +#define FREEBSD32_SYS_ffclock_setestimate 242 +#define FREEBSD32_SYS_ffclock_getestimate 243 #define FREEBSD32_SYS_minherit 250 #define FREEBSD32_SYS_rfork 251 #define FREEBSD32_SYS_openbsd_poll 252 Modified: head/sys/compat/freebsd32/freebsd32_syscalls.c ============================================================================== --- head/sys/compat/freebsd32/freebsd32_syscalls.c Mon Nov 21 00:49:46 2011 (r227775) +++ head/sys/compat/freebsd32/freebsd32_syscalls.c Mon Nov 21 01:26:10 2011 (r227776) @@ -251,9 +251,9 @@ const char *freebsd32_syscallnames[] = { "#238", /* 238 = timer_gettime */ "#239", /* 239 = timer_getoverrun */ "freebsd32_nanosleep", /* 240 = freebsd32_nanosleep */ - "#241", /* 241 = nosys */ - "#242", /* 242 = nosys */ - "#243", /* 243 = nosys */ + "ffclock_getcounter", /* 241 = ffclock_getcounter */ + "ffclock_setestimate", /* 242 = ffclock_setestimate */ + "ffclock_getestimate", /* 243 = ffclock_getestimate */ "#244", /* 244 = nosys */ "#245", /* 245 = nosys */ "#246", /* 246 = nosys */ Modified: head/sys/compat/freebsd32/freebsd32_sysent.c ============================================================================== --- head/sys/compat/freebsd32/freebsd32_sysent.c Mon Nov 21 00:49:46 2011 (r227775) +++ head/sys/compat/freebsd32/freebsd32_sysent.c Mon Nov 21 01:26:10 2011 (r227776) @@ -288,9 +288,9 @@ struct sysent freebsd32_sysent[] = { { 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0, SY_THR_ABSENT }, /* 238 = timer_gettime */ { 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0, SY_THR_ABSENT }, /* 239 = timer_getoverrun */ { AS(freebsd32_nanosleep_args), (sy_call_t *)freebsd32_nanosleep, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 240 = freebsd32_nanosleep */ - { 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0, SY_THR_ABSENT }, /* 241 = nosys */ - { 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0, SY_THR_ABSENT }, /* 242 = nosys */ - { 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0, SY_THR_ABSENT }, /* 243 = nosys */ + { AS(ffclock_getcounter_args), (sy_call_t *)sys_ffclock_getcounter, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 241 = ffclock_getcounter */ + { AS(ffclock_setestimate_args), (sy_call_t *)sys_ffclock_setestimate, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 242 = ffclock_setestimate */ + { AS(ffclock_getestimate_args), (sy_call_t *)sys_ffclock_getestimate, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 243 = ffclock_getestimate */ { 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0, SY_THR_ABSENT }, /* 244 = nosys */ { 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0, SY_THR_ABSENT }, /* 245 = nosys */ { 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0, SY_THR_ABSENT }, /* 246 = nosys */ Modified: head/sys/compat/freebsd32/freebsd32_systrace_args.c ============================================================================== --- head/sys/compat/freebsd32/freebsd32_systrace_args.c Mon Nov 21 00:49:46 2011 (r227775) +++ head/sys/compat/freebsd32/freebsd32_systrace_args.c Mon Nov 21 01:26:10 2011 (r227776) @@ -1203,6 +1203,27 @@ systrace_args(int sysnum, void *params, *n_args = 2; break; } + /* ffclock_getcounter */ + case 241: { + struct ffclock_getcounter_args *p = params; + uarg[0] = (intptr_t) p->ffcount; /* ffcounter * */ + *n_args = 1; + break; + } + /* ffclock_setestimate */ + case 242: { + struct ffclock_setestimate_args *p = params; + uarg[0] = (intptr_t) p->cest; /* struct ffclock_estimate * */ + *n_args = 1; + break; + } + /* ffclock_getestimate */ + case 243: { + struct ffclock_getestimate_args *p = params; + uarg[0] = (intptr_t) p->cest; /* struct ffclock_estimate * */ + *n_args = 1; + break; + } /* minherit */ case 250: { struct minherit_args *p = params; @@ -4940,6 +4961,36 @@ systrace_entry_setargdesc(int sysnum, in break; }; break; + /* ffclock_getcounter */ + case 241: + switch(ndx) { + case 0: + p = "ffcounter *"; + break; + default: + break; + }; + break; + /* ffclock_setestimate */ + case 242: + switch(ndx) { + case 0: + p = "struct ffclock_estimate *"; + break; + default: + break; + }; + break; + /* ffclock_getestimate */ + case 243: + switch(ndx) { + case 0: + p = "struct ffclock_estimate *"; + break; + default: + break; + }; + break; /* minherit */ case 250: switch(ndx) { @@ -8824,6 +8875,21 @@ systrace_return_setargdesc(int sysnum, i if (ndx == 0 || ndx == 1) p = "int"; break; + /* ffclock_getcounter */ + case 241: + if (ndx == 0 || ndx == 1) + p = "int"; + break; + /* ffclock_setestimate */ + case 242: + if (ndx == 0 || ndx == 1) + p = "int"; + break; + /* ffclock_getestimate */ + case 243: + if (ndx == 0 || ndx == 1) + p = "int"; + break; /* minherit */ case 250: if (ndx == 0 || ndx == 1) Modified: head/sys/compat/freebsd32/syscalls.master ============================================================================== --- head/sys/compat/freebsd32/syscalls.master Mon Nov 21 00:49:46 2011 (r227775) +++ head/sys/compat/freebsd32/syscalls.master Mon Nov 21 01:26:10 2011 (r227776) @@ -447,9 +447,11 @@ 240 AUE_NULL STD { int freebsd32_nanosleep( \ const struct timespec32 *rqtp, \ struct timespec32 *rmtp); } -241 AUE_NULL UNIMPL nosys -242 AUE_NULL UNIMPL nosys -243 AUE_NULL UNIMPL nosys +241 AUE_NULL NOPROTO { int ffclock_getcounter(ffcounter *ffcount); } +242 AUE_NULL NOPROTO { int ffclock_setestimate( \ + struct ffclock_estimate *cest); } +243 AUE_NULL NOPROTO { int ffclock_getestimate( \ + struct ffclock_estimate *cest); } 244 AUE_NULL UNIMPL nosys 245 AUE_NULL UNIMPL nosys 246 AUE_NULL UNIMPL nosys Modified: head/sys/conf/files ============================================================================== --- head/sys/conf/files Mon Nov 21 00:49:46 2011 (r227775) +++ head/sys/conf/files Mon Nov 21 01:26:10 2011 (r227776) @@ -2341,7 +2341,7 @@ kern/kern_event.c standard kern/kern_exec.c standard kern/kern_exit.c standard kern/kern_fail.c standard -kern/kern_ffclock.c optional ffclock +kern/kern_ffclock.c standard kern/kern_fork.c standard kern/kern_gzio.c optional gzio kern/kern_hhook.c standard Modified: head/sys/i386/linux/linux_proto.h ============================================================================== --- head/sys/i386/linux/linux_proto.h Mon Nov 21 00:49:46 2011 (r227775) +++ head/sys/i386/linux/linux_proto.h Mon Nov 21 01:26:10 2011 (r227776) @@ -12,6 +12,7 @@ #include #include #include +#include #include #include Modified: head/sys/kern/init_sysent.c ============================================================================== --- head/sys/kern/init_sysent.c Mon Nov 21 00:49:46 2011 (r227775) +++ head/sys/kern/init_sysent.c Mon Nov 21 01:26:10 2011 (r227776) @@ -275,9 +275,9 @@ struct sysent sysent[] = { { AS(ktimer_gettime_args), (sy_call_t *)sys_ktimer_gettime, AUE_NULL, NULL, 0, 0, SYF_CAPENABLED, SY_THR_STATIC }, /* 238 = ktimer_gettime */ { AS(ktimer_getoverrun_args), (sy_call_t *)sys_ktimer_getoverrun, AUE_NULL, NULL, 0, 0, SYF_CAPENABLED, SY_THR_STATIC }, /* 239 = ktimer_getoverrun */ { AS(nanosleep_args), (sy_call_t *)sys_nanosleep, AUE_NULL, NULL, 0, 0, SYF_CAPENABLED, SY_THR_STATIC }, /* 240 = nanosleep */ - { 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0, SY_THR_ABSENT }, /* 241 = nosys */ - { 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0, SY_THR_ABSENT }, /* 242 = nosys */ - { 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0, SY_THR_ABSENT }, /* 243 = nosys */ + { AS(ffclock_getcounter_args), (sy_call_t *)sys_ffclock_getcounter, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 241 = ffclock_getcounter */ + { AS(ffclock_setestimate_args), (sy_call_t *)sys_ffclock_setestimate, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 242 = ffclock_setestimate */ + { AS(ffclock_getestimate_args), (sy_call_t *)sys_ffclock_getestimate, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 243 = ffclock_getestimate */ { 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0, SY_THR_ABSENT }, /* 244 = nosys */ { 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0, SY_THR_ABSENT }, /* 245 = nosys */ { 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0, SY_THR_ABSENT }, /* 246 = nosys */ Modified: head/sys/kern/kern_ffclock.c ============================================================================== --- head/sys/kern/kern_ffclock.c Mon Nov 21 00:49:46 2011 (r227775) +++ head/sys/kern/kern_ffclock.c Mon Nov 21 01:26:10 2011 (r227776) @@ -30,14 +30,29 @@ #include __FBSDID("$FreeBSD$"); +#include "opt_ffclock.h" + #include +#include +#include +#include +#include +#include +#include +#include #include +#include +#include #include #include #include +#ifdef FFCLOCK + extern struct ffclock_estimate ffclock_estimate; extern struct bintime ffclock_boottime; +extern int8_t ffclock_updated; +extern struct mtx ffclock_mtx; /* * Feed-forward clock absolute time. This should be the preferred way to read @@ -208,6 +223,12 @@ sysctl_kern_ffclock_active(SYSCTL_HANDLE SYSCTL_PROC(_kern_ffclock, OID_AUTO, active, CTLTYPE_STRING | CTLFLAG_RW, 0, 0, sysctl_kern_ffclock_active, "A", "Kernel clock selected"); +int sysctl_kern_ffclock_ffcounter_bypass = 0; + +SYSCTL_INT(_kern_ffclock, OID_AUTO, ffcounter_bypass, CTLFLAG_RW, + &sysctl_kern_ffclock_ffcounter_bypass, 0, + "Use reliable hardware timecounter as the Feed-Forward Counter"); + /* * High level functions to access the Feed-Forward Clock. */ @@ -341,3 +362,112 @@ ffclock_microdifftime(ffcounter ffdelta, ffclock_difftime(ffdelta, &bt, NULL); bintime2timeval(&bt, tvp); } + +/* + * System call allowing userland applications to retrieve the current value of + * the Feed-Forward Clock counter. + */ +#ifndef _SYS_SYSPROTO_H_ +struct ffclock_getcounter_args { + ffcounter *ffcount; +}; +#endif +/* ARGSUSED */ +int +sys_ffclock_getcounter(struct thread *td, struct ffclock_getcounter_args *uap) +{ + ffcounter ffcount; + int error; + + ffcount = 0; + ffclock_read_counter(&ffcount); + if (ffcount == 0) + return (EAGAIN); + error = copyout(&ffcount, uap->ffcount, sizeof(ffcounter)); + + return (error); +} + +/* + * System call allowing the synchronisation daemon to push new feed-foward clock + * estimates to the kernel. Acquire ffclock_mtx to prevent concurrent updates + * and ensure data consistency. + * NOTE: ffclock_updated signals the fftimehands that new estimates are + * available. The updated estimates are picked up by the fftimehands on next + * tick, which could take as long as 1/hz seconds (if ticks are not missed). + */ +#ifndef _SYS_SYSPROTO_H_ +struct ffclock_setestimate_args { + struct ffclock_estimate *cest; +}; +#endif +/* ARGSUSED */ +int +sys_ffclock_setestimate(struct thread *td, struct ffclock_setestimate_args *uap) +{ + struct ffclock_estimate cest; + int error; + + /* Reuse of PRIV_CLOCK_SETTIME. */ + if ((error = priv_check(td, PRIV_CLOCK_SETTIME)) != 0) + return (error); + + if ((error = copyin(uap->cest, &cest, sizeof(struct ffclock_estimate))) + != 0) + return (error); + + mtx_lock(&ffclock_mtx); + memcpy(&ffclock_estimate, &cest, sizeof(struct ffclock_estimate)); + ffclock_updated++; + mtx_unlock(&ffclock_mtx); + return (error); +} + +/* + * System call allowing userland applications to retrieve the clock estimates + * stored within the kernel. It is useful to kickstart the synchronisation + * daemon with the kernel's knowledge of hardware timecounter. + */ +#ifndef _SYS_SYSPROTO_H_ +struct ffclock_getestimate_args { + struct ffclock_estimate *cest; +}; +#endif +/* ARGSUSED */ +int +sys_ffclock_getestimate(struct thread *td, struct ffclock_getestimate_args *uap) +{ + struct ffclock_estimate cest; + int error; + + mtx_lock(&ffclock_mtx); + memcpy(&cest, &ffclock_estimate, sizeof(struct ffclock_estimate)); + mtx_unlock(&ffclock_mtx); + error = copyout(&cest, uap->cest, sizeof(struct ffclock_estimate)); + return (error); +} + +#else /* !FFCLOCK */ + +int +sys_ffclock_getcounter(struct thread *td, struct ffclock_getcounter_args *uap) +{ + + return (ENOSYS); +} + +int +sys_ffclock_setestimate(struct thread *td, struct ffclock_setestimate_args *uap) +{ + + return (ENOSYS); +} + +int +sys_ffclock_getestimate(struct thread *td, struct ffclock_getestimate_args *uap) +{ + + return (ENOSYS); +} + +#endif /* FFCLOCK */ Modified: head/sys/kern/makesyscalls.sh ============================================================================== --- head/sys/kern/makesyscalls.sh Mon Nov 21 00:49:46 2011 (r227775) +++ head/sys/kern/makesyscalls.sh Mon Nov 21 01:26:10 2011 (r227776) @@ -154,6 +154,7 @@ s/\$//g printf "#include \n" > sysarg printf "#include \n" > sysarg printf "#include \n" > sysarg + printf "#include \n" > sysarg printf "#include \n" > sysarg printf "#include \n\n" > sysarg printf "#include \n\n" > sysarg Modified: head/sys/kern/syscalls.c ============================================================================== --- head/sys/kern/syscalls.c Mon Nov 21 00:49:46 2011 (r227775) +++ head/sys/kern/syscalls.c Mon Nov 21 01:26:10 2011 (r227776) @@ -248,9 +248,9 @@ const char *syscallnames[] = { "ktimer_gettime", /* 238 = ktimer_gettime */ "ktimer_getoverrun", /* 239 = ktimer_getoverrun */ "nanosleep", /* 240 = nanosleep */ - "#241", /* 241 = nosys */ - "#242", /* 242 = nosys */ - "#243", /* 243 = nosys */ + "ffclock_getcounter", /* 241 = ffclock_getcounter */ + "ffclock_setestimate", /* 242 = ffclock_setestimate */ + "ffclock_getestimate", /* 243 = ffclock_getestimate */ "#244", /* 244 = nosys */ "#245", /* 245 = nosys */ "#246", /* 246 = nosys */ Modified: head/sys/kern/syscalls.master ============================================================================== --- head/sys/kern/syscalls.master Mon Nov 21 00:49:46 2011 (r227775) +++ head/sys/kern/syscalls.master Mon Nov 21 01:26:10 2011 (r227776) @@ -456,9 +456,11 @@ 239 AUE_NULL STD { int ktimer_getoverrun(int timerid); } 240 AUE_NULL STD { int nanosleep(const struct timespec *rqtp, \ struct timespec *rmtp); } -241 AUE_NULL UNIMPL nosys -242 AUE_NULL UNIMPL nosys -243 AUE_NULL UNIMPL nosys +241 AUE_NULL STD { int ffclock_getcounter(ffcounter *ffcount); } +242 AUE_NULL STD { int ffclock_setestimate( \ + struct ffclock_estimate *cest); } +243 AUE_NULL STD { int ffclock_getestimate( \ + struct ffclock_estimate *cest); } 244 AUE_NULL UNIMPL nosys 245 AUE_NULL UNIMPL nosys 246 AUE_NULL UNIMPL nosys Modified: head/sys/kern/systrace_args.c ============================================================================== --- head/sys/kern/systrace_args.c Mon Nov 21 00:49:46 2011 (r227775) +++ head/sys/kern/systrace_args.c Mon Nov 21 01:26:10 2011 (r227776) @@ -1337,6 +1337,27 @@ systrace_args(int sysnum, void *params, *n_args = 2; break; } + /* ffclock_getcounter */ + case 241: { + struct ffclock_getcounter_args *p = params; + uarg[0] = (intptr_t) p->ffcount; /* ffcounter * */ + *n_args = 1; + break; + } + /* ffclock_setestimate */ + case 242: { + struct ffclock_setestimate_args *p = params; + uarg[0] = (intptr_t) p->cest; /* struct ffclock_estimate * */ + *n_args = 1; + break; + } + /* ffclock_getestimate */ + case 243: { + struct ffclock_getestimate_args *p = params; + uarg[0] = (intptr_t) p->cest; /* struct ffclock_estimate * */ + *n_args = 1; + break; + } /* ntp_gettime */ case 248: { struct ntp_gettime_args *p = params; @@ -5381,6 +5402,36 @@ systrace_entry_setargdesc(int sysnum, in break; }; break; + /* ffclock_getcounter */ + case 241: + switch(ndx) { + case 0: + p = "ffcounter *"; + break; + default: + break; + }; + break; + /* ffclock_setestimate */ + case 242: + switch(ndx) { + case 0: + p = "struct ffclock_estimate *"; + break; + default: + break; + }; + break; + /* ffclock_getestimate */ + case 243: + switch(ndx) { + case 0: + p = "struct ffclock_estimate *"; + break; + default: + break; + }; + break; /* ntp_gettime */ case 248: switch(ndx) { @@ -9398,6 +9449,21 @@ systrace_return_setargdesc(int sysnum, i if (ndx == 0 || ndx == 1) p = "int"; break; + /* ffclock_getcounter */ + case 241: + if (ndx == 0 || ndx == 1) + p = "int"; + break; + /* ffclock_setestimate */ + case 242: + if (ndx == 0 || ndx == 1) + p = "int"; + break; + /* ffclock_getestimate */ + case 243: + if (ndx == 0 || ndx == 1) + p = "int"; + break; /* ntp_gettime */ case 248: if (ndx == 0 || ndx == 1) Modified: head/sys/sys/syscall.h ============================================================================== --- head/sys/sys/syscall.h Mon Nov 21 00:49:46 2011 (r227775) +++ head/sys/sys/syscall.h Mon Nov 21 01:26:10 2011 (r227776) @@ -216,6 +216,9 @@ #define SYS_ktimer_gettime 238 #define SYS_ktimer_getoverrun 239 #define SYS_nanosleep 240 +#define SYS_ffclock_getcounter 241 +#define SYS_ffclock_setestimate 242 +#define SYS_ffclock_getestimate 243 #define SYS_ntp_gettime 248 #define SYS_minherit 250 #define SYS_rfork 251 Modified: head/sys/sys/syscall.mk ============================================================================== --- head/sys/sys/syscall.mk Mon Nov 21 00:49:46 2011 (r227775) +++ head/sys/sys/syscall.mk Mon Nov 21 01:26:10 2011 (r227776) @@ -168,6 +168,9 @@ MIASM = \ ktimer_gettime.o \ ktimer_getoverrun.o \ nanosleep.o \ + ffclock_getcounter.o \ + ffclock_setestimate.o \ + ffclock_getestimate.o \ ntp_gettime.o \ minherit.o \ rfork.o \ Modified: head/sys/sys/sysproto.h ============================================================================== --- head/sys/sys/sysproto.h Mon Nov 21 00:49:46 2011 (r227775) +++ head/sys/sys/sysproto.h Mon Nov 21 01:26:10 2011 (r227776) @@ -12,6 +12,7 @@ #include #include #include +#include #include #include @@ -726,6 +727,15 @@ struct nanosleep_args { char rqtp_l_[PADL_(const struct timespec *)]; const struct timespec * rqtp; char rqtp_r_[PADR_(const struct timespec *)]; char rmtp_l_[PADL_(struct timespec *)]; struct timespec * rmtp; char rmtp_r_[PADR_(struct timespec *)]; }; +struct ffclock_getcounter_args { + char ffcount_l_[PADL_(ffcounter *)]; ffcounter * ffcount; char ffcount_r_[PADR_(ffcounter *)]; +}; +struct ffclock_setestimate_args { + char cest_l_[PADL_(struct ffclock_estimate *)]; struct ffclock_estimate * cest; char cest_r_[PADR_(struct ffclock_estimate *)]; +}; +struct ffclock_getestimate_args { + char cest_l_[PADL_(struct ffclock_estimate *)]; struct ffclock_estimate * cest; char cest_r_[PADR_(struct ffclock_estimate *)]; +}; struct ntp_gettime_args { char ntvp_l_[PADL_(struct ntptimeval *)]; struct ntptimeval * ntvp; char ntvp_r_[PADR_(struct ntptimeval *)]; }; @@ -1894,6 +1904,9 @@ int sys_ktimer_settime(struct thread *, int sys_ktimer_gettime(struct thread *, struct ktimer_gettime_args *); int sys_ktimer_getoverrun(struct thread *, struct ktimer_getoverrun_args *); int sys_nanosleep(struct thread *, struct nanosleep_args *); +int sys_ffclock_getcounter(struct thread *, struct ffclock_getcounter_args *); +int sys_ffclock_setestimate(struct thread *, struct ffclock_setestimate_args *); +int sys_ffclock_getestimate(struct thread *, struct ffclock_getestimate_args *); int sys_ntp_gettime(struct thread *, struct ntp_gettime_args *); int sys_minherit(struct thread *, struct minherit_args *); int sys_rfork(struct thread *, struct rfork_args *); @@ -2581,6 +2594,9 @@ int freebsd7_shmctl(struct thread *, str #define SYS_AUE_ktimer_gettime AUE_NULL #define SYS_AUE_ktimer_getoverrun AUE_NULL #define SYS_AUE_nanosleep AUE_NULL +#define SYS_AUE_ffclock_getcounter AUE_NULL +#define SYS_AUE_ffclock_setestimate AUE_NULL +#define SYS_AUE_ffclock_getestimate AUE_NULL #define SYS_AUE_ntp_gettime AUE_NULL #define SYS_AUE_minherit AUE_MINHERIT #define SYS_AUE_rfork AUE_RFORK Modified: head/sys/sys/timeffc.h ============================================================================== --- head/sys/sys/timeffc.h Mon Nov 21 00:49:46 2011 (r227775) +++ head/sys/sys/timeffc.h Mon Nov 21 01:26:10 2011 (r227776) @@ -164,6 +164,15 @@ void ffclock_bindifftime(ffcounter ffdel void ffclock_nanodifftime(ffcounter ffdelta, struct timespec *tsp); void ffclock_microdifftime(ffcounter ffdelta, struct timeval *tvp); +#else /* !_KERNEL */ + +/* Feed-Forward Clock system calls. */ +__BEGIN_DECLS +int ffclock_getcounter(ffcounter *ffcount); +int ffclock_getestimate(struct ffclock_estimate *cest); +int ffclock_setestimate(struct ffclock_estimate *cest); +__END_DECLS + #endif /* _KERNEL */ #endif /* __BSD_VISIBLE */ #endif /* _SYS_TIMEFF_H_ */