Commit 0ba97bc4 authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge branch 'timers-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip

Pull timer updates from Ingo Molnar:
 "The main changes in this cycle were:

   - rework hrtimer expiry calculation in hrtimer_interrupt(): the
     previous code had a subtle bug where expiry caching would miss an
     expiry, resulting in occasional bogus (late) expiry of hrtimers.

   - continuing Y2038 fixes

   - ktime division optimization

   - misc smaller fixes and cleanups"

* 'timers-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
  hrtimer: Make __hrtimer_get_next_event() static
  rtc: Convert rtc_set_ntp_time() to use timespec64
  rtc: Remove redundant rtc_valid_tm() from rtc_hctosys()
  rtc: Modify rtc_hctosys() to address y2038 issues
  rtc: Update rtc-dev to use y2038-safe time interfaces
  rtc: Update interface.c to use y2038-safe time interfaces
  time: Expose get_monotonic_boottime64 for in-kernel use
  time: Expose getboottime64 for in-kernel uses
  ktime: Optimize ktime_divns for constant divisors
  hrtimer: Prevent stale expiry time in hrtimer_interrupt()
  ktime.h: Introduce ktime_ms_delta
parents 5b9b28a6 4ebbda52
Loading
Loading
Loading
Loading
+5 −13
Original line number Diff line number Diff line
@@ -26,7 +26,7 @@ static int __init rtc_hctosys(void)
{
	int err = -ENODEV;
	struct rtc_time tm;
	struct timespec tv = {
	struct timespec64 tv64 = {
		.tv_nsec = NSEC_PER_SEC >> 1,
	};
	struct rtc_device *rtc = rtc_class_open(CONFIG_RTC_HCTOSYS_DEVICE);
@@ -45,25 +45,17 @@ static int __init rtc_hctosys(void)

	}

	err = rtc_valid_tm(&tm);
	if (err) {
		dev_err(rtc->dev.parent,
			"hctosys: invalid date/time\n");
		goto err_invalid;
	}

	rtc_tm_to_time(&tm, &tv.tv_sec);
	tv64.tv_sec = rtc_tm_to_time64(&tm);

	err = do_settimeofday(&tv);
	err = do_settimeofday64(&tv64);

	dev_info(rtc->dev.parent,
		"setting system clock to "
		"%d-%02d-%02d %02d:%02d:%02d UTC (%u)\n",
		"%d-%02d-%02d %02d:%02d:%02d UTC (%lld)\n",
		tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday,
		tm.tm_hour, tm.tm_min, tm.tm_sec,
		(unsigned int) tv.tv_sec);
		(long long) tv64.tv_sec);

err_invalid:
err_read:
	rtc_class_close(rtc);

+10 −12
Original line number Diff line number Diff line
@@ -73,10 +73,8 @@ int rtc_set_time(struct rtc_device *rtc, struct rtc_time *tm)
	else if (rtc->ops->set_time)
		err = rtc->ops->set_time(rtc->dev.parent, tm);
	else if (rtc->ops->set_mmss) {
		unsigned long secs;
		err = rtc_tm_to_time(tm, &secs);
		if (err == 0)
			err = rtc->ops->set_mmss(rtc->dev.parent, secs);
		time64_t secs64 = rtc_tm_to_time64(tm);
		err = rtc->ops->set_mmss(rtc->dev.parent, secs64);
	} else
		err = -EINVAL;

@@ -105,7 +103,7 @@ int rtc_set_mmss(struct rtc_device *rtc, unsigned long secs)

		err = rtc->ops->read_time(rtc->dev.parent, &old);
		if (err == 0) {
			rtc_time_to_tm(secs, &new);
			rtc_time64_to_tm(secs, &new);

			/*
			 * avoid writing when we're going to change the day of
@@ -157,7 +155,7 @@ int __rtc_read_alarm(struct rtc_device *rtc, struct rtc_wkalrm *alarm)
	int err;
	struct rtc_time before, now;
	int first_time = 1;
	unsigned long t_now, t_alm;
	time64_t t_now, t_alm;
	enum { none, day, month, year } missing = none;
	unsigned days;

@@ -258,8 +256,8 @@ int __rtc_read_alarm(struct rtc_device *rtc, struct rtc_wkalrm *alarm)
	}

	/* with luck, no rollover is needed */
	rtc_tm_to_time(&now, &t_now);
	rtc_tm_to_time(&alarm->time, &t_alm);
	t_now = rtc_tm_to_time64(&now);
	t_alm = rtc_tm_to_time64(&alarm->time);
	if (t_now < t_alm)
		goto done;

@@ -273,7 +271,7 @@ int __rtc_read_alarm(struct rtc_device *rtc, struct rtc_wkalrm *alarm)
	case day:
		dev_dbg(&rtc->dev, "alarm rollover: %s\n", "day");
		t_alm += 24 * 60 * 60;
		rtc_time_to_tm(t_alm, &alarm->time);
		rtc_time64_to_tm(t_alm, &alarm->time);
		break;

	/* Month rollover ... if it's the 31th, an alarm on the 3rd will
@@ -346,19 +344,19 @@ EXPORT_SYMBOL_GPL(rtc_read_alarm);
static int __rtc_set_alarm(struct rtc_device *rtc, struct rtc_wkalrm *alarm)
{
	struct rtc_time tm;
	long now, scheduled;
	time64_t now, scheduled;
	int err;

	err = rtc_valid_tm(&alarm->time);
	if (err)
		return err;
	rtc_tm_to_time(&alarm->time, &scheduled);
	scheduled = rtc_tm_to_time64(&alarm->time);

	/* Make sure we're not setting alarms in the past */
	err = __rtc_read_time(rtc, &tm);
	if (err)
		return err;
	rtc_tm_to_time(&tm, &now);
	now = rtc_tm_to_time64(&tm);
	if (scheduled <= now)
		return -ETIME;
	/*
+4 −4
Original line number Diff line number Diff line
@@ -304,12 +304,12 @@ static long rtc_dev_ioctl(struct file *file,
		 * Not supported here.
		 */
		{
			unsigned long now, then;
			time64_t now, then;

			err = rtc_read_time(rtc, &tm);
			if (err < 0)
				return err;
			rtc_tm_to_time(&tm, &now);
			now = rtc_tm_to_time64(&tm);

			alarm.time.tm_mday = tm.tm_mday;
			alarm.time.tm_mon = tm.tm_mon;
@@ -317,11 +317,11 @@ static long rtc_dev_ioctl(struct file *file,
			err  = rtc_valid_tm(&alarm.time);
			if (err < 0)
				return err;
			rtc_tm_to_time(&alarm.time, &then);
			then = rtc_tm_to_time64(&alarm.time);

			/* alarm may need to wrap into tomorrow */
			if (then < now) {
				rtc_time_to_tm(now + 24 * 60 * 60, &tm);
				rtc_time64_to_tm(now + 24 * 60 * 60, &tm);
				alarm.time.tm_mday = tm.tm_mday;
				alarm.time.tm_mon = tm.tm_mon;
				alarm.time.tm_year = tm.tm_year;
+3 −3
Original line number Diff line number Diff line
@@ -20,16 +20,16 @@
 *
 * If temporary failure is indicated the caller should try again 'soon'
 */
int rtc_set_ntp_time(struct timespec now)
int rtc_set_ntp_time(struct timespec64 now)
{
	struct rtc_device *rtc;
	struct rtc_time tm;
	int err = -ENODEV;

	if (now.tv_nsec < (NSEC_PER_SEC >> 1))
		rtc_time_to_tm(now.tv_sec, &tm);
		rtc_time64_to_tm(now.tv_sec, &tm);
	else
		rtc_time_to_tm(now.tv_sec + 1, &tm);
		rtc_time64_to_tm(now.tv_sec + 1, &tm);

	rtc = rtc_class_open(CONFIG_RTC_HCTOSYS_DEVICE);
	if (rtc) {
+2 −0
Original line number Diff line number Diff line
@@ -170,6 +170,7 @@ enum hrtimer_base_type {
 * @clock_was_set:	Indicates that clock was set from irq context.
 * @expires_next:	absolute time of the next event which was scheduled
 *			via clock_set_next_event()
 * @in_hrtirq:		hrtimer_interrupt() is currently executing
 * @hres_active:	State of high resolution mode
 * @hang_detected:	The last hrtimer interrupt detected a hang
 * @nr_events:		Total number of hrtimer interrupt events
@@ -185,6 +186,7 @@ struct hrtimer_cpu_base {
	unsigned int			clock_was_set;
#ifdef CONFIG_HIGH_RES_TIMERS
	ktime_t				expires_next;
	int				in_hrtirq;
	int				hres_active;
	int				hang_detected;
	unsigned long			nr_events;
Loading