aboutsummaryrefslogtreecommitdiffstats
path: root/kernel
diff options
context:
space:
mode:
authorJohn Stultz <john.stultz@linaro.org>2013-03-22 15:28:15 -0400
committerJohn Stultz <john.stultz@linaro.org>2013-04-04 16:18:15 -0400
commit87ace39b7168bd9d352c1c52b6f5d88eb1876cf8 (patch)
tree57f19306b0f2e9b99430f92a4ba9a7ac9454e2e0 /kernel
parente4085693f629ded8ac8c35b5cdd324d20242990b (diff)
ntp: Rework do_adjtimex to take timespec and tai arguments
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 <tglx@linutronix.de> Cc: Richard Cochran <richardcochran@gmail.com> Cc: Prarit Bhargava <prarit@redhat.com> Signed-off-by: John Stultz <john.stultz@linaro.org>
Diffstat (limited to 'kernel')
-rw-r--r--kernel/time/ntp.c18
-rw-r--r--kernel/time/ntp_internal.h2
-rw-r--r--kernel/time/timekeeping.c13
3 files changed, 17 insertions, 16 deletions
diff --git a/kernel/time/ntp.c b/kernel/time/ntp.c
index 2dc60c6fe76b..d17e13c0147d 100644
--- a/kernel/time/ntp.c
+++ b/kernel/time/ntp.c
@@ -662,10 +662,8 @@ int ntp_validate_timex(struct timex *txc)
662 * adjtimex mainly allows reading (and writing, if superuser) of 662 * adjtimex mainly allows reading (and writing, if superuser) of
663 * kernel time-keeping variables. used by xntpd. 663 * kernel time-keeping variables. used by xntpd.
664 */ 664 */
665int __do_adjtimex(struct timex *txc) 665int __do_adjtimex(struct timex *txc, struct timespec *ts, s32 *time_tai)
666{ 666{
667 struct timespec ts;
668 u32 time_tai, orig_tai;
669 int result; 667 int result;
670 668
671 if (txc->modes & ADJ_SETOFFSET) { 669 if (txc->modes & ADJ_SETOFFSET) {
@@ -679,9 +677,6 @@ int __do_adjtimex(struct timex *txc)
679 return result; 677 return result;
680 } 678 }
681 679
682 getnstimeofday(&ts);
683 orig_tai = time_tai = timekeeping_get_tai_offset();
684
685 raw_spin_lock_irq(&ntp_lock); 680 raw_spin_lock_irq(&ntp_lock);
686 681
687 if (txc->modes & ADJ_ADJTIME) { 682 if (txc->modes & ADJ_ADJTIME) {
@@ -697,7 +692,7 @@ int __do_adjtimex(struct timex *txc)
697 692
698 /* If there are input parameters, then process them: */ 693 /* If there are input parameters, then process them: */
699 if (txc->modes) 694 if (txc->modes)
700 process_adjtimex_modes(txc, &ts, &time_tai); 695 process_adjtimex_modes(txc, ts, time_tai);
701 696
702 txc->offset = shift_right(time_offset * NTP_INTERVAL_FREQ, 697 txc->offset = shift_right(time_offset * NTP_INTERVAL_FREQ,
703 NTP_SCALE_SHIFT); 698 NTP_SCALE_SHIFT);
@@ -719,18 +714,15 @@ int __do_adjtimex(struct timex *txc)
719 txc->precision = 1; 714 txc->precision = 1;
720 txc->tolerance = MAXFREQ_SCALED / PPM_SCALE; 715 txc->tolerance = MAXFREQ_SCALED / PPM_SCALE;
721 txc->tick = tick_usec; 716 txc->tick = tick_usec;
722 txc->tai = time_tai; 717 txc->tai = *time_tai;
723 718
724 /* fill PPS status fields */ 719 /* fill PPS status fields */
725 pps_fill_timex(txc); 720 pps_fill_timex(txc);
726 721
727 raw_spin_unlock_irq(&ntp_lock); 722 raw_spin_unlock_irq(&ntp_lock);
728 723
729 if (time_tai != orig_tai) 724 txc->time.tv_sec = ts->tv_sec;
730 timekeeping_set_tai_offset(time_tai); 725 txc->time.tv_usec = ts->tv_nsec;
731
732 txc->time.tv_sec = ts.tv_sec;
733 txc->time.tv_usec = ts.tv_nsec;
734 if (!(time_status & STA_NANO)) 726 if (!(time_status & STA_NANO))
735 txc->time.tv_usec /= NSEC_PER_USEC; 727 txc->time.tv_usec /= NSEC_PER_USEC;
736 728
diff --git a/kernel/time/ntp_internal.h b/kernel/time/ntp_internal.h
index a2a397659e46..1950cb4ca2a4 100644
--- a/kernel/time/ntp_internal.h
+++ b/kernel/time/ntp_internal.h
@@ -7,6 +7,6 @@ extern void ntp_clear(void);
7extern u64 ntp_tick_length(void); 7extern u64 ntp_tick_length(void);
8extern int second_overflow(unsigned long secs); 8extern int second_overflow(unsigned long secs);
9extern int ntp_validate_timex(struct timex *); 9extern int ntp_validate_timex(struct timex *);
10extern int __do_adjtimex(struct timex *); 10extern int __do_adjtimex(struct timex *, struct timespec *, s32 *);
11extern void __hardpps(const struct timespec *, const struct timespec *); 11extern void __hardpps(const struct timespec *, const struct timespec *);
12#endif /* _LINUX_NTP_INTERNAL_H */ 12#endif /* _LINUX_NTP_INTERNAL_H */
diff --git a/kernel/time/timekeeping.c b/kernel/time/timekeeping.c
index f6c8a7279157..5f7a2330dc3c 100644
--- a/kernel/time/timekeeping.c
+++ b/kernel/time/timekeeping.c
@@ -1618,6 +1618,8 @@ EXPORT_SYMBOL_GPL(ktime_get_monotonic_offset);
1618 */ 1618 */
1619int do_adjtimex(struct timex *txc) 1619int do_adjtimex(struct timex *txc)
1620{ 1620{
1621 struct timespec ts;
1622 s32 tai, orig_tai;
1621 int ret; 1623 int ret;
1622 1624
1623 /* Validate the data before disabling interrupts */ 1625 /* Validate the data before disabling interrupts */
@@ -1625,9 +1627,16 @@ int do_adjtimex(struct timex *txc)
1625 if (ret) 1627 if (ret)
1626 return ret; 1628 return ret;
1627 1629
1628 return __do_adjtimex(txc); 1630 getnstimeofday(&ts);
1629} 1631 orig_tai = tai = timekeeping_get_tai_offset();
1632
1633 ret = __do_adjtimex(txc, &ts, &tai);
1630 1634
1635 if (tai != orig_tai)
1636 timekeeping_set_tai_offset(tai);
1637
1638 return ret;
1639}
1631 1640
1632#ifdef CONFIG_NTP_PPS 1641#ifdef CONFIG_NTP_PPS
1633/** 1642/**