svn commit: r227776 - in head: lib/libc/sys sys/amd64/linux32
sys/compat/freebsd32 sys/conf sys/i386/linux sys/kern sys/sys
Lawrence Stewart
lstewart at FreeBSD.org
Mon Nov 21 01:26:11 UTC 2011
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 at unimelb.edu.au
+in collaboration with
+.An Darryl Veitch Aq dveitch at 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 <sys/signal.h>
#include <sys/acl.h>
#include <sys/cpuset.h>
+#include <sys/_ffcounter.h>
#include <sys/_semaphore.h>
#include <sys/ucontext.h>
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 <sys/signal.h>
#include <sys/acl.h>
#include <sys/cpuset.h>
+#include <sys/_ffcounter.h>
#include <sys/_semaphore.h>
#include <sys/ucontext.h>
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 <sys/signal.h>
#include <sys/acl.h>
#include <sys/cpuset.h>
+#include <sys/_ffcounter.h>
#include <sys/_semaphore.h>
#include <sys/ucontext.h>
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 <sys/cdefs.h>
__FBSDID("$FreeBSD$");
+#include "opt_ffclock.h"
+
#include <sys/param.h>
+#include <sys/bus.h>
+#include <sys/kernel.h>
+#include <sys/lock.h>
+#include <sys/module.h>
+#include <sys/mutex.h>
+#include <sys/priv.h>
+#include <sys/proc.h>
#include <sys/sbuf.h>
+#include <sys/sysent.h>
+#include <sys/sysproto.h>
#include <sys/sysctl.h>
#include <sys/systm.h>
#include <sys/timeffc.h>
+#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 <sys/signal.h>\n" > sysarg
printf "#include <sys/acl.h>\n" > sysarg
printf "#include <sys/cpuset.h>\n" > sysarg
+ printf "#include <sys/_ffcounter.h>\n" > sysarg
printf "#include <sys/_semaphore.h>\n" > sysarg
printf "#include <sys/ucontext.h>\n\n" > sysarg
printf "#include <bsm/audit_kevents.h>\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 <sys/signal.h>
#include <sys/acl.h>
#include <sys/cpuset.h>
+#include <sys/_ffcounter.h>
#include <sys/_semaphore.h>
#include <sys/ucontext.h>
@@ -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_ */
More information about the svn-src-all
mailing list