On Mon, Jan 30, 2023 at 03:39:45PM +0000, Wojtek Wasko via Linuxptp-devel wrote: > Current code only prints a message in case the kernel returns an error > for a clock adjustment. Failing to adjust clock leads to an inconsistent > state in which a servo continues to report "locked" state while the > underlying PHC's state is essentially undetermined. > > This change resets the servo in case of failure to adjust the clock.
I like the error handling, but I'd like to have this one patch split into a series of four patches: 1. Let methods in clockadj.[ch] return errors to caller. 2. Implement error handling in ptp4l. 3. Implement error handling in phc2sys. 4. Implement error handling in ts2phc. That way, in the unlikely event of a regression, we can revert 2, 3, or 4. Also, I have a few minor comments on coding style... > diff --git a/clock.c b/clock.c > index 134c7c3..ff1abbf 100644 > --- a/clock.c > +++ b/clock.c > @@ -1778,18 +1778,20 @@ static void clock_step_window(struct clock *c) > c->step_window_counter = c->step_window; > } > > -static void clock_synchronize_locked(struct clock *c, double adj) > +static int clock_synchronize_locked(struct clock *c, double adj) > { > if (c->sanity_check) { > clockcheck_freq(c->sanity_check, clockadj_get_freq(c->clkid)); > } > - clockadj_set_freq(c->clkid, -adj); > + if (clockadj_set_freq(c->clkid, -adj) < 0) > + return -1; Please don't omit the braces, and drop the '< 0' clockadj_set_freq returns either 0 or -1, so the test should be simplified to 'if (clockadj_set_freq()) { ... }' > if (c->clkid == CLOCK_REALTIME) { > sysclk_set_sync(); > } > if (c->sanity_check) { > clockcheck_set_freq(c->sanity_check, -adj); > } > + return 0; > } > > enum servo_state clock_synchronize(struct clock *c, tmv_t ingress, tmv_t > origin) > @@ -1841,8 +1843,10 @@ enum servo_state clock_synchronize(struct clock *c, > tmv_t ingress, tmv_t origin) > case SERVO_UNLOCKED: > break; > case SERVO_JUMP: > - clockadj_set_freq(c->clkid, -adj); > - clockadj_step(c->clkid, -tmv_to_nanoseconds(c->master_offset)); > + if (clockadj_set_freq(c->clkid, -adj) < 0) > + goto servo_unlock; Same here > + if (clockadj_step(c->clkid, > -tmv_to_nanoseconds(c->master_offset)) < 0) > + goto servo_unlock; and here > c->ingress_ts = tmv_zero(); > if (c->sanity_check) { > clockcheck_set_freq(c->sanity_check, -adj); > @@ -1853,14 +1857,17 @@ enum servo_state clock_synchronize(struct clock *c, > tmv_t ingress, tmv_t origin) > clock_step_window(c); > break; > case SERVO_LOCKED: > - clock_synchronize_locked(c, adj); > + if (clock_synchronize_locked(c, adj) < 0) > + goto servo_unlock; ditto > break; > case SERVO_LOCKED_STABLE: > if (c->write_phase_mode) { > - clockadj_set_phase(c->clkid, -offset); > + if (clockadj_set_phase(c->clkid, -offset) < 0) > + goto servo_unlock; ditto > adj = 0; > } else { > - clock_synchronize_locked(c, adj); > + if (clock_synchronize_locked(c, adj) < 0) > + goto servo_unlock; ditto > } > break; > } > @@ -1877,6 +1884,11 @@ enum servo_state clock_synchronize(struct clock *c, > tmv_t ingress, tmv_t origin) > clock_notify_event(c, NOTIFY_TIME_SYNC); > > return state; > + > +servo_unlock: > + servo_reset(c->servo); > + c->servo_state = SERVO_UNLOCKED; > + return SERVO_UNLOCKED; > } > > void clock_sync_interval(struct clock *c, int n) > diff --git a/clockadj.c b/clockadj.c > index 4c920b9..1437ec0 100644 > --- a/clockadj.c > +++ b/clockadj.c > @@ -48,7 +48,7 @@ void clockadj_init(clockid_t clkid) > #endif > } > > -void clockadj_set_freq(clockid_t clkid, double freq) > +int clockadj_set_freq(clockid_t clkid, double freq) > { > struct timex tx; > memset(&tx, 0, sizeof(tx)); > @@ -62,8 +62,11 @@ void clockadj_set_freq(clockid_t clkid, double freq) > > tx.modes |= ADJ_FREQUENCY; > tx.freq = (long) (freq * 65.536); > - if (clock_adjtime(clkid, &tx) < 0) > + if (clock_adjtime(clkid, &tx) < 0) { FYI here the '< 0" makes sense, because clock_adjtime is the cousin of adjtimex which can return both -1 and positive time code. > pr_err("failed to adjust the clock: %m"); > + return -1; > + } > + return 0; > } > > double clockadj_get_freq(clockid_t clkid) Thanks, Richard _______________________________________________ Linuxptp-devel mailing list Linuxptp-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/linuxptp-devel