Skip to content

Commit

Permalink
ntp: Rework do_adjtimex to take timespec and tai arguments
Browse files Browse the repository at this point in the history
In order to change the locking rules, we need to provide
the timespec and tai values rather then having the ntp
logic acquire these values itself.

Cc: Thomas Gleixner <[email protected]>
Cc: Richard Cochran <[email protected]>
Cc: Prarit Bhargava <[email protected]>
Signed-off-by: John Stultz <[email protected]>
  • Loading branch information
johnstultz-work committed Apr 4, 2013
1 parent e408569 commit 87ace39
Show file tree
Hide file tree
Showing 3 changed files with 17 additions and 16 deletions.
18 changes: 5 additions & 13 deletions kernel/time/ntp.c
Original file line number Diff line number Diff line change
Expand Up @@ -662,10 +662,8 @@ int ntp_validate_timex(struct timex *txc)
* adjtimex mainly allows reading (and writing, if superuser) of
* kernel time-keeping variables. used by xntpd.
*/
int __do_adjtimex(struct timex *txc)
int __do_adjtimex(struct timex *txc, struct timespec *ts, s32 *time_tai)
{
struct timespec ts;
u32 time_tai, orig_tai;
int result;

if (txc->modes & ADJ_SETOFFSET) {
Expand All @@ -679,9 +677,6 @@ int __do_adjtimex(struct timex *txc)
return result;
}

getnstimeofday(&ts);
orig_tai = time_tai = timekeeping_get_tai_offset();

raw_spin_lock_irq(&ntp_lock);

if (txc->modes & ADJ_ADJTIME) {
Expand All @@ -697,7 +692,7 @@ int __do_adjtimex(struct timex *txc)

/* If there are input parameters, then process them: */
if (txc->modes)
process_adjtimex_modes(txc, &ts, &time_tai);
process_adjtimex_modes(txc, ts, time_tai);

txc->offset = shift_right(time_offset * NTP_INTERVAL_FREQ,
NTP_SCALE_SHIFT);
Expand All @@ -719,18 +714,15 @@ int __do_adjtimex(struct timex *txc)
txc->precision = 1;
txc->tolerance = MAXFREQ_SCALED / PPM_SCALE;
txc->tick = tick_usec;
txc->tai = time_tai;
txc->tai = *time_tai;

/* fill PPS status fields */
pps_fill_timex(txc);

raw_spin_unlock_irq(&ntp_lock);

if (time_tai != orig_tai)
timekeeping_set_tai_offset(time_tai);

txc->time.tv_sec = ts.tv_sec;
txc->time.tv_usec = ts.tv_nsec;
txc->time.tv_sec = ts->tv_sec;
txc->time.tv_usec = ts->tv_nsec;
if (!(time_status & STA_NANO))
txc->time.tv_usec /= NSEC_PER_USEC;

Expand Down
2 changes: 1 addition & 1 deletion kernel/time/ntp_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,6 @@ extern void ntp_clear(void);
extern u64 ntp_tick_length(void);
extern int second_overflow(unsigned long secs);
extern int ntp_validate_timex(struct timex *);
extern int __do_adjtimex(struct timex *);
extern int __do_adjtimex(struct timex *, struct timespec *, s32 *);
extern void __hardpps(const struct timespec *, const struct timespec *);
#endif /* _LINUX_NTP_INTERNAL_H */
13 changes: 11 additions & 2 deletions kernel/time/timekeeping.c
Original file line number Diff line number Diff line change
Expand Up @@ -1618,16 +1618,25 @@ EXPORT_SYMBOL_GPL(ktime_get_monotonic_offset);
*/
int do_adjtimex(struct timex *txc)
{
struct timespec ts;
s32 tai, orig_tai;
int ret;

/* Validate the data before disabling interrupts */
ret = ntp_validate_timex(txc);
if (ret)
return ret;

return __do_adjtimex(txc);
}
getnstimeofday(&ts);
orig_tai = tai = timekeeping_get_tai_offset();

ret = __do_adjtimex(txc, &ts, &tai);

if (tai != orig_tai)
timekeeping_set_tai_offset(tai);

return ret;
}

#ifdef CONFIG_NTP_PPS
/**
Expand Down

0 comments on commit 87ace39

Please sign in to comment.