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 jrid...@unimelb.edu.au
+in collaboration with
+.An Darryl Veitch Aq dvei...@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_ */
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to