phc2sys: split update_sync_offset
Split the generic (global) part of update_sync_offset and the part that affects individual clocks. This is in preparation for phc2sys handling synchronization of more clocks. Signed-off-by: Jiri Benc <jbenc@redhat.com>master
parent
a1bee8fbb7
commit
423eb54530
71
phc2sys.c
71
phc2sys.c
|
@ -60,7 +60,9 @@
|
||||||
#define PMC_UPDATE_INTERVAL (60 * NS_PER_SEC)
|
#define PMC_UPDATE_INTERVAL (60 * NS_PER_SEC)
|
||||||
|
|
||||||
struct clock;
|
struct clock;
|
||||||
static int update_sync_offset(struct clock *clock, int64_t offset, uint64_t ts);
|
static int update_sync_offset(struct clock *clock);
|
||||||
|
static int clock_handle_leap(struct clock *clock, clockid_t src,
|
||||||
|
int64_t offset, uint64_t ts, int do_leap);
|
||||||
|
|
||||||
static clockid_t clock_open(char *device)
|
static clockid_t clock_open(char *device)
|
||||||
{
|
{
|
||||||
|
@ -181,13 +183,14 @@ static void update_clock_stats(struct clock *clock,
|
||||||
stats_reset(clock->delay_stats);
|
stats_reset(clock->delay_stats);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void update_clock(struct clock *clock,
|
static void update_clock(struct clock *clock, clockid_t src,
|
||||||
int64_t offset, uint64_t ts, int64_t delay)
|
int64_t offset, uint64_t ts, int64_t delay,
|
||||||
|
int do_leap)
|
||||||
{
|
{
|
||||||
enum servo_state state;
|
enum servo_state state;
|
||||||
double ppb;
|
double ppb;
|
||||||
|
|
||||||
if (update_sync_offset(clock, offset, ts))
|
if (clock_handle_leap(clock, src, offset, ts, do_leap))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (clock->sync_offset_direction)
|
if (clock->sync_offset_direction)
|
||||||
|
@ -268,6 +271,7 @@ static int do_pps_loop(struct clock *clock, int fd,
|
||||||
{
|
{
|
||||||
int64_t pps_offset, phc_offset, phc_delay;
|
int64_t pps_offset, phc_offset, phc_delay;
|
||||||
uint64_t pps_ts, phc_ts;
|
uint64_t pps_ts, phc_ts;
|
||||||
|
int do_leap;
|
||||||
|
|
||||||
clock->source_label = "pps";
|
clock->source_label = "pps";
|
||||||
|
|
||||||
|
@ -304,7 +308,10 @@ static int do_pps_loop(struct clock *clock, int fd,
|
||||||
pps_offset = pps_ts - phc_ts;
|
pps_offset = pps_ts - phc_ts;
|
||||||
}
|
}
|
||||||
|
|
||||||
update_clock(clock, pps_offset, pps_ts, -1);
|
do_leap = update_sync_offset(clock);
|
||||||
|
if (do_leap <= 0)
|
||||||
|
continue;
|
||||||
|
update_clock(clock, src, pps_offset, pps_ts, -1, do_leap);
|
||||||
}
|
}
|
||||||
close(fd);
|
close(fd);
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -316,6 +323,7 @@ static int do_sysoff_loop(struct clock *clock, clockid_t src,
|
||||||
uint64_t ts;
|
uint64_t ts;
|
||||||
int64_t offset, delay;
|
int64_t offset, delay;
|
||||||
int err = 0, fd = CLOCKID_TO_FD(src);
|
int err = 0, fd = CLOCKID_TO_FD(src);
|
||||||
|
int do_leap;
|
||||||
|
|
||||||
clock->source_label = "sys";
|
clock->source_label = "sys";
|
||||||
|
|
||||||
|
@ -325,7 +333,10 @@ static int do_sysoff_loop(struct clock *clock, clockid_t src,
|
||||||
err = -1;
|
err = -1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
update_clock(clock, offset, ts, delay);
|
do_leap = update_sync_offset(clock);
|
||||||
|
if (do_leap <= 0)
|
||||||
|
continue;
|
||||||
|
update_clock(clock, src, offset, ts, delay, do_leap);
|
||||||
}
|
}
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
@ -335,6 +346,7 @@ static int do_phc_loop(struct clock *clock, clockid_t src,
|
||||||
{
|
{
|
||||||
uint64_t ts;
|
uint64_t ts;
|
||||||
int64_t offset, delay;
|
int64_t offset, delay;
|
||||||
|
int do_leap;
|
||||||
|
|
||||||
clock->source_label = "phc";
|
clock->source_label = "phc";
|
||||||
|
|
||||||
|
@ -344,7 +356,10 @@ static int do_phc_loop(struct clock *clock, clockid_t src,
|
||||||
&offset, &ts, &delay)) {
|
&offset, &ts, &delay)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
update_clock(clock, offset, ts, delay);
|
do_leap = update_sync_offset(clock);
|
||||||
|
if (do_leap <= 0)
|
||||||
|
continue;
|
||||||
|
update_clock(clock, src, offset, ts, delay, do_leap);
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -495,10 +510,19 @@ static void close_pmc(struct clock *clock)
|
||||||
clock->pmc = NULL;
|
clock->pmc = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int update_sync_offset(struct clock *clock, int64_t offset, uint64_t ts)
|
/* Returns: -1 in case of error, 0 for normal sync, 1 to leap clock */
|
||||||
|
static int update_sync_offset(struct clock *clock)
|
||||||
{
|
{
|
||||||
|
struct timespec tp;
|
||||||
|
uint64_t ts;
|
||||||
int clock_leap;
|
int clock_leap;
|
||||||
|
|
||||||
|
if (clock_gettime(CLOCK_REALTIME, &tp)) {
|
||||||
|
pr_err("failed to read clock: %m");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
ts = tp.tv_sec * NS_PER_SEC + tp.tv_nsec;
|
||||||
|
|
||||||
if (clock->pmc &&
|
if (clock->pmc &&
|
||||||
!(ts > clock->pmc_last_update &&
|
!(ts > clock->pmc_last_update &&
|
||||||
ts - clock->pmc_last_update < PMC_UPDATE_INTERVAL)) {
|
ts - clock->pmc_last_update < PMC_UPDATE_INTERVAL)) {
|
||||||
|
@ -511,9 +535,28 @@ static int update_sync_offset(struct clock *clock, int64_t offset, uint64_t ts)
|
||||||
if (!clock->leap && !clock->leap_set)
|
if (!clock->leap && !clock->leap_set)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
clock_leap = leap_second_status(ts, clock->leap_set,
|
||||||
|
&clock->leap, &clock->sync_offset);
|
||||||
|
if (clock->leap_set != clock_leap) {
|
||||||
|
clock->leap_set = clock_leap;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Returns: non-zero to skip clock update */
|
||||||
|
static int clock_handle_leap(struct clock *clock, clockid_t src,
|
||||||
|
int64_t offset, uint64_t ts, int do_leap)
|
||||||
|
{
|
||||||
|
if (!clock->leap && !do_leap)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (clock->clkid != CLOCK_REALTIME && src != CLOCK_REALTIME)
|
||||||
|
return 0;
|
||||||
|
|
||||||
/* If the system clock is the master clock, get a time stamp from
|
/* If the system clock is the master clock, get a time stamp from
|
||||||
it, as it is the clock which will include the leap second. */
|
it, as it is the clock which will include the leap second. */
|
||||||
if (clock->clkid != CLOCK_REALTIME) {
|
if (src == CLOCK_REALTIME) {
|
||||||
struct timespec tp;
|
struct timespec tp;
|
||||||
if (clock_gettime(CLOCK_REALTIME, &tp)) {
|
if (clock_gettime(CLOCK_REALTIME, &tp)) {
|
||||||
pr_err("failed to read clock: %m");
|
pr_err("failed to read clock: %m");
|
||||||
|
@ -533,17 +576,13 @@ static int update_sync_offset(struct clock *clock, int64_t offset, uint64_t ts)
|
||||||
/* Suspend clock updates in the last second before midnight. */
|
/* Suspend clock updates in the last second before midnight. */
|
||||||
if (is_utc_ambiguous(ts)) {
|
if (is_utc_ambiguous(ts)) {
|
||||||
pr_info("clock update suspended due to leap second");
|
pr_info("clock update suspended due to leap second");
|
||||||
return -1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
clock_leap = leap_second_status(ts, clock->leap_set,
|
if (do_leap) {
|
||||||
&clock->leap, &clock->sync_offset);
|
|
||||||
|
|
||||||
if (clock->leap_set != clock_leap) {
|
|
||||||
/* Only the system clock can leap. */
|
/* Only the system clock can leap. */
|
||||||
if (clock->clkid == CLOCK_REALTIME && clock->kernel_leap)
|
if (clock->clkid == CLOCK_REALTIME && clock->kernel_leap)
|
||||||
sysclk_set_leap(clock_leap);
|
sysclk_set_leap(clock->leap_set);
|
||||||
clock->leap_set = clock_leap;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
Loading…
Reference in New Issue