| [chrony-dev] [RFC PATCH v1 13/17] conf, sys_linux: Add dynamic auxiliary clock implementation |
[ Thread Index |
Date Index
| More chrony.tuxfamily.org/chrony-dev Archives
]
- To: chrony-dev@xxxxxxxxxxxxxxxxxxxx
- Subject: [chrony-dev] [RFC PATCH v1 13/17] conf, sys_linux: Add dynamic auxiliary clock implementation
- From: Christopher S M Hall <christopher.s.hall@xxxxxxxxx>
- Date: Sat, 6 Dec 2025 06:10:59 +0000
- Cc: christopher.s.hall@xxxxxxxxx, david.zage@xxxxxxxxx, yoong.siang.song@xxxxxxxxx
- Dkim-signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1765002156; x=1796538156; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=sElml68xdVKPkfo0fWSE6wMR4g5BbSWGHajglyFJALM=; b=W4aUrAmarssR0+wO2Tei0P4LyTbyemUX5VSLoOfzIWkjnTIBGKFNqbTb KaQxkupylBnDHSmKtQJ8WR7xBM2xmjXkiw2zJ1/hpetIzMQ1b1Yb1m0Fh h8RcQl0HJFwGxQla2mi19cgIX7wd6kzPidQMMsREJD4xnJInZ3vz5amHn /M6g+6YcgoeLKFxA6xO+BowcIgpyFJpyC/0bseFi4e9KfCJzj9ivQdmr5 OrVij8n+cV+eXOpLsP2C+Uv7lG6rut8AA7p4GKPYZswR5LK1fgj41+dIC amWLdeEcV40ZdcyoK8MNDnUAygq2IWtpNa9iXIszbgjXk80fN9ALbCTUU g==;
In most uses of auxiliary clocks, the clock will allocated at runtime rather than being preallocated. This
patch adds code to allocate the clock within Chrony, by adding another 'auxclockid' directive option
'alloc'. This option takes no arguments and calls platform specific code from conf.c to find a free auxiliary
clock. The function *alloc and *Free functions in conf.c are used to call platform specific code to check
for the availability of a clock and free an allocated clock. Currently, auxiliary clocks are supported only
on Linux platforms.
---
conf.c | 63 +++++++++++++++++++++++++++++++++++++++++++++++++-
conf.h | 2 ++
sys_linux.c | 66 +++++++++++++++++++++++++++++++++++++++++++++++++++++
sys_linux.h | 4 ++++
4 files changed, 134 insertions(+), 1 deletion(-)
diff --git a/conf.c b/conf.c
index 7bbf1f5..a1bedd0 100644
--- a/conf.c
+++ b/conf.c
@@ -100,6 +100,7 @@ static void parse_tempcomp(char *);
#ifdef FEAT_AUXCLOCK
static int get_auxclockid_first(int *clockid);
static int get_auxclockid_last(int *clockid);
+static int alloc_auxclockid(int *clockid);
#endif
/* ================================================== */
@@ -1714,8 +1715,8 @@ static void parse_auxclockid(char *subcmd, int *enable, int *clockid)
arg_count = get_number_of_args(subcmd);
switch (arg_count) {
default:
- case 1:
command_parse_error();
+ case 1:
break;
case 2:
arg = CPS_SplitWord(subcmd);
@@ -1730,6 +1731,10 @@ static void parse_auxclockid(char *subcmd, int *enable, int *clockid)
other_parse_error("AUX clock ID specified, but allowed IDs is unknown\n");
parse_int(arg, clockid, first_clockid, last_clockid);
*enable = 1;
+ } else if (!strcasecmp(subcmd, "alloc") && arg_count == 1) {
+ if (alloc_auxclockid(clockid))
+ other_parse_error("AUX clock ID allocation requested, but none could be found\n");
+ *enable = -1;
} else if (!strcasecmp(subcmd, "off")) {
;
} else {
@@ -3012,6 +3017,51 @@ get_auxclockid_last(int *clockid)
/* ================================================== */
+static int
+check_auxclockid(int clockid)
+{
+#ifdef LINUX
+ return SYS_Linux_CheckAuxClock(clockid);
+#endif
+ return 0;
+}
+
+/* ================================================== */
+
+static int
+alloc_auxclockid(int *clockid)
+{
+ int clockid_first, clockid_last;
+
+ if (get_auxclockid_first(&clockid_first) || get_auxclockid_last(&clockid_last))
+ return -1;
+ for (int i = clockid_first; i <= clockid_last; ++i) {
+ int retval = check_auxclockid(i);
+ if (retval < 0)
+ return retval;
+ if (retval > 0) {
+ *clockid = i;
+ use_auxclock = -1;
+ return 0;
+ }
+ }
+ return -1;
+}
+
+/* ================================================== */
+
+void
+CNF_FreeAuxClockId(int clockid)
+{
+ if (CNF_GetAuxClockDynamic()) {
+#ifdef LINUX
+ SYS_Linux_FreeAuxClock(clockid);
+#endif
+ }
+}
+
+/* ================================================== */
+
const int*
CNF_GetAuxClockId()
{
@@ -3021,4 +3071,15 @@ CNF_GetAuxClockId()
return NULL;
}
+/* ================================================== */
+
+int
+CNF_GetAuxClockDynamic()
+{
+ if (use_auxclock == -1) {
+ return 1;
+ }
+ return 0;
+}
+
#endif
diff --git a/conf.h b/conf.h
index 0fa0895..c5164c0 100644
--- a/conf.h
+++ b/conf.h
@@ -184,6 +184,8 @@ extern int CNF_GetNoCertTimeCheck(void);
extern int CNF_GetOffsetSanityCheck(void);
#ifdef FEAT_AUXCLOCK
extern const int *CNF_GetAuxClockId(void);
+extern int CNF_GetAuxClockDynamic(void);
+extern void CNF_FreeAuxClockId(int clockid);
#endif
#endif /* GOT_CONF_H */
diff --git a/sys_linux.c b/sys_linux.c
index 9258143..c327653 100644
--- a/sys_linux.c
+++ b/sys_linux.c
@@ -35,6 +35,9 @@
#include <sys/utsname.h>
#include <linux/timex.h>
+#ifdef FEAT_AUXCLOCK
+#include <dirent.h>
+#endif
#if defined(FEAT_PHC) || defined(HAVE_LINUX_TIMESTAMPING)
#include <linux/ptp_clock.h>
@@ -85,6 +88,11 @@
#define ADJ_NANO 0x2000 /* select nanosecond resolution */
#endif
+#ifdef FEAT_AUXCLOCK
+#define AUX_CLOCK_DIR "/sys/kernel/time/aux_clocks/"
+#define AUX_CLOCK_ENABLE_FILE "aux_clock_enable"
+#endif
+
/* This is the uncompensated system tick value */
static int nominal_tick;
@@ -1095,5 +1103,63 @@ SYS_Linux_GetAuxClockLast(int *clockid)
return 0;
}
+int
+SYS_Linux_CheckAuxClock(int clockid)
+{
+ char clock_filename[sizeof(AUX_CLOCK_DIR)+4+sizeof(AUX_CLOCK_ENABLE_FILE)] = AUX_CLOCK_DIR;
+ struct dirent *entry;
+ int index;
+ DIR *dir;
+
+ snprintf(clock_filename+strlen(AUX_CLOCK_DIR), 4, "%hhu/", (uint8_t)(clockid - CLOCK_AUX));
+ if((dir = opendir(clock_filename)) == NULL) {
+ LOG(LOGS_WARN, "Cannot read directory: %s; disabling AUX clocks\n", clock_filename);
+ return -1;
+ }
+
+ index = strlen(clock_filename);
+ while ((entry = readdir(dir)) != NULL) {
+ if (!strcmp(entry->d_name, AUX_CLOCK_ENABLE_FILE) && entry->d_type == DT_REG) {
+ int fd;
+ char enable;
+
+ strcpy(clock_filename+index, entry->d_name);
+ if ((fd = open(clock_filename, O_RDWR)) == -1) {
+ LOG(LOGS_WARN, "Cannot open file: %s; disabling AUX clocks\n", clock_filename);
+ return -1;
+ }
+ if (!read(fd, &enable, 1)) {
+ LOG(LOGS_WARN, "Cannot read file: %s; disabling AUX clocks\n", clock_filename);
+ return -1;
+ }
+ if (enable == '0') {
+ enable = '1';
+ if (!write(fd, &enable, 1)) {
+ LOG(LOGS_WARN, "Cannot write file: %s; disabling AUX clocks\n", clock_filename);
+ return -1;
+ }
+ return 1;
+ }
+ }
+ }
+
+ return 0;
+}
+
+void
+SYS_Linux_FreeAuxClock(int clockid)
+{
+ char clock_filename[sizeof(AUX_CLOCK_DIR)+4+sizeof(AUX_CLOCK_ENABLE_FILE)] = AUX_CLOCK_DIR;
+ char zero = '0';
+ int fd;
+
+ sprintf(clock_filename+strlen(AUX_CLOCK_DIR), "%hhu/%s", (uint8_t)clockid - CLOCK_AUX, AUX_CLOCK_ENABLE_FILE);
+ fd = open(clock_filename, O_RDWR);
+ if (fd == -1)
+ return;
+ (void)!write(fd, &zero, sizeof(zero));
+ close(fd);
+}
+
#endif /* FEAT_AUXCLOCK */
#endif /* FEAT_PHC || HAVE_LINUX_TIMESTAMPING */
diff --git a/sys_linux.h b/sys_linux.h
index e81ff51..81e49e0 100644
--- a/sys_linux.h
+++ b/sys_linux.h
@@ -55,4 +55,8 @@ extern int SYS_Linux_GetAuxClockFirst(int *clockid);
extern int SYS_Linux_GetAuxClockLast(int *clockid);
+extern int SYS_Linux_CheckAuxClock(int clockid);
+
+extern void SYS_Linux_FreeAuxClock(int clockid);
+
#endif /* GOT_SYS_LINUX_H */
--
2.34.1
--
To unsubscribe email chrony-dev-request@xxxxxxxxxxxxxxxxxxxx with "unsubscribe" in the subject.
For help email chrony-dev-request@xxxxxxxxxxxxxxxxxxxx with "help" in the subject.
Trouble? Email listmaster@xxxxxxxxxxxxxxxxxxxx.