mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: Ben Hutchings <ben@decadent.org.uk>
To: linux-kernel@vger.kernel.org, stable@vger.kernel.org
Cc: akpm@linux-foundation.org, "John Stultz" <john.stultz@linaro.org>,
	"Thomas Gleixner" <tglx@linutronix.de>,
	dhowells@redhat.com, linux-m68k@vger.kernel.org,
	"Peter Zijlstra" <peterz@infradead.org>
Subject: [PATCH 3.2 02/67] hrtimer: Handle remaining time proper for TIME_LOW_RES
Date: Tue, 23 Feb 2016 21:42:03 +0000	[thread overview]
Message-ID: <lsq.1456263723.362668490@decadent.org.uk> (raw)
In-Reply-To: <lsq.1456263722.390955919@decadent.org.uk>

3.2.78-rc1 review patch.  If anyone has any objections, please let me know.

------------------

From: Thomas Gleixner <tglx@linutronix.de>

commit 203cbf77de59fc8f13502dcfd11350c6d4a5c95f upstream.

If CONFIG_TIME_LOW_RES is enabled we add a jiffie to the relative timeout to
prevent short sleeps, but we do not account for that in interfaces which
retrieve the remaining time.

Helge observed that timerfd can return a remaining time larger than the
relative timeout. That's not expected and breaks userland test programs.

Store the information that the timer was armed relative and provide functions
to adjust the remaining time. To avoid bloating the hrtimer struct make state
a u8, which as a bonus results in better code on x86 at least.

Reported-and-tested-by: Helge Deller <deller@gmx.de>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: John Stultz <john.stultz@linaro.org>
Cc: linux-m68k@lists.linux-m68k.org
Cc: dhowells@redhat.com
Link: http://lkml.kernel.org/r/20160114164159.273328486@linutronix.de
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
[bwh: Backported to 3.2:
 - Use #ifdef instead of IS_ENABLED() as that doesn't work for config
   symbols that don't exist on the current architecture
 - Use KTIME_LOW_RES directly instead of hrtimer_resolution
 - Use ktime_sub() instead of modifying ktime::tv64 directly
 - Adjust filename, context]
Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
---
 include/linux/hrtimer.h  | 34 +++++++++++++++++++++++++++---
 kernel/hrtimer.c         | 55 ++++++++++++++++++++++++++++++++----------------
 kernel/time/timer_list.c |  2 +-
 3 files changed, 69 insertions(+), 22 deletions(-)

--- a/include/linux/hrtimer.h
+++ b/include/linux/hrtimer.h
@@ -96,6 +96,7 @@ enum hrtimer_restart {
  * @function:	timer expiry callback function
  * @base:	pointer to the timer base (per cpu and per clock)
  * @state:	state information (See bit values above)
+ * @is_rel:	Set if the timer was armed relative
  * @start_site:	timer statistics field to store the site where the timer
  *		was started
  * @start_comm: timer statistics field to store the name of the process which
@@ -110,7 +111,8 @@ struct hrtimer {
 	ktime_t				_softexpires;
 	enum hrtimer_restart		(*function)(struct hrtimer *);
 	struct hrtimer_clock_base	*base;
-	unsigned long			state;
+	u8				state;
+	u8				is_rel;
 #ifdef CONFIG_TIMER_STATS
 	int				start_pid;
 	void				*start_site;
@@ -315,6 +317,29 @@ static inline void clock_was_set_delayed
 
 #endif
 
+static inline ktime_t
+__hrtimer_expires_remaining_adjusted(const struct hrtimer *timer, ktime_t now)
+{
+	ktime_t rem = ktime_sub(timer->node.expires, now);
+
+	/*
+	 * Adjust relative timers for the extra we added in
+	 * hrtimer_start_range_ns() to prevent short timeouts.
+	 */
+#ifdef CONFIG_TIME_LOW_RES
+	if (timer->is_rel)
+		rem = ktime_sub(rem, KTIME_LOW_RES);
+#endif
+	return rem;
+}
+
+static inline ktime_t
+hrtimer_expires_remaining_adjusted(const struct hrtimer *timer)
+{
+	return __hrtimer_expires_remaining_adjusted(timer,
+						    timer->base->get_time());
+}
+
 extern void clock_was_set(void);
 #ifdef CONFIG_TIMERFD
 extern void timerfd_clock_was_set(void);
@@ -383,7 +408,12 @@ static inline int hrtimer_restart(struct
 }
 
 /* Query timers: */
-extern ktime_t hrtimer_get_remaining(const struct hrtimer *timer);
+extern ktime_t __hrtimer_get_remaining(const struct hrtimer *timer, bool adjust);
+
+static inline ktime_t hrtimer_get_remaining(const struct hrtimer *timer)
+{
+	return __hrtimer_get_remaining(timer, false);
+}
 extern int hrtimer_get_res(const clockid_t which_clock, struct timespec *tp);
 
 extern ktime_t hrtimer_get_next_event(void);
--- a/kernel/hrtimer.c
+++ b/kernel/hrtimer.c
@@ -910,7 +910,7 @@ static int enqueue_hrtimer(struct hrtime
  */
 static void __remove_hrtimer(struct hrtimer *timer,
 			     struct hrtimer_clock_base *base,
-			     unsigned long newstate, int reprogram)
+			     u8 newstate, int reprogram)
 {
 	struct timerqueue_node *next_timer;
 	if (!(timer->state & HRTIMER_STATE_ENQUEUED))
@@ -944,7 +944,7 @@ static inline int
 remove_hrtimer(struct hrtimer *timer, struct hrtimer_clock_base *base)
 {
 	if (hrtimer_is_queued(timer)) {
-		unsigned long state;
+		u8 state;
 		int reprogram;
 
 		/*
@@ -970,6 +970,22 @@ remove_hrtimer(struct hrtimer *timer, st
 	return 0;
 }
 
+static inline ktime_t hrtimer_update_lowres(struct hrtimer *timer, ktime_t tim,
+					    const enum hrtimer_mode mode)
+{
+#ifdef CONFIG_TIME_LOW_RES
+	/*
+	 * CONFIG_TIME_LOW_RES indicates that the system has no way to return
+	 * granular time values. For relative timers we add KTIME_LOW_RES
+	 * (i.e. one jiffie) to prevent short timeouts.
+	 */
+	timer->is_rel = mode & HRTIMER_MODE_REL;
+	if (timer->is_rel)
+		tim = ktime_add_safe(tim, KTIME_LOW_RES);
+#endif
+	return tim;
+}
+
 int __hrtimer_start_range_ns(struct hrtimer *timer, ktime_t tim,
 		unsigned long delta_ns, const enum hrtimer_mode mode,
 		int wakeup)
@@ -983,19 +999,10 @@ int __hrtimer_start_range_ns(struct hrti
 	/* Remove an active timer from the queue: */
 	ret = remove_hrtimer(timer, base);
 
-	if (mode & HRTIMER_MODE_REL) {
+	if (mode & HRTIMER_MODE_REL)
 		tim = ktime_add_safe(tim, base->get_time());
-		/*
-		 * CONFIG_TIME_LOW_RES is a temporary way for architectures
-		 * to signal that they simply return xtime in
-		 * do_gettimeoffset(). In this case we want to round up by
-		 * resolution when starting a relative timer, to avoid short
-		 * timeouts. This will go away with the GTOD framework.
-		 */
-#ifdef CONFIG_TIME_LOW_RES
-		tim = ktime_add_safe(tim, base->resolution);
-#endif
-	}
+
+	tim = hrtimer_update_lowres(timer, tim, mode);
 
 	hrtimer_set_expires_range_ns(timer, tim, delta_ns);
 
@@ -1120,19 +1127,25 @@ EXPORT_SYMBOL_GPL(hrtimer_cancel);
 /**
  * hrtimer_get_remaining - get remaining time for the timer
  * @timer:	the timer to read
+ * @adjust:	adjust relative timers when CONFIG_TIME_LOW_RES=y
  */
-ktime_t hrtimer_get_remaining(const struct hrtimer *timer)
+ktime_t __hrtimer_get_remaining(const struct hrtimer *timer, bool adjust)
 {
 	unsigned long flags;
 	ktime_t rem;
 
 	lock_hrtimer_base(timer, &flags);
-	rem = hrtimer_expires_remaining(timer);
+#ifdef CONFIG_TIME_LOW_RES
+	if (adjust)
+		rem = hrtimer_expires_remaining_adjusted(timer);
+	else
+#endif
+		rem = hrtimer_expires_remaining(timer);
 	unlock_hrtimer_base(timer, &flags);
 
 	return rem;
 }
-EXPORT_SYMBOL_GPL(hrtimer_get_remaining);
+EXPORT_SYMBOL_GPL(__hrtimer_get_remaining);
 
 #ifdef CONFIG_NO_HZ
 /**
@@ -1249,6 +1262,15 @@ static void __run_hrtimer(struct hrtimer
 	fn = timer->function;
 
 	/*
+	 * Clear the 'is relative' flag for the TIME_LOW_RES case. If the
+	 * timer is restarted with a period then it becomes an absolute
+	 * timer. If its not restarted it does not matter.
+	 */
+#ifdef CONFIG_TIME_LOW_RES
+	timer->is_rel = false;
+#endif
+
+	/*
 	 * Because we run timers from hardirq context, there is no chance
 	 * they get migrated to another cpu, therefore its safe to unlock
 	 * the timer base.
--- a/kernel/time/timer_list.c
+++ b/kernel/time/timer_list.c
@@ -57,7 +57,7 @@ print_timer(struct seq_file *m, struct h
 	print_name_offset(m, taddr);
 	SEQ_printf(m, ", ");
 	print_name_offset(m, timer->function);
-	SEQ_printf(m, ", S:%02lx", timer->state);
+	SEQ_printf(m, ", S:%02x", timer->state);
 #ifdef CONFIG_TIMER_STATS
 	SEQ_printf(m, ", ");
 	print_name_offset(m, timer->start_site);

  parent reply	other threads:[~2016-02-23 22:04 UTC|newest]

Thread overview: 74+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-02-23 21:42 [PATCH 3.2 00/67] 3.2.78-rc1 review Ben Hutchings
2016-02-23 21:42 ` [PATCH 3.2 11/67] USB: cp210x: add ID for IAI USB to RS485 adaptor Ben Hutchings
2016-02-23 21:42 ` [PATCH 3.2 43/67] [media] tda1004x: only update the frontend properties if locked Ben Hutchings
2016-02-23 21:42 ` [PATCH 3.2 01/67] KVM: vmx: fix MPX detection Ben Hutchings
2016-02-23 21:42 ` [PATCH 3.2 47/67] mm, vmstat: fix wrong WQ sleep when memory reclaim doesn't make any progress Ben Hutchings
2016-02-23 21:42 ` [PATCH 3.2 23/67] SCSI: fix crashes in sd and sr runtime PM Ben Hutchings
2016-02-23 21:42 ` [PATCH 3.2 19/67] libata: disable forced PORTS_IMPL for >= AHCI 1.3 Ben Hutchings
2016-02-23 21:42 ` [PATCH 3.2 59/67] ARM: 8519/1: ICST: try other dividends than 1 Ben Hutchings
2016-02-23 21:42 ` [PATCH 3.2 64/67] pipe: limit the per-user amount of pages allocated in pipes Ben Hutchings
2016-02-23 21:42 ` [PATCH 3.2 57/67] ALSA: timer: Fix race at concurrent reads Ben Hutchings
2016-02-23 21:42 ` [PATCH 3.2 56/67] ALSA: timer: Fix race between stop and interrupt Ben Hutchings
2016-02-23 21:42 ` [PATCH 3.2 58/67] ahci: Intel DNV device IDs SATA Ben Hutchings
2016-02-23 21:42 ` [PATCH 3.2 13/67] USB: serial: visor: fix crash on detecting device without write_urbs Ben Hutchings
2016-02-23 21:42 ` [PATCH 3.2 08/67] af_unix: fix struct pid memory leak Ben Hutchings
2016-02-23 22:07   ` Rainer Weikusat
2016-02-24 21:24     ` Ben Hutchings
2016-02-25  7:26       ` Willy Tarreau
2016-02-23 21:42 ` [PATCH 3.2 31/67] ALSA: seq: Fix race at closing in virmidi driver Ben Hutchings
2016-02-23 21:42 ` [PATCH 3.2 53/67] ALSA: timer: Fix wrong instance passed to slave callbacks Ben Hutchings
2016-02-23 21:42 ` [PATCH 3.2 25/67] crypto: shash - Fix has_key setting Ben Hutchings
2016-02-23 21:42 ` [PATCH 3.2 40/67] Revert "xhci: don't finish a TD if we get a short-transfer event mid TD" Ben Hutchings
2016-02-23 21:42 ` [PATCH 3.2 17/67] USB: serial: ftdi_sio: add support for Yaesu SCU-18 cable Ben Hutchings
2016-02-23 21:42 ` [PATCH 3.2 33/67] ALSA: pcm: Fix potential deadlock in OSS emulation Ben Hutchings
2016-02-23 21:42 ` [PATCH 3.2 54/67] ARM: 8517/1: ICST: avoid arithmetic overflow in icst_hz() Ben Hutchings
2016-02-23 21:42 ` [PATCH 3.2 20/67] virtio_pci: fix use after free on release Ben Hutchings
2016-02-23 21:42 ` [PATCH 3.2 14/67] USB: serial: option: Adding support for Telit LE922 Ben Hutchings
2016-02-23 21:42 ` [PATCH 3.2 16/67] ALSA: seq: Degrade the error message for too many opens Ben Hutchings
2016-02-23 21:42 ` [PATCH 3.2 52/67] ALSA: dummy: Implement timer backend switching more safely Ben Hutchings
2016-02-23 21:42 ` [PATCH 3.2 28/67] x86/mm/pat: Avoid truncation when converting cpa->numpages to address Ben Hutchings
2016-02-23 21:42 ` [PATCH 3.2 15/67] ALSA: seq: Fix incorrect sanity check at snd_seq_oss_synth_cleanup() Ben Hutchings
2016-02-23 21:42 ` Ben Hutchings [this message]
2016-02-23 21:42 ` [PATCH 3.2 22/67] perf annotate browser: Fix behaviour of Shift-Tab with nothing focussed Ben Hutchings
2016-02-23 21:42 ` [PATCH 3.2 45/67] [media] saa7134-alsa: Only frees registered sound cards Ben Hutchings
2016-02-23 21:42 ` [PATCH 3.2 35/67] ALSA: timer: Fix link corruption due to double start or stop Ben Hutchings
2016-02-23 21:42 ` [PATCH 3.2 39/67] ALSA: seq: Fix lockdep warnings due to double mutex locks Ben Hutchings
2016-02-23 21:42 ` [PATCH 3.2 03/67] timerfd: Handle relative timers with CONFIG_TIME_LOW_RES proper Ben Hutchings
2016-02-23 21:42 ` [PATCH 3.2 63/67] unix: correctly track in-flight fds in sending process user_struct Ben Hutchings
2016-02-23 21:42 ` [PATCH 3.2 24/67] tty: Fix unsafe ldisc reference via ioctl(TIOCGETD) Ben Hutchings
2016-02-23 21:42 ` [PATCH 3.2 36/67] libata: fix sff host state machine locking while polling Ben Hutchings
2016-02-23 21:42 ` [PATCH 3.2 48/67] ocfs2/dlm: clear refmap bit of recovery lock while doing local recovery cleanup Ben Hutchings
2016-02-23 21:42 ` [PATCH 3.2 66/67] pipe: Fix buffer offset after partially failed read Ben Hutchings
2016-02-23 21:42 ` [PATCH 3.2 49/67] crypto: user - lock crypto_alg_list on alg dump Ben Hutchings
2016-02-23 21:42 ` [PATCH 3.2 37/67] ALSA: rawmidi: Make snd_rawmidi_transmit() race-free Ben Hutchings
2016-02-23 21:42 ` [PATCH 3.2 51/67] klist: fix starting point removed bug in klist iterators Ben Hutchings
2016-02-23 21:42 ` [PATCH 3.2 12/67] USB: visor: fix null-deref at probe Ben Hutchings
2016-02-23 21:42 ` [PATCH 3.2 07/67] cdc-acm:exclude Samsung phone 04e8:685d Ben Hutchings
2016-02-23 21:42 ` [PATCH 3.2 04/67] posix-timers: Handle relative timers with CONFIG_TIME_LOW_RES proper Ben Hutchings
2016-02-23 21:42 ` [PATCH 3.2 30/67] intel_scu_ipcutil: underflow in scu_reg_access() Ben Hutchings
2016-02-23 21:42 ` [PATCH 3.2 61/67] ALSA: usb-audio: avoid freeing umidi object twice Ben Hutchings
2016-02-23 21:42 ` [PATCH 3.2 18/67] PCI/AER: Flush workqueue on device remove to avoid use-after-free Ben Hutchings
2016-02-23 21:42 ` [PATCH 3.2 32/67] ALSA: rawmidi: Remove kernel WARNING for NULL user-space buffer check Ben Hutchings
2016-02-23 21:42 ` [PATCH 3.2 21/67] rfkill: fix rfkill_fop_read wait_event usage Ben Hutchings
2016-02-23 21:42 ` [PATCH 3.2 55/67] sctp: translate network order to host order when users get a hmacid Ben Hutchings
2016-02-23 21:42 ` [PATCH 3.2 06/67] usb: cdc-acm: send zero packet for intel 7260 modem Ben Hutchings
2016-02-23 21:42 ` [PATCH 3.2 10/67] sctp: allow setting SCTP_SACK_IMMEDIATELY by the application Ben Hutchings
2016-02-23 21:42 ` [PATCH 3.2 67/67] sched: fix __sched_setscheduler() vs load balancing race Ben Hutchings
2016-02-23 21:42 ` [PATCH 3.2 27/67] drm/vmwgfx: respect 'nomodeset' Ben Hutchings
2016-02-23 21:42 ` [PATCH 3.2 09/67] pptp: fix illegal memory access caused by multiple bind()s Ben Hutchings
2016-02-23 21:42 ` [PATCH 3.2 26/67] ALSA: dummy: Disable switching timer backend via sysfs Ben Hutchings
2016-02-23 21:42 ` [PATCH 3.2 46/67] scsi_dh_rdac: always retry MODE SELECT on command lock violation Ben Hutchings
2016-02-23 21:42 ` [PATCH 3.2 60/67] btrfs: properly set the termination value of ctx->pos in readdir Ben Hutchings
2016-02-23 21:42 ` [PATCH 3.2 50/67] crypto: algif_skcipher - Do not dereference ctx without socket lock Ben Hutchings
2016-02-23 21:42 ` [PATCH 3.2 41/67] usb: xhci: apply XHCI_PME_STUCK_QUIRK to Intel Broxton-M platforms Ben Hutchings
2016-02-23 21:42 ` [PATCH 3.2 44/67] ALSA: timer: Fix leftover link at closing Ben Hutchings
2016-02-23 21:42 ` [PATCH 3.2 38/67] ALSA: rawmidi: Fix race at copying & updating the position Ben Hutchings
2016-02-23 21:42 ` [PATCH 3.2 65/67] iw_cxgb3: Fix incorrectly returning error on success Ben Hutchings
2016-02-23 21:42 ` [PATCH 3.2 34/67] ALSA: seq: Fix yet another races among ALSA timer accesses Ben Hutchings
2016-02-23 21:42 ` [PATCH 3.2 42/67] xhci: Fix list corruption in urb dequeue at host removal Ben Hutchings
2016-02-23 21:42 ` [PATCH 3.2 29/67] crypto: algif_hash - wait for crypto_ahash_init() to complete Ben Hutchings
2016-02-23 21:42 ` [PATCH 3.2 62/67] unix: properly account for FDs passed over unix sockets Ben Hutchings
2016-02-23 21:42 ` [PATCH 3.2 05/67] itimers: Handle relative timers with CONFIG_TIME_LOW_RES proper Ben Hutchings
2016-02-24  0:48 ` [PATCH 3.2 00/67] 3.2.78-rc1 review Ben Hutchings
2016-02-24  2:48 ` Guenter Roeck
2016-02-24 14:41   ` Ben Hutchings

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=lsq.1456263723.362668490@decadent.org.uk \
    --to=ben@decadent.org.uk \
    --cc=akpm@linux-foundation.org \
    --cc=dhowells@redhat.com \
    --cc=john.stultz@linaro.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-m68k@vger.kernel.org \
    --cc=peterz@infradead.org \
    --cc=stable@vger.kernel.org \
    --cc=tglx@linutronix.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®