Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 21 Nov 2011 01:26:10 +0000 (UTC)
From:      Lawrence Stewart <lstewart@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r227776 - in head: lib/libc/sys sys/amd64/linux32 sys/compat/freebsd32 sys/conf sys/i386/linux sys/kern sys/sys
Message-ID:  <201111210126.pAL1QAkg017923@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
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 <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_ */



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201111210126.pAL1QAkg017923>