All of lore.kernel.org
 help / color / mirror / Atom feed
* [patch 00/26] alarmtimers/posixtimers: Bug fixes and spec conformity changes
@ 2017-05-30 21:15 Thomas Gleixner
  2017-05-30 21:15 ` [patch 01/26] alarmtimer: Prevent overflow of relative timers Thomas Gleixner
                   ` (25 more replies)
  0 siblings, 26 replies; 66+ messages in thread
From: Thomas Gleixner @ 2017-05-30 21:15 UTC (permalink / raw)
  To: LKML; +Cc: John Stultz, Peter Zijlstra, Ingo Molnar

The syzkaller folks reported an RCU stall while fuzzing the posix timer
interface with CLOCK_ALARMTIMER_*.

While fixing this issue, I noticed that the posix timer implementation of
alarm timers lacks quite some of the features of the regular hrtimer based
posix timers.

That makes alarm timer bases posix timer not conform to the spec and also
the unconditional self rearming of those timer is suboptimal.

Instead of copying the posix timer hrtimer based mechanism over to alarm
timers with the risk of getting out of sync sooner than later, I decided to
add a few callbacks to the kclock struct which describes the different
posix timer clocks, so the existing and proven to be correct implementation
can be reused and we have only one implementation to maintain, aside of the
special magic which handles the CPU/PROCESS/THREAD clock ids.

Patch 1/2 are the bugfixes addressing the reported problem (#1) and a
similar one (#2) which I detected in review.

Patch 3-8 are cleanups which I put in front of the actual rework, including
the removal of unused and prone to be implemnted wrong posix timer
callbacks for the dynamic posix clocks.

Patch 9-20 prepare the code in posix-timer.c for sharing and reuse and the
remaining patches 21-26 switch the alarm timers over.

Passes LTP and GLIBC tests and a few other test cases I have around.

Thanks,

	tglx
---
 b/kernel/time/posix-timers.h   |   13 +
 include/asm-generic/siginfo.h  |    2 
 include/linux/posix-clock.h    |   22 --
 include/linux/posix-timers.h   |  117 ++++++-----
 kernel/signal.c                |    2 
 kernel/time/alarmtimer.c       |  200 +++++++++-----------
 kernel/time/posix-clock.c      |  115 -----------
 kernel/time/posix-cpu-timers.c |   36 +--
 kernel/time/posix-timers.c     |  410 ++++++++++++++++++++++-------------------
 9 files changed, 429 insertions(+), 488 deletions(-)

^ permalink raw reply	[flat|nested] 66+ messages in thread

* [patch 01/26] alarmtimer: Prevent overflow of relative timers
  2017-05-30 21:15 [patch 00/26] alarmtimers/posixtimers: Bug fixes and spec conformity changes Thomas Gleixner
@ 2017-05-30 21:15 ` Thomas Gleixner
  2017-06-04 13:21   ` [tip:timers/urgent] " tip-bot for Thomas Gleixner
  2017-06-04 13:24   ` tip-bot for Thomas Gleixner
  2017-05-30 21:15 ` [patch 02/26] alarmtimer: Rate limit periodic intervals Thomas Gleixner
                   ` (24 subsequent siblings)
  25 siblings, 2 replies; 66+ messages in thread
From: Thomas Gleixner @ 2017-05-30 21:15 UTC (permalink / raw)
  To: LKML
  Cc: John Stultz, Peter Zijlstra, Ingo Molnar, Andrey Konovalov,
	Dmitry Vyukov, Kostya Serebryany, syzkaller

[-- Attachment #1: alarmtimer--Prevent-overflow-of-relative-timers.patch --]
[-- Type: text/plain, Size: 1721 bytes --]

Andrey reported a alartimer related RCU stall while fuzzing the kernel with
syzkaller.

The reason for this is an overflow in ktime_add() which brings the
resulting time into negative space and causes immediate expiry of the
timer. The following rearm with a small interval does not bring the timer
back into positive space due to the same issue.

This results in a permanent firing alarmtimer which hogs the CPU.

Use ktime_add_safe() instead which detects the overflow and clamps the
result to KTIME_SEC_MAX.

Reported-by: Andrey Konovalov <andreyknvl@google.com>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Cc: Dmitry Vyukov <dvyukov@google.com>
Cc: Kostya Serebryany <kcc@google.com>
Cc: syzkaller <syzkaller@googlegroups.com>
---
 kernel/time/alarmtimer.c |    6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

--- a/kernel/time/alarmtimer.c
+++ b/kernel/time/alarmtimer.c
@@ -357,7 +357,7 @@ void alarm_start_relative(struct alarm *
 {
 	struct alarm_base *base = &alarm_bases[alarm->type];
 
-	start = ktime_add(start, base->gettime());
+	start = ktime_add_safe(start, base->gettime());
 	alarm_start(alarm, start);
 }
 EXPORT_SYMBOL_GPL(alarm_start_relative);
@@ -445,7 +445,7 @@ u64 alarm_forward(struct alarm *alarm, k
 		overrun++;
 	}
 
-	alarm->node.expires = ktime_add(alarm->node.expires, interval);
+	alarm->node.expires = ktime_add_safe(alarm->node.expires, interval);
 	return overrun;
 }
 EXPORT_SYMBOL_GPL(alarm_forward);
@@ -668,7 +668,7 @@ static int alarm_timer_set(struct k_itim
 		ktime_t now;
 
 		now = alarm_bases[timr->it.alarm.alarmtimer.type].gettime();
-		exp = ktime_add(now, exp);
+		exp = ktime_add_safe(now, exp);
 	}
 
 	alarm_start(&timr->it.alarm.alarmtimer, exp);

^ permalink raw reply	[flat|nested] 66+ messages in thread

* [patch 02/26] alarmtimer: Rate limit periodic intervals
  2017-05-30 21:15 [patch 00/26] alarmtimers/posixtimers: Bug fixes and spec conformity changes Thomas Gleixner
  2017-05-30 21:15 ` [patch 01/26] alarmtimer: Prevent overflow of relative timers Thomas Gleixner
@ 2017-05-30 21:15 ` Thomas Gleixner
  2017-06-04 13:22   ` [tip:timers/urgent] " tip-bot for Thomas Gleixner
  2017-06-04 13:25   ` tip-bot for Thomas Gleixner
  2017-05-30 21:15 ` [patch 03/26] alarmtimer: Remove pointless config conditional Thomas Gleixner
                   ` (23 subsequent siblings)
  25 siblings, 2 replies; 66+ messages in thread
From: Thomas Gleixner @ 2017-05-30 21:15 UTC (permalink / raw)
  To: LKML
  Cc: John Stultz, Peter Zijlstra, Ingo Molnar, Dmitry Vyukov,
	Kostya Serebryany, syzkaller

[-- Attachment #1: alarmtimer--Rate-limit-intervals.patch --]
[-- Type: text/plain, Size: 1747 bytes --]

The alarmtimer code has another source of potentially rearming itself too
fast. Interval timers with a very samll interval have a similar CPU hog
effect as the previously fixed overflow issue.

The reason is that alarmtimers do not implement the normal protection
against this kind of problem which the other posix timer use:

  timer expires -> queue signal -> deliver signal -> rearm timer

This scheme brings the rearming under scheduler control and prevents
permanently firing timers which hog the CPU.

Bringing this scheme to the alarm timer code is a major overhaul because it
lacks all the necessary mechanisms completely.

So for a quick fix limit the interval to one jiffie. This is not
problematic in practice as alarmtimers are usually backed by an RTC for
suspend which have 1 second resolution. It could be therefor argued that
the resolution of this clock should be set to 1 second in general, but
that's outside the scope of this fix.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Cc: Dmitry Vyukov <dvyukov@google.com>
Cc: Kostya Serebryany <kcc@google.com>
Cc: syzkaller <syzkaller@googlegroups.com>
---
 kernel/time/alarmtimer.c |    8 ++++++++
 1 file changed, 8 insertions(+)

--- a/kernel/time/alarmtimer.c
+++ b/kernel/time/alarmtimer.c
@@ -662,6 +662,14 @@ static int alarm_timer_set(struct k_itim
 
 	/* start the timer */
 	timr->it.alarm.interval = timespec64_to_ktime(new_setting->it_interval);
+
+	/*
+	 * Rate limit to the tick as a hot fix to prevent DOS. Will be
+	 * mopped up later.
+	 */
+	if (timr->it.alarm.interval < TICK_NSEC)
+		timr->it.alarm.interval = TICK_NSEC;
+
 	exp = timespec64_to_ktime(new_setting->it_value);
 	/* Convert (if necessary) to absolute time */
 	if (flags != TIMER_ABSTIME) {

^ permalink raw reply	[flat|nested] 66+ messages in thread

* [patch 03/26] alarmtimer: Remove pointless config conditional
  2017-05-30 21:15 [patch 00/26] alarmtimers/posixtimers: Bug fixes and spec conformity changes Thomas Gleixner
  2017-05-30 21:15 ` [patch 01/26] alarmtimer: Prevent overflow of relative timers Thomas Gleixner
  2017-05-30 21:15 ` [patch 02/26] alarmtimer: Rate limit periodic intervals Thomas Gleixner
@ 2017-05-30 21:15 ` Thomas Gleixner
  2017-06-05  8:13   ` [tip:timers/core] " tip-bot for Thomas Gleixner
  2017-05-30 21:15 ` [patch 04/26] posix-timers: Remove unused export of posix_timer_event() Thomas Gleixner
                   ` (22 subsequent siblings)
  25 siblings, 1 reply; 66+ messages in thread
From: Thomas Gleixner @ 2017-05-30 21:15 UTC (permalink / raw)
  To: LKML; +Cc: John Stultz, Peter Zijlstra, Ingo Molnar

[-- Attachment #1: alarmtimer--Remove-pointless-config-conditional.patch --]
[-- Type: text/plain, Size: 622 bytes --]

Having a IF_ENABLED(CONFIG_POSIX_TIMERS) inside of a
#ifdef CONFIG_POSIX_TIMERS section is pointless.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
 kernel/time/alarmtimer.c |    3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

--- a/kernel/time/alarmtimer.c
+++ b/kernel/time/alarmtimer.c
@@ -520,8 +520,7 @@ static enum alarmtimer_restart alarm_han
 
 	spin_lock_irqsave(&ptr->it_lock, flags);
 	if ((ptr->it_sigev_notify & ~SIGEV_THREAD_ID) != SIGEV_NONE) {
-		if (IS_ENABLED(CONFIG_POSIX_TIMERS) &&
-		    posix_timer_event(ptr, 0) != 0)
+		if (posix_timer_event(ptr, 0))
 			ptr->it_overrun++;
 	}
 

^ permalink raw reply	[flat|nested] 66+ messages in thread

* [patch 04/26] posix-timers: Remove unused export of posix_timer_event()
  2017-05-30 21:15 [patch 00/26] alarmtimers/posixtimers: Bug fixes and spec conformity changes Thomas Gleixner
                   ` (2 preceding siblings ...)
  2017-05-30 21:15 ` [patch 03/26] alarmtimer: Remove pointless config conditional Thomas Gleixner
@ 2017-05-30 21:15 ` Thomas Gleixner
  2017-06-05  8:13   ` [tip:timers/core] " tip-bot for Thomas Gleixner
  2017-05-30 21:15 ` [patch 05/26] posix-clocks: Remove interval timer facility and mmap/fasync callbacks Thomas Gleixner
                   ` (21 subsequent siblings)
  25 siblings, 1 reply; 66+ messages in thread
From: Thomas Gleixner @ 2017-05-30 21:15 UTC (permalink / raw)
  To: LKML; +Cc: John Stultz, Peter Zijlstra, Ingo Molnar

[-- Attachment #1: posix-timers--Remove-unused-export-of-posix_timer_event--.patch --]
[-- Type: text/plain, Size: 523 bytes --]

Since the removal of the mmtimer driver the export is not longer needed.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
 kernel/time/posix-timers.c |    1 -
 1 file changed, 1 deletion(-)

--- a/kernel/time/posix-timers.c
+++ b/kernel/time/posix-timers.c
@@ -442,7 +442,6 @@ int posix_timer_event(struct k_itimer *t
 	/* If we failed to send the signal the timer stops. */
 	return ret > 0;
 }
-EXPORT_SYMBOL_GPL(posix_timer_event);
 
 /*
  * This function gets called when a POSIX.1b interval timer expires.  It

^ permalink raw reply	[flat|nested] 66+ messages in thread

* [patch 05/26] posix-clocks: Remove interval timer facility and mmap/fasync callbacks
  2017-05-30 21:15 [patch 00/26] alarmtimers/posixtimers: Bug fixes and spec conformity changes Thomas Gleixner
                   ` (3 preceding siblings ...)
  2017-05-30 21:15 ` [patch 04/26] posix-timers: Remove unused export of posix_timer_event() Thomas Gleixner
@ 2017-05-30 21:15 ` Thomas Gleixner
  2017-05-31  9:00   ` Richard Cochran
  2017-06-05  8:14   ` [tip:timers/core] " tip-bot for Thomas Gleixner
  2017-05-30 21:15 ` [patch 06/26] posix-timers: Avoid gazillions of forward declarations Thomas Gleixner
                   ` (20 subsequent siblings)
  25 siblings, 2 replies; 66+ messages in thread
From: Thomas Gleixner @ 2017-05-30 21:15 UTC (permalink / raw)
  To: LKML; +Cc: John Stultz, Peter Zijlstra, Ingo Molnar

[-- Attachment #1: posix-clocks--Remove-interval-timer-facility.patch --]
[-- Type: text/plain, Size: 5436 bytes --]

The only user of this facility is ptp_clock, which does not implement any of
those functions.

Remove them to prevent accidental users. Especially the interval timer
interfaces are now more or less impossible to implement because the
necessary infrastructure has been confined to the core code. Aside of that
it's really complex to make these callbacks implemented according to spec
as the alarm timer implementation demonstrates. If at all then a nanosleep
callback might be a reasonable extension. For now keep just what ptp_clock
needs.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
 include/linux/posix-clock.h |   22 --------
 kernel/time/posix-clock.c   |  113 --------------------------------------------
 2 files changed, 135 deletions(-)

--- a/include/linux/posix-clock.h
+++ b/include/linux/posix-clock.h
@@ -42,12 +42,6 @@ struct posix_clock;
  * @clock_gettime:  Read the current time
  * @clock_getres:   Get the clock resolution
  * @clock_settime:  Set the current time value
- * @timer_create:   Create a new timer
- * @timer_delete:   Remove a previously created timer
- * @timer_gettime:  Get remaining time and interval of a timer
- * @timer_settime: Set a timer's initial expiration and interval
- * @fasync:         Optional character device fasync method
- * @mmap:           Optional character device mmap method
  * @open:           Optional character device open method
  * @release:        Optional character device release method
  * @ioctl:          Optional character device ioctl method
@@ -66,28 +60,12 @@ struct posix_clock_operations {
 	int  (*clock_settime)(struct posix_clock *pc,
 			      const struct timespec64 *ts);
 
-	int  (*timer_create) (struct posix_clock *pc, struct k_itimer *kit);
-
-	int  (*timer_delete) (struct posix_clock *pc, struct k_itimer *kit);
-
-	void (*timer_gettime)(struct posix_clock *pc,
-			      struct k_itimer *kit, struct itimerspec64 *tsp);
-
-	int  (*timer_settime)(struct posix_clock *pc,
-			      struct k_itimer *kit, int flags,
-			      struct itimerspec64 *tsp, struct itimerspec64 *old);
 	/*
 	 * Optional character device methods:
 	 */
-	int     (*fasync)  (struct posix_clock *pc,
-			    int fd, struct file *file, int on);
-
 	long    (*ioctl)   (struct posix_clock *pc,
 			    unsigned int cmd, unsigned long arg);
 
-	int     (*mmap)    (struct posix_clock *pc,
-			    struct vm_area_struct *vma);
-
 	int     (*open)    (struct posix_clock *pc, fmode_t f_mode);
 
 	uint    (*poll)    (struct posix_clock *pc,
--- a/kernel/time/posix-clock.c
+++ b/kernel/time/posix-clock.c
@@ -82,38 +82,6 @@ static unsigned int posix_clock_poll(str
 	return result;
 }
 
-static int posix_clock_fasync(int fd, struct file *fp, int on)
-{
-	struct posix_clock *clk = get_posix_clock(fp);
-	int err = 0;
-
-	if (!clk)
-		return -ENODEV;
-
-	if (clk->ops.fasync)
-		err = clk->ops.fasync(clk, fd, fp, on);
-
-	put_posix_clock(clk);
-
-	return err;
-}
-
-static int posix_clock_mmap(struct file *fp, struct vm_area_struct *vma)
-{
-	struct posix_clock *clk = get_posix_clock(fp);
-	int err = -ENODEV;
-
-	if (!clk)
-		return -ENODEV;
-
-	if (clk->ops.mmap)
-		err = clk->ops.mmap(clk, vma);
-
-	put_posix_clock(clk);
-
-	return err;
-}
-
 static long posix_clock_ioctl(struct file *fp,
 			      unsigned int cmd, unsigned long arg)
 {
@@ -199,8 +167,6 @@ static const struct file_operations posi
 	.unlocked_ioctl	= posix_clock_ioctl,
 	.open		= posix_clock_open,
 	.release	= posix_clock_release,
-	.fasync		= posix_clock_fasync,
-	.mmap		= posix_clock_mmap,
 #ifdef CONFIG_COMPAT
 	.compat_ioctl	= posix_clock_compat_ioctl,
 #endif
@@ -359,88 +325,9 @@ static int pc_clock_settime(clockid_t id
 	return err;
 }
 
-static int pc_timer_create(struct k_itimer *kit)
-{
-	clockid_t id = kit->it_clock;
-	struct posix_clock_desc cd;
-	int err;
-
-	err = get_clock_desc(id, &cd);
-	if (err)
-		return err;
-
-	if (cd.clk->ops.timer_create)
-		err = cd.clk->ops.timer_create(cd.clk, kit);
-	else
-		err = -EOPNOTSUPP;
-
-	put_clock_desc(&cd);
-
-	return err;
-}
-
-static int pc_timer_delete(struct k_itimer *kit)
-{
-	clockid_t id = kit->it_clock;
-	struct posix_clock_desc cd;
-	int err;
-
-	err = get_clock_desc(id, &cd);
-	if (err)
-		return err;
-
-	if (cd.clk->ops.timer_delete)
-		err = cd.clk->ops.timer_delete(cd.clk, kit);
-	else
-		err = -EOPNOTSUPP;
-
-	put_clock_desc(&cd);
-
-	return err;
-}
-
-static void pc_timer_gettime(struct k_itimer *kit, struct itimerspec64 *ts)
-{
-	clockid_t id = kit->it_clock;
-	struct posix_clock_desc cd;
-
-	if (get_clock_desc(id, &cd))
-		return;
-
-	if (cd.clk->ops.timer_gettime)
-		cd.clk->ops.timer_gettime(cd.clk, kit, ts);
-
-	put_clock_desc(&cd);
-}
-
-static int pc_timer_settime(struct k_itimer *kit, int flags,
-			    struct itimerspec64 *ts, struct itimerspec64 *old)
-{
-	clockid_t id = kit->it_clock;
-	struct posix_clock_desc cd;
-	int err;
-
-	err = get_clock_desc(id, &cd);
-	if (err)
-		return err;
-
-	if (cd.clk->ops.timer_settime)
-		err = cd.clk->ops.timer_settime(cd.clk, kit, flags, ts, old);
-	else
-		err = -EOPNOTSUPP;
-
-	put_clock_desc(&cd);
-
-	return err;
-}
-
 const struct k_clock clock_posix_dynamic = {
 	.clock_getres	= pc_clock_getres,
 	.clock_set	= pc_clock_settime,
 	.clock_get	= pc_clock_gettime,
 	.clock_adj	= pc_clock_adjtime,
-	.timer_create	= pc_timer_create,
-	.timer_set	= pc_timer_settime,
-	.timer_del	= pc_timer_delete,
-	.timer_get	= pc_timer_gettime,
 };

^ permalink raw reply	[flat|nested] 66+ messages in thread

* [patch 06/26] posix-timers: Avoid gazillions of forward declarations
  2017-05-30 21:15 [patch 00/26] alarmtimers/posixtimers: Bug fixes and spec conformity changes Thomas Gleixner
                   ` (4 preceding siblings ...)
  2017-05-30 21:15 ` [patch 05/26] posix-clocks: Remove interval timer facility and mmap/fasync callbacks Thomas Gleixner
@ 2017-05-30 21:15 ` Thomas Gleixner
  2017-06-05  8:14   ` [tip:timers/core] " tip-bot for Thomas Gleixner
  2017-05-30 21:15 ` [patch 07/26] posix-timers: Cleanup struct k_itimer Thomas Gleixner
                   ` (19 subsequent siblings)
  25 siblings, 1 reply; 66+ messages in thread
From: Thomas Gleixner @ 2017-05-30 21:15 UTC (permalink / raw)
  To: LKML; +Cc: John Stultz, Peter Zijlstra, Ingo Molnar

[-- Attachment #1: posix-timers--Avoid-gazillions-of-forward-declarations.patch --]
[-- Type: text/plain, Size: 7574 bytes --]

Move it below the actual implementations as there are new callbacks coming
which would require even more forward declarations.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
 kernel/time/posix-timers.c |  190 +++++++++++++++++++++------------------------
 1 file changed, 89 insertions(+), 101 deletions(-)

--- a/kernel/time/posix-timers.c
+++ b/kernel/time/posix-timers.c
@@ -69,6 +69,9 @@ static struct kmem_cache *posix_timers_c
 static DEFINE_HASHTABLE(posix_timers_hashtable, 9);
 static DEFINE_SPINLOCK(hash_lock);
 
+static const struct k_clock * const posix_clocks[];
+static const struct k_clock *clockid_to_kclock(const clockid_t id);
+
 /*
  * we assume that the new SIGEV_THREAD_ID shares no bits with the other
  * SIGEV values.  Here we put out an error if this assumption fails.
@@ -124,20 +127,6 @@ static DEFINE_SPINLOCK(hash_lock);
  *	    have is CLOCK_REALTIME and its high res counter part, both of
  *	    which we beg off on and pass to do_sys_settimeofday().
  */
-
-/*
- * These ones are defined below.
- */
-static int common_nsleep(const clockid_t, int flags, struct timespec64 *t,
-			 struct timespec __user *rmtp);
-static int common_timer_create(struct k_itimer *new_timer);
-static void common_timer_get(struct k_itimer *, struct itimerspec64 *);
-static int common_timer_set(struct k_itimer *, int,
-			    struct itimerspec64 *, struct itimerspec64 *);
-static int common_timer_del(struct k_itimer *timer);
-
-static enum hrtimer_restart posix_timer_fn(struct hrtimer *data);
-
 static struct k_itimer *__lock_timer(timer_t timer_id, unsigned long *flags);
 
 #define lock_timer(tid, flags)						   \
@@ -278,82 +267,6 @@ static int posix_get_hrtimer_res(clockid
 	return 0;
 }
 
-
-static const struct k_clock clock_realtime = {
-	.clock_getres	= posix_get_hrtimer_res,
-	.clock_get	= posix_clock_realtime_get,
-	.clock_set	= posix_clock_realtime_set,
-	.clock_adj	= posix_clock_realtime_adj,
-	.nsleep		= common_nsleep,
-	.nsleep_restart	= hrtimer_nanosleep_restart,
-	.timer_create	= common_timer_create,
-	.timer_set	= common_timer_set,
-	.timer_get	= common_timer_get,
-	.timer_del	= common_timer_del,
-};
-
-static const struct k_clock clock_monotonic = {
-	.clock_getres	= posix_get_hrtimer_res,
-	.clock_get	= posix_ktime_get_ts,
-	.nsleep		= common_nsleep,
-	.nsleep_restart	= hrtimer_nanosleep_restart,
-	.timer_create	= common_timer_create,
-	.timer_set	= common_timer_set,
-	.timer_get	= common_timer_get,
-	.timer_del	= common_timer_del,
-};
-
-static const struct k_clock clock_monotonic_raw = {
-	.clock_getres	= posix_get_hrtimer_res,
-	.clock_get	= posix_get_monotonic_raw,
-};
-
-static const struct k_clock clock_realtime_coarse = {
-	.clock_getres	= posix_get_coarse_res,
-	.clock_get	= posix_get_realtime_coarse,
-};
-
-static const struct k_clock clock_monotonic_coarse = {
-	.clock_getres	= posix_get_coarse_res,
-	.clock_get	= posix_get_monotonic_coarse,
-};
-
-static const struct k_clock clock_tai = {
-	.clock_getres	= posix_get_hrtimer_res,
-	.clock_get	= posix_get_tai,
-	.nsleep		= common_nsleep,
-	.nsleep_restart	= hrtimer_nanosleep_restart,
-	.timer_create	= common_timer_create,
-	.timer_set	= common_timer_set,
-	.timer_get	= common_timer_get,
-	.timer_del	= common_timer_del,
-};
-
-static const struct k_clock clock_boottime = {
-	.clock_getres	= posix_get_hrtimer_res,
-	.clock_get	= posix_get_boottime,
-	.nsleep		= common_nsleep,
-	.nsleep_restart	= hrtimer_nanosleep_restart,
-	.timer_create	= common_timer_create,
-	.timer_set	= common_timer_set,
-	.timer_get	= common_timer_get,
-	.timer_del	= common_timer_del,
-};
-
-static const struct k_clock * const posix_clocks[] = {
-	[CLOCK_REALTIME]		= &clock_realtime,
-	[CLOCK_MONOTONIC]		= &clock_monotonic,
-	[CLOCK_PROCESS_CPUTIME_ID]	= &clock_process,
-	[CLOCK_THREAD_CPUTIME_ID]	= &clock_thread,
-	[CLOCK_MONOTONIC_RAW]		= &clock_monotonic_raw,
-	[CLOCK_REALTIME_COARSE]		= &clock_realtime_coarse,
-	[CLOCK_MONOTONIC_COARSE]	= &clock_monotonic_coarse,
-	[CLOCK_BOOTTIME]		= &clock_boottime,
-	[CLOCK_REALTIME_ALARM]		= &alarm_clock,
-	[CLOCK_BOOTTIME_ALARM]		= &alarm_clock,
-	[CLOCK_TAI]			= &clock_tai,
-};
-
 /*
  * Initialize everything, well, just everything in Posix clocks/timers ;)
  */
@@ -567,17 +480,6 @@ static void release_posix_timer(struct k
 	call_rcu(&tmr->it.rcu, k_itimer_rcu_free);
 }
 
-static const struct k_clock *clockid_to_kclock(const clockid_t id)
-{
-	if (id < 0)
-		return (id & CLOCKFD_MASK) == CLOCKFD ?
-			&clock_posix_dynamic : &clock_posix_cpu;
-
-	if (id >= ARRAY_SIZE(posix_clocks) || !posix_clocks[id])
-		return NULL;
-	return posix_clocks[id];
-}
-
 static int common_timer_create(struct k_itimer *new_timer)
 {
 	hrtimer_init(&new_timer->it.real.timer, new_timer->it_clock, 0);
@@ -1129,3 +1031,89 @@ long clock_nanosleep_restart(struct rest
 
 	return kc->nsleep_restart(restart_block);
 }
+
+static const struct k_clock clock_realtime = {
+	.clock_getres	= posix_get_hrtimer_res,
+	.clock_get	= posix_clock_realtime_get,
+	.clock_set	= posix_clock_realtime_set,
+	.clock_adj	= posix_clock_realtime_adj,
+	.nsleep		= common_nsleep,
+	.nsleep_restart	= hrtimer_nanosleep_restart,
+	.timer_create	= common_timer_create,
+	.timer_set	= common_timer_set,
+	.timer_get	= common_timer_get,
+	.timer_del	= common_timer_del,
+};
+
+static const struct k_clock clock_monotonic = {
+	.clock_getres	= posix_get_hrtimer_res,
+	.clock_get	= posix_ktime_get_ts,
+	.nsleep		= common_nsleep,
+	.nsleep_restart	= hrtimer_nanosleep_restart,
+	.timer_create	= common_timer_create,
+	.timer_set	= common_timer_set,
+	.timer_get	= common_timer_get,
+	.timer_del	= common_timer_del,
+};
+
+static const struct k_clock clock_monotonic_raw = {
+	.clock_getres	= posix_get_hrtimer_res,
+	.clock_get	= posix_get_monotonic_raw,
+};
+
+static const struct k_clock clock_realtime_coarse = {
+	.clock_getres	= posix_get_coarse_res,
+	.clock_get	= posix_get_realtime_coarse,
+};
+
+static const struct k_clock clock_monotonic_coarse = {
+	.clock_getres	= posix_get_coarse_res,
+	.clock_get	= posix_get_monotonic_coarse,
+};
+
+static const struct k_clock clock_tai = {
+	.clock_getres	= posix_get_hrtimer_res,
+	.clock_get	= posix_get_tai,
+	.nsleep		= common_nsleep,
+	.nsleep_restart	= hrtimer_nanosleep_restart,
+	.timer_create	= common_timer_create,
+	.timer_set	= common_timer_set,
+	.timer_get	= common_timer_get,
+	.timer_del	= common_timer_del,
+};
+
+static const struct k_clock clock_boottime = {
+	.clock_getres	= posix_get_hrtimer_res,
+	.clock_get	= posix_get_boottime,
+	.nsleep		= common_nsleep,
+	.nsleep_restart	= hrtimer_nanosleep_restart,
+	.timer_create	= common_timer_create,
+	.timer_set	= common_timer_set,
+	.timer_get	= common_timer_get,
+	.timer_del	= common_timer_del,
+};
+
+static const struct k_clock * const posix_clocks[] = {
+	[CLOCK_REALTIME]		= &clock_realtime,
+	[CLOCK_MONOTONIC]		= &clock_monotonic,
+	[CLOCK_PROCESS_CPUTIME_ID]	= &clock_process,
+	[CLOCK_THREAD_CPUTIME_ID]	= &clock_thread,
+	[CLOCK_MONOTONIC_RAW]		= &clock_monotonic_raw,
+	[CLOCK_REALTIME_COARSE]		= &clock_realtime_coarse,
+	[CLOCK_MONOTONIC_COARSE]	= &clock_monotonic_coarse,
+	[CLOCK_BOOTTIME]		= &clock_boottime,
+	[CLOCK_REALTIME_ALARM]		= &alarm_clock,
+	[CLOCK_BOOTTIME_ALARM]		= &alarm_clock,
+	[CLOCK_TAI]			= &clock_tai,
+};
+
+static const struct k_clock *clockid_to_kclock(const clockid_t id)
+{
+	if (id < 0)
+		return (id & CLOCKFD_MASK) == CLOCKFD ?
+			&clock_posix_dynamic : &clock_posix_cpu;
+
+	if (id >= ARRAY_SIZE(posix_clocks) || !posix_clocks[id])
+		return NULL;
+	return posix_clocks[id];
+}

^ permalink raw reply	[flat|nested] 66+ messages in thread

* [patch 07/26] posix-timers: Cleanup struct k_itimer
  2017-05-30 21:15 [patch 00/26] alarmtimers/posixtimers: Bug fixes and spec conformity changes Thomas Gleixner
                   ` (5 preceding siblings ...)
  2017-05-30 21:15 ` [patch 06/26] posix-timers: Avoid gazillions of forward declarations Thomas Gleixner
@ 2017-05-30 21:15 ` Thomas Gleixner
  2017-06-05  8:15   ` [tip:timers/core] " tip-bot for Thomas Gleixner
  2017-05-30 21:15 ` [patch 08/26] posix-timers: Move posix-timer internals to core Thomas Gleixner
                   ` (18 subsequent siblings)
  25 siblings, 1 reply; 66+ messages in thread
From: Thomas Gleixner @ 2017-05-30 21:15 UTC (permalink / raw)
  To: LKML; +Cc: John Stultz, Peter Zijlstra, Ingo Molnar

[-- Attachment #1: posix-timers--Cleanup-struct-k_itimer.patch --]
[-- Type: text/plain, Size: 2996 bytes --]

As a preparation for further changes, cleanup the formatting of the
k_itimer structure and add kernel doc comments.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
 include/linux/posix-timers.h |   61 ++++++++++++++++++++++++++++---------------
 1 file changed, 40 insertions(+), 21 deletions(-)

--- a/include/linux/posix-timers.h
+++ b/include/linux/posix-timers.h
@@ -48,35 +48,54 @@ struct cpu_timer_list {
 #define FD_TO_CLOCKID(fd)	((~(clockid_t) (fd) << 3) | CLOCKFD)
 #define CLOCKID_TO_FD(clk)	((unsigned int) ~((clk) >> 3))
 
-/* POSIX.1b interval timer structure. */
-struct k_itimer {
-	struct list_head list;		/* free/ allocate list */
-	struct hlist_node t_hash;
-	spinlock_t it_lock;
-	clockid_t it_clock;		/* which timer type */
-	timer_t it_id;			/* timer id */
-	int it_overrun;			/* overrun on pending signal  */
-	int it_overrun_last;		/* overrun on last delivered signal */
-	int it_requeue_pending;		/* waiting to requeue this timer */
 #define REQUEUE_PENDING 1
-	int it_sigev_notify;		/* notify word of sigevent struct */
-	struct signal_struct *it_signal;
+
+/**
+ * struct k_itimer - POSIX.1b interval timer structure.
+ * @list:		List head for binding the timer to signals->posix_timers
+ * @t_hash:		Entry in the posix timer hash table
+ * @it_lock:		Lock protecting the timer
+ * @it_clock:		The posix timer clock id
+ * @it_id:		The posix timer id for identifying the timer
+ * @it_overrun:		The overrun counter for pending signals
+ * @it_overrun_last:	The overrun at the time of the last delivered signal
+ * @it_requeue_pending:	Indicator that timer waits for being requeued on
+ *			signal delivery
+ * @it_sigev_notify:	The notify word of sigevent struct for signal delivery
+ * @it_signal:		Pointer to the creators signal struct
+ * @it_pid:		The pid of the process/task targeted by the signal
+ * @it_process:		The task to wakeup on clock_nanosleep (CPU timers)
+ * @sigq:		Pointer to preallocated sigqueue
+ * @it:			Union representing the various posix timer type
+ *			internals. Also used for rcu freeing the timer.
+ */
+struct k_itimer {
+	struct list_head	list;
+	struct hlist_node	t_hash;
+	spinlock_t		it_lock;
+	clockid_t		it_clock;
+	timer_t			it_id;
+	int			it_overrun;
+	int			it_overrun_last;
+	int			it_requeue_pending;
+	int			it_sigev_notify;
+	struct signal_struct	*it_signal;
 	union {
-		struct pid *it_pid;	/* pid of process to send signal to */
-		struct task_struct *it_process;	/* for clock_nanosleep */
+		struct pid		*it_pid;
+		struct task_struct	*it_process;
 	};
-	struct sigqueue *sigq;		/* signal queue entry. */
+	struct sigqueue		*sigq;
 	union {
 		struct {
-			struct hrtimer timer;
-			ktime_t interval;
+			struct hrtimer	timer;
+			ktime_t		interval;
 		} real;
-		struct cpu_timer_list cpu;
+		struct cpu_timer_list	cpu;
 		struct {
-			struct alarm alarmtimer;
-			ktime_t interval;
+			struct alarm	alarmtimer;
+			ktime_t		interval;
 		} alarm;
-		struct rcu_head rcu;
+		struct rcu_head		rcu;
 	} it;
 };
 

^ permalink raw reply	[flat|nested] 66+ messages in thread

* [patch 08/26] posix-timers: Move posix-timer internals to core
  2017-05-30 21:15 [patch 00/26] alarmtimers/posixtimers: Bug fixes and spec conformity changes Thomas Gleixner
                   ` (6 preceding siblings ...)
  2017-05-30 21:15 ` [patch 07/26] posix-timers: Cleanup struct k_itimer Thomas Gleixner
@ 2017-05-30 21:15 ` Thomas Gleixner
  2017-05-31 15:37   ` Christoph Hellwig
  2017-06-05  8:15   ` [tip:timers/core] " tip-bot for Thomas Gleixner
  2017-05-30 21:15 ` [patch 09/26] posix-timers: Unify overrun/requeue_pending handling Thomas Gleixner
                   ` (17 subsequent siblings)
  25 siblings, 2 replies; 66+ messages in thread
From: Thomas Gleixner @ 2017-05-30 21:15 UTC (permalink / raw)
  To: LKML; +Cc: John Stultz, Peter Zijlstra, Ingo Molnar

[-- Attachment #1: posix-timers--Move-posix-timer-internals-to-core.patch --]
[-- Type: text/plain, Size: 2640 bytes --]

None of these declarations is required outside of kernel/time. Move them to
an internal header.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
 include/linux/posix-timers.h   |   11 -----------
 kernel/time/alarmtimer.c       |    2 ++
 kernel/time/posix-clock.c      |    2 ++
 kernel/time/posix-cpu-timers.c |    2 ++
 kernel/time/posix-timers.c     |    1 +
 kernel/time/posix-timers.h     |    9 +++++++++
 6 files changed, 16 insertions(+), 11 deletions(-)

--- a/include/linux/posix-timers.h
+++ b/include/linux/posix-timers.h
@@ -118,17 +118,6 @@ struct k_clock {
 			   struct itimerspec64 *cur_setting);
 };
 
-extern const struct k_clock clock_posix_cpu;
-extern const struct k_clock clock_posix_dynamic;
-extern const struct k_clock clock_process;
-extern const struct k_clock clock_thread;
-extern const struct k_clock alarm_clock;
-
-/* function to call to trigger timer event */
-int posix_timer_event(struct k_itimer *timr, int si_private);
-
-void posix_cpu_timer_schedule(struct k_itimer *timer);
-
 void run_posix_cpu_timers(struct task_struct *task);
 void posix_cpu_timers_exit(struct task_struct *task);
 void posix_cpu_timers_exit_group(struct task_struct *task);
--- a/kernel/time/alarmtimer.c
+++ b/kernel/time/alarmtimer.c
@@ -28,6 +28,8 @@
 #include <linux/workqueue.h>
 #include <linux/freezer.h>
 
+#include "posix-timers.h"
+
 #define CREATE_TRACE_POINTS
 #include <trace/events/alarmtimer.h>
 
--- a/kernel/time/posix-clock.c
+++ b/kernel/time/posix-clock.c
@@ -25,6 +25,8 @@
 #include <linux/syscalls.h>
 #include <linux/uaccess.h>
 
+#include "posix-timers.h"
+
 static void delete_clock(struct kref *kref);
 
 /*
--- a/kernel/time/posix-cpu-timers.c
+++ b/kernel/time/posix-cpu-timers.c
@@ -13,6 +13,8 @@
 #include <linux/tick.h>
 #include <linux/workqueue.h>
 
+#include "posix-timers.h"
+
 /*
  * Called after updating RLIMIT_CPU to run cpu timer and update
  * tsk->signal->cputime_expires expiration cache if necessary. Needs
--- a/kernel/time/posix-timers.c
+++ b/kernel/time/posix-timers.c
@@ -51,6 +51,7 @@
 #include <linux/hashtable.h>
 
 #include "timekeeping.h"
+#include "posix-timers.h"
 
 /*
  * Management arrays for POSIX timers. Timers are now kept in static hash table
--- /dev/null
+++ b/kernel/time/posix-timers.h
@@ -0,0 +1,9 @@
+extern const struct k_clock clock_posix_cpu;
+extern const struct k_clock clock_posix_dynamic;
+extern const struct k_clock clock_process;
+extern const struct k_clock clock_thread;
+extern const struct k_clock alarm_clock;
+
+int posix_timer_event(struct k_itimer *timr, int si_private);
+
+void posix_cpu_timer_schedule(struct k_itimer *timer);

^ permalink raw reply	[flat|nested] 66+ messages in thread

* [patch 09/26] posix-timers: Unify overrun/requeue_pending handling
  2017-05-30 21:15 [patch 00/26] alarmtimers/posixtimers: Bug fixes and spec conformity changes Thomas Gleixner
                   ` (7 preceding siblings ...)
  2017-05-30 21:15 ` [patch 08/26] posix-timers: Move posix-timer internals to core Thomas Gleixner
@ 2017-05-30 21:15 ` Thomas Gleixner
  2017-06-05  8:16   ` [tip:timers/core] " tip-bot for Thomas Gleixner
  2017-05-30 21:15 ` [patch 10/26] posix-timers: Move interval out of the union Thomas Gleixner
                   ` (16 subsequent siblings)
  25 siblings, 1 reply; 66+ messages in thread
From: Thomas Gleixner @ 2017-05-30 21:15 UTC (permalink / raw)
  To: LKML; +Cc: John Stultz, Peter Zijlstra, Ingo Molnar

[-- Attachment #1: posix-timers--Unify-overrun-requeue_pending-handling.patch --]
[-- Type: text/plain, Size: 2963 bytes --]

hrtimer based posix-timers and posix-cpu-timers handle the update of the
rearming and overflow related status fields differently.

Move that update to the common rearming code.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
 kernel/time/posix-cpu-timers.c |   18 +++++++-----------
 kernel/time/posix-timers.c     |   15 ++++++++-------
 2 files changed, 15 insertions(+), 18 deletions(-)

--- a/kernel/time/posix-cpu-timers.c
+++ b/kernel/time/posix-cpu-timers.c
@@ -527,6 +527,7 @@ static void cpu_timer_fire(struct k_itim
 		 * ticking in case the signal is deliverable next time.
 		 */
 		posix_cpu_timer_schedule(timer);
+		++timer->it_requeue_pending;
 	}
 }
 
@@ -989,12 +990,12 @@ void posix_cpu_timer_schedule(struct k_i
 		cpu_clock_sample(timer->it_clock, p, &now);
 		bump_cpu_timer(timer, now);
 		if (unlikely(p->exit_state))
-			goto out;
+			return;
 
 		/* Protect timer list r/w in arm_timer() */
 		sighand = lock_task_sighand(p, &flags);
 		if (!sighand)
-			goto out;
+			return;
 	} else {
 		/*
 		 * Protect arm_timer() and timer sampling in case of call to
@@ -1007,11 +1008,10 @@ void posix_cpu_timer_schedule(struct k_i
 			 * We can't even collect a sample any more.
 			 */
 			timer->it.cpu.expires = 0;
-			goto out;
+			return;
 		} else if (unlikely(p->exit_state) && thread_group_empty(p)) {
-			unlock_task_sighand(p, &flags);
-			/* Optimizations: if the process is dying, no need to rearm */
-			goto out;
+			/* If the process is dying, no need to rearm */
+			goto unlock;
 		}
 		cpu_timer_sample_group(timer->it_clock, p, &now);
 		bump_cpu_timer(timer, now);
@@ -1023,12 +1023,8 @@ void posix_cpu_timer_schedule(struct k_i
 	 */
 	WARN_ON_ONCE(!irqs_disabled());
 	arm_timer(timer);
+unlock:
 	unlock_task_sighand(p, &flags);
-
-out:
-	timer->it_overrun_last = timer->it_overrun;
-	timer->it_overrun = -1;
-	++timer->it_requeue_pending;
 }
 
 /**
--- a/kernel/time/posix-timers.c
+++ b/kernel/time/posix-timers.c
@@ -291,10 +291,6 @@ static void schedule_next_timer(struct k
 	timr->it_overrun += (unsigned int) hrtimer_forward(timer,
 						timer->base->get_time(),
 						timr->it.real.interval);
-
-	timr->it_overrun_last = timr->it_overrun;
-	timr->it_overrun = -1;
-	++timr->it_requeue_pending;
 	hrtimer_restart(timer);
 }
 
@@ -315,18 +311,23 @@ void do_schedule_next_timer(struct sigin
 	unsigned long flags;
 
 	timr = lock_timer(info->si_tid, &flags);
+	if (!timr)
+		return;
 
-	if (timr && timr->it_requeue_pending == info->si_sys_private) {
+	if (timr->it_requeue_pending == info->si_sys_private) {
 		if (timr->it_clock < 0)
 			posix_cpu_timer_schedule(timr);
 		else
 			schedule_next_timer(timr);
 
+		timr->it_overrun_last = timr->it_overrun;
+		timr->it_overrun = -1;
+		++timr->it_requeue_pending;
+
 		info->si_overrun += timr->it_overrun_last;
 	}
 
-	if (timr)
-		unlock_timer(timr, flags);
+	unlock_timer(timr, flags);
 }
 
 int posix_timer_event(struct k_itimer *timr, int si_private)

^ permalink raw reply	[flat|nested] 66+ messages in thread

* [patch 10/26] posix-timers: Move interval out of the union
  2017-05-30 21:15 [patch 00/26] alarmtimers/posixtimers: Bug fixes and spec conformity changes Thomas Gleixner
                   ` (8 preceding siblings ...)
  2017-05-30 21:15 ` [patch 09/26] posix-timers: Unify overrun/requeue_pending handling Thomas Gleixner
@ 2017-05-30 21:15 ` Thomas Gleixner
  2017-06-05  8:17   ` [tip:timers/core] " tip-bot for Thomas Gleixner
  2017-05-30 21:15 ` [patch 11/26] posix-timers: Store k_clock pointer in k_itimer Thomas Gleixner
                   ` (15 subsequent siblings)
  25 siblings, 1 reply; 66+ messages in thread
From: Thomas Gleixner @ 2017-05-30 21:15 UTC (permalink / raw)
  To: LKML; +Cc: John Stultz, Peter Zijlstra, Ingo Molnar

[-- Attachment #1: posix-timers--Move-interval-out-of-the-union.patch --]
[-- Type: text/plain, Size: 5494 bytes --]

Preparatory patch to unify the alarm timer and hrtimer based posix interval
timer handling.

The interval is used as a criteria for rearming decisions so moving it out
of the clock specific data structures allows later unification.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
 include/linux/posix-timers.h |    4 ++--
 kernel/time/alarmtimer.c     |   13 ++++++-------
 kernel/time/posix-timers.c   |   20 ++++++++++----------
 3 files changed, 18 insertions(+), 19 deletions(-)

--- a/include/linux/posix-timers.h
+++ b/include/linux/posix-timers.h
@@ -62,6 +62,7 @@ struct cpu_timer_list {
  * @it_requeue_pending:	Indicator that timer waits for being requeued on
  *			signal delivery
  * @it_sigev_notify:	The notify word of sigevent struct for signal delivery
+ * @it_interval:	The interval for periodic timers
  * @it_signal:		Pointer to the creators signal struct
  * @it_pid:		The pid of the process/task targeted by the signal
  * @it_process:		The task to wakeup on clock_nanosleep (CPU timers)
@@ -79,6 +80,7 @@ struct k_itimer {
 	int			it_overrun_last;
 	int			it_requeue_pending;
 	int			it_sigev_notify;
+	ktime_t			it_interval;
 	struct signal_struct	*it_signal;
 	union {
 		struct pid		*it_pid;
@@ -88,12 +90,10 @@ struct k_itimer {
 	union {
 		struct {
 			struct hrtimer	timer;
-			ktime_t		interval;
 		} real;
 		struct cpu_timer_list	cpu;
 		struct {
 			struct alarm	alarmtimer;
-			ktime_t		interval;
 		} alarm;
 		struct rcu_head		rcu;
 	} it;
--- a/kernel/time/alarmtimer.c
+++ b/kernel/time/alarmtimer.c
@@ -527,9 +527,8 @@ static enum alarmtimer_restart alarm_han
 	}
 
 	/* Re-add periodic timers */
-	if (ptr->it.alarm.interval) {
-		ptr->it_overrun += alarm_forward(alarm, now,
-						ptr->it.alarm.interval);
+	if (ptr->it_interval) {
+		ptr->it_overrun += alarm_forward(alarm, now, ptr->it_interval);
 		result = ALARMTIMER_RESTART;
 	}
 	spin_unlock_irqrestore(&ptr->it_lock, flags);
@@ -613,7 +612,7 @@ static void alarm_timer_get(struct k_iti
 		cur_setting->it_value.tv_nsec = 0;
 	}
 
-	cur_setting->it_interval = ktime_to_timespec64(timr->it.alarm.interval);
+	cur_setting->it_interval = ktime_to_timespec64(timr->it_interval);
 }
 
 /**
@@ -662,14 +661,14 @@ static int alarm_timer_set(struct k_itim
 		return TIMER_RETRY;
 
 	/* start the timer */
-	timr->it.alarm.interval = timespec64_to_ktime(new_setting->it_interval);
+	timr->it_interval = timespec64_to_ktime(new_setting->it_interval);
 
 	/*
 	 * Rate limit to the tick as a hot fix to prevent DOS. Will be
 	 * mopped up later.
 	 */
-	if (timr->it.alarm.interval < TICK_NSEC)
-		timr->it.alarm.interval = TICK_NSEC;
+	if (timr->it_interval < TICK_NSEC)
+		timr->it_interval = TICK_NSEC;
 
 	exp = timespec64_to_ktime(new_setting->it_value);
 	/* Convert (if necessary) to absolute time */
--- a/kernel/time/posix-timers.c
+++ b/kernel/time/posix-timers.c
@@ -285,12 +285,12 @@ static void schedule_next_timer(struct k
 {
 	struct hrtimer *timer = &timr->it.real.timer;
 
-	if (timr->it.real.interval == 0)
+	if (!timr->it_interval)
 		return;
 
 	timr->it_overrun += (unsigned int) hrtimer_forward(timer,
 						timer->base->get_time(),
-						timr->it.real.interval);
+						timr->it_interval);
 	hrtimer_restart(timer);
 }
 
@@ -375,7 +375,7 @@ static enum hrtimer_restart posix_timer_
 	timr = container_of(timer, struct k_itimer, it.real.timer);
 	spin_lock_irqsave(&timr->it_lock, flags);
 
-	if (timr->it.real.interval != 0)
+	if (timr->it_interval != 0)
 		si_private = ++timr->it_requeue_pending;
 
 	if (posix_timer_event(timr, si_private)) {
@@ -384,7 +384,7 @@ static enum hrtimer_restart posix_timer_
 		 * we will not get a call back to restart it AND
 		 * it should be restarted.
 		 */
-		if (timr->it.real.interval != 0) {
+		if (timr->it_interval != 0) {
 			ktime_t now = hrtimer_cb_get_time(timer);
 
 			/*
@@ -413,13 +413,13 @@ static enum hrtimer_restart posix_timer_
 			{
 				ktime_t kj = NSEC_PER_SEC / HZ;
 
-				if (timr->it.real.interval < kj)
+				if (timr->it_interval < kj)
 					now = ktime_add(now, kj);
 			}
 #endif
 			timr->it_overrun += (unsigned int)
 				hrtimer_forward(timer, now,
-						timr->it.real.interval);
+						timr->it_interval);
 			ret = HRTIMER_RESTART;
 			++timr->it_requeue_pending;
 		}
@@ -631,7 +631,7 @@ common_timer_get(struct k_itimer *timr,
 
 	memset(cur_setting, 0, sizeof(*cur_setting));
 
-	iv = timr->it.real.interval;
+	iv = timr->it_interval;
 
 	/* interval timer ? */
 	if (iv)
@@ -732,7 +732,7 @@ common_timer_set(struct k_itimer *timr,
 		common_timer_get(timr, old_setting);
 
 	/* disable the timer */
-	timr->it.real.interval = 0;
+	timr->it_interval = 0;
 	/*
 	 * careful here.  If smp we could be in the "fire" routine which will
 	 * be spinning as we hold the lock.  But this is ONLY an SMP issue.
@@ -755,7 +755,7 @@ common_timer_set(struct k_itimer *timr,
 	hrtimer_set_expires(timer, timespec64_to_ktime(new_setting->it_value));
 
 	/* Convert interval */
-	timr->it.real.interval = timespec64_to_ktime(new_setting->it_interval);
+	timr->it_interval = timespec64_to_ktime(new_setting->it_interval);
 
 	/* SIGEV_NONE timers are not queued ! See common_timer_get */
 	if (((timr->it_sigev_notify & ~SIGEV_THREAD_ID) == SIGEV_NONE)) {
@@ -820,7 +820,7 @@ SYSCALL_DEFINE4(timer_settime, timer_t,
 
 static int common_timer_del(struct k_itimer *timer)
 {
-	timer->it.real.interval = 0;
+	timer->it_interval = 0;
 
 	if (hrtimer_try_to_cancel(&timer->it.real.timer) < 0)
 		return TIMER_RETRY;

^ permalink raw reply	[flat|nested] 66+ messages in thread

* [patch 11/26] posix-timers: Store k_clock pointer in k_itimer
  2017-05-30 21:15 [patch 00/26] alarmtimers/posixtimers: Bug fixes and spec conformity changes Thomas Gleixner
                   ` (9 preceding siblings ...)
  2017-05-30 21:15 ` [patch 10/26] posix-timers: Move interval out of the union Thomas Gleixner
@ 2017-05-30 21:15 ` Thomas Gleixner
  2017-06-05  8:17   ` [tip:timers/core] " tip-bot for Thomas Gleixner
  2017-05-30 21:15 ` [patch 12/26] posix-timers: Add timer_rearm() callback Thomas Gleixner
                   ` (14 subsequent siblings)
  25 siblings, 1 reply; 66+ messages in thread
From: Thomas Gleixner @ 2017-05-30 21:15 UTC (permalink / raw)
  To: LKML; +Cc: John Stultz, Peter Zijlstra, Ingo Molnar

[-- Attachment #1: posix-timers--Store-k_clock-pointer-in-k_itimer.patch --]
[-- Type: text/plain, Size: 2519 bytes --]

Having the k_clock pointer in the k_itimer struct avoids the lookup in
several code pathes and makes the next steps of unification of the hrtimer
and alarmtimer based posix timers simpler.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
 include/linux/posix-timers.h   |    2 ++
 kernel/time/posix-cpu-timers.c |    2 ++
 kernel/time/posix-timers.c     |    7 ++++---
 3 files changed, 8 insertions(+), 3 deletions(-)

--- a/include/linux/posix-timers.h
+++ b/include/linux/posix-timers.h
@@ -55,6 +55,7 @@ struct cpu_timer_list {
  * @list:		List head for binding the timer to signals->posix_timers
  * @t_hash:		Entry in the posix timer hash table
  * @it_lock:		Lock protecting the timer
+ * @kclock:		Pointer to the k_clock struct handling this timer
  * @it_clock:		The posix timer clock id
  * @it_id:		The posix timer id for identifying the timer
  * @it_overrun:		The overrun counter for pending signals
@@ -74,6 +75,7 @@ struct k_itimer {
 	struct list_head	list;
 	struct hlist_node	t_hash;
 	spinlock_t		it_lock;
+	const struct k_clock	*kclock;
 	clockid_t		it_clock;
 	timer_t			it_id;
 	int			it_overrun;
--- a/kernel/time/posix-cpu-timers.c
+++ b/kernel/time/posix-cpu-timers.c
@@ -324,6 +324,8 @@ static int posix_cpu_timer_create(struct
 	if (CPUCLOCK_WHICH(new_timer->it_clock) >= CPUCLOCK_MAX)
 		return -EINVAL;
 
+	new_timer->kclock = &clock_posix_cpu;
+
 	INIT_LIST_HEAD(&new_timer->it.cpu.entry);
 
 	rcu_read_lock();
--- a/kernel/time/posix-timers.c
+++ b/kernel/time/posix-timers.c
@@ -519,6 +519,7 @@ SYSCALL_DEFINE3(timer_create, const cloc
 	it_id_set = IT_ID_SET;
 	new_timer->it_id = (timer_t) new_timer_id;
 	new_timer->it_clock = which_clock;
+	new_timer->kclock = kc;
 	new_timer->it_overrun = -1;
 
 	if (timer_event_spec) {
@@ -679,7 +680,7 @@ SYSCALL_DEFINE2(timer_gettime, timer_t,
 	if (!timr)
 		return -EINVAL;
 
-	kc = clockid_to_kclock(timr->it_clock);
+	kc = timr->kclock;
 	if (WARN_ON_ONCE(!kc || !kc->timer_get))
 		ret = -EINVAL;
 	else
@@ -798,7 +799,7 @@ SYSCALL_DEFINE4(timer_settime, timer_t,
 	if (!timr)
 		return -EINVAL;
 
-	kc = clockid_to_kclock(timr->it_clock);
+	kc = timr->kclock;
 	if (WARN_ON_ONCE(!kc || !kc->timer_set))
 		error = -EINVAL;
 	else
@@ -829,7 +830,7 @@ static int common_timer_del(struct k_iti
 
 static inline int timer_delete_hook(struct k_itimer *timer)
 {
-	const struct k_clock *kc = clockid_to_kclock(timer->it_clock);
+	const struct k_clock *kc = timer->kclock;
 
 	if (WARN_ON_ONCE(!kc || !kc->timer_del))
 		return -EINVAL;

^ permalink raw reply	[flat|nested] 66+ messages in thread

* [patch 12/26] posix-timers: Add timer_rearm() callback
  2017-05-30 21:15 [patch 00/26] alarmtimers/posixtimers: Bug fixes and spec conformity changes Thomas Gleixner
                   ` (10 preceding siblings ...)
  2017-05-30 21:15 ` [patch 11/26] posix-timers: Store k_clock pointer in k_itimer Thomas Gleixner
@ 2017-05-30 21:15 ` Thomas Gleixner
  2017-06-05  8:18   ` [tip:timers/core] " tip-bot for Thomas Gleixner
  2017-05-30 21:15 ` [patch 13/26] posix-timers: Rename do_schedule_next_timer Thomas Gleixner
                   ` (13 subsequent siblings)
  25 siblings, 1 reply; 66+ messages in thread
From: Thomas Gleixner @ 2017-05-30 21:15 UTC (permalink / raw)
  To: LKML; +Cc: John Stultz, Peter Zijlstra, Ingo Molnar

[-- Attachment #1: posix-timers--Add-timer_rearm---callback.patch --]
[-- Type: text/plain, Size: 2218 bytes --]

Add a timer_rearm() callback which is used to make the rescheduling of
posix interval timers independent of the underlying clock implementation.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
 include/linux/posix-timers.h |   36 ++++++++++++++++++++----------------
 1 file changed, 20 insertions(+), 16 deletions(-)

--- a/include/linux/posix-timers.h
+++ b/include/linux/posix-timers.h
@@ -101,23 +101,27 @@ struct k_itimer {
 	} it;
 };
 
-struct k_clock {
-	int (*clock_getres) (const clockid_t which_clock, struct timespec64 *tp);
-	int (*clock_set) (const clockid_t which_clock,
-			  const struct timespec64 *tp);
-	int (*clock_get) (const clockid_t which_clock, struct timespec64 *tp);
-	int (*clock_adj) (const clockid_t which_clock, struct timex *tx);
-	int (*timer_create) (struct k_itimer *timer);
-	int (*nsleep) (const clockid_t which_clock, int flags,
-		       struct timespec64 *, struct timespec __user *);
-	long (*nsleep_restart) (struct restart_block *restart_block);
-	int (*timer_set) (struct k_itimer *timr, int flags,
-			  struct itimerspec64 *new_setting,
-			  struct itimerspec64 *old_setting);
-	int (*timer_del) (struct k_itimer *timr);
 #define TIMER_RETRY 1
-	void (*timer_get) (struct k_itimer *timr,
-			   struct itimerspec64 *cur_setting);
+
+struct k_clock {
+	int	(*clock_getres)(const clockid_t which_clock,
+				struct timespec64 *tp);
+	int	(*clock_set)(const clockid_t which_clock,
+			     const struct timespec64 *tp);
+	int	(*clock_get)(const clockid_t which_clock,
+			     struct timespec64 *tp);
+	int	(*clock_adj)(const clockid_t which_clock, struct timex *tx);
+	int	(*timer_create)(struct k_itimer *timer);
+	int	(*nsleep)(const clockid_t which_clock, int flags,
+			  struct timespec64 *, struct timespec __user *);
+	long	(*nsleep_restart)(struct restart_block *restart_block);
+	int	(*timer_set)(struct k_itimer *timr, int flags,
+			     struct itimerspec64 *new_setting,
+			     struct itimerspec64 *old_setting);
+	int	(*timer_del)(struct k_itimer *timr);
+	void	(*timer_get)(struct k_itimer *timr,
+			     struct itimerspec64 *cur_setting);
+	void	(*timer_rearm)(struct k_itimer *timr);
 };
 
 void run_posix_cpu_timers(struct task_struct *task);

^ permalink raw reply	[flat|nested] 66+ messages in thread

* [patch 13/26] posix-timers: Rename do_schedule_next_timer
  2017-05-30 21:15 [patch 00/26] alarmtimers/posixtimers: Bug fixes and spec conformity changes Thomas Gleixner
                   ` (11 preceding siblings ...)
  2017-05-30 21:15 ` [patch 12/26] posix-timers: Add timer_rearm() callback Thomas Gleixner
@ 2017-05-30 21:15 ` Thomas Gleixner
  2017-05-31 15:39   ` Christoph Hellwig
  2017-06-05  8:18   ` [tip:timers/core] " tip-bot for Thomas Gleixner
  2017-05-30 21:15 ` [patch 14/26] posix-timers: Use timer_rearm() callback in posixtimer_rearm() Thomas Gleixner
                   ` (12 subsequent siblings)
  25 siblings, 2 replies; 66+ messages in thread
From: Thomas Gleixner @ 2017-05-30 21:15 UTC (permalink / raw)
  To: LKML; +Cc: John Stultz, Peter Zijlstra, Ingo Molnar

[-- Attachment #1: posix-timers--Rename-do_schedule_next_timer.patch --]
[-- Type: text/plain, Size: 2977 bytes --]

That function is a misnomer. Rename it with a proper prefix to
posixtimer_rearm().

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
 include/asm-generic/siginfo.h  |    2 +-
 kernel/signal.c                |    2 +-
 kernel/time/posix-cpu-timers.c |    2 +-
 kernel/time/posix-timers.c     |   10 +++++-----
 4 files changed, 8 insertions(+), 8 deletions(-)

--- a/include/asm-generic/siginfo.h
+++ b/include/asm-generic/siginfo.h
@@ -15,7 +15,7 @@
 #define __SI_CODE(T,N)	((T) | ((N) & 0xffff))
 
 struct siginfo;
-void do_schedule_next_timer(struct siginfo *info);
+void posixtimer_rearm(struct siginfo *info);
 
 extern int copy_siginfo_to_user(struct siginfo __user *to, const struct siginfo *from);
 
--- a/kernel/signal.c
+++ b/kernel/signal.c
@@ -629,7 +629,7 @@ int dequeue_signal(struct task_struct *t
 		 * about to disable them again anyway.
 		 */
 		spin_unlock(&tsk->sighand->siglock);
-		do_schedule_next_timer(info);
+		posixtimer_rearm(info);
 		spin_lock(&tsk->sighand->siglock);
 	}
 #endif
--- a/kernel/time/posix-cpu-timers.c
+++ b/kernel/time/posix-cpu-timers.c
@@ -973,7 +973,7 @@ static void check_process_timers(struct
 }
 
 /*
- * This is called from the signal code (via do_schedule_next_timer)
+ * This is called from the signal code (via posixtimer_rearm)
  * when the last timer signal was delivered and we have to reload the timer.
  */
 void posix_cpu_timer_schedule(struct k_itimer *timer)
--- a/kernel/time/posix-timers.c
+++ b/kernel/time/posix-timers.c
@@ -305,7 +305,7 @@ static void schedule_next_timer(struct k
  * To protect against the timer going away while the interrupt is queued,
  * we require that the it_requeue_pending flag be set.
  */
-void do_schedule_next_timer(struct siginfo *info)
+void posixtimer_rearm(struct siginfo *info)
 {
 	struct k_itimer *timr;
 	unsigned long flags;
@@ -336,12 +336,12 @@ int posix_timer_event(struct k_itimer *t
 	int shared, ret = -1;
 	/*
 	 * FIXME: if ->sigq is queued we can race with
-	 * dequeue_signal()->do_schedule_next_timer().
+	 * dequeue_signal()->posixtimer_rearm().
 	 *
 	 * If dequeue_signal() sees the "right" value of
-	 * si_sys_private it calls do_schedule_next_timer().
+	 * si_sys_private it calls posixtimer_rearm().
 	 * We re-queue ->sigq and drop ->it_lock().
-	 * do_schedule_next_timer() locks the timer
+	 * posixtimer_rearm() locks the timer
 	 * and re-schedules it while ->sigq is pending.
 	 * Not really bad, but not that we want.
 	 */
@@ -701,7 +701,7 @@ SYSCALL_DEFINE2(timer_gettime, timer_t,
  * accumulating overruns on the next timer.  The overrun is frozen when
  * the signal is delivered, either at the notify time (if the info block
  * is not queued) or at the actual delivery time (as we are informed by
- * the call back to do_schedule_next_timer().  So all we need to do is
+ * the call back to posixtimer_rearm().  So all we need to do is
  * to pick up the frozen overrun.
  */
 SYSCALL_DEFINE1(timer_getoverrun, timer_t, timer_id)

^ permalink raw reply	[flat|nested] 66+ messages in thread

* [patch 14/26] posix-timers: Use timer_rearm() callback in posixtimer_rearm()
  2017-05-30 21:15 [patch 00/26] alarmtimers/posixtimers: Bug fixes and spec conformity changes Thomas Gleixner
                   ` (12 preceding siblings ...)
  2017-05-30 21:15 ` [patch 13/26] posix-timers: Rename do_schedule_next_timer Thomas Gleixner
@ 2017-05-30 21:15 ` Thomas Gleixner
  2017-06-05  8:19   ` [tip:timers/core] " tip-bot for Thomas Gleixner
  2017-05-30 21:15 ` [patch 15/26] posix-timers: Add active flag to k_itimer Thomas Gleixner
                   ` (11 subsequent siblings)
  25 siblings, 1 reply; 66+ messages in thread
From: Thomas Gleixner @ 2017-05-30 21:15 UTC (permalink / raw)
  To: LKML; +Cc: John Stultz, Peter Zijlstra, Ingo Molnar

[-- Attachment #1: posix-timers--Use-timer_rearm--callback-in-posixtimer_rearm.patch --]
[-- Type: text/plain, Size: 3692 bytes --]

Use the new timer_rearm() callback to replace the conditional hardcoded
calls into the hrtimer and cpu timer code.

This allows later to bring the same logic to alarmtimers.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
 kernel/time/posix-cpu-timers.c |    7 +++++--
 kernel/time/posix-timers.c     |   12 ++++++------
 kernel/time/posix-timers.h     |    2 --
 3 files changed, 11 insertions(+), 10 deletions(-)

--- a/kernel/time/posix-cpu-timers.c
+++ b/kernel/time/posix-cpu-timers.c
@@ -15,6 +15,8 @@
 
 #include "posix-timers.h"
 
+static void posix_cpu_timer_rearm(struct k_itimer *timer);
+
 /*
  * Called after updating RLIMIT_CPU to run cpu timer and update
  * tsk->signal->cputime_expires expiration cache if necessary. Needs
@@ -528,7 +530,7 @@ static void cpu_timer_fire(struct k_itim
 		 * reload the timer.  But we need to keep it
 		 * ticking in case the signal is deliverable next time.
 		 */
-		posix_cpu_timer_schedule(timer);
+		posix_cpu_timer_rearm(timer);
 		++timer->it_requeue_pending;
 	}
 }
@@ -976,7 +978,7 @@ static void check_process_timers(struct
  * This is called from the signal code (via posixtimer_rearm)
  * when the last timer signal was delivered and we have to reload the timer.
  */
-void posix_cpu_timer_schedule(struct k_itimer *timer)
+static void posix_cpu_timer_rearm(struct k_itimer *timer)
 {
 	struct sighand_struct *sighand;
 	unsigned long flags;
@@ -1423,6 +1425,7 @@ const struct k_clock clock_posix_cpu = {
 	.timer_set	= posix_cpu_timer_set,
 	.timer_del	= posix_cpu_timer_del,
 	.timer_get	= posix_cpu_timer_get,
+	.timer_rearm	= posix_cpu_timer_rearm,
 };
 
 const struct k_clock clock_process = {
--- a/kernel/time/posix-timers.c
+++ b/kernel/time/posix-timers.c
@@ -278,10 +278,9 @@ static __init int init_posix_timers(void
 					NULL);
 	return 0;
 }
-
 __initcall(init_posix_timers);
 
-static void schedule_next_timer(struct k_itimer *timr)
+static void common_hrtimer_rearm(struct k_itimer *timr)
 {
 	struct hrtimer *timer = &timr->it.real.timer;
 
@@ -315,10 +314,7 @@ void posixtimer_rearm(struct siginfo *in
 		return;
 
 	if (timr->it_requeue_pending == info->si_sys_private) {
-		if (timr->it_clock < 0)
-			posix_cpu_timer_schedule(timr);
-		else
-			schedule_next_timer(timr);
+		timr->kclock->timer_rearm(timr);
 
 		timr->it_overrun_last = timr->it_overrun;
 		timr->it_overrun = -1;
@@ -1046,6 +1042,7 @@ static const struct k_clock clock_realti
 	.timer_set	= common_timer_set,
 	.timer_get	= common_timer_get,
 	.timer_del	= common_timer_del,
+	.timer_rearm	= common_hrtimer_rearm,
 };
 
 static const struct k_clock clock_monotonic = {
@@ -1057,6 +1054,7 @@ static const struct k_clock clock_monoto
 	.timer_set	= common_timer_set,
 	.timer_get	= common_timer_get,
 	.timer_del	= common_timer_del,
+	.timer_rearm	= common_hrtimer_rearm,
 };
 
 static const struct k_clock clock_monotonic_raw = {
@@ -1083,6 +1081,7 @@ static const struct k_clock clock_tai =
 	.timer_set	= common_timer_set,
 	.timer_get	= common_timer_get,
 	.timer_del	= common_timer_del,
+	.timer_rearm	= common_hrtimer_rearm,
 };
 
 static const struct k_clock clock_boottime = {
@@ -1094,6 +1093,7 @@ static const struct k_clock clock_bootti
 	.timer_set	= common_timer_set,
 	.timer_get	= common_timer_get,
 	.timer_del	= common_timer_del,
+	.timer_rearm	= common_hrtimer_rearm,
 };
 
 static const struct k_clock * const posix_clocks[] = {
--- a/kernel/time/posix-timers.h
+++ b/kernel/time/posix-timers.h
@@ -5,5 +5,3 @@ extern const struct k_clock clock_thread
 extern const struct k_clock alarm_clock;
 
 int posix_timer_event(struct k_itimer *timr, int si_private);
-
-void posix_cpu_timer_schedule(struct k_itimer *timer);

^ permalink raw reply	[flat|nested] 66+ messages in thread

* [patch 15/26] posix-timers: Add active flag to k_itimer
  2017-05-30 21:15 [patch 00/26] alarmtimers/posixtimers: Bug fixes and spec conformity changes Thomas Gleixner
                   ` (13 preceding siblings ...)
  2017-05-30 21:15 ` [patch 14/26] posix-timers: Use timer_rearm() callback in posixtimer_rearm() Thomas Gleixner
@ 2017-05-30 21:15 ` Thomas Gleixner
  2017-06-05  8:20   ` [tip:timers/core] " tip-bot for Thomas Gleixner
  2017-05-30 21:15 ` [patch 16/26] posix-timers: Add forward/remaining callbacks Thomas Gleixner
                   ` (10 subsequent siblings)
  25 siblings, 1 reply; 66+ messages in thread
From: Thomas Gleixner @ 2017-05-30 21:15 UTC (permalink / raw)
  To: LKML; +Cc: John Stultz, Peter Zijlstra, Ingo Molnar

[-- Attachment #1: posix-timers--Add-active-flag-to-k_itimer.patch --]
[-- Type: text/plain, Size: 2552 bytes --]

Keep track of the activation state of posix timers. This is a preparatory
change for making common_timer_get() usable by both hrtimer and alarm timer
implementations.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
 include/linux/posix-timers.h |    2 ++
 kernel/time/posix-timers.c   |    8 +++++++-
 2 files changed, 9 insertions(+), 1 deletion(-)

--- a/include/linux/posix-timers.h
+++ b/include/linux/posix-timers.h
@@ -58,6 +58,7 @@ struct cpu_timer_list {
  * @kclock:		Pointer to the k_clock struct handling this timer
  * @it_clock:		The posix timer clock id
  * @it_id:		The posix timer id for identifying the timer
+ * @it_active:		Marker that timer is active
  * @it_overrun:		The overrun counter for pending signals
  * @it_overrun_last:	The overrun at the time of the last delivered signal
  * @it_requeue_pending:	Indicator that timer waits for being requeued on
@@ -78,6 +79,7 @@ struct k_itimer {
 	const struct k_clock	*kclock;
 	clockid_t		it_clock;
 	timer_t			it_id;
+	int			it_active;
 	int			it_overrun;
 	int			it_overrun_last;
 	int			it_requeue_pending;
--- a/kernel/time/posix-timers.c
+++ b/kernel/time/posix-timers.c
@@ -316,6 +316,7 @@ void posixtimer_rearm(struct siginfo *in
 	if (timr->it_requeue_pending == info->si_sys_private) {
 		timr->kclock->timer_rearm(timr);
 
+		timr->it_active = 1;
 		timr->it_overrun_last = timr->it_overrun;
 		timr->it_overrun = -1;
 		++timr->it_requeue_pending;
@@ -371,6 +372,7 @@ static enum hrtimer_restart posix_timer_
 	timr = container_of(timer, struct k_itimer, it.real.timer);
 	spin_lock_irqsave(&timr->it_lock, flags);
 
+	timr->it_active = 0;
 	if (timr->it_interval != 0)
 		si_private = ++timr->it_requeue_pending;
 
@@ -418,6 +420,7 @@ static enum hrtimer_restart posix_timer_
 						timr->it_interval);
 			ret = HRTIMER_RESTART;
 			++timr->it_requeue_pending;
+			timr->it_active = 1;
 		}
 	}
 
@@ -737,7 +740,8 @@ common_timer_set(struct k_itimer *timr,
 	if (hrtimer_try_to_cancel(timer) < 0)
 		return TIMER_RETRY;
 
-	timr->it_requeue_pending = (timr->it_requeue_pending + 2) & 
+	timr->it_active = 0;
+	timr->it_requeue_pending = (timr->it_requeue_pending + 2) &
 		~REQUEUE_PENDING;
 	timr->it_overrun_last = 0;
 
@@ -763,6 +767,7 @@ common_timer_set(struct k_itimer *timr,
 		return 0;
 	}
 
+	timr->it_active = 1;
 	hrtimer_start_expires(timer, mode);
 	return 0;
 }
@@ -821,6 +826,7 @@ static int common_timer_del(struct k_iti
 
 	if (hrtimer_try_to_cancel(&timer->it.real.timer) < 0)
 		return TIMER_RETRY;
+	timer->it_active = 0;
 	return 0;
 }
 

^ permalink raw reply	[flat|nested] 66+ messages in thread

* [patch 16/26] posix-timers: Add forward/remaining callbacks
  2017-05-30 21:15 [patch 00/26] alarmtimers/posixtimers: Bug fixes and spec conformity changes Thomas Gleixner
                   ` (14 preceding siblings ...)
  2017-05-30 21:15 ` [patch 15/26] posix-timers: Add active flag to k_itimer Thomas Gleixner
@ 2017-05-30 21:15 ` Thomas Gleixner
  2017-06-05  8:20   ` [tip:timers/core] " tip-bot for Thomas Gleixner
  2017-05-30 21:15 ` [patch 17/26] posix-timers: Make use of " Thomas Gleixner
                   ` (9 subsequent siblings)
  25 siblings, 1 reply; 66+ messages in thread
From: Thomas Gleixner @ 2017-05-30 21:15 UTC (permalink / raw)
  To: LKML; +Cc: John Stultz, Peter Zijlstra, Ingo Molnar

[-- Attachment #1: posix-timers--Add-forward-remaining-callbacks.patch --]
[-- Type: text/plain, Size: 670 bytes --]

Add two callbacks to kclock which allow using common_)timer_get() for both
hrtimer and alarm timer based clocks.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
 include/linux/posix-timers.h |    2 ++
 1 file changed, 2 insertions(+)

--- a/include/linux/posix-timers.h
+++ b/include/linux/posix-timers.h
@@ -124,6 +124,8 @@ struct k_clock {
 	void	(*timer_get)(struct k_itimer *timr,
 			     struct itimerspec64 *cur_setting);
 	void	(*timer_rearm)(struct k_itimer *timr);
+	int	(*timer_forward)(struct k_itimer *timr, ktime_t now);
+	ktime_t	(*timer_remaining)(struct k_itimer *timr, ktime_t now);
 };
 
 void run_posix_cpu_timers(struct task_struct *task);

^ permalink raw reply	[flat|nested] 66+ messages in thread

* [patch 17/26] posix-timers: Make use of forward/remaining callbacks
  2017-05-30 21:15 [patch 00/26] alarmtimers/posixtimers: Bug fixes and spec conformity changes Thomas Gleixner
                   ` (15 preceding siblings ...)
  2017-05-30 21:15 ` [patch 16/26] posix-timers: Add forward/remaining callbacks Thomas Gleixner
@ 2017-05-30 21:15 ` Thomas Gleixner
  2017-06-05  8:21   ` [tip:timers/core] " tip-bot for Thomas Gleixner
  2017-05-30 21:15 ` [patch 18/26] posix-timers: Zero settings value in common code Thomas Gleixner
                   ` (8 subsequent siblings)
  25 siblings, 1 reply; 66+ messages in thread
From: Thomas Gleixner @ 2017-05-30 21:15 UTC (permalink / raw)
  To: LKML; +Cc: John Stultz, Peter Zijlstra, Ingo Molnar

[-- Attachment #1: posix-timers--Make-use-of-forward-remaining-callbacks.patch --]
[-- Type: text/plain, Size: 4520 bytes --]

Replace the hrtimer calls by calls to the new forward/remaining kclock
callbacks and move the hrtimer specific implementation into the
corresponding callback functions.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
 kernel/time/posix-timers.c |   64 ++++++++++++++++++++++++++++++++++-----------
 1 file changed, 49 insertions(+), 15 deletions(-)

--- a/kernel/time/posix-timers.c
+++ b/kernel/time/posix-timers.c
@@ -607,6 +607,20 @@ static struct k_itimer *__lock_timer(tim
 	return NULL;
 }
 
+static ktime_t common_hrtimer_remaining(struct k_itimer *timr, ktime_t now)
+{
+	struct hrtimer *timer = &timr->it.real.timer;
+
+	return __hrtimer_expires_remaining_adjusted(timer, now);
+}
+
+static int common_hrtimer_forward(struct k_itimer *timr, ktime_t now)
+{
+	struct hrtimer *timer = &timr->it.real.timer;
+
+	return (int)hrtimer_forward(timer, now, timr->it_interval);
+}
+
 /*
  * Get the time remaining on a POSIX.1b interval timer.  This function
  * is ALWAYS called with spin_lock_irq on the timer, thus it must not
@@ -626,42 +640,54 @@ static struct k_itimer *__lock_timer(tim
 static void
 common_timer_get(struct k_itimer *timr, struct itimerspec64 *cur_setting)
 {
+	const struct k_clock *kc = timr->kclock;
 	ktime_t now, remaining, iv;
-	struct hrtimer *timer = &timr->it.real.timer;
+	struct timespec64 ts64;
+	bool sig_none;
 
 	memset(cur_setting, 0, sizeof(*cur_setting));
 
+	sig_none = (timr->it_sigev_notify & ~SIGEV_THREAD_ID) != SIGEV_NONE;
 	iv = timr->it_interval;
 
 	/* interval timer ? */
-	if (iv)
+	if (iv) {
 		cur_setting->it_interval = ktime_to_timespec64(iv);
-	else if (!hrtimer_active(timer) &&
-		 (timr->it_sigev_notify & ~SIGEV_THREAD_ID) != SIGEV_NONE)
-		return;
+	} else if (!timr->it_active) {
+		/*
+		 * SIGEV_NONE oneshot timers are never queued. Check them
+		 * below.
+		 */
+		if (!sig_none)
+			return;
+	}
 
-	now = timer->base->get_time();
+	/*
+	 * The timespec64 based conversion is suboptimal, but it's not
+	 * worth to implement yet another callback.
+	 */
+	kc->clock_get(timr->it_clock, &ts64);
+	now = timespec64_to_ktime(ts64);
 
 	/*
-	 * When a requeue is pending or this is a SIGEV_NONE
-	 * timer move the expiry time forward by intervals, so
-	 * expiry is > now.
+	 * When a requeue is pending or this is a SIGEV_NONE timer move the
+	 * expiry time forward by intervals, so expiry is > now.
 	 */
-	if (iv && (timr->it_requeue_pending & REQUEUE_PENDING ||
-		   (timr->it_sigev_notify & ~SIGEV_THREAD_ID) == SIGEV_NONE))
-		timr->it_overrun += (unsigned int) hrtimer_forward(timer, now, iv);
+	if (iv && (timr->it_requeue_pending & REQUEUE_PENDING || sig_none))
+		timr->it_overrun += kc->timer_forward(timr, now);
 
-	remaining = __hrtimer_expires_remaining_adjusted(timer, now);
+	remaining = kc->timer_remaining(timr, now);
 	/* Return 0 only, when the timer is expired and not pending */
 	if (remaining <= 0) {
 		/*
 		 * A single shot SIGEV_NONE timer must return 0, when
 		 * it is expired !
 		 */
-		if ((timr->it_sigev_notify & ~SIGEV_THREAD_ID) != SIGEV_NONE)
+		if (!sig_none)
 			cur_setting->it_value.tv_nsec = 1;
-	} else
+	} else {
 		cur_setting->it_value = ktime_to_timespec64(remaining);
+	}
 }
 
 /* Get the time remaining on a POSIX.1b interval timer. */
@@ -1049,6 +1075,8 @@ static const struct k_clock clock_realti
 	.timer_get	= common_timer_get,
 	.timer_del	= common_timer_del,
 	.timer_rearm	= common_hrtimer_rearm,
+	.timer_forward	= common_hrtimer_forward,
+	.timer_remaining= common_hrtimer_remaining,
 };
 
 static const struct k_clock clock_monotonic = {
@@ -1061,6 +1089,8 @@ static const struct k_clock clock_monoto
 	.timer_get	= common_timer_get,
 	.timer_del	= common_timer_del,
 	.timer_rearm	= common_hrtimer_rearm,
+	.timer_forward	= common_hrtimer_forward,
+	.timer_remaining= common_hrtimer_remaining,
 };
 
 static const struct k_clock clock_monotonic_raw = {
@@ -1088,6 +1118,8 @@ static const struct k_clock clock_tai =
 	.timer_get	= common_timer_get,
 	.timer_del	= common_timer_del,
 	.timer_rearm	= common_hrtimer_rearm,
+	.timer_forward	= common_hrtimer_forward,
+	.timer_remaining= common_hrtimer_remaining,
 };
 
 static const struct k_clock clock_boottime = {
@@ -1100,6 +1132,8 @@ static const struct k_clock clock_bootti
 	.timer_get	= common_timer_get,
 	.timer_del	= common_timer_del,
 	.timer_rearm	= common_hrtimer_rearm,
+	.timer_forward	= common_hrtimer_forward,
+	.timer_remaining= common_hrtimer_remaining,
 };
 
 static const struct k_clock * const posix_clocks[] = {

^ permalink raw reply	[flat|nested] 66+ messages in thread

* [patch 18/26] posix-timers: Zero settings value in common code
  2017-05-30 21:15 [patch 00/26] alarmtimers/posixtimers: Bug fixes and spec conformity changes Thomas Gleixner
                   ` (16 preceding siblings ...)
  2017-05-30 21:15 ` [patch 17/26] posix-timers: Make use of " Thomas Gleixner
@ 2017-05-30 21:15 ` Thomas Gleixner
  2017-06-05  8:21   ` [tip:timers/core] " tip-bot for Thomas Gleixner
  2017-05-30 21:15 ` [patch 19/26] posix-timers: Add cancel/arm callbacks Thomas Gleixner
                   ` (7 subsequent siblings)
  25 siblings, 1 reply; 66+ messages in thread
From: Thomas Gleixner @ 2017-05-30 21:15 UTC (permalink / raw)
  To: LKML; +Cc: John Stultz, Peter Zijlstra, Ingo Molnar

[-- Attachment #1: posix-timers--Zero-settings-value-in-common-code.patch --]
[-- Type: text/plain, Size: 1573 bytes --]

Zero out the settings struct in the common code so the callbacks do not
have to do it themself.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
 kernel/time/posix-cpu-timers.c |    5 +----
 kernel/time/posix-timers.c     |    3 +--
 2 files changed, 2 insertions(+), 6 deletions(-)

--- a/kernel/time/posix-cpu-timers.c
+++ b/kernel/time/posix-cpu-timers.c
@@ -719,10 +719,8 @@ static void posix_cpu_timer_get(struct k
 	 */
 	itp->it_interval = ns_to_timespec64(timer->it.cpu.incr);
 
-	if (timer->it.cpu.expires == 0) {	/* Timer not armed at all.  */
-		itp->it_value.tv_sec = itp->it_value.tv_nsec = 0;
+	if (!timer->it.cpu.expires)
 		return;
-	}
 
 	/*
 	 * Sample the clock to take the difference with the expiry time.
@@ -746,7 +744,6 @@ static void posix_cpu_timer_get(struct k
 			 * Call the timer disarmed, nothing else to do.
 			 */
 			timer->it.cpu.expires = 0;
-			itp->it_value = ns_to_timespec64(timer->it.cpu.expires);
 			return;
 		} else {
 			cpu_timer_sample_group(timer->it_clock, p, &now);
--- a/kernel/time/posix-timers.c
+++ b/kernel/time/posix-timers.c
@@ -645,8 +645,6 @@ common_timer_get(struct k_itimer *timr,
 	struct timespec64 ts64;
 	bool sig_none;
 
-	memset(cur_setting, 0, sizeof(*cur_setting));
-
 	sig_none = (timr->it_sigev_notify & ~SIGEV_THREAD_ID) != SIGEV_NONE;
 	iv = timr->it_interval;
 
@@ -705,6 +703,7 @@ SYSCALL_DEFINE2(timer_gettime, timer_t,
 	if (!timr)
 		return -EINVAL;
 
+	memset(&cur_setting64, 0, sizeof(cur_setting64));
 	kc = timr->kclock;
 	if (WARN_ON_ONCE(!kc || !kc->timer_get))
 		ret = -EINVAL;

^ permalink raw reply	[flat|nested] 66+ messages in thread

* [patch 19/26] posix-timers: Add cancel/arm callbacks
  2017-05-30 21:15 [patch 00/26] alarmtimers/posixtimers: Bug fixes and spec conformity changes Thomas Gleixner
                   ` (17 preceding siblings ...)
  2017-05-30 21:15 ` [patch 18/26] posix-timers: Zero settings value in common code Thomas Gleixner
@ 2017-05-30 21:15 ` Thomas Gleixner
  2017-06-05  8:22   ` [tip:timers/core] " tip-bot for Thomas Gleixner
  2017-05-30 21:15 ` [patch 20/26] posix-timers: Make use of " Thomas Gleixner
                   ` (6 subsequent siblings)
  25 siblings, 1 reply; 66+ messages in thread
From: Thomas Gleixner @ 2017-05-30 21:15 UTC (permalink / raw)
  To: LKML; +Cc: John Stultz, Peter Zijlstra, Ingo Molnar

[-- Attachment #1: posix-timers--Add-cancel-arm-callbacks.patch --]
[-- Type: text/plain, Size: 885 bytes --]

Add timer_try_to_cancel() and timer_arm() callbacks to kclock which allow
to make common_timer_set() usable by both hrtimer and alarmtimer based
clocks.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
 include/linux/posix-timers.h |    3 +++
 1 file changed, 3 insertions(+)

Index: b/include/linux/posix-timers.h
===================================================================
--- a/include/linux/posix-timers.h
+++ b/include/linux/posix-timers.h
@@ -126,6 +126,9 @@ struct k_clock {
 	void	(*timer_rearm)(struct k_itimer *timr);
 	int	(*timer_forward)(struct k_itimer *timr, ktime_t now);
 	ktime_t	(*timer_remaining)(struct k_itimer *timr, ktime_t now);
+	int	(*timer_try_to_cancel)(struct k_itimer *timr);
+	void	(*timer_arm)(struct k_itimer *timr, ktime_t expires,
+			     bool absolute, bool sigev_none);
 };
 
 void run_posix_cpu_timers(struct task_struct *task);

^ permalink raw reply	[flat|nested] 66+ messages in thread

* [patch 20/26] posix-timers: Make use of cancel/arm callbacks
  2017-05-30 21:15 [patch 00/26] alarmtimers/posixtimers: Bug fixes and spec conformity changes Thomas Gleixner
                   ` (18 preceding siblings ...)
  2017-05-30 21:15 ` [patch 19/26] posix-timers: Add cancel/arm callbacks Thomas Gleixner
@ 2017-05-30 21:15 ` Thomas Gleixner
  2017-06-05  8:22   ` [tip:timers/core] " tip-bot for Thomas Gleixner
  2017-05-30 21:15 ` [patch 21/26] alarmtimer: Implement timer_rearm() callback Thomas Gleixner
                   ` (5 subsequent siblings)
  25 siblings, 1 reply; 66+ messages in thread
From: Thomas Gleixner @ 2017-05-30 21:15 UTC (permalink / raw)
  To: LKML; +Cc: John Stultz, Peter Zijlstra, Ingo Molnar

[-- Attachment #1: posix-timers--Make-use-of-cancel-arm-callbacks.patch --]
[-- Type: text/plain, Size: 8870 bytes --]

Replace the hrtimer calls by calls to the new try_to_cancel()/arm() kclock
callbacks and move the hrtimer specific implementation into the
corresponding callback functions.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
 kernel/time/posix-timers.c |  181 ++++++++++++++++++++++++---------------------
 1 file changed, 100 insertions(+), 81 deletions(-)

Index: b/kernel/time/posix-timers.c
===================================================================
--- a/kernel/time/posix-timers.c
+++ b/kernel/time/posix-timers.c
@@ -744,25 +744,49 @@ SYSCALL_DEFINE1(timer_getoverrun, timer_
 	return overrun;
 }
 
+static void common_hrtimer_arm(struct k_itimer *timr, ktime_t expires,
+			       bool absolute, bool sigev_none)
+{
+	struct hrtimer *timer = &timr->it.real.timer;
+	enum hrtimer_mode mode;
+
+	mode = absolute ? HRTIMER_MODE_ABS : HRTIMER_MODE_REL;
+	hrtimer_init(&timr->it.real.timer, timr->it_clock, mode);
+	timr->it.real.timer.function = posix_timer_fn;
+
+	if (!absolute)
+		expires = ktime_add_safe(expires, timer->base->get_time());
+	hrtimer_set_expires(timer, expires);
+
+	if (!sigev_none)
+		hrtimer_start_expires(timer, HRTIMER_MODE_ABS);
+}
+
+static int common_hrtimer_try_to_cancel(struct k_itimer *timr)
+{
+	return hrtimer_try_to_cancel(&timr->it.real.timer);
+}
+
 /* Set a POSIX.1b interval timer. */
-/* timr->it_lock is taken. */
 static int
 common_timer_set(struct k_itimer *timr, int flags,
-		 struct itimerspec64 *new_setting, struct itimerspec64 *old_setting)
+		 struct itimerspec64 *new_setting,
+		 struct itimerspec64 *old_setting)
 {
-	struct hrtimer *timer = &timr->it.real.timer;
-	enum hrtimer_mode mode;
+	const struct k_clock *kc = timr->kclock;
+	bool sigev_none;
+	ktime_t expires;
 
 	if (old_setting)
 		common_timer_get(timr, old_setting);
 
-	/* disable the timer */
+	/* Prevent rearming by clearing the interval */
 	timr->it_interval = 0;
 	/*
-	 * careful here.  If smp we could be in the "fire" routine which will
-	 * be spinning as we hold the lock.  But this is ONLY an SMP issue.
+	 * Careful here. On SMP systems the timer expiry function could be
+	 * active and spinning on timr->it_lock.
 	 */
-	if (hrtimer_try_to_cancel(timer) < 0)
+	if (kc->timer_try_to_cancel(timr) < 0)
 		return TIMER_RETRY;
 
 	timr->it_active = 0;
@@ -770,30 +794,16 @@ common_timer_set(struct k_itimer *timr,
 		~REQUEUE_PENDING;
 	timr->it_overrun_last = 0;
 
-	/* switch off the timer when it_value is zero */
+	/* Switch off the timer when it_value is zero */
 	if (!new_setting->it_value.tv_sec && !new_setting->it_value.tv_nsec)
 		return 0;
 
-	mode = flags & TIMER_ABSTIME ? HRTIMER_MODE_ABS : HRTIMER_MODE_REL;
-	hrtimer_init(&timr->it.real.timer, timr->it_clock, mode);
-	timr->it.real.timer.function = posix_timer_fn;
-
-	hrtimer_set_expires(timer, timespec64_to_ktime(new_setting->it_value));
-
-	/* Convert interval */
 	timr->it_interval = timespec64_to_ktime(new_setting->it_interval);
+	expires = timespec64_to_ktime(new_setting->it_value);
+	sigev_none = (timr->it_sigev_notify & ~SIGEV_THREAD_ID) == SIGEV_NONE;
 
-	/* SIGEV_NONE timers are not queued ! See common_timer_get */
-	if (((timr->it_sigev_notify & ~SIGEV_THREAD_ID) == SIGEV_NONE)) {
-		/* Setup correct expiry time for relative timers */
-		if (mode == HRTIMER_MODE_REL) {
-			hrtimer_add_expires(timer, timer->base->get_time());
-		}
-		return 0;
-	}
-
-	timr->it_active = 1;
-	hrtimer_start_expires(timer, mode);
+	kc->timer_arm(timr, expires, flags & TIMER_ABSTIME, sigev_none);
+	timr->it_active = !sigev_none;
 	return 0;
 }
 
@@ -847,9 +857,10 @@ SYSCALL_DEFINE4(timer_settime, timer_t,
 
 static int common_timer_del(struct k_itimer *timer)
 {
-	timer->it_interval = 0;
+	const struct k_clock *kc = timer->kclock;
 
-	if (hrtimer_try_to_cancel(&timer->it.real.timer) < 0)
+	timer->it_interval = 0;
+	if (kc->timer_try_to_cancel(timer) < 0)
 		return TIMER_RETRY;
 	timer->it_active = 0;
 	return 0;
@@ -1063,76 +1074,84 @@ long clock_nanosleep_restart(struct rest
 }
 
 static const struct k_clock clock_realtime = {
-	.clock_getres	= posix_get_hrtimer_res,
-	.clock_get	= posix_clock_realtime_get,
-	.clock_set	= posix_clock_realtime_set,
-	.clock_adj	= posix_clock_realtime_adj,
-	.nsleep		= common_nsleep,
-	.nsleep_restart	= hrtimer_nanosleep_restart,
-	.timer_create	= common_timer_create,
-	.timer_set	= common_timer_set,
-	.timer_get	= common_timer_get,
-	.timer_del	= common_timer_del,
-	.timer_rearm	= common_hrtimer_rearm,
-	.timer_forward	= common_hrtimer_forward,
-	.timer_remaining= common_hrtimer_remaining,
+	.clock_getres		= posix_get_hrtimer_res,
+	.clock_get		= posix_clock_realtime_get,
+	.clock_set		= posix_clock_realtime_set,
+	.clock_adj		= posix_clock_realtime_adj,
+	.nsleep			= common_nsleep,
+	.nsleep_restart		= hrtimer_nanosleep_restart,
+	.timer_create		= common_timer_create,
+	.timer_set		= common_timer_set,
+	.timer_get		= common_timer_get,
+	.timer_del		= common_timer_del,
+	.timer_rearm		= common_hrtimer_rearm,
+	.timer_forward		= common_hrtimer_forward,
+	.timer_remaining	= common_hrtimer_remaining,
+	.timer_try_to_cancel	= common_hrtimer_try_to_cancel,
+	.timer_arm		= common_hrtimer_arm,
 };
 
 static const struct k_clock clock_monotonic = {
-	.clock_getres	= posix_get_hrtimer_res,
-	.clock_get	= posix_ktime_get_ts,
-	.nsleep		= common_nsleep,
-	.nsleep_restart	= hrtimer_nanosleep_restart,
-	.timer_create	= common_timer_create,
-	.timer_set	= common_timer_set,
-	.timer_get	= common_timer_get,
-	.timer_del	= common_timer_del,
-	.timer_rearm	= common_hrtimer_rearm,
-	.timer_forward	= common_hrtimer_forward,
-	.timer_remaining= common_hrtimer_remaining,
+	.clock_getres		= posix_get_hrtimer_res,
+	.clock_get		= posix_ktime_get_ts,
+	.nsleep			= common_nsleep,
+	.nsleep_restart		= hrtimer_nanosleep_restart,
+	.timer_create		= common_timer_create,
+	.timer_set		= common_timer_set,
+	.timer_get		= common_timer_get,
+	.timer_del		= common_timer_del,
+	.timer_rearm		= common_hrtimer_rearm,
+	.timer_forward		= common_hrtimer_forward,
+	.timer_remaining	= common_hrtimer_remaining,
+	.timer_try_to_cancel	= common_hrtimer_try_to_cancel,
+	.timer_arm		= common_hrtimer_arm,
 };
 
 static const struct k_clock clock_monotonic_raw = {
-	.clock_getres	= posix_get_hrtimer_res,
-	.clock_get	= posix_get_monotonic_raw,
+	.clock_getres		= posix_get_hrtimer_res,
+	.clock_get		= posix_get_monotonic_raw,
 };
 
 static const struct k_clock clock_realtime_coarse = {
-	.clock_getres	= posix_get_coarse_res,
-	.clock_get	= posix_get_realtime_coarse,
+	.clock_getres		= posix_get_coarse_res,
+	.clock_get		= posix_get_realtime_coarse,
 };
 
 static const struct k_clock clock_monotonic_coarse = {
-	.clock_getres	= posix_get_coarse_res,
-	.clock_get	= posix_get_monotonic_coarse,
+	.clock_getres		= posix_get_coarse_res,
+	.clock_get		= posix_get_monotonic_coarse,
 };
 
 static const struct k_clock clock_tai = {
-	.clock_getres	= posix_get_hrtimer_res,
-	.clock_get	= posix_get_tai,
-	.nsleep		= common_nsleep,
-	.nsleep_restart	= hrtimer_nanosleep_restart,
-	.timer_create	= common_timer_create,
-	.timer_set	= common_timer_set,
-	.timer_get	= common_timer_get,
-	.timer_del	= common_timer_del,
-	.timer_rearm	= common_hrtimer_rearm,
-	.timer_forward	= common_hrtimer_forward,
-	.timer_remaining= common_hrtimer_remaining,
+	.clock_getres		= posix_get_hrtimer_res,
+	.clock_get		= posix_get_tai,
+	.nsleep			= common_nsleep,
+	.nsleep_restart		= hrtimer_nanosleep_restart,
+	.timer_create		= common_timer_create,
+	.timer_set		= common_timer_set,
+	.timer_get		= common_timer_get,
+	.timer_del		= common_timer_del,
+	.timer_rearm		= common_hrtimer_rearm,
+	.timer_forward		= common_hrtimer_forward,
+	.timer_remaining	= common_hrtimer_remaining,
+	.timer_try_to_cancel	= common_hrtimer_try_to_cancel,
+	.timer_arm		= common_hrtimer_arm,
 };
 
 static const struct k_clock clock_boottime = {
-	.clock_getres	= posix_get_hrtimer_res,
-	.clock_get	= posix_get_boottime,
-	.nsleep		= common_nsleep,
-	.nsleep_restart	= hrtimer_nanosleep_restart,
-	.timer_create	= common_timer_create,
-	.timer_set	= common_timer_set,
-	.timer_get	= common_timer_get,
-	.timer_del	= common_timer_del,
-	.timer_rearm	= common_hrtimer_rearm,
-	.timer_forward	= common_hrtimer_forward,
-	.timer_remaining= common_hrtimer_remaining,
+	.clock_getres		= posix_get_hrtimer_res,
+	.clock_get		= posix_get_boottime,
+	.nsleep			= common_nsleep,
+	.nsleep_restart		= hrtimer_nanosleep_restart,
+	.timer_create		= common_timer_create,
+	.timer_set		= common_timer_set,
+	.timer_get		= common_timer_get,
+	.timer_del		= common_timer_del,
+	.timer_rearm		= common_hrtimer_rearm,
+	.timer_forward		= common_hrtimer_forward,
+	.timer_remaining	= common_hrtimer_remaining,
+	.timer_try_to_cancel	= common_hrtimer_try_to_cancel,
+	.timer_arm		= common_hrtimer_arm,
 };
 
 static const struct k_clock * const posix_clocks[] = {

^ permalink raw reply	[flat|nested] 66+ messages in thread

* [patch 21/26] alarmtimer: Implement timer_rearm() callback
  2017-05-30 21:15 [patch 00/26] alarmtimers/posixtimers: Bug fixes and spec conformity changes Thomas Gleixner
                   ` (19 preceding siblings ...)
  2017-05-30 21:15 ` [patch 20/26] posix-timers: Make use of " Thomas Gleixner
@ 2017-05-30 21:15 ` Thomas Gleixner
  2017-06-05  8:23   ` [tip:timers/core] " tip-bot for Thomas Gleixner
  2017-05-30 21:15 ` [patch 22/26] alarmtimer: Implement forward callback Thomas Gleixner
                   ` (4 subsequent siblings)
  25 siblings, 1 reply; 66+ messages in thread
From: Thomas Gleixner @ 2017-05-30 21:15 UTC (permalink / raw)
  To: LKML; +Cc: John Stultz, Peter Zijlstra, Ingo Molnar

[-- Attachment #1: alarmtimer--Implement-timer_rearm---callback.patch --]
[-- Type: text/plain, Size: 1330 bytes --]

Preparatory change to utilize the common posix timer mechanisms.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
 kernel/time/alarmtimer.c |   15 ++++++++++++++-
 1 file changed, 14 insertions(+), 1 deletion(-)

--- a/kernel/time/alarmtimer.c
+++ b/kernel/time/alarmtimer.c
@@ -537,6 +537,18 @@ static enum alarmtimer_restart alarm_han
 }
 
 /**
+ * alarm_timer_rearm - Posix timer callback for rearming timer
+ * @timr:	Pointer to the posixtimer data struct
+ */
+static void alarm_timer_rearm(struct k_itimer *timr)
+{
+	struct alarm *alarm = &timr->it.alarm.alarmtimer;
+
+	timr->it_overrun += alarm_forward_now(alarm, timr->it_interval);
+	alarm_start(alarm, alarm->node.expires);
+}
+
+/**
  * alarm_clock_getres - posix getres interface
  * @which_clock: clockid
  * @tp: timespec to fill
@@ -594,7 +606,7 @@ static int alarm_timer_create(struct k_i
 
 /**
  * alarm_timer_get - posix timer_get interface
- * @new_timer: k_itimer pointer
+ * @timr: k_itimer pointer
  * @cur_setting: itimerspec data to fill
  *
  * Copies out the current itimerspec data
@@ -863,6 +875,7 @@ const struct k_clock alarm_clock = {
 	.timer_set	= alarm_timer_set,
 	.timer_del	= alarm_timer_del,
 	.timer_get	= alarm_timer_get,
+	.timer_rearm	= alarm_timer_rearm,
 	.nsleep		= alarm_timer_nsleep,
 };
 #endif /* CONFIG_POSIX_TIMERS */

^ permalink raw reply	[flat|nested] 66+ messages in thread

* [patch 22/26] alarmtimer: Implement forward callback
  2017-05-30 21:15 [patch 00/26] alarmtimers/posixtimers: Bug fixes and spec conformity changes Thomas Gleixner
                   ` (20 preceding siblings ...)
  2017-05-30 21:15 ` [patch 21/26] alarmtimer: Implement timer_rearm() callback Thomas Gleixner
@ 2017-05-30 21:15 ` Thomas Gleixner
  2017-06-05  8:24   ` [tip:timers/core] " tip-bot for Thomas Gleixner
  2017-05-30 21:15 ` [patch 23/26] alarmtimer: Implement remaining callback Thomas Gleixner
                   ` (3 subsequent siblings)
  25 siblings, 1 reply; 66+ messages in thread
From: Thomas Gleixner @ 2017-05-30 21:15 UTC (permalink / raw)
  To: LKML; +Cc: John Stultz, Peter Zijlstra, Ingo Molnar

[-- Attachment #1: alarmtimer--Implement-forward-callback.patch --]
[-- Type: text/plain, Size: 1076 bytes --]

Preparatory change to utilize the common posix timer mechanisms.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
 kernel/time/alarmtimer.c |   13 +++++++++++++
 1 file changed, 13 insertions(+)

--- a/kernel/time/alarmtimer.c
+++ b/kernel/time/alarmtimer.c
@@ -549,6 +549,18 @@ static void alarm_timer_rearm(struct k_i
 }
 
 /**
+ * alarm_timer_forward - Posix timer callback for forwarding timer
+ * @timr:	Pointer to the posixtimer data struct
+ * @now:	Current time to forward the timer against
+ */
+static int alarm_timer_forward(struct k_itimer *timr, ktime_t now)
+{
+	struct alarm *alarm = &timr->it.alarm.alarmtimer;
+
+	return (int) alarm_forward(alarm, timr->it_interval, now);
+}
+
+/**
  * alarm_clock_getres - posix getres interface
  * @which_clock: clockid
  * @tp: timespec to fill
@@ -876,6 +888,7 @@ const struct k_clock alarm_clock = {
 	.timer_del	= alarm_timer_del,
 	.timer_get	= alarm_timer_get,
 	.timer_rearm	= alarm_timer_rearm,
+	.timer_forward	= alarm_timer_forward,
 	.nsleep		= alarm_timer_nsleep,
 };
 #endif /* CONFIG_POSIX_TIMERS */

^ permalink raw reply	[flat|nested] 66+ messages in thread

* [patch 23/26] alarmtimer: Implement remaining callback
  2017-05-30 21:15 [patch 00/26] alarmtimers/posixtimers: Bug fixes and spec conformity changes Thomas Gleixner
                   ` (21 preceding siblings ...)
  2017-05-30 21:15 ` [patch 22/26] alarmtimer: Implement forward callback Thomas Gleixner
@ 2017-05-30 21:15 ` Thomas Gleixner
  2017-06-05  8:24   ` [tip:timers/core] " tip-bot for Thomas Gleixner
  2017-05-30 21:15 ` [patch 24/26] alarmtimer: Implement try_to_cancel callback Thomas Gleixner
                   ` (2 subsequent siblings)
  25 siblings, 1 reply; 66+ messages in thread
From: Thomas Gleixner @ 2017-05-30 21:15 UTC (permalink / raw)
  To: LKML; +Cc: John Stultz, Peter Zijlstra, Ingo Molnar

[-- Attachment #1: alarmtimer--Implement-remaining-callback.patch --]
[-- Type: text/plain, Size: 1658 bytes --]

Preparatory change to utilize the common posix timer mechanisms.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
 kernel/time/alarmtimer.c |   31 ++++++++++++++++++++++---------
 1 file changed, 22 insertions(+), 9 deletions(-)

--- a/kernel/time/alarmtimer.c
+++ b/kernel/time/alarmtimer.c
@@ -561,6 +561,18 @@ static int alarm_timer_forward(struct k_
 }
 
 /**
+ * alarm_timer_remaining - Posix timer callback to retrieve remaining time
+ * @timr:	Pointer to the posixtimer data struct
+ * @now:	Current time to calculate against
+ */
+static ktime_t alarm_timer_remaining(struct k_itimer *timr, ktime_t now)
+{
+	struct alarm *alarm = &timr->it.alarm.alarmtimer;
+
+	return ktime_sub(now, alarm->node.expires);
+}
+
+/**
  * alarm_clock_getres - posix getres interface
  * @which_clock: clockid
  * @tp: timespec to fill
@@ -881,15 +893,16 @@ static int alarm_timer_nsleep(const cloc
 }
 
 const struct k_clock alarm_clock = {
-	.clock_getres	= alarm_clock_getres,
-	.clock_get	= alarm_clock_get,
-	.timer_create	= alarm_timer_create,
-	.timer_set	= alarm_timer_set,
-	.timer_del	= alarm_timer_del,
-	.timer_get	= alarm_timer_get,
-	.timer_rearm	= alarm_timer_rearm,
-	.timer_forward	= alarm_timer_forward,
-	.nsleep		= alarm_timer_nsleep,
+	.clock_getres		= alarm_clock_getres,
+	.clock_get		= alarm_clock_get,
+	.timer_create		= alarm_timer_create,
+	.timer_set		= alarm_timer_set,
+	.timer_del		= alarm_timer_del,
+	.timer_get		= alarm_timer_get,
+	.timer_rearm		= alarm_timer_rearm,
+	.timer_forward		= alarm_timer_forward,
+	.timer_remaining	= alarm_timer_remaining,
+	.nsleep			= alarm_timer_nsleep,
 };
 #endif /* CONFIG_POSIX_TIMERS */
 

^ permalink raw reply	[flat|nested] 66+ messages in thread

* [patch 24/26] alarmtimer: Implement try_to_cancel callback
  2017-05-30 21:15 [patch 00/26] alarmtimers/posixtimers: Bug fixes and spec conformity changes Thomas Gleixner
                   ` (22 preceding siblings ...)
  2017-05-30 21:15 ` [patch 23/26] alarmtimer: Implement remaining callback Thomas Gleixner
@ 2017-05-30 21:15 ` Thomas Gleixner
  2017-06-05  8:25   ` [tip:timers/core] " tip-bot for Thomas Gleixner
  2017-05-30 21:15 ` [patch 25/26] alarmtimer: Implement arm callback Thomas Gleixner
  2017-05-30 21:15 ` [patch 26/26] alarmtimer: Switch over to generic set/get/rearm routine Thomas Gleixner
  25 siblings, 1 reply; 66+ messages in thread
From: Thomas Gleixner @ 2017-05-30 21:15 UTC (permalink / raw)
  To: LKML; +Cc: John Stultz, Peter Zijlstra, Ingo Molnar

[-- Attachment #1: alarmtimer--Implement-try_to_cancel-callback.patch --]
[-- Type: text/plain, Size: 995 bytes --]

Preparatory change to utilize the common posix timer mechanisms.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
 kernel/time/alarmtimer.c |   10 ++++++++++
 1 file changed, 10 insertions(+)

--- a/kernel/time/alarmtimer.c
+++ b/kernel/time/alarmtimer.c
@@ -573,6 +573,15 @@ static ktime_t alarm_timer_remaining(str
 }
 
 /**
+ * alarm_timer_try_to_cancel - Posix timer callback to cancel a timer
+ * @timr:	Pointer to the posixtimer data struct
+ */
+static int alarm_timer_try_to_cancel(struct k_itimer *timr)
+{
+	return alarm_try_to_cancel(&timr->it.alarm.alarmtimer);
+}
+
+/**
  * alarm_clock_getres - posix getres interface
  * @which_clock: clockid
  * @tp: timespec to fill
@@ -902,6 +911,7 @@ const struct k_clock alarm_clock = {
 	.timer_rearm		= alarm_timer_rearm,
 	.timer_forward		= alarm_timer_forward,
 	.timer_remaining	= alarm_timer_remaining,
+	.timer_try_to_cancel	= alarm_timer_try_to_cancel,
 	.nsleep			= alarm_timer_nsleep,
 };
 #endif /* CONFIG_POSIX_TIMERS */

^ permalink raw reply	[flat|nested] 66+ messages in thread

* [patch 25/26] alarmtimer: Implement arm callback
  2017-05-30 21:15 [patch 00/26] alarmtimers/posixtimers: Bug fixes and spec conformity changes Thomas Gleixner
                   ` (23 preceding siblings ...)
  2017-05-30 21:15 ` [patch 24/26] alarmtimer: Implement try_to_cancel callback Thomas Gleixner
@ 2017-05-30 21:15 ` Thomas Gleixner
  2017-06-05  8:25   ` [tip:timers/core] " tip-bot for Thomas Gleixner
  2017-05-30 21:15 ` [patch 26/26] alarmtimer: Switch over to generic set/get/rearm routine Thomas Gleixner
  25 siblings, 1 reply; 66+ messages in thread
From: Thomas Gleixner @ 2017-05-30 21:15 UTC (permalink / raw)
  To: LKML; +Cc: John Stultz, Peter Zijlstra, Ingo Molnar

[-- Attachment #1: alarmtimer--Implement-arm-callback.patch --]
[-- Type: text/plain, Size: 1520 bytes --]

Preparatory change to utilize the common posix timer mechanisms.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
 kernel/time/alarmtimer.c |   22 ++++++++++++++++++++++
 1 file changed, 22 insertions(+)

Index: b/kernel/time/alarmtimer.c
===================================================================
--- a/kernel/time/alarmtimer.c
+++ b/kernel/time/alarmtimer.c
@@ -582,6 +582,27 @@ static int alarm_timer_try_to_cancel(str
 }
 
 /**
+ * alarm_timer_arm - Posix timer callback to arm a timer
+ * @timr:	Pointer to the posixtimer data struct
+ * @expires:	The new expiry time
+ * @absolute:	Expiry value is absolute time
+ * @sigev_none:	Posix timer does not deliver signals
+ */
+static void alarm_timer_arm(struct k_itimer *timr, ktime_t expires,
+			    bool absolute, bool sigev_none)
+{
+	struct alarm *alarm = &timr->it.alarm.alarmtimer;
+	struct alarm_base *base = &alarm_bases[alarm->type];
+
+	if (!absolute)
+		expires = ktime_add_safe(expires, base->gettime());
+	if (sigev_none)
+		alarm->node.expires = expires;
+	else
+		alarm_start(&timr->it.alarm.alarmtimer, expires);
+}
+
+/**
  * alarm_clock_getres - posix getres interface
  * @which_clock: clockid
  * @tp: timespec to fill
@@ -908,6 +929,7 @@ const struct k_clock alarm_clock = {
 	.timer_set		= alarm_timer_set,
 	.timer_del		= alarm_timer_del,
 	.timer_get		= alarm_timer_get,
+	.timer_arm		= alarm_timer_arm,
 	.timer_rearm		= alarm_timer_rearm,
 	.timer_forward		= alarm_timer_forward,
 	.timer_remaining	= alarm_timer_remaining,

^ permalink raw reply	[flat|nested] 66+ messages in thread

* [patch 26/26] alarmtimer: Switch over to generic set/get/rearm routine
  2017-05-30 21:15 [patch 00/26] alarmtimers/posixtimers: Bug fixes and spec conformity changes Thomas Gleixner
                   ` (24 preceding siblings ...)
  2017-05-30 21:15 ` [patch 25/26] alarmtimer: Implement arm callback Thomas Gleixner
@ 2017-05-30 21:15 ` Thomas Gleixner
  2017-06-05  8:26   ` [tip:timers/core] " tip-bot for Thomas Gleixner
  25 siblings, 1 reply; 66+ messages in thread
From: Thomas Gleixner @ 2017-05-30 21:15 UTC (permalink / raw)
  To: LKML; +Cc: John Stultz, Peter Zijlstra, Ingo Molnar

[-- Attachment #1: alarmtimer--Switch-over-to-generic-set-get-rearm-routine.patch --]
[-- Type: text/plain, Size: 6293 bytes --]

All required callbacks are in place. Switch the alarm timer based posix
interval timer callbacks to the common implementation and remove the
incorrect private implementation.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
 kernel/time/alarmtimer.c   |  121 ++++++---------------------------------------
 kernel/time/posix-timers.c |   12 +---
 kernel/time/posix-timers.h |    6 ++
 3 files changed, 29 insertions(+), 110 deletions(-)

--- a/kernel/time/alarmtimer.c
+++ b/kernel/time/alarmtimer.c
@@ -515,20 +515,26 @@ static enum alarmtimer_type clock2alarm(
 static enum alarmtimer_restart alarm_handle_timer(struct alarm *alarm,
 							ktime_t now)
 {
-	unsigned long flags;
 	struct k_itimer *ptr = container_of(alarm, struct k_itimer,
-						it.alarm.alarmtimer);
+					    it.alarm.alarmtimer);
 	enum alarmtimer_restart result = ALARMTIMER_NORESTART;
+	unsigned long flags;
+	int si_private = 0;
 
 	spin_lock_irqsave(&ptr->it_lock, flags);
-	if ((ptr->it_sigev_notify & ~SIGEV_THREAD_ID) != SIGEV_NONE) {
-		if (posix_timer_event(ptr, 0))
-			ptr->it_overrun++;
-	}
 
-	/* Re-add periodic timers */
-	if (ptr->it_interval) {
-		ptr->it_overrun += alarm_forward(alarm, now, ptr->it_interval);
+	ptr->it_active = 0;
+	if (ptr->it_interval)
+		si_private = ++ptr->it_requeue_pending;
+
+	if (posix_timer_event(ptr, si_private) && ptr->it_interval) {
+		/*
+		 * Handle ignored signals and rearm the timer. This will go
+		 * away once we handle ignored signals proper.
+		 */
+		ptr->it_overrun += alarm_forward_now(alarm, ptr->it_interval);
+		++ptr->it_requeue_pending;
+		ptr->it_active = 1;
 		result = ALARMTIMER_RESTART;
 	}
 	spin_unlock_irqrestore(&ptr->it_lock, flags);
@@ -659,97 +665,6 @@ static int alarm_timer_create(struct k_i
 }
 
 /**
- * alarm_timer_get - posix timer_get interface
- * @timr: k_itimer pointer
- * @cur_setting: itimerspec data to fill
- *
- * Copies out the current itimerspec data
- */
-static void alarm_timer_get(struct k_itimer *timr,
-			    struct itimerspec64 *cur_setting)
-{
-	ktime_t relative_expiry_time =
-		alarm_expires_remaining(&(timr->it.alarm.alarmtimer));
-
-	if (ktime_to_ns(relative_expiry_time) > 0) {
-		cur_setting->it_value = ktime_to_timespec64(relative_expiry_time);
-	} else {
-		cur_setting->it_value.tv_sec = 0;
-		cur_setting->it_value.tv_nsec = 0;
-	}
-
-	cur_setting->it_interval = ktime_to_timespec64(timr->it_interval);
-}
-
-/**
- * alarm_timer_del - posix timer_del interface
- * @timr: k_itimer pointer to be deleted
- *
- * Cancels any programmed alarms for the given timer.
- */
-static int alarm_timer_del(struct k_itimer *timr)
-{
-	if (!rtcdev)
-		return -ENOTSUPP;
-
-	if (alarm_try_to_cancel(&timr->it.alarm.alarmtimer) < 0)
-		return TIMER_RETRY;
-
-	return 0;
-}
-
-/**
- * alarm_timer_set - posix timer_set interface
- * @timr: k_itimer pointer to be deleted
- * @flags: timer flags
- * @new_setting: itimerspec to be used
- * @old_setting: itimerspec being replaced
- *
- * Sets the timer to new_setting, and starts the timer.
- */
-static int alarm_timer_set(struct k_itimer *timr, int flags,
-			   struct itimerspec64 *new_setting,
-			   struct itimerspec64 *old_setting)
-{
-	ktime_t exp;
-
-	if (!rtcdev)
-		return -ENOTSUPP;
-
-	if (flags & ~TIMER_ABSTIME)
-		return -EINVAL;
-
-	if (old_setting)
-		alarm_timer_get(timr, old_setting);
-
-	/* If the timer was already set, cancel it */
-	if (alarm_try_to_cancel(&timr->it.alarm.alarmtimer) < 0)
-		return TIMER_RETRY;
-
-	/* start the timer */
-	timr->it_interval = timespec64_to_ktime(new_setting->it_interval);
-
-	/*
-	 * Rate limit to the tick as a hot fix to prevent DOS. Will be
-	 * mopped up later.
-	 */
-	if (timr->it_interval < TICK_NSEC)
-		timr->it_interval = TICK_NSEC;
-
-	exp = timespec64_to_ktime(new_setting->it_value);
-	/* Convert (if necessary) to absolute time */
-	if (flags != TIMER_ABSTIME) {
-		ktime_t now;
-
-		now = alarm_bases[timr->it.alarm.alarmtimer.type].gettime();
-		exp = ktime_add_safe(now, exp);
-	}
-
-	alarm_start(&timr->it.alarm.alarmtimer, exp);
-	return 0;
-}
-
-/**
  * alarmtimer_nsleep_wakeup - Wakeup function for alarm_timer_nsleep
  * @alarm: ptr to alarm that fired
  *
@@ -926,9 +841,9 @@ const struct k_clock alarm_clock = {
 	.clock_getres		= alarm_clock_getres,
 	.clock_get		= alarm_clock_get,
 	.timer_create		= alarm_timer_create,
-	.timer_set		= alarm_timer_set,
-	.timer_del		= alarm_timer_del,
-	.timer_get		= alarm_timer_get,
+	.timer_set		= common_timer_set,
+	.timer_del		= common_timer_del,
+	.timer_get		= common_timer_get,
 	.timer_arm		= alarm_timer_arm,
 	.timer_rearm		= alarm_timer_rearm,
 	.timer_forward		= alarm_timer_forward,
--- a/kernel/time/posix-timers.c
+++ b/kernel/time/posix-timers.c
@@ -637,8 +637,7 @@ static int common_hrtimer_forward(struct
  * it is the same as a requeue pending timer WRT to what we should
  * report.
  */
-static void
-common_timer_get(struct k_itimer *timr, struct itimerspec64 *cur_setting)
+void common_timer_get(struct k_itimer *timr, struct itimerspec64 *cur_setting)
 {
 	const struct k_clock *kc = timr->kclock;
 	ktime_t now, remaining, iv;
@@ -768,10 +767,9 @@ static int common_hrtimer_try_to_cancel(
 }
 
 /* Set a POSIX.1b interval timer. */
-static int
-common_timer_set(struct k_itimer *timr, int flags,
-		 struct itimerspec64 *new_setting,
-		 struct itimerspec64 *old_setting)
+int common_timer_set(struct k_itimer *timr, int flags,
+		     struct itimerspec64 *new_setting,
+		     struct itimerspec64 *old_setting)
 {
 	const struct k_clock *kc = timr->kclock;
 	bool sigev_none;
@@ -855,7 +853,7 @@ SYSCALL_DEFINE4(timer_settime, timer_t,
 	return error;
 }
 
-static int common_timer_del(struct k_itimer *timer)
+int common_timer_del(struct k_itimer *timer)
 {
 	const struct k_clock *kc = timer->kclock;
 
--- a/kernel/time/posix-timers.h
+++ b/kernel/time/posix-timers.h
@@ -5,3 +5,9 @@ extern const struct k_clock clock_thread
 extern const struct k_clock alarm_clock;
 
 int posix_timer_event(struct k_itimer *timr, int si_private);
+
+void common_timer_get(struct k_itimer *timr, struct itimerspec64 *cur_setting);
+int common_timer_set(struct k_itimer *timr, int flags,
+		     struct itimerspec64 *new_setting,
+		     struct itimerspec64 *old_setting);
+int common_timer_del(struct k_itimer *timer);

^ permalink raw reply	[flat|nested] 66+ messages in thread

* Re: [patch 05/26] posix-clocks: Remove interval timer facility and mmap/fasync callbacks
  2017-05-30 21:15 ` [patch 05/26] posix-clocks: Remove interval timer facility and mmap/fasync callbacks Thomas Gleixner
@ 2017-05-31  9:00   ` Richard Cochran
  2017-06-05  8:14   ` [tip:timers/core] " tip-bot for Thomas Gleixner
  1 sibling, 0 replies; 66+ messages in thread
From: Richard Cochran @ 2017-05-31  9:00 UTC (permalink / raw)
  To: Thomas Gleixner; +Cc: LKML, John Stultz, Peter Zijlstra, Ingo Molnar

On Tue, May 30, 2017 at 11:15:38PM +0200, Thomas Gleixner wrote:
> The only user of this facility is ptp_clock, which does not implement any of
> those functions.
> 
> Remove them to prevent accidental users. Especially the interval timer
> interfaces are now more or less impossible to implement because the
> necessary infrastructure has been confined to the core code. Aside of that
> it's really complex to make these callbacks implemented according to spec
> as the alarm timer implementation demonstrates. If at all then a nanosleep
> callback might be a reasonable extension. For now keep just what ptp_clock
> needs.
> 
> Signed-off-by: Thomas Gleixner <tglx@linutronix.de>

Acked-by: Richard Cochran <richardcochran@gmail.com>

For the record, recently someone did try to implement this interface
for the i210 card.  Although there were issues in the implementation,
still I was curious enough to test the performance.

   https://www.mail-archive.com/linuxptp-devel@lists.sourceforge.net/msg01738.html

The result confirmed my expectation that using the normal system clock
sychronized to the PHC using the phc2sys utility yields better
performance than the direct timer_settime() implementation.

The nanosleep() idea might be worthwhile, but only for devices with
directly mapped registers (like in some SoCs) and not for the common
PCIe devices.  In any case, I am happy to see the timer interface
removed, as it is basically useless and gives people false
impressions.

Could you please include this documentation fix, too?

Thanks,
Richard

---8<---
diff --git a/Documentation/ptp/ptp.txt b/Documentation/ptp/ptp.txt
index ae8fef8..11e904e 100644
--- a/Documentation/ptp/ptp.txt
+++ b/Documentation/ptp/ptp.txt
@@ -18,7 +18,6 @@
     - Adjust clock frequency
 
   + Ancillary clock features
-    - One short or periodic alarms, with signal delivery to user program
     - Time stamp external events
     - Period output signals configurable from user space
     - Synchronization of the Linux system time via the PPS subsystem
@@ -48,9 +47,7 @@
    User space programs may control the clock using standardized
    ioctls. A program may query, enable, configure, and disable the
    ancillary clock features. User space can receive time stamped
-   events via blocking read() and poll(). One shot and periodic
-   signals may be configured via the POSIX timer_settime() system
-   call.
+   events via blocking read() and poll().
 
 ** Writing clock drivers
 

^ permalink raw reply	[flat|nested] 66+ messages in thread

* Re: [patch 08/26] posix-timers: Move posix-timer internals to core
  2017-05-30 21:15 ` [patch 08/26] posix-timers: Move posix-timer internals to core Thomas Gleixner
@ 2017-05-31 15:37   ` Christoph Hellwig
  2017-06-05  8:15   ` [tip:timers/core] " tip-bot for Thomas Gleixner
  1 sibling, 0 replies; 66+ messages in thread
From: Christoph Hellwig @ 2017-05-31 15:37 UTC (permalink / raw)
  To: Thomas Gleixner; +Cc: LKML, John Stultz, Peter Zijlstra, Ingo Molnar

On Tue, May 30, 2017 at 11:15:41PM +0200, Thomas Gleixner wrote:
> None of these declarations is required outside of kernel/time. Move them to
> an internal header.

It seems like struct k_clock itself could be marked private as well.

And with a small exported helper for /the /proc/timers implementation
struct k_itimer could be marked private, too.

^ permalink raw reply	[flat|nested] 66+ messages in thread

* Re: [patch 13/26] posix-timers: Rename do_schedule_next_timer
  2017-05-30 21:15 ` [patch 13/26] posix-timers: Rename do_schedule_next_timer Thomas Gleixner
@ 2017-05-31 15:39   ` Christoph Hellwig
  2017-06-01 20:50     ` Thomas Gleixner
  2017-06-05  8:18   ` [tip:timers/core] " tip-bot for Thomas Gleixner
  1 sibling, 1 reply; 66+ messages in thread
From: Christoph Hellwig @ 2017-05-31 15:39 UTC (permalink / raw)
  To: Thomas Gleixner; +Cc: LKML, John Stultz, Peter Zijlstra, Ingo Molnar

On Tue, May 30, 2017 at 11:15:46PM +0200, Thomas Gleixner wrote:
> That function is a misnomer. Rename it with a proper prefix to
> posixtimer_rearm().

Please also move it out of asm-generic/siginfo.h as it's implemented
and used in generic code only, and there is no arch override at all.

In fact it seems like asm-generic/siginfo.h should probably just move
to include/linux/signinfo.h.

^ permalink raw reply	[flat|nested] 66+ messages in thread

* Re: [patch 13/26] posix-timers: Rename do_schedule_next_timer
  2017-05-31 15:39   ` Christoph Hellwig
@ 2017-06-01 20:50     ` Thomas Gleixner
  2017-06-02  7:00       ` Christoph Hellwig
  0 siblings, 1 reply; 66+ messages in thread
From: Thomas Gleixner @ 2017-06-01 20:50 UTC (permalink / raw)
  To: Christoph Hellwig; +Cc: LKML, John Stultz, Peter Zijlstra, Ingo Molnar

On Wed, 31 May 2017, Christoph Hellwig wrote:

> On Tue, May 30, 2017 at 11:15:46PM +0200, Thomas Gleixner wrote:
> > That function is a misnomer. Rename it with a proper prefix to
> > posixtimer_rearm().
> 
> Please also move it out of asm-generic/siginfo.h as it's implemented
> and used in generic code only, and there is no arch override at all.
> 
> In fact it seems like asm-generic/siginfo.h should probably just move
> to include/linux/signinfo.h.

That's one convoluted mess.

# find -name siginfo.h | xargs grep 'include.*siginfo.h'

./arch/score/include/uapi/asm/siginfo.h:#include <asm-generic/siginfo.h>
./arch/powerpc/include/uapi/asm/siginfo.h:#include <asm-generic/siginfo.h>
./arch/sparc/include/asm/siginfo.h:#include <uapi/asm/siginfo.h>
./arch/sparc/include/uapi/asm/siginfo.h:#include <asm-generic/siginfo.h>
./arch/metag/include/uapi/asm/siginfo.h:#include <asm-generic/siginfo.h>
./arch/frv/include/uapi/asm/siginfo.h:#include <asm-generic/siginfo.h>
./arch/x86/include/uapi/asm/siginfo.h:#include <asm-generic/siginfo.h>
./arch/alpha/include/uapi/asm/siginfo.h:#include <asm-generic/siginfo.h>
./arch/tile/include/uapi/asm/siginfo.h:#include <asm-generic/siginfo.h>
./arch/mn10300/include/uapi/asm/siginfo.h:#include <asm-generic/siginfo.h>
./arch/m32r/include/uapi/asm/siginfo.h:#include <asm-generic/siginfo.h>
./arch/blackfin/include/uapi/asm/siginfo.h:#include <asm-generic/siginfo.h>
./arch/ia64/include/asm/siginfo.h:#include <uapi/asm/siginfo.h>
./arch/ia64/include/uapi/asm/siginfo.h:#include <asm-generic/siginfo.h>
./arch/arm64/include/uapi/asm/siginfo.h:#include <asm-generic/siginfo.h>
./arch/parisc/include/uapi/asm/siginfo.h:#include <asm-generic/siginfo.h>
./arch/mips/include/uapi/asm/siginfo.h:#include <asm-generic/siginfo.h>
./arch/s390/include/uapi/asm/siginfo.h: *  Derived from "include/asm-i386/siginfo.h"
./arch/s390/include/uapi/asm/siginfo.h:#include <asm-generic/siginfo.h>
./arch/microblaze/include/uapi/asm/siginfo.h:#include <asm-generic/siginfo.h>
./include/asm-generic/siginfo.h:#include <uapi/asm-generic/siginfo.h>

Why the heck include uapi headers asm-generic/siginfo.h ???

Thanks,

	tglx

^ permalink raw reply	[flat|nested] 66+ messages in thread

* Re: [patch 13/26] posix-timers: Rename do_schedule_next_timer
  2017-06-01 20:50     ` Thomas Gleixner
@ 2017-06-02  7:00       ` Christoph Hellwig
  0 siblings, 0 replies; 66+ messages in thread
From: Christoph Hellwig @ 2017-06-02  7:00 UTC (permalink / raw)
  To: Thomas Gleixner
  Cc: Christoph Hellwig, LKML, John Stultz, Peter Zijlstra, Ingo Molnar

On Thu, Jun 01, 2017 at 10:50:42PM +0200, Thomas Gleixner wrote:
> On Wed, 31 May 2017, Christoph Hellwig wrote:
> 
> > On Tue, May 30, 2017 at 11:15:46PM +0200, Thomas Gleixner wrote:
> > > That function is a misnomer. Rename it with a proper prefix to
> > > posixtimer_rearm().
> > 
> > Please also move it out of asm-generic/siginfo.h as it's implemented
> > and used in generic code only, and there is no arch override at all.
> > 
> > In fact it seems like asm-generic/siginfo.h should probably just move
> > to include/linux/signinfo.h.
> 
> That's one convoluted mess.

Yes.  I tried to give it some love 2 days ago but my first attempt
failed badly.  Here is what I'm at now, but it's not quite ready for
prime time:

   http://git.infradead.org/users/hch/misc.git/shortlog/refs/heads/siginfo

^ permalink raw reply	[flat|nested] 66+ messages in thread

* [tip:timers/urgent] alarmtimer: Prevent overflow of relative timers
  2017-05-30 21:15 ` [patch 01/26] alarmtimer: Prevent overflow of relative timers Thomas Gleixner
@ 2017-06-04 13:21   ` tip-bot for Thomas Gleixner
  2017-06-04 13:24   ` tip-bot for Thomas Gleixner
  1 sibling, 0 replies; 66+ messages in thread
From: tip-bot for Thomas Gleixner @ 2017-06-04 13:21 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: peterz, andreyknvl, kcc, john.stultz, dvyukov, linux-kernel,
	mingo, syzkaller, hpa, tglx

Commit-ID:  ecd7d6ff04a59478c41987051dd8f15258cea6af
Gitweb:     http://git.kernel.org/tip/ecd7d6ff04a59478c41987051dd8f15258cea6af
Author:     Thomas Gleixner <tglx@linutronix.de>
AuthorDate: Tue, 30 May 2017 23:15:34 +0200
Committer:  Thomas Gleixner <tglx@linutronix.de>
CommitDate: Sun, 4 Jun 2017 15:18:27 +0200

alarmtimer: Prevent overflow of relative timers

Andrey reported a alartimer related RCU stall while fuzzing the kernel with
syzkaller.

The reason for this is an overflow in ktime_add() which brings the
resulting time into negative space and causes immediate expiry of the
timer. The following rearm with a small interval does not bring the timer
back into positive space due to the same issue.

This results in a permanent firing alarmtimer which hogs the CPU.

Use ktime_add_safe() instead which detects the overflow and clamps the
result to KTIME_SEC_MAX.

Reported-by: Andrey Konovalov <andreyknvl@google.com>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Kostya Serebryany <kcc@google.com>
Cc: syzkaller <syzkaller@googlegroups.com>
Cc: John Stultz <john.stultz@linaro.org>
Cc: Dmitry Vyukov <dvyukov@google.com>
Link: http://lkml.kernel.org/r/20170530211655.802921648@linutronix.de

---
 kernel/time/alarmtimer.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/kernel/time/alarmtimer.c b/kernel/time/alarmtimer.c
index 5cb5b00..2b2e032 100644
--- a/kernel/time/alarmtimer.c
+++ b/kernel/time/alarmtimer.c
@@ -387,7 +387,7 @@ void alarm_start_relative(struct alarm *alarm, ktime_t start)
 {
 	struct alarm_base *base = &alarm_bases[alarm->type];
 
-	start = ktime_add(start, base->gettime());
+	start = ktime_add_safe(start, base->gettime());
 	alarm_start(alarm, start);
 }
 EXPORT_SYMBOL_GPL(alarm_start_relative);
@@ -475,7 +475,7 @@ u64 alarm_forward(struct alarm *alarm, ktime_t now, ktime_t interval)
 		overrun++;
 	}
 
-	alarm->node.expires = ktime_add(alarm->node.expires, interval);
+	alarm->node.expires = ktime_add_safe(alarm->node.expires, interval);
 	return overrun;
 }
 EXPORT_SYMBOL_GPL(alarm_forward);
@@ -666,7 +666,7 @@ static int alarm_timer_set(struct k_itimer *timr, int flags,
 		ktime_t now;
 
 		now = alarm_bases[timr->it.alarm.alarmtimer.type].gettime();
-		exp = ktime_add(now, exp);
+		exp = ktime_add_safe(now, exp);
 	}
 
 	alarm_start(&timr->it.alarm.alarmtimer, exp);

^ permalink raw reply	[flat|nested] 66+ messages in thread

* [tip:timers/urgent] alarmtimer: Rate limit periodic intervals
  2017-05-30 21:15 ` [patch 02/26] alarmtimer: Rate limit periodic intervals Thomas Gleixner
@ 2017-06-04 13:22   ` tip-bot for Thomas Gleixner
  2017-06-04 13:25   ` tip-bot for Thomas Gleixner
  1 sibling, 0 replies; 66+ messages in thread
From: tip-bot for Thomas Gleixner @ 2017-06-04 13:22 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: tglx, peterz, linux-kernel, hpa, syzkaller, kcc, mingo, dvyukov,
	john.stultz

Commit-ID:  a90b040d8a7a206dd1863c60a47ace5319c99321
Gitweb:     http://git.kernel.org/tip/a90b040d8a7a206dd1863c60a47ace5319c99321
Author:     Thomas Gleixner <tglx@linutronix.de>
AuthorDate: Tue, 30 May 2017 23:15:35 +0200
Committer:  Thomas Gleixner <tglx@linutronix.de>
CommitDate: Sun, 4 Jun 2017 15:18:28 +0200

alarmtimer: Rate limit periodic intervals

The alarmtimer code has another source of potentially rearming itself too
fast. Interval timers with a very samll interval have a similar CPU hog
effect as the previously fixed overflow issue.

The reason is that alarmtimers do not implement the normal protection
against this kind of problem which the other posix timer use:

  timer expires -> queue signal -> deliver signal -> rearm timer

This scheme brings the rearming under scheduler control and prevents
permanently firing timers which hog the CPU.

Bringing this scheme to the alarm timer code is a major overhaul because it
lacks all the necessary mechanisms completely.

So for a quick fix limit the interval to one jiffie. This is not
problematic in practice as alarmtimers are usually backed by an RTC for
suspend which have 1 second resolution. It could be therefor argued that
the resolution of this clock should be set to 1 second in general, but
that's outside the scope of this fix.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Kostya Serebryany <kcc@google.com>
Cc: syzkaller <syzkaller@googlegroups.com>
Cc: John Stultz <john.stultz@linaro.org>
Cc: Dmitry Vyukov <dvyukov@google.com>
Link: http://lkml.kernel.org/r/20170530211655.896767100@linutronix.de

---
 kernel/time/alarmtimer.c | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/kernel/time/alarmtimer.c b/kernel/time/alarmtimer.c
index 2b2e032..ee2f420 100644
--- a/kernel/time/alarmtimer.c
+++ b/kernel/time/alarmtimer.c
@@ -660,6 +660,14 @@ static int alarm_timer_set(struct k_itimer *timr, int flags,
 
 	/* start the timer */
 	timr->it.alarm.interval = timespec64_to_ktime(new_setting->it_interval);
+
+	/*
+	 * Rate limit to the tick as a hot fix to prevent DOS. Will be
+	 * mopped up later.
+	 */
+	if (timr->it.alarm.interval < TICK_NSEC)
+		timr->it.alarm.interval = TICK_NSEC;
+
 	exp = timespec64_to_ktime(new_setting->it_value);
 	/* Convert (if necessary) to absolute time */
 	if (flags != TIMER_ABSTIME) {

^ permalink raw reply	[flat|nested] 66+ messages in thread

* [tip:timers/urgent] alarmtimer: Prevent overflow of relative timers
  2017-05-30 21:15 ` [patch 01/26] alarmtimer: Prevent overflow of relative timers Thomas Gleixner
  2017-06-04 13:21   ` [tip:timers/urgent] " tip-bot for Thomas Gleixner
@ 2017-06-04 13:24   ` tip-bot for Thomas Gleixner
  1 sibling, 0 replies; 66+ messages in thread
From: tip-bot for Thomas Gleixner @ 2017-06-04 13:24 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: andreyknvl, john.stultz, kcc, mingo, tglx, hpa, linux-kernel,
	syzkaller, peterz, dvyukov

Commit-ID:  f4781e76f90df7aec400635d73ea4c35ee1d4765
Gitweb:     http://git.kernel.org/tip/f4781e76f90df7aec400635d73ea4c35ee1d4765
Author:     Thomas Gleixner <tglx@linutronix.de>
AuthorDate: Tue, 30 May 2017 23:15:34 +0200
Committer:  Thomas Gleixner <tglx@linutronix.de>
CommitDate: Sun, 4 Jun 2017 15:21:18 +0200

alarmtimer: Prevent overflow of relative timers

Andrey reported a alartimer related RCU stall while fuzzing the kernel with
syzkaller.

The reason for this is an overflow in ktime_add() which brings the
resulting time into negative space and causes immediate expiry of the
timer. The following rearm with a small interval does not bring the timer
back into positive space due to the same issue.

This results in a permanent firing alarmtimer which hogs the CPU.

Use ktime_add_safe() instead which detects the overflow and clamps the
result to KTIME_SEC_MAX.

Reported-by: Andrey Konovalov <andreyknvl@google.com>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Kostya Serebryany <kcc@google.com>
Cc: syzkaller <syzkaller@googlegroups.com>
Cc: John Stultz <john.stultz@linaro.org>
Cc: Dmitry Vyukov <dvyukov@google.com>
Cc: stable@vger.kernel.org
Link: http://lkml.kernel.org/r/20170530211655.802921648@linutronix.de

---
 kernel/time/alarmtimer.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/kernel/time/alarmtimer.c b/kernel/time/alarmtimer.c
index 5cb5b00..2b2e032 100644
--- a/kernel/time/alarmtimer.c
+++ b/kernel/time/alarmtimer.c
@@ -387,7 +387,7 @@ void alarm_start_relative(struct alarm *alarm, ktime_t start)
 {
 	struct alarm_base *base = &alarm_bases[alarm->type];
 
-	start = ktime_add(start, base->gettime());
+	start = ktime_add_safe(start, base->gettime());
 	alarm_start(alarm, start);
 }
 EXPORT_SYMBOL_GPL(alarm_start_relative);
@@ -475,7 +475,7 @@ u64 alarm_forward(struct alarm *alarm, ktime_t now, ktime_t interval)
 		overrun++;
 	}
 
-	alarm->node.expires = ktime_add(alarm->node.expires, interval);
+	alarm->node.expires = ktime_add_safe(alarm->node.expires, interval);
 	return overrun;
 }
 EXPORT_SYMBOL_GPL(alarm_forward);
@@ -666,7 +666,7 @@ static int alarm_timer_set(struct k_itimer *timr, int flags,
 		ktime_t now;
 
 		now = alarm_bases[timr->it.alarm.alarmtimer.type].gettime();
-		exp = ktime_add(now, exp);
+		exp = ktime_add_safe(now, exp);
 	}
 
 	alarm_start(&timr->it.alarm.alarmtimer, exp);

^ permalink raw reply	[flat|nested] 66+ messages in thread

* [tip:timers/urgent] alarmtimer: Rate limit periodic intervals
  2017-05-30 21:15 ` [patch 02/26] alarmtimer: Rate limit periodic intervals Thomas Gleixner
  2017-06-04 13:22   ` [tip:timers/urgent] " tip-bot for Thomas Gleixner
@ 2017-06-04 13:25   ` tip-bot for Thomas Gleixner
  1 sibling, 0 replies; 66+ messages in thread
From: tip-bot for Thomas Gleixner @ 2017-06-04 13:25 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: mingo, syzkaller, dvyukov, kcc, john.stultz, linux-kernel, hpa,
	tglx, peterz

Commit-ID:  ff86bf0c65f14346bf2440534f9ba5ac232c39a0
Gitweb:     http://git.kernel.org/tip/ff86bf0c65f14346bf2440534f9ba5ac232c39a0
Author:     Thomas Gleixner <tglx@linutronix.de>
AuthorDate: Tue, 30 May 2017 23:15:35 +0200
Committer:  Thomas Gleixner <tglx@linutronix.de>
CommitDate: Sun, 4 Jun 2017 15:21:18 +0200

alarmtimer: Rate limit periodic intervals

The alarmtimer code has another source of potentially rearming itself too
fast. Interval timers with a very samll interval have a similar CPU hog
effect as the previously fixed overflow issue.

The reason is that alarmtimers do not implement the normal protection
against this kind of problem which the other posix timer use:

  timer expires -> queue signal -> deliver signal -> rearm timer

This scheme brings the rearming under scheduler control and prevents
permanently firing timers which hog the CPU.

Bringing this scheme to the alarm timer code is a major overhaul because it
lacks all the necessary mechanisms completely.

So for a quick fix limit the interval to one jiffie. This is not
problematic in practice as alarmtimers are usually backed by an RTC for
suspend which have 1 second resolution. It could be therefor argued that
the resolution of this clock should be set to 1 second in general, but
that's outside the scope of this fix.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Kostya Serebryany <kcc@google.com>
Cc: syzkaller <syzkaller@googlegroups.com>
Cc: John Stultz <john.stultz@linaro.org>
Cc: Dmitry Vyukov <dvyukov@google.com>
Cc: stable@vger.kernel.org
Link: http://lkml.kernel.org/r/20170530211655.896767100@linutronix.de

---
 kernel/time/alarmtimer.c | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/kernel/time/alarmtimer.c b/kernel/time/alarmtimer.c
index 2b2e032..ee2f420 100644
--- a/kernel/time/alarmtimer.c
+++ b/kernel/time/alarmtimer.c
@@ -660,6 +660,14 @@ static int alarm_timer_set(struct k_itimer *timr, int flags,
 
 	/* start the timer */
 	timr->it.alarm.interval = timespec64_to_ktime(new_setting->it_interval);
+
+	/*
+	 * Rate limit to the tick as a hot fix to prevent DOS. Will be
+	 * mopped up later.
+	 */
+	if (timr->it.alarm.interval < TICK_NSEC)
+		timr->it.alarm.interval = TICK_NSEC;
+
 	exp = timespec64_to_ktime(new_setting->it_value);
 	/* Convert (if necessary) to absolute time */
 	if (flags != TIMER_ABSTIME) {

^ permalink raw reply	[flat|nested] 66+ messages in thread

* [tip:timers/core] alarmtimer: Remove pointless config conditional
  2017-05-30 21:15 ` [patch 03/26] alarmtimer: Remove pointless config conditional Thomas Gleixner
@ 2017-06-05  8:13   ` tip-bot for Thomas Gleixner
  0 siblings, 0 replies; 66+ messages in thread
From: tip-bot for Thomas Gleixner @ 2017-06-05  8:13 UTC (permalink / raw)
  To: linux-tip-commits; +Cc: peterz, mingo, tglx, john.stultz, linux-kernel, hpa

Commit-ID:  18c700c4e3d0a37c43a2df8b8f740121d4dac645
Gitweb:     http://git.kernel.org/tip/18c700c4e3d0a37c43a2df8b8f740121d4dac645
Author:     Thomas Gleixner <tglx@linutronix.de>
AuthorDate: Tue, 30 May 2017 23:15:36 +0200
Committer:  Thomas Gleixner <tglx@linutronix.de>
CommitDate: Sun, 4 Jun 2017 15:40:22 +0200

alarmtimer: Remove pointless config conditional

Having a IF_ENABLED(CONFIG_POSIX_TIMERS) inside of a
#ifdef CONFIG_POSIX_TIMERS section is pointless.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: John Stultz <john.stultz@linaro.org>
Link: http://lkml.kernel.org/r/20170530211655.975218056@linutronix.de

---
 kernel/time/alarmtimer.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/kernel/time/alarmtimer.c b/kernel/time/alarmtimer.c
index e645dcc..2a8675f 100644
--- a/kernel/time/alarmtimer.c
+++ b/kernel/time/alarmtimer.c
@@ -520,8 +520,7 @@ static enum alarmtimer_restart alarm_handle_timer(struct alarm *alarm,
 
 	spin_lock_irqsave(&ptr->it_lock, flags);
 	if ((ptr->it_sigev_notify & ~SIGEV_THREAD_ID) != SIGEV_NONE) {
-		if (IS_ENABLED(CONFIG_POSIX_TIMERS) &&
-		    posix_timer_event(ptr, 0) != 0)
+		if (posix_timer_event(ptr, 0))
 			ptr->it_overrun++;
 	}
 

^ permalink raw reply	[flat|nested] 66+ messages in thread

* [tip:timers/core] posix-timers: Remove unused export of posix_timer_event()
  2017-05-30 21:15 ` [patch 04/26] posix-timers: Remove unused export of posix_timer_event() Thomas Gleixner
@ 2017-06-05  8:13   ` tip-bot for Thomas Gleixner
  0 siblings, 0 replies; 66+ messages in thread
From: tip-bot for Thomas Gleixner @ 2017-06-05  8:13 UTC (permalink / raw)
  To: linux-tip-commits; +Cc: linux-kernel, hpa, john.stultz, tglx, peterz, mingo

Commit-ID:  a81129e5a189973abd661704b261f8aad9325407
Gitweb:     http://git.kernel.org/tip/a81129e5a189973abd661704b261f8aad9325407
Author:     Thomas Gleixner <tglx@linutronix.de>
AuthorDate: Tue, 30 May 2017 23:15:37 +0200
Committer:  Thomas Gleixner <tglx@linutronix.de>
CommitDate: Sun, 4 Jun 2017 15:40:22 +0200

posix-timers: Remove unused export of posix_timer_event()

Since the removal of the mmtimer driver the export is not longer needed.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: John Stultz <john.stultz@linaro.org>
Link: http://lkml.kernel.org/r/20170530211656.052744418@linutronix.de

---
 kernel/time/posix-timers.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/kernel/time/posix-timers.c b/kernel/time/posix-timers.c
index 0c0cccf..44d4865 100644
--- a/kernel/time/posix-timers.c
+++ b/kernel/time/posix-timers.c
@@ -442,7 +442,6 @@ int posix_timer_event(struct k_itimer *timr, int si_private)
 	/* If we failed to send the signal the timer stops. */
 	return ret > 0;
 }
-EXPORT_SYMBOL_GPL(posix_timer_event);
 
 /*
  * This function gets called when a POSIX.1b interval timer expires.  It

^ permalink raw reply	[flat|nested] 66+ messages in thread

* [tip:timers/core] posix-clocks: Remove interval timer facility and mmap/fasync callbacks
  2017-05-30 21:15 ` [patch 05/26] posix-clocks: Remove interval timer facility and mmap/fasync callbacks Thomas Gleixner
  2017-05-31  9:00   ` Richard Cochran
@ 2017-06-05  8:14   ` tip-bot for Thomas Gleixner
  1 sibling, 0 replies; 66+ messages in thread
From: tip-bot for Thomas Gleixner @ 2017-06-05  8:14 UTC (permalink / raw)
  To: linux-tip-commits; +Cc: mingo, john.stultz, peterz, tglx, hpa, linux-kernel

Commit-ID:  3a06c7ac24f9f24ec059cd77c2dbdf7fbfd0aaaf
Gitweb:     http://git.kernel.org/tip/3a06c7ac24f9f24ec059cd77c2dbdf7fbfd0aaaf
Author:     Thomas Gleixner <tglx@linutronix.de>
AuthorDate: Tue, 30 May 2017 23:15:38 +0200
Committer:  Thomas Gleixner <tglx@linutronix.de>
CommitDate: Sun, 4 Jun 2017 15:40:22 +0200

posix-clocks: Remove interval timer facility and mmap/fasync callbacks

The only user of this facility is ptp_clock, which does not implement any of
those functions.

Remove them to prevent accidental users. Especially the interval timer
interfaces are now more or less impossible to implement because the
necessary infrastructure has been confined to the core code. Aside of that
it's really complex to make these callbacks implemented according to spec
as the alarm timer implementation demonstrates. If at all then a nanosleep
callback might be a reasonable extension. For now keep just what ptp_clock
needs.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: John Stultz <john.stultz@linaro.org>
Link: http://lkml.kernel.org/r/20170530211656.145036286@linutronix.de

---
 include/linux/posix-clock.h |  22 ---------
 kernel/time/posix-clock.c   | 113 --------------------------------------------
 2 files changed, 135 deletions(-)

diff --git a/include/linux/posix-clock.h b/include/linux/posix-clock.h
index 83b22ae..38d8225 100644
--- a/include/linux/posix-clock.h
+++ b/include/linux/posix-clock.h
@@ -42,12 +42,6 @@ struct posix_clock;
  * @clock_gettime:  Read the current time
  * @clock_getres:   Get the clock resolution
  * @clock_settime:  Set the current time value
- * @timer_create:   Create a new timer
- * @timer_delete:   Remove a previously created timer
- * @timer_gettime:  Get remaining time and interval of a timer
- * @timer_settime: Set a timer's initial expiration and interval
- * @fasync:         Optional character device fasync method
- * @mmap:           Optional character device mmap method
  * @open:           Optional character device open method
  * @release:        Optional character device release method
  * @ioctl:          Optional character device ioctl method
@@ -66,28 +60,12 @@ struct posix_clock_operations {
 	int  (*clock_settime)(struct posix_clock *pc,
 			      const struct timespec64 *ts);
 
-	int  (*timer_create) (struct posix_clock *pc, struct k_itimer *kit);
-
-	int  (*timer_delete) (struct posix_clock *pc, struct k_itimer *kit);
-
-	void (*timer_gettime)(struct posix_clock *pc,
-			      struct k_itimer *kit, struct itimerspec64 *tsp);
-
-	int  (*timer_settime)(struct posix_clock *pc,
-			      struct k_itimer *kit, int flags,
-			      struct itimerspec64 *tsp, struct itimerspec64 *old);
 	/*
 	 * Optional character device methods:
 	 */
-	int     (*fasync)  (struct posix_clock *pc,
-			    int fd, struct file *file, int on);
-
 	long    (*ioctl)   (struct posix_clock *pc,
 			    unsigned int cmd, unsigned long arg);
 
-	int     (*mmap)    (struct posix_clock *pc,
-			    struct vm_area_struct *vma);
-
 	int     (*open)    (struct posix_clock *pc, fmode_t f_mode);
 
 	uint    (*poll)    (struct posix_clock *pc,
diff --git a/kernel/time/posix-clock.c b/kernel/time/posix-clock.c
index 7e45300..bd4fb78 100644
--- a/kernel/time/posix-clock.c
+++ b/kernel/time/posix-clock.c
@@ -82,38 +82,6 @@ static unsigned int posix_clock_poll(struct file *fp, poll_table *wait)
 	return result;
 }
 
-static int posix_clock_fasync(int fd, struct file *fp, int on)
-{
-	struct posix_clock *clk = get_posix_clock(fp);
-	int err = 0;
-
-	if (!clk)
-		return -ENODEV;
-
-	if (clk->ops.fasync)
-		err = clk->ops.fasync(clk, fd, fp, on);
-
-	put_posix_clock(clk);
-
-	return err;
-}
-
-static int posix_clock_mmap(struct file *fp, struct vm_area_struct *vma)
-{
-	struct posix_clock *clk = get_posix_clock(fp);
-	int err = -ENODEV;
-
-	if (!clk)
-		return -ENODEV;
-
-	if (clk->ops.mmap)
-		err = clk->ops.mmap(clk, vma);
-
-	put_posix_clock(clk);
-
-	return err;
-}
-
 static long posix_clock_ioctl(struct file *fp,
 			      unsigned int cmd, unsigned long arg)
 {
@@ -199,8 +167,6 @@ static const struct file_operations posix_clock_file_operations = {
 	.unlocked_ioctl	= posix_clock_ioctl,
 	.open		= posix_clock_open,
 	.release	= posix_clock_release,
-	.fasync		= posix_clock_fasync,
-	.mmap		= posix_clock_mmap,
 #ifdef CONFIG_COMPAT
 	.compat_ioctl	= posix_clock_compat_ioctl,
 #endif
@@ -359,88 +325,9 @@ out:
 	return err;
 }
 
-static int pc_timer_create(struct k_itimer *kit)
-{
-	clockid_t id = kit->it_clock;
-	struct posix_clock_desc cd;
-	int err;
-
-	err = get_clock_desc(id, &cd);
-	if (err)
-		return err;
-
-	if (cd.clk->ops.timer_create)
-		err = cd.clk->ops.timer_create(cd.clk, kit);
-	else
-		err = -EOPNOTSUPP;
-
-	put_clock_desc(&cd);
-
-	return err;
-}
-
-static int pc_timer_delete(struct k_itimer *kit)
-{
-	clockid_t id = kit->it_clock;
-	struct posix_clock_desc cd;
-	int err;
-
-	err = get_clock_desc(id, &cd);
-	if (err)
-		return err;
-
-	if (cd.clk->ops.timer_delete)
-		err = cd.clk->ops.timer_delete(cd.clk, kit);
-	else
-		err = -EOPNOTSUPP;
-
-	put_clock_desc(&cd);
-
-	return err;
-}
-
-static void pc_timer_gettime(struct k_itimer *kit, struct itimerspec64 *ts)
-{
-	clockid_t id = kit->it_clock;
-	struct posix_clock_desc cd;
-
-	if (get_clock_desc(id, &cd))
-		return;
-
-	if (cd.clk->ops.timer_gettime)
-		cd.clk->ops.timer_gettime(cd.clk, kit, ts);
-
-	put_clock_desc(&cd);
-}
-
-static int pc_timer_settime(struct k_itimer *kit, int flags,
-			    struct itimerspec64 *ts, struct itimerspec64 *old)
-{
-	clockid_t id = kit->it_clock;
-	struct posix_clock_desc cd;
-	int err;
-
-	err = get_clock_desc(id, &cd);
-	if (err)
-		return err;
-
-	if (cd.clk->ops.timer_settime)
-		err = cd.clk->ops.timer_settime(cd.clk, kit, flags, ts, old);
-	else
-		err = -EOPNOTSUPP;
-
-	put_clock_desc(&cd);
-
-	return err;
-}
-
 const struct k_clock clock_posix_dynamic = {
 	.clock_getres	= pc_clock_getres,
 	.clock_set	= pc_clock_settime,
 	.clock_get	= pc_clock_gettime,
 	.clock_adj	= pc_clock_adjtime,
-	.timer_create	= pc_timer_create,
-	.timer_set	= pc_timer_settime,
-	.timer_del	= pc_timer_delete,
-	.timer_get	= pc_timer_gettime,
 };

^ permalink raw reply	[flat|nested] 66+ messages in thread

* [tip:timers/core] posix-timers: Avoid gazillions of forward declarations
  2017-05-30 21:15 ` [patch 06/26] posix-timers: Avoid gazillions of forward declarations Thomas Gleixner
@ 2017-06-05  8:14   ` tip-bot for Thomas Gleixner
  0 siblings, 0 replies; 66+ messages in thread
From: tip-bot for Thomas Gleixner @ 2017-06-05  8:14 UTC (permalink / raw)
  To: linux-tip-commits; +Cc: mingo, tglx, linux-kernel, hpa, john.stultz, peterz

Commit-ID:  6631fa12c105e326bbe5fb215eb216e86c90d1ba
Gitweb:     http://git.kernel.org/tip/6631fa12c105e326bbe5fb215eb216e86c90d1ba
Author:     Thomas Gleixner <tglx@linutronix.de>
AuthorDate: Tue, 30 May 2017 23:15:39 +0200
Committer:  Thomas Gleixner <tglx@linutronix.de>
CommitDate: Sun, 4 Jun 2017 15:40:23 +0200

posix-timers: Avoid gazillions of forward declarations

Move it below the actual implementations as there are new callbacks coming
which would require even more forward declarations.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: John Stultz <john.stultz@linaro.org>
Link: http://lkml.kernel.org/r/20170530211656.238209952@linutronix.de

---
 kernel/time/posix-timers.c | 190 +++++++++++++++++++++------------------------
 1 file changed, 89 insertions(+), 101 deletions(-)

diff --git a/kernel/time/posix-timers.c b/kernel/time/posix-timers.c
index 44d4865..b60b655 100644
--- a/kernel/time/posix-timers.c
+++ b/kernel/time/posix-timers.c
@@ -69,6 +69,9 @@ static struct kmem_cache *posix_timers_cache;
 static DEFINE_HASHTABLE(posix_timers_hashtable, 9);
 static DEFINE_SPINLOCK(hash_lock);
 
+static const struct k_clock * const posix_clocks[];
+static const struct k_clock *clockid_to_kclock(const clockid_t id);
+
 /*
  * we assume that the new SIGEV_THREAD_ID shares no bits with the other
  * SIGEV values.  Here we put out an error if this assumption fails.
@@ -124,20 +127,6 @@ static DEFINE_SPINLOCK(hash_lock);
  *	    have is CLOCK_REALTIME and its high res counter part, both of
  *	    which we beg off on and pass to do_sys_settimeofday().
  */
-
-/*
- * These ones are defined below.
- */
-static int common_nsleep(const clockid_t, int flags, struct timespec64 *t,
-			 struct timespec __user *rmtp);
-static int common_timer_create(struct k_itimer *new_timer);
-static void common_timer_get(struct k_itimer *, struct itimerspec64 *);
-static int common_timer_set(struct k_itimer *, int,
-			    struct itimerspec64 *, struct itimerspec64 *);
-static int common_timer_del(struct k_itimer *timer);
-
-static enum hrtimer_restart posix_timer_fn(struct hrtimer *data);
-
 static struct k_itimer *__lock_timer(timer_t timer_id, unsigned long *flags);
 
 #define lock_timer(tid, flags)						   \
@@ -278,82 +267,6 @@ static int posix_get_hrtimer_res(clockid_t which_clock, struct timespec64 *tp)
 	return 0;
 }
 
-
-static const struct k_clock clock_realtime = {
-	.clock_getres	= posix_get_hrtimer_res,
-	.clock_get	= posix_clock_realtime_get,
-	.clock_set	= posix_clock_realtime_set,
-	.clock_adj	= posix_clock_realtime_adj,
-	.nsleep		= common_nsleep,
-	.nsleep_restart	= hrtimer_nanosleep_restart,
-	.timer_create	= common_timer_create,
-	.timer_set	= common_timer_set,
-	.timer_get	= common_timer_get,
-	.timer_del	= common_timer_del,
-};
-
-static const struct k_clock clock_monotonic = {
-	.clock_getres	= posix_get_hrtimer_res,
-	.clock_get	= posix_ktime_get_ts,
-	.nsleep		= common_nsleep,
-	.nsleep_restart	= hrtimer_nanosleep_restart,
-	.timer_create	= common_timer_create,
-	.timer_set	= common_timer_set,
-	.timer_get	= common_timer_get,
-	.timer_del	= common_timer_del,
-};
-
-static const struct k_clock clock_monotonic_raw = {
-	.clock_getres	= posix_get_hrtimer_res,
-	.clock_get	= posix_get_monotonic_raw,
-};
-
-static const struct k_clock clock_realtime_coarse = {
-	.clock_getres	= posix_get_coarse_res,
-	.clock_get	= posix_get_realtime_coarse,
-};
-
-static const struct k_clock clock_monotonic_coarse = {
-	.clock_getres	= posix_get_coarse_res,
-	.clock_get	= posix_get_monotonic_coarse,
-};
-
-static const struct k_clock clock_tai = {
-	.clock_getres	= posix_get_hrtimer_res,
-	.clock_get	= posix_get_tai,
-	.nsleep		= common_nsleep,
-	.nsleep_restart	= hrtimer_nanosleep_restart,
-	.timer_create	= common_timer_create,
-	.timer_set	= common_timer_set,
-	.timer_get	= common_timer_get,
-	.timer_del	= common_timer_del,
-};
-
-static const struct k_clock clock_boottime = {
-	.clock_getres	= posix_get_hrtimer_res,
-	.clock_get	= posix_get_boottime,
-	.nsleep		= common_nsleep,
-	.nsleep_restart	= hrtimer_nanosleep_restart,
-	.timer_create	= common_timer_create,
-	.timer_set	= common_timer_set,
-	.timer_get	= common_timer_get,
-	.timer_del	= common_timer_del,
-};
-
-static const struct k_clock * const posix_clocks[] = {
-	[CLOCK_REALTIME]		= &clock_realtime,
-	[CLOCK_MONOTONIC]		= &clock_monotonic,
-	[CLOCK_PROCESS_CPUTIME_ID]	= &clock_process,
-	[CLOCK_THREAD_CPUTIME_ID]	= &clock_thread,
-	[CLOCK_MONOTONIC_RAW]		= &clock_monotonic_raw,
-	[CLOCK_REALTIME_COARSE]		= &clock_realtime_coarse,
-	[CLOCK_MONOTONIC_COARSE]	= &clock_monotonic_coarse,
-	[CLOCK_BOOTTIME]		= &clock_boottime,
-	[CLOCK_REALTIME_ALARM]		= &alarm_clock,
-	[CLOCK_BOOTTIME_ALARM]		= &alarm_clock,
-	[CLOCK_TAI]			= &clock_tai,
-};
-
 /*
  * Initialize everything, well, just everything in Posix clocks/timers ;)
  */
@@ -567,17 +480,6 @@ static void release_posix_timer(struct k_itimer *tmr, int it_id_set)
 	call_rcu(&tmr->it.rcu, k_itimer_rcu_free);
 }
 
-static const struct k_clock *clockid_to_kclock(const clockid_t id)
-{
-	if (id < 0)
-		return (id & CLOCKFD_MASK) == CLOCKFD ?
-			&clock_posix_dynamic : &clock_posix_cpu;
-
-	if (id >= ARRAY_SIZE(posix_clocks) || !posix_clocks[id])
-		return NULL;
-	return posix_clocks[id];
-}
-
 static int common_timer_create(struct k_itimer *new_timer)
 {
 	hrtimer_init(&new_timer->it.real.timer, new_timer->it_clock, 0);
@@ -1129,3 +1031,89 @@ long clock_nanosleep_restart(struct restart_block *restart_block)
 
 	return kc->nsleep_restart(restart_block);
 }
+
+static const struct k_clock clock_realtime = {
+	.clock_getres	= posix_get_hrtimer_res,
+	.clock_get	= posix_clock_realtime_get,
+	.clock_set	= posix_clock_realtime_set,
+	.clock_adj	= posix_clock_realtime_adj,
+	.nsleep		= common_nsleep,
+	.nsleep_restart	= hrtimer_nanosleep_restart,
+	.timer_create	= common_timer_create,
+	.timer_set	= common_timer_set,
+	.timer_get	= common_timer_get,
+	.timer_del	= common_timer_del,
+};
+
+static const struct k_clock clock_monotonic = {
+	.clock_getres	= posix_get_hrtimer_res,
+	.clock_get	= posix_ktime_get_ts,
+	.nsleep		= common_nsleep,
+	.nsleep_restart	= hrtimer_nanosleep_restart,
+	.timer_create	= common_timer_create,
+	.timer_set	= common_timer_set,
+	.timer_get	= common_timer_get,
+	.timer_del	= common_timer_del,
+};
+
+static const struct k_clock clock_monotonic_raw = {
+	.clock_getres	= posix_get_hrtimer_res,
+	.clock_get	= posix_get_monotonic_raw,
+};
+
+static const struct k_clock clock_realtime_coarse = {
+	.clock_getres	= posix_get_coarse_res,
+	.clock_get	= posix_get_realtime_coarse,
+};
+
+static const struct k_clock clock_monotonic_coarse = {
+	.clock_getres	= posix_get_coarse_res,
+	.clock_get	= posix_get_monotonic_coarse,
+};
+
+static const struct k_clock clock_tai = {
+	.clock_getres	= posix_get_hrtimer_res,
+	.clock_get	= posix_get_tai,
+	.nsleep		= common_nsleep,
+	.nsleep_restart	= hrtimer_nanosleep_restart,
+	.timer_create	= common_timer_create,
+	.timer_set	= common_timer_set,
+	.timer_get	= common_timer_get,
+	.timer_del	= common_timer_del,
+};
+
+static const struct k_clock clock_boottime = {
+	.clock_getres	= posix_get_hrtimer_res,
+	.clock_get	= posix_get_boottime,
+	.nsleep		= common_nsleep,
+	.nsleep_restart	= hrtimer_nanosleep_restart,
+	.timer_create	= common_timer_create,
+	.timer_set	= common_timer_set,
+	.timer_get	= common_timer_get,
+	.timer_del	= common_timer_del,
+};
+
+static const struct k_clock * const posix_clocks[] = {
+	[CLOCK_REALTIME]		= &clock_realtime,
+	[CLOCK_MONOTONIC]		= &clock_monotonic,
+	[CLOCK_PROCESS_CPUTIME_ID]	= &clock_process,
+	[CLOCK_THREAD_CPUTIME_ID]	= &clock_thread,
+	[CLOCK_MONOTONIC_RAW]		= &clock_monotonic_raw,
+	[CLOCK_REALTIME_COARSE]		= &clock_realtime_coarse,
+	[CLOCK_MONOTONIC_COARSE]	= &clock_monotonic_coarse,
+	[CLOCK_BOOTTIME]		= &clock_boottime,
+	[CLOCK_REALTIME_ALARM]		= &alarm_clock,
+	[CLOCK_BOOTTIME_ALARM]		= &alarm_clock,
+	[CLOCK_TAI]			= &clock_tai,
+};
+
+static const struct k_clock *clockid_to_kclock(const clockid_t id)
+{
+	if (id < 0)
+		return (id & CLOCKFD_MASK) == CLOCKFD ?
+			&clock_posix_dynamic : &clock_posix_cpu;
+
+	if (id >= ARRAY_SIZE(posix_clocks) || !posix_clocks[id])
+		return NULL;
+	return posix_clocks[id];
+}

^ permalink raw reply	[flat|nested] 66+ messages in thread

* [tip:timers/core] posix-timers: Cleanup struct k_itimer
  2017-05-30 21:15 ` [patch 07/26] posix-timers: Cleanup struct k_itimer Thomas Gleixner
@ 2017-06-05  8:15   ` tip-bot for Thomas Gleixner
  0 siblings, 0 replies; 66+ messages in thread
From: tip-bot for Thomas Gleixner @ 2017-06-05  8:15 UTC (permalink / raw)
  To: linux-tip-commits; +Cc: john.stultz, peterz, tglx, hpa, mingo, linux-kernel

Commit-ID:  03676b41a8ffcbb1f6d9eb6ca754b2bfa431fd59
Gitweb:     http://git.kernel.org/tip/03676b41a8ffcbb1f6d9eb6ca754b2bfa431fd59
Author:     Thomas Gleixner <tglx@linutronix.de>
AuthorDate: Tue, 30 May 2017 23:15:40 +0200
Committer:  Thomas Gleixner <tglx@linutronix.de>
CommitDate: Sun, 4 Jun 2017 15:40:23 +0200

posix-timers: Cleanup struct k_itimer

As a preparation for further changes, cleanup the formatting of the
k_itimer structure and add kernel doc comments.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: John Stultz <john.stultz@linaro.org>
Link: http://lkml.kernel.org/r/20170530211656.316574129@linutronix.de

---
 include/linux/posix-timers.h | 61 +++++++++++++++++++++++++++++---------------
 1 file changed, 40 insertions(+), 21 deletions(-)

diff --git a/include/linux/posix-timers.h b/include/linux/posix-timers.h
index 8929f7e..e06062c 100644
--- a/include/linux/posix-timers.h
+++ b/include/linux/posix-timers.h
@@ -49,35 +49,54 @@ struct cpu_timer_list {
 #define FD_TO_CLOCKID(fd)	((~(clockid_t) (fd) << 3) | CLOCKFD)
 #define CLOCKID_TO_FD(clk)	((unsigned int) ~((clk) >> 3))
 
-/* POSIX.1b interval timer structure. */
-struct k_itimer {
-	struct list_head list;		/* free/ allocate list */
-	struct hlist_node t_hash;
-	spinlock_t it_lock;
-	clockid_t it_clock;		/* which timer type */
-	timer_t it_id;			/* timer id */
-	int it_overrun;			/* overrun on pending signal  */
-	int it_overrun_last;		/* overrun on last delivered signal */
-	int it_requeue_pending;		/* waiting to requeue this timer */
 #define REQUEUE_PENDING 1
-	int it_sigev_notify;		/* notify word of sigevent struct */
-	struct signal_struct *it_signal;
+
+/**
+ * struct k_itimer - POSIX.1b interval timer structure.
+ * @list:		List head for binding the timer to signals->posix_timers
+ * @t_hash:		Entry in the posix timer hash table
+ * @it_lock:		Lock protecting the timer
+ * @it_clock:		The posix timer clock id
+ * @it_id:		The posix timer id for identifying the timer
+ * @it_overrun:		The overrun counter for pending signals
+ * @it_overrun_last:	The overrun at the time of the last delivered signal
+ * @it_requeue_pending:	Indicator that timer waits for being requeued on
+ *			signal delivery
+ * @it_sigev_notify:	The notify word of sigevent struct for signal delivery
+ * @it_signal:		Pointer to the creators signal struct
+ * @it_pid:		The pid of the process/task targeted by the signal
+ * @it_process:		The task to wakeup on clock_nanosleep (CPU timers)
+ * @sigq:		Pointer to preallocated sigqueue
+ * @it:			Union representing the various posix timer type
+ *			internals. Also used for rcu freeing the timer.
+ */
+struct k_itimer {
+	struct list_head	list;
+	struct hlist_node	t_hash;
+	spinlock_t		it_lock;
+	clockid_t		it_clock;
+	timer_t			it_id;
+	int			it_overrun;
+	int			it_overrun_last;
+	int			it_requeue_pending;
+	int			it_sigev_notify;
+	struct signal_struct	*it_signal;
 	union {
-		struct pid *it_pid;	/* pid of process to send signal to */
-		struct task_struct *it_process;	/* for clock_nanosleep */
+		struct pid		*it_pid;
+		struct task_struct	*it_process;
 	};
-	struct sigqueue *sigq;		/* signal queue entry. */
+	struct sigqueue		*sigq;
 	union {
 		struct {
-			struct hrtimer timer;
-			ktime_t interval;
+			struct hrtimer	timer;
+			ktime_t		interval;
 		} real;
-		struct cpu_timer_list cpu;
+		struct cpu_timer_list	cpu;
 		struct {
-			struct alarm alarmtimer;
-			ktime_t interval;
+			struct alarm	alarmtimer;
+			ktime_t		interval;
 		} alarm;
-		struct rcu_head rcu;
+		struct rcu_head		rcu;
 	} it;
 };
 

^ permalink raw reply	[flat|nested] 66+ messages in thread

* [tip:timers/core] posix-timers: Move posix-timer internals to core
  2017-05-30 21:15 ` [patch 08/26] posix-timers: Move posix-timer internals to core Thomas Gleixner
  2017-05-31 15:37   ` Christoph Hellwig
@ 2017-06-05  8:15   ` tip-bot for Thomas Gleixner
  1 sibling, 0 replies; 66+ messages in thread
From: tip-bot for Thomas Gleixner @ 2017-06-05  8:15 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: hpa, mingo, tglx, hch, john.stultz, peterz, linux-kernel

Commit-ID:  bab0aae9dcba9466dcc968b8bd21914f8f691631
Gitweb:     http://git.kernel.org/tip/bab0aae9dcba9466dcc968b8bd21914f8f691631
Author:     Thomas Gleixner <tglx@linutronix.de>
AuthorDate: Tue, 30 May 2017 23:15:41 +0200
Committer:  Thomas Gleixner <tglx@linutronix.de>
CommitDate: Sun, 4 Jun 2017 15:40:23 +0200

posix-timers: Move posix-timer internals to core

None of these declarations is required outside of kernel/time. Move them to
an internal header.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: John Stultz <john.stultz@linaro.org>
Cc: Christoph Hellwig <hch@lst.de>
Link: http://lkml.kernel.org/r/20170530211656.394803853@linutronix.de

---
 include/linux/posix-timers.h   | 30 ------------------------------
 kernel/time/alarmtimer.c       |  2 ++
 kernel/time/posix-clock.c      |  2 ++
 kernel/time/posix-cpu-timers.c |  2 ++
 kernel/time/posix-timers.c     |  1 +
 kernel/time/posix-timers.h     | 29 +++++++++++++++++++++++++++++
 6 files changed, 36 insertions(+), 30 deletions(-)

diff --git a/include/linux/posix-timers.h b/include/linux/posix-timers.h
index e06062c..a372e7e 100644
--- a/include/linux/posix-timers.h
+++ b/include/linux/posix-timers.h
@@ -100,36 +100,6 @@ struct k_itimer {
 	} it;
 };
 
-struct k_clock {
-	int (*clock_getres) (const clockid_t which_clock, struct timespec64 *tp);
-	int (*clock_set) (const clockid_t which_clock,
-			  const struct timespec64 *tp);
-	int (*clock_get) (const clockid_t which_clock, struct timespec64 *tp);
-	int (*clock_adj) (const clockid_t which_clock, struct timex *tx);
-	int (*timer_create) (struct k_itimer *timer);
-	int (*nsleep) (const clockid_t which_clock, int flags,
-		       struct timespec64 *, struct timespec __user *);
-	long (*nsleep_restart) (struct restart_block *restart_block);
-	int (*timer_set) (struct k_itimer *timr, int flags,
-			  struct itimerspec64 *new_setting,
-			  struct itimerspec64 *old_setting);
-	int (*timer_del) (struct k_itimer *timr);
-#define TIMER_RETRY 1
-	void (*timer_get) (struct k_itimer *timr,
-			   struct itimerspec64 *cur_setting);
-};
-
-extern const struct k_clock clock_posix_cpu;
-extern const struct k_clock clock_posix_dynamic;
-extern const struct k_clock clock_process;
-extern const struct k_clock clock_thread;
-extern const struct k_clock alarm_clock;
-
-/* function to call to trigger timer event */
-int posix_timer_event(struct k_itimer *timr, int si_private);
-
-void posix_cpu_timer_schedule(struct k_itimer *timer);
-
 void run_posix_cpu_timers(struct task_struct *task);
 void posix_cpu_timers_exit(struct task_struct *task);
 void posix_cpu_timers_exit_group(struct task_struct *task);
diff --git a/kernel/time/alarmtimer.c b/kernel/time/alarmtimer.c
index 2a8675f..36855d6 100644
--- a/kernel/time/alarmtimer.c
+++ b/kernel/time/alarmtimer.c
@@ -28,6 +28,8 @@
 #include <linux/workqueue.h>
 #include <linux/freezer.h>
 
+#include "posix-timers.h"
+
 #define CREATE_TRACE_POINTS
 #include <trace/events/alarmtimer.h>
 
diff --git a/kernel/time/posix-clock.c b/kernel/time/posix-clock.c
index bd4fb78..17cdc55 100644
--- a/kernel/time/posix-clock.c
+++ b/kernel/time/posix-clock.c
@@ -25,6 +25,8 @@
 #include <linux/syscalls.h>
 #include <linux/uaccess.h>
 
+#include "posix-timers.h"
+
 static void delete_clock(struct kref *kref);
 
 /*
diff --git a/kernel/time/posix-cpu-timers.c b/kernel/time/posix-cpu-timers.c
index c994347..a77a792 100644
--- a/kernel/time/posix-cpu-timers.c
+++ b/kernel/time/posix-cpu-timers.c
@@ -13,6 +13,8 @@
 #include <linux/tick.h>
 #include <linux/workqueue.h>
 
+#include "posix-timers.h"
+
 /*
  * Called after updating RLIMIT_CPU to run cpu timer and update
  * tsk->signal->cputime_expires expiration cache if necessary. Needs
diff --git a/kernel/time/posix-timers.c b/kernel/time/posix-timers.c
index b60b655..dee6a0d 100644
--- a/kernel/time/posix-timers.c
+++ b/kernel/time/posix-timers.c
@@ -51,6 +51,7 @@
 #include <linux/hashtable.h>
 
 #include "timekeeping.h"
+#include "posix-timers.h"
 
 /*
  * Management arrays for POSIX timers. Timers are now kept in static hash table
diff --git a/kernel/time/posix-timers.h b/kernel/time/posix-timers.h
new file mode 100644
index 0000000..ad2dbd2
--- /dev/null
+++ b/kernel/time/posix-timers.h
@@ -0,0 +1,29 @@
+#define TIMER_RETRY 1
+
+struct k_clock {
+	int (*clock_getres) (const clockid_t which_clock, struct timespec64 *tp);
+	int (*clock_set) (const clockid_t which_clock,
+			  const struct timespec64 *tp);
+	int (*clock_get) (const clockid_t which_clock, struct timespec64 *tp);
+	int (*clock_adj) (const clockid_t which_clock, struct timex *tx);
+	int (*timer_create) (struct k_itimer *timer);
+	int (*nsleep) (const clockid_t which_clock, int flags,
+		       struct timespec64 *, struct timespec __user *);
+	long (*nsleep_restart) (struct restart_block *restart_block);
+	int (*timer_set) (struct k_itimer *timr, int flags,
+			  struct itimerspec64 *new_setting,
+			  struct itimerspec64 *old_setting);
+	int (*timer_del) (struct k_itimer *timr);
+	void (*timer_get) (struct k_itimer *timr,
+			   struct itimerspec64 *cur_setting);
+};
+
+extern const struct k_clock clock_posix_cpu;
+extern const struct k_clock clock_posix_dynamic;
+extern const struct k_clock clock_process;
+extern const struct k_clock clock_thread;
+extern const struct k_clock alarm_clock;
+
+int posix_timer_event(struct k_itimer *timr, int si_private);
+
+void posix_cpu_timer_schedule(struct k_itimer *timer);

^ permalink raw reply	[flat|nested] 66+ messages in thread

* [tip:timers/core] posix-timers: Unify overrun/requeue_pending handling
  2017-05-30 21:15 ` [patch 09/26] posix-timers: Unify overrun/requeue_pending handling Thomas Gleixner
@ 2017-06-05  8:16   ` tip-bot for Thomas Gleixner
  0 siblings, 0 replies; 66+ messages in thread
From: tip-bot for Thomas Gleixner @ 2017-06-05  8:16 UTC (permalink / raw)
  To: linux-tip-commits; +Cc: linux-kernel, tglx, peterz, hpa, john.stultz, mingo

Commit-ID:  af888d677a3f4473c198b4720319dd037f398b51
Gitweb:     http://git.kernel.org/tip/af888d677a3f4473c198b4720319dd037f398b51
Author:     Thomas Gleixner <tglx@linutronix.de>
AuthorDate: Tue, 30 May 2017 23:15:42 +0200
Committer:  Thomas Gleixner <tglx@linutronix.de>
CommitDate: Sun, 4 Jun 2017 15:40:24 +0200

posix-timers: Unify overrun/requeue_pending handling

hrtimer based posix-timers and posix-cpu-timers handle the update of the
rearming and overflow related status fields differently.

Move that update to the common rearming code.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: John Stultz <john.stultz@linaro.org>
Link: http://lkml.kernel.org/r/20170530211656.484936964@linutronix.de

---
 kernel/time/posix-cpu-timers.c | 18 +++++++-----------
 kernel/time/posix-timers.c     | 15 ++++++++-------
 2 files changed, 15 insertions(+), 18 deletions(-)

diff --git a/kernel/time/posix-cpu-timers.c b/kernel/time/posix-cpu-timers.c
index a77a792..1683e50 100644
--- a/kernel/time/posix-cpu-timers.c
+++ b/kernel/time/posix-cpu-timers.c
@@ -527,6 +527,7 @@ static void cpu_timer_fire(struct k_itimer *timer)
 		 * ticking in case the signal is deliverable next time.
 		 */
 		posix_cpu_timer_schedule(timer);
+		++timer->it_requeue_pending;
 	}
 }
 
@@ -997,12 +998,12 @@ void posix_cpu_timer_schedule(struct k_itimer *timer)
 		cpu_clock_sample(timer->it_clock, p, &now);
 		bump_cpu_timer(timer, now);
 		if (unlikely(p->exit_state))
-			goto out;
+			return;
 
 		/* Protect timer list r/w in arm_timer() */
 		sighand = lock_task_sighand(p, &flags);
 		if (!sighand)
-			goto out;
+			return;
 	} else {
 		/*
 		 * Protect arm_timer() and timer sampling in case of call to
@@ -1015,11 +1016,10 @@ void posix_cpu_timer_schedule(struct k_itimer *timer)
 			 * We can't even collect a sample any more.
 			 */
 			timer->it.cpu.expires = 0;
-			goto out;
+			return;
 		} else if (unlikely(p->exit_state) && thread_group_empty(p)) {
-			unlock_task_sighand(p, &flags);
-			/* Optimizations: if the process is dying, no need to rearm */
-			goto out;
+			/* If the process is dying, no need to rearm */
+			goto unlock;
 		}
 		cpu_timer_sample_group(timer->it_clock, p, &now);
 		bump_cpu_timer(timer, now);
@@ -1031,12 +1031,8 @@ void posix_cpu_timer_schedule(struct k_itimer *timer)
 	 */
 	WARN_ON_ONCE(!irqs_disabled());
 	arm_timer(timer);
+unlock:
 	unlock_task_sighand(p, &flags);
-
-out:
-	timer->it_overrun_last = timer->it_overrun;
-	timer->it_overrun = -1;
-	++timer->it_requeue_pending;
 }
 
 /**
diff --git a/kernel/time/posix-timers.c b/kernel/time/posix-timers.c
index dee6a0d..79a00e0 100644
--- a/kernel/time/posix-timers.c
+++ b/kernel/time/posix-timers.c
@@ -291,10 +291,6 @@ static void schedule_next_timer(struct k_itimer *timr)
 	timr->it_overrun += (unsigned int) hrtimer_forward(timer,
 						timer->base->get_time(),
 						timr->it.real.interval);
-
-	timr->it_overrun_last = timr->it_overrun;
-	timr->it_overrun = -1;
-	++timr->it_requeue_pending;
 	hrtimer_restart(timer);
 }
 
@@ -315,18 +311,23 @@ void do_schedule_next_timer(struct siginfo *info)
 	unsigned long flags;
 
 	timr = lock_timer(info->si_tid, &flags);
+	if (!timr)
+		return;
 
-	if (timr && timr->it_requeue_pending == info->si_sys_private) {
+	if (timr->it_requeue_pending == info->si_sys_private) {
 		if (timr->it_clock < 0)
 			posix_cpu_timer_schedule(timr);
 		else
 			schedule_next_timer(timr);
 
+		timr->it_overrun_last = timr->it_overrun;
+		timr->it_overrun = -1;
+		++timr->it_requeue_pending;
+
 		info->si_overrun += timr->it_overrun_last;
 	}
 
-	if (timr)
-		unlock_timer(timr, flags);
+	unlock_timer(timr, flags);
 }
 
 int posix_timer_event(struct k_itimer *timr, int si_private)

^ permalink raw reply	[flat|nested] 66+ messages in thread

* [tip:timers/core] posix-timers: Move interval out of the union
  2017-05-30 21:15 ` [patch 10/26] posix-timers: Move interval out of the union Thomas Gleixner
@ 2017-06-05  8:17   ` tip-bot for Thomas Gleixner
  0 siblings, 0 replies; 66+ messages in thread
From: tip-bot for Thomas Gleixner @ 2017-06-05  8:17 UTC (permalink / raw)
  To: linux-tip-commits; +Cc: peterz, linux-kernel, tglx, mingo, john.stultz, hpa

Commit-ID:  80105cd0e62ba8a2caf8eebd52f42952c7c04046
Gitweb:     http://git.kernel.org/tip/80105cd0e62ba8a2caf8eebd52f42952c7c04046
Author:     Thomas Gleixner <tglx@linutronix.de>
AuthorDate: Tue, 30 May 2017 23:15:43 +0200
Committer:  Thomas Gleixner <tglx@linutronix.de>
CommitDate: Sun, 4 Jun 2017 15:40:24 +0200

posix-timers: Move interval out of the union

Preparatory patch to unify the alarm timer and hrtimer based posix interval
timer handling.

The interval is used as a criteria for rearming decisions so moving it out
of the clock specific data structures allows later unification.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: John Stultz <john.stultz@linaro.org>
Link: http://lkml.kernel.org/r/20170530211656.563922908@linutronix.de

---
 include/linux/posix-timers.h |  4 ++--
 kernel/time/alarmtimer.c     | 13 ++++++-------
 kernel/time/posix-timers.c   | 20 ++++++++++----------
 3 files changed, 18 insertions(+), 19 deletions(-)

diff --git a/include/linux/posix-timers.h b/include/linux/posix-timers.h
index a372e7e..908048f 100644
--- a/include/linux/posix-timers.h
+++ b/include/linux/posix-timers.h
@@ -63,6 +63,7 @@ struct cpu_timer_list {
  * @it_requeue_pending:	Indicator that timer waits for being requeued on
  *			signal delivery
  * @it_sigev_notify:	The notify word of sigevent struct for signal delivery
+ * @it_interval:	The interval for periodic timers
  * @it_signal:		Pointer to the creators signal struct
  * @it_pid:		The pid of the process/task targeted by the signal
  * @it_process:		The task to wakeup on clock_nanosleep (CPU timers)
@@ -80,6 +81,7 @@ struct k_itimer {
 	int			it_overrun_last;
 	int			it_requeue_pending;
 	int			it_sigev_notify;
+	ktime_t			it_interval;
 	struct signal_struct	*it_signal;
 	union {
 		struct pid		*it_pid;
@@ -89,12 +91,10 @@ struct k_itimer {
 	union {
 		struct {
 			struct hrtimer	timer;
-			ktime_t		interval;
 		} real;
 		struct cpu_timer_list	cpu;
 		struct {
 			struct alarm	alarmtimer;
-			ktime_t		interval;
 		} alarm;
 		struct rcu_head		rcu;
 	} it;
diff --git a/kernel/time/alarmtimer.c b/kernel/time/alarmtimer.c
index 36855d6..5b8cf4b 100644
--- a/kernel/time/alarmtimer.c
+++ b/kernel/time/alarmtimer.c
@@ -527,9 +527,8 @@ static enum alarmtimer_restart alarm_handle_timer(struct alarm *alarm,
 	}
 
 	/* Re-add periodic timers */
-	if (ptr->it.alarm.interval) {
-		ptr->it_overrun += alarm_forward(alarm, now,
-						ptr->it.alarm.interval);
+	if (ptr->it_interval) {
+		ptr->it_overrun += alarm_forward(alarm, now, ptr->it_interval);
 		result = ALARMTIMER_RESTART;
 	}
 	spin_unlock_irqrestore(&ptr->it_lock, flags);
@@ -613,7 +612,7 @@ static void alarm_timer_get(struct k_itimer *timr,
 		cur_setting->it_value.tv_nsec = 0;
 	}
 
-	cur_setting->it_interval = ktime_to_timespec64(timr->it.alarm.interval);
+	cur_setting->it_interval = ktime_to_timespec64(timr->it_interval);
 }
 
 /**
@@ -662,14 +661,14 @@ static int alarm_timer_set(struct k_itimer *timr, int flags,
 		return TIMER_RETRY;
 
 	/* start the timer */
-	timr->it.alarm.interval = timespec64_to_ktime(new_setting->it_interval);
+	timr->it_interval = timespec64_to_ktime(new_setting->it_interval);
 
 	/*
 	 * Rate limit to the tick as a hot fix to prevent DOS. Will be
 	 * mopped up later.
 	 */
-	if (timr->it.alarm.interval < TICK_NSEC)
-		timr->it.alarm.interval = TICK_NSEC;
+	if (timr->it_interval < TICK_NSEC)
+		timr->it_interval = TICK_NSEC;
 
 	exp = timespec64_to_ktime(new_setting->it_value);
 	/* Convert (if necessary) to absolute time */
diff --git a/kernel/time/posix-timers.c b/kernel/time/posix-timers.c
index 79a00e0..7dd992c 100644
--- a/kernel/time/posix-timers.c
+++ b/kernel/time/posix-timers.c
@@ -285,12 +285,12 @@ static void schedule_next_timer(struct k_itimer *timr)
 {
 	struct hrtimer *timer = &timr->it.real.timer;
 
-	if (timr->it.real.interval == 0)
+	if (!timr->it_interval)
 		return;
 
 	timr->it_overrun += (unsigned int) hrtimer_forward(timer,
 						timer->base->get_time(),
-						timr->it.real.interval);
+						timr->it_interval);
 	hrtimer_restart(timer);
 }
 
@@ -375,7 +375,7 @@ static enum hrtimer_restart posix_timer_fn(struct hrtimer *timer)
 	timr = container_of(timer, struct k_itimer, it.real.timer);
 	spin_lock_irqsave(&timr->it_lock, flags);
 
-	if (timr->it.real.interval != 0)
+	if (timr->it_interval != 0)
 		si_private = ++timr->it_requeue_pending;
 
 	if (posix_timer_event(timr, si_private)) {
@@ -384,7 +384,7 @@ static enum hrtimer_restart posix_timer_fn(struct hrtimer *timer)
 		 * we will not get a call back to restart it AND
 		 * it should be restarted.
 		 */
-		if (timr->it.real.interval != 0) {
+		if (timr->it_interval != 0) {
 			ktime_t now = hrtimer_cb_get_time(timer);
 
 			/*
@@ -413,13 +413,13 @@ static enum hrtimer_restart posix_timer_fn(struct hrtimer *timer)
 			{
 				ktime_t kj = NSEC_PER_SEC / HZ;
 
-				if (timr->it.real.interval < kj)
+				if (timr->it_interval < kj)
 					now = ktime_add(now, kj);
 			}
 #endif
 			timr->it_overrun += (unsigned int)
 				hrtimer_forward(timer, now,
-						timr->it.real.interval);
+						timr->it_interval);
 			ret = HRTIMER_RESTART;
 			++timr->it_requeue_pending;
 		}
@@ -631,7 +631,7 @@ common_timer_get(struct k_itimer *timr, struct itimerspec64 *cur_setting)
 
 	memset(cur_setting, 0, sizeof(*cur_setting));
 
-	iv = timr->it.real.interval;
+	iv = timr->it_interval;
 
 	/* interval timer ? */
 	if (iv)
@@ -732,7 +732,7 @@ common_timer_set(struct k_itimer *timr, int flags,
 		common_timer_get(timr, old_setting);
 
 	/* disable the timer */
-	timr->it.real.interval = 0;
+	timr->it_interval = 0;
 	/*
 	 * careful here.  If smp we could be in the "fire" routine which will
 	 * be spinning as we hold the lock.  But this is ONLY an SMP issue.
@@ -755,7 +755,7 @@ common_timer_set(struct k_itimer *timr, int flags,
 	hrtimer_set_expires(timer, timespec64_to_ktime(new_setting->it_value));
 
 	/* Convert interval */
-	timr->it.real.interval = timespec64_to_ktime(new_setting->it_interval);
+	timr->it_interval = timespec64_to_ktime(new_setting->it_interval);
 
 	/* SIGEV_NONE timers are not queued ! See common_timer_get */
 	if (((timr->it_sigev_notify & ~SIGEV_THREAD_ID) == SIGEV_NONE)) {
@@ -820,7 +820,7 @@ retry:
 
 static int common_timer_del(struct k_itimer *timer)
 {
-	timer->it.real.interval = 0;
+	timer->it_interval = 0;
 
 	if (hrtimer_try_to_cancel(&timer->it.real.timer) < 0)
 		return TIMER_RETRY;

^ permalink raw reply	[flat|nested] 66+ messages in thread

* [tip:timers/core] posix-timers: Store k_clock pointer in k_itimer
  2017-05-30 21:15 ` [patch 11/26] posix-timers: Store k_clock pointer in k_itimer Thomas Gleixner
@ 2017-06-05  8:17   ` tip-bot for Thomas Gleixner
  0 siblings, 0 replies; 66+ messages in thread
From: tip-bot for Thomas Gleixner @ 2017-06-05  8:17 UTC (permalink / raw)
  To: linux-tip-commits; +Cc: linux-kernel, tglx, mingo, john.stultz, hpa, peterz

Commit-ID:  d97bb75ddd2f38068df01da8abf26df78756253c
Gitweb:     http://git.kernel.org/tip/d97bb75ddd2f38068df01da8abf26df78756253c
Author:     Thomas Gleixner <tglx@linutronix.de>
AuthorDate: Tue, 30 May 2017 23:15:44 +0200
Committer:  Thomas Gleixner <tglx@linutronix.de>
CommitDate: Sun, 4 Jun 2017 15:40:25 +0200

posix-timers: Store k_clock pointer in k_itimer

Having the k_clock pointer in the k_itimer struct avoids the lookup in
several code pathes and makes the next steps of unification of the hrtimer
and alarmtimer based posix timers simpler.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: John Stultz <john.stultz@linaro.org>
Link: http://lkml.kernel.org/r/20170530211656.641222072@linutronix.de

---
 include/linux/posix-timers.h   | 2 ++
 kernel/time/posix-cpu-timers.c | 2 ++
 kernel/time/posix-timers.c     | 7 ++++---
 3 files changed, 8 insertions(+), 3 deletions(-)

diff --git a/include/linux/posix-timers.h b/include/linux/posix-timers.h
index 908048f..8f9cca3 100644
--- a/include/linux/posix-timers.h
+++ b/include/linux/posix-timers.h
@@ -56,6 +56,7 @@ struct cpu_timer_list {
  * @list:		List head for binding the timer to signals->posix_timers
  * @t_hash:		Entry in the posix timer hash table
  * @it_lock:		Lock protecting the timer
+ * @kclock:		Pointer to the k_clock struct handling this timer
  * @it_clock:		The posix timer clock id
  * @it_id:		The posix timer id for identifying the timer
  * @it_overrun:		The overrun counter for pending signals
@@ -75,6 +76,7 @@ struct k_itimer {
 	struct list_head	list;
 	struct hlist_node	t_hash;
 	spinlock_t		it_lock;
+	const struct k_clock	*kclock;
 	clockid_t		it_clock;
 	timer_t			it_id;
 	int			it_overrun;
diff --git a/kernel/time/posix-cpu-timers.c b/kernel/time/posix-cpu-timers.c
index 1683e50..0123ece 100644
--- a/kernel/time/posix-cpu-timers.c
+++ b/kernel/time/posix-cpu-timers.c
@@ -324,6 +324,8 @@ static int posix_cpu_timer_create(struct k_itimer *new_timer)
 	if (CPUCLOCK_WHICH(new_timer->it_clock) >= CPUCLOCK_MAX)
 		return -EINVAL;
 
+	new_timer->kclock = &clock_posix_cpu;
+
 	INIT_LIST_HEAD(&new_timer->it.cpu.entry);
 
 	rcu_read_lock();
diff --git a/kernel/time/posix-timers.c b/kernel/time/posix-timers.c
index 7dd992c..eb007e1 100644
--- a/kernel/time/posix-timers.c
+++ b/kernel/time/posix-timers.c
@@ -519,6 +519,7 @@ SYSCALL_DEFINE3(timer_create, const clockid_t, which_clock,
 	it_id_set = IT_ID_SET;
 	new_timer->it_id = (timer_t) new_timer_id;
 	new_timer->it_clock = which_clock;
+	new_timer->kclock = kc;
 	new_timer->it_overrun = -1;
 
 	if (timer_event_spec) {
@@ -679,7 +680,7 @@ SYSCALL_DEFINE2(timer_gettime, timer_t, timer_id,
 	if (!timr)
 		return -EINVAL;
 
-	kc = clockid_to_kclock(timr->it_clock);
+	kc = timr->kclock;
 	if (WARN_ON_ONCE(!kc || !kc->timer_get))
 		ret = -EINVAL;
 	else
@@ -798,7 +799,7 @@ retry:
 	if (!timr)
 		return -EINVAL;
 
-	kc = clockid_to_kclock(timr->it_clock);
+	kc = timr->kclock;
 	if (WARN_ON_ONCE(!kc || !kc->timer_set))
 		error = -EINVAL;
 	else
@@ -829,7 +830,7 @@ static int common_timer_del(struct k_itimer *timer)
 
 static inline int timer_delete_hook(struct k_itimer *timer)
 {
-	const struct k_clock *kc = clockid_to_kclock(timer->it_clock);
+	const struct k_clock *kc = timer->kclock;
 
 	if (WARN_ON_ONCE(!kc || !kc->timer_del))
 		return -EINVAL;

^ permalink raw reply	[flat|nested] 66+ messages in thread

* [tip:timers/core] posix-timers: Add timer_rearm() callback
  2017-05-30 21:15 ` [patch 12/26] posix-timers: Add timer_rearm() callback Thomas Gleixner
@ 2017-06-05  8:18   ` tip-bot for Thomas Gleixner
  0 siblings, 0 replies; 66+ messages in thread
From: tip-bot for Thomas Gleixner @ 2017-06-05  8:18 UTC (permalink / raw)
  To: linux-tip-commits; +Cc: peterz, linux-kernel, tglx, john.stultz, mingo, hpa

Commit-ID:  30802945893bc944b5971b408b37511a03b54e5c
Gitweb:     http://git.kernel.org/tip/30802945893bc944b5971b408b37511a03b54e5c
Author:     Thomas Gleixner <tglx@linutronix.de>
AuthorDate: Tue, 30 May 2017 23:15:45 +0200
Committer:  Thomas Gleixner <tglx@linutronix.de>
CommitDate: Sun, 4 Jun 2017 15:40:25 +0200

posix-timers: Add timer_rearm() callback

Add a timer_rearm() callback which is used to make the rescheduling of
posix interval timers independent of the underlying clock implementation.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: John Stultz <john.stultz@linaro.org>
Link: http://lkml.kernel.org/r/20170530211656.732632167@linutronix.de

---
 kernel/time/posix-timers.h | 33 ++++++++++++++++++---------------
 1 file changed, 18 insertions(+), 15 deletions(-)

diff --git a/kernel/time/posix-timers.h b/kernel/time/posix-timers.h
index ad2dbd2..02ffd1b 100644
--- a/kernel/time/posix-timers.h
+++ b/kernel/time/posix-timers.h
@@ -1,21 +1,24 @@
 #define TIMER_RETRY 1
 
 struct k_clock {
-	int (*clock_getres) (const clockid_t which_clock, struct timespec64 *tp);
-	int (*clock_set) (const clockid_t which_clock,
-			  const struct timespec64 *tp);
-	int (*clock_get) (const clockid_t which_clock, struct timespec64 *tp);
-	int (*clock_adj) (const clockid_t which_clock, struct timex *tx);
-	int (*timer_create) (struct k_itimer *timer);
-	int (*nsleep) (const clockid_t which_clock, int flags,
-		       struct timespec64 *, struct timespec __user *);
-	long (*nsleep_restart) (struct restart_block *restart_block);
-	int (*timer_set) (struct k_itimer *timr, int flags,
-			  struct itimerspec64 *new_setting,
-			  struct itimerspec64 *old_setting);
-	int (*timer_del) (struct k_itimer *timr);
-	void (*timer_get) (struct k_itimer *timr,
-			   struct itimerspec64 *cur_setting);
+	int	(*clock_getres)(const clockid_t which_clock,
+				struct timespec64 *tp);
+	int	(*clock_set)(const clockid_t which_clock,
+			     const struct timespec64 *tp);
+	int	(*clock_get)(const clockid_t which_clock,
+			     struct timespec64 *tp);
+	int	(*clock_adj)(const clockid_t which_clock, struct timex *tx);
+	int	(*timer_create)(struct k_itimer *timer);
+	int	(*nsleep)(const clockid_t which_clock, int flags,
+			  struct timespec64 *, struct timespec __user *);
+	long	(*nsleep_restart)(struct restart_block *restart_block);
+	int	(*timer_set)(struct k_itimer *timr, int flags,
+			     struct itimerspec64 *new_setting,
+			     struct itimerspec64 *old_setting);
+	int	(*timer_del)(struct k_itimer *timr);
+	void	(*timer_get)(struct k_itimer *timr,
+			     struct itimerspec64 *cur_setting);
+	void	(*timer_rearm)(struct k_itimer *timr);
 };
 
 extern const struct k_clock clock_posix_cpu;

^ permalink raw reply	[flat|nested] 66+ messages in thread

* [tip:timers/core] posix-timers: Rename do_schedule_next_timer
  2017-05-30 21:15 ` [patch 13/26] posix-timers: Rename do_schedule_next_timer Thomas Gleixner
  2017-05-31 15:39   ` Christoph Hellwig
@ 2017-06-05  8:18   ` tip-bot for Thomas Gleixner
  1 sibling, 0 replies; 66+ messages in thread
From: tip-bot for Thomas Gleixner @ 2017-06-05  8:18 UTC (permalink / raw)
  To: linux-tip-commits; +Cc: mingo, john.stultz, linux-kernel, tglx, hpa, peterz

Commit-ID:  96fe3b072f134e4993f829d599eaa1e0eb5a10e5
Gitweb:     http://git.kernel.org/tip/96fe3b072f134e4993f829d599eaa1e0eb5a10e5
Author:     Thomas Gleixner <tglx@linutronix.de>
AuthorDate: Tue, 30 May 2017 23:15:46 +0200
Committer:  Thomas Gleixner <tglx@linutronix.de>
CommitDate: Sun, 4 Jun 2017 15:40:25 +0200

posix-timers: Rename do_schedule_next_timer

That function is a misnomer. Rename it with a proper prefix to
posixtimer_rearm().

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: John Stultz <john.stultz@linaro.org>
Link: http://lkml.kernel.org/r/20170530211656.811362578@linutronix.de

---
 include/linux/posix-timers.h   |  2 +-
 kernel/signal.c                |  2 +-
 kernel/time/posix-cpu-timers.c |  2 +-
 kernel/time/posix-timers.c     | 10 +++++-----
 4 files changed, 8 insertions(+), 8 deletions(-)

diff --git a/include/linux/posix-timers.h b/include/linux/posix-timers.h
index 8f9cca3..771e5f7 100644
--- a/include/linux/posix-timers.h
+++ b/include/linux/posix-timers.h
@@ -112,6 +112,6 @@ long clock_nanosleep_restart(struct restart_block *restart_block);
 
 void update_rlimit_cpu(struct task_struct *task, unsigned long rlim_new);
 
-void do_schedule_next_timer(struct siginfo *info);
+void posixtimer_rearm(struct siginfo *info);
 
 #endif
diff --git a/kernel/signal.c b/kernel/signal.c
index 1f85c84..d031cd2 100644
--- a/kernel/signal.c
+++ b/kernel/signal.c
@@ -630,7 +630,7 @@ int dequeue_signal(struct task_struct *tsk, sigset_t *mask, siginfo_t *info)
 		 * about to disable them again anyway.
 		 */
 		spin_unlock(&tsk->sighand->siglock);
-		do_schedule_next_timer(info);
+		posixtimer_rearm(info);
 		spin_lock(&tsk->sighand->siglock);
 	}
 #endif
diff --git a/kernel/time/posix-cpu-timers.c b/kernel/time/posix-cpu-timers.c
index 0123ece..1ba576d 100644
--- a/kernel/time/posix-cpu-timers.c
+++ b/kernel/time/posix-cpu-timers.c
@@ -981,7 +981,7 @@ static void check_process_timers(struct task_struct *tsk,
 }
 
 /*
- * This is called from the signal code (via do_schedule_next_timer)
+ * This is called from the signal code (via posixtimer_rearm)
  * when the last timer signal was delivered and we have to reload the timer.
  */
 void posix_cpu_timer_schedule(struct k_itimer *timer)
diff --git a/kernel/time/posix-timers.c b/kernel/time/posix-timers.c
index eb007e1..036b7e7 100644
--- a/kernel/time/posix-timers.c
+++ b/kernel/time/posix-timers.c
@@ -305,7 +305,7 @@ static void schedule_next_timer(struct k_itimer *timr)
  * To protect against the timer going away while the interrupt is queued,
  * we require that the it_requeue_pending flag be set.
  */
-void do_schedule_next_timer(struct siginfo *info)
+void posixtimer_rearm(struct siginfo *info)
 {
 	struct k_itimer *timr;
 	unsigned long flags;
@@ -336,12 +336,12 @@ int posix_timer_event(struct k_itimer *timr, int si_private)
 	int shared, ret = -1;
 	/*
 	 * FIXME: if ->sigq is queued we can race with
-	 * dequeue_signal()->do_schedule_next_timer().
+	 * dequeue_signal()->posixtimer_rearm().
 	 *
 	 * If dequeue_signal() sees the "right" value of
-	 * si_sys_private it calls do_schedule_next_timer().
+	 * si_sys_private it calls posixtimer_rearm().
 	 * We re-queue ->sigq and drop ->it_lock().
-	 * do_schedule_next_timer() locks the timer
+	 * posixtimer_rearm() locks the timer
 	 * and re-schedules it while ->sigq is pending.
 	 * Not really bad, but not that we want.
 	 */
@@ -701,7 +701,7 @@ SYSCALL_DEFINE2(timer_gettime, timer_t, timer_id,
  * accumulating overruns on the next timer.  The overrun is frozen when
  * the signal is delivered, either at the notify time (if the info block
  * is not queued) or at the actual delivery time (as we are informed by
- * the call back to do_schedule_next_timer().  So all we need to do is
+ * the call back to posixtimer_rearm().  So all we need to do is
  * to pick up the frozen overrun.
  */
 SYSCALL_DEFINE1(timer_getoverrun, timer_t, timer_id)

^ permalink raw reply	[flat|nested] 66+ messages in thread

* [tip:timers/core] posix-timers: Use timer_rearm() callback in posixtimer_rearm()
  2017-05-30 21:15 ` [patch 14/26] posix-timers: Use timer_rearm() callback in posixtimer_rearm() Thomas Gleixner
@ 2017-06-05  8:19   ` tip-bot for Thomas Gleixner
  0 siblings, 0 replies; 66+ messages in thread
From: tip-bot for Thomas Gleixner @ 2017-06-05  8:19 UTC (permalink / raw)
  To: linux-tip-commits; +Cc: tglx, hpa, linux-kernel, mingo, peterz, john.stultz

Commit-ID:  f37fb0aa4f453c7c785bbcecc4991ac48c5c0e51
Gitweb:     http://git.kernel.org/tip/f37fb0aa4f453c7c785bbcecc4991ac48c5c0e51
Author:     Thomas Gleixner <tglx@linutronix.de>
AuthorDate: Tue, 30 May 2017 23:15:47 +0200
Committer:  Thomas Gleixner <tglx@linutronix.de>
CommitDate: Sun, 4 Jun 2017 15:40:26 +0200

posix-timers: Use timer_rearm() callback in posixtimer_rearm()

Use the new timer_rearm() callback to replace the conditional hardcoded
calls into the hrtimer and cpu timer code.

This allows later to bring the same logic to alarmtimers.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: John Stultz <john.stultz@linaro.org>
Link: http://lkml.kernel.org/r/20170530211656.889661919@linutronix.de

---
 kernel/time/posix-cpu-timers.c |  7 +++++--
 kernel/time/posix-timers.c     | 12 ++++++------
 kernel/time/posix-timers.h     |  2 --
 3 files changed, 11 insertions(+), 10 deletions(-)

diff --git a/kernel/time/posix-cpu-timers.c b/kernel/time/posix-cpu-timers.c
index 1ba576d..96c833a 100644
--- a/kernel/time/posix-cpu-timers.c
+++ b/kernel/time/posix-cpu-timers.c
@@ -15,6 +15,8 @@
 
 #include "posix-timers.h"
 
+static void posix_cpu_timer_rearm(struct k_itimer *timer);
+
 /*
  * Called after updating RLIMIT_CPU to run cpu timer and update
  * tsk->signal->cputime_expires expiration cache if necessary. Needs
@@ -528,7 +530,7 @@ static void cpu_timer_fire(struct k_itimer *timer)
 		 * reload the timer.  But we need to keep it
 		 * ticking in case the signal is deliverable next time.
 		 */
-		posix_cpu_timer_schedule(timer);
+		posix_cpu_timer_rearm(timer);
 		++timer->it_requeue_pending;
 	}
 }
@@ -984,7 +986,7 @@ static void check_process_timers(struct task_struct *tsk,
  * This is called from the signal code (via posixtimer_rearm)
  * when the last timer signal was delivered and we have to reload the timer.
  */
-void posix_cpu_timer_schedule(struct k_itimer *timer)
+static void posix_cpu_timer_rearm(struct k_itimer *timer)
 {
 	struct sighand_struct *sighand;
 	unsigned long flags;
@@ -1431,6 +1433,7 @@ const struct k_clock clock_posix_cpu = {
 	.timer_set	= posix_cpu_timer_set,
 	.timer_del	= posix_cpu_timer_del,
 	.timer_get	= posix_cpu_timer_get,
+	.timer_rearm	= posix_cpu_timer_rearm,
 };
 
 const struct k_clock clock_process = {
diff --git a/kernel/time/posix-timers.c b/kernel/time/posix-timers.c
index 036b7e7..b12582a 100644
--- a/kernel/time/posix-timers.c
+++ b/kernel/time/posix-timers.c
@@ -278,10 +278,9 @@ static __init int init_posix_timers(void)
 					NULL);
 	return 0;
 }
-
 __initcall(init_posix_timers);
 
-static void schedule_next_timer(struct k_itimer *timr)
+static void common_hrtimer_rearm(struct k_itimer *timr)
 {
 	struct hrtimer *timer = &timr->it.real.timer;
 
@@ -315,10 +314,7 @@ void posixtimer_rearm(struct siginfo *info)
 		return;
 
 	if (timr->it_requeue_pending == info->si_sys_private) {
-		if (timr->it_clock < 0)
-			posix_cpu_timer_schedule(timr);
-		else
-			schedule_next_timer(timr);
+		timr->kclock->timer_rearm(timr);
 
 		timr->it_overrun_last = timr->it_overrun;
 		timr->it_overrun = -1;
@@ -1046,6 +1042,7 @@ static const struct k_clock clock_realtime = {
 	.timer_set	= common_timer_set,
 	.timer_get	= common_timer_get,
 	.timer_del	= common_timer_del,
+	.timer_rearm	= common_hrtimer_rearm,
 };
 
 static const struct k_clock clock_monotonic = {
@@ -1057,6 +1054,7 @@ static const struct k_clock clock_monotonic = {
 	.timer_set	= common_timer_set,
 	.timer_get	= common_timer_get,
 	.timer_del	= common_timer_del,
+	.timer_rearm	= common_hrtimer_rearm,
 };
 
 static const struct k_clock clock_monotonic_raw = {
@@ -1083,6 +1081,7 @@ static const struct k_clock clock_tai = {
 	.timer_set	= common_timer_set,
 	.timer_get	= common_timer_get,
 	.timer_del	= common_timer_del,
+	.timer_rearm	= common_hrtimer_rearm,
 };
 
 static const struct k_clock clock_boottime = {
@@ -1094,6 +1093,7 @@ static const struct k_clock clock_boottime = {
 	.timer_set	= common_timer_set,
 	.timer_get	= common_timer_get,
 	.timer_del	= common_timer_del,
+	.timer_rearm	= common_hrtimer_rearm,
 };
 
 static const struct k_clock * const posix_clocks[] = {
diff --git a/kernel/time/posix-timers.h b/kernel/time/posix-timers.h
index 02ffd1b..1f6f6f9 100644
--- a/kernel/time/posix-timers.h
+++ b/kernel/time/posix-timers.h
@@ -28,5 +28,3 @@ extern const struct k_clock clock_thread;
 extern const struct k_clock alarm_clock;
 
 int posix_timer_event(struct k_itimer *timr, int si_private);
-
-void posix_cpu_timer_schedule(struct k_itimer *timer);

^ permalink raw reply	[flat|nested] 66+ messages in thread

* [tip:timers/core] posix-timers: Add active flag to k_itimer
  2017-05-30 21:15 ` [patch 15/26] posix-timers: Add active flag to k_itimer Thomas Gleixner
@ 2017-06-05  8:20   ` tip-bot for Thomas Gleixner
  0 siblings, 0 replies; 66+ messages in thread
From: tip-bot for Thomas Gleixner @ 2017-06-05  8:20 UTC (permalink / raw)
  To: linux-tip-commits; +Cc: tglx, peterz, john.stultz, mingo, hpa, linux-kernel

Commit-ID:  21e55c1f83880a56360287c00f2b5cd5e5a4a912
Gitweb:     http://git.kernel.org/tip/21e55c1f83880a56360287c00f2b5cd5e5a4a912
Author:     Thomas Gleixner <tglx@linutronix.de>
AuthorDate: Tue, 30 May 2017 23:15:48 +0200
Committer:  Thomas Gleixner <tglx@linutronix.de>
CommitDate: Sun, 4 Jun 2017 15:40:26 +0200

posix-timers: Add active flag to k_itimer

Keep track of the activation state of posix timers. This is a preparatory
change for making common_timer_get() usable by both hrtimer and alarm timer
implementations.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: John Stultz <john.stultz@linaro.org>
Link: http://lkml.kernel.org/r/20170530211656.967783982@linutronix.de

---
 include/linux/posix-timers.h | 2 ++
 kernel/time/posix-timers.c   | 8 +++++++-
 2 files changed, 9 insertions(+), 1 deletion(-)

diff --git a/include/linux/posix-timers.h b/include/linux/posix-timers.h
index 771e5f7..667095d 100644
--- a/include/linux/posix-timers.h
+++ b/include/linux/posix-timers.h
@@ -59,6 +59,7 @@ struct cpu_timer_list {
  * @kclock:		Pointer to the k_clock struct handling this timer
  * @it_clock:		The posix timer clock id
  * @it_id:		The posix timer id for identifying the timer
+ * @it_active:		Marker that timer is active
  * @it_overrun:		The overrun counter for pending signals
  * @it_overrun_last:	The overrun at the time of the last delivered signal
  * @it_requeue_pending:	Indicator that timer waits for being requeued on
@@ -79,6 +80,7 @@ struct k_itimer {
 	const struct k_clock	*kclock;
 	clockid_t		it_clock;
 	timer_t			it_id;
+	int			it_active;
 	int			it_overrun;
 	int			it_overrun_last;
 	int			it_requeue_pending;
diff --git a/kernel/time/posix-timers.c b/kernel/time/posix-timers.c
index b12582a..795215b 100644
--- a/kernel/time/posix-timers.c
+++ b/kernel/time/posix-timers.c
@@ -316,6 +316,7 @@ void posixtimer_rearm(struct siginfo *info)
 	if (timr->it_requeue_pending == info->si_sys_private) {
 		timr->kclock->timer_rearm(timr);
 
+		timr->it_active = 1;
 		timr->it_overrun_last = timr->it_overrun;
 		timr->it_overrun = -1;
 		++timr->it_requeue_pending;
@@ -371,6 +372,7 @@ static enum hrtimer_restart posix_timer_fn(struct hrtimer *timer)
 	timr = container_of(timer, struct k_itimer, it.real.timer);
 	spin_lock_irqsave(&timr->it_lock, flags);
 
+	timr->it_active = 0;
 	if (timr->it_interval != 0)
 		si_private = ++timr->it_requeue_pending;
 
@@ -418,6 +420,7 @@ static enum hrtimer_restart posix_timer_fn(struct hrtimer *timer)
 						timr->it_interval);
 			ret = HRTIMER_RESTART;
 			++timr->it_requeue_pending;
+			timr->it_active = 1;
 		}
 	}
 
@@ -737,7 +740,8 @@ common_timer_set(struct k_itimer *timr, int flags,
 	if (hrtimer_try_to_cancel(timer) < 0)
 		return TIMER_RETRY;
 
-	timr->it_requeue_pending = (timr->it_requeue_pending + 2) & 
+	timr->it_active = 0;
+	timr->it_requeue_pending = (timr->it_requeue_pending + 2) &
 		~REQUEUE_PENDING;
 	timr->it_overrun_last = 0;
 
@@ -763,6 +767,7 @@ common_timer_set(struct k_itimer *timr, int flags,
 		return 0;
 	}
 
+	timr->it_active = 1;
 	hrtimer_start_expires(timer, mode);
 	return 0;
 }
@@ -821,6 +826,7 @@ static int common_timer_del(struct k_itimer *timer)
 
 	if (hrtimer_try_to_cancel(&timer->it.real.timer) < 0)
 		return TIMER_RETRY;
+	timer->it_active = 0;
 	return 0;
 }
 

^ permalink raw reply	[flat|nested] 66+ messages in thread

* [tip:timers/core] posix-timers: Add forward/remaining callbacks
  2017-05-30 21:15 ` [patch 16/26] posix-timers: Add forward/remaining callbacks Thomas Gleixner
@ 2017-06-05  8:20   ` tip-bot for Thomas Gleixner
  0 siblings, 0 replies; 66+ messages in thread
From: tip-bot for Thomas Gleixner @ 2017-06-05  8:20 UTC (permalink / raw)
  To: linux-tip-commits; +Cc: hpa, tglx, linux-kernel, peterz, john.stultz, mingo

Commit-ID:  63841b2a6969501de183efafc14d20175e402804
Gitweb:     http://git.kernel.org/tip/63841b2a6969501de183efafc14d20175e402804
Author:     Thomas Gleixner <tglx@linutronix.de>
AuthorDate: Tue, 30 May 2017 23:15:49 +0200
Committer:  Thomas Gleixner <tglx@linutronix.de>
CommitDate: Sun, 4 Jun 2017 15:40:27 +0200

posix-timers: Add forward/remaining callbacks

Add two callbacks to kclock which allow using common_)timer_get() for both
hrtimer and alarm timer based clocks.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: John Stultz <john.stultz@linaro.org>
Link: http://lkml.kernel.org/r/20170530211657.044915536@linutronix.de

---
 kernel/time/posix-timers.h | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/kernel/time/posix-timers.h b/kernel/time/posix-timers.h
index 1f6f6f9..3bc5b74 100644
--- a/kernel/time/posix-timers.h
+++ b/kernel/time/posix-timers.h
@@ -19,6 +19,8 @@ struct k_clock {
 	void	(*timer_get)(struct k_itimer *timr,
 			     struct itimerspec64 *cur_setting);
 	void	(*timer_rearm)(struct k_itimer *timr);
+	int	(*timer_forward)(struct k_itimer *timr, ktime_t now);
+	ktime_t	(*timer_remaining)(struct k_itimer *timr, ktime_t now);
 };
 
 extern const struct k_clock clock_posix_cpu;

^ permalink raw reply	[flat|nested] 66+ messages in thread

* [tip:timers/core] posix-timers: Make use of forward/remaining callbacks
  2017-05-30 21:15 ` [patch 17/26] posix-timers: Make use of " Thomas Gleixner
@ 2017-06-05  8:21   ` tip-bot for Thomas Gleixner
  0 siblings, 0 replies; 66+ messages in thread
From: tip-bot for Thomas Gleixner @ 2017-06-05  8:21 UTC (permalink / raw)
  To: linux-tip-commits; +Cc: linux-kernel, hpa, mingo, john.stultz, peterz, tglx

Commit-ID:  91d57bae08689199c8acc77a8b3b41150cafab1c
Gitweb:     http://git.kernel.org/tip/91d57bae08689199c8acc77a8b3b41150cafab1c
Author:     Thomas Gleixner <tglx@linutronix.de>
AuthorDate: Tue, 30 May 2017 23:15:50 +0200
Committer:  Thomas Gleixner <tglx@linutronix.de>
CommitDate: Sun, 4 Jun 2017 15:40:27 +0200

posix-timers: Make use of forward/remaining callbacks

Replace the hrtimer calls by calls to the new forward/remaining kclock
callbacks and move the hrtimer specific implementation into the
corresponding callback functions.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: John Stultz <john.stultz@linaro.org>
Link: http://lkml.kernel.org/r/20170530211657.121437232@linutronix.de

---
 kernel/time/posix-timers.c | 64 +++++++++++++++++++++++++++++++++++-----------
 1 file changed, 49 insertions(+), 15 deletions(-)

diff --git a/kernel/time/posix-timers.c b/kernel/time/posix-timers.c
index 795215b..48f6c37 100644
--- a/kernel/time/posix-timers.c
+++ b/kernel/time/posix-timers.c
@@ -607,6 +607,20 @@ static struct k_itimer *__lock_timer(timer_t timer_id, unsigned long *flags)
 	return NULL;
 }
 
+static ktime_t common_hrtimer_remaining(struct k_itimer *timr, ktime_t now)
+{
+	struct hrtimer *timer = &timr->it.real.timer;
+
+	return __hrtimer_expires_remaining_adjusted(timer, now);
+}
+
+static int common_hrtimer_forward(struct k_itimer *timr, ktime_t now)
+{
+	struct hrtimer *timer = &timr->it.real.timer;
+
+	return (int)hrtimer_forward(timer, now, timr->it_interval);
+}
+
 /*
  * Get the time remaining on a POSIX.1b interval timer.  This function
  * is ALWAYS called with spin_lock_irq on the timer, thus it must not
@@ -626,42 +640,54 @@ static struct k_itimer *__lock_timer(timer_t timer_id, unsigned long *flags)
 static void
 common_timer_get(struct k_itimer *timr, struct itimerspec64 *cur_setting)
 {
+	const struct k_clock *kc = timr->kclock;
 	ktime_t now, remaining, iv;
-	struct hrtimer *timer = &timr->it.real.timer;
+	struct timespec64 ts64;
+	bool sig_none;
 
 	memset(cur_setting, 0, sizeof(*cur_setting));
 
+	sig_none = (timr->it_sigev_notify & ~SIGEV_THREAD_ID) != SIGEV_NONE;
 	iv = timr->it_interval;
 
 	/* interval timer ? */
-	if (iv)
+	if (iv) {
 		cur_setting->it_interval = ktime_to_timespec64(iv);
-	else if (!hrtimer_active(timer) &&
-		 (timr->it_sigev_notify & ~SIGEV_THREAD_ID) != SIGEV_NONE)
-		return;
+	} else if (!timr->it_active) {
+		/*
+		 * SIGEV_NONE oneshot timers are never queued. Check them
+		 * below.
+		 */
+		if (!sig_none)
+			return;
+	}
 
-	now = timer->base->get_time();
+	/*
+	 * The timespec64 based conversion is suboptimal, but it's not
+	 * worth to implement yet another callback.
+	 */
+	kc->clock_get(timr->it_clock, &ts64);
+	now = timespec64_to_ktime(ts64);
 
 	/*
-	 * When a requeue is pending or this is a SIGEV_NONE
-	 * timer move the expiry time forward by intervals, so
-	 * expiry is > now.
+	 * When a requeue is pending or this is a SIGEV_NONE timer move the
+	 * expiry time forward by intervals, so expiry is > now.
 	 */
-	if (iv && (timr->it_requeue_pending & REQUEUE_PENDING ||
-		   (timr->it_sigev_notify & ~SIGEV_THREAD_ID) == SIGEV_NONE))
-		timr->it_overrun += (unsigned int) hrtimer_forward(timer, now, iv);
+	if (iv && (timr->it_requeue_pending & REQUEUE_PENDING || sig_none))
+		timr->it_overrun += kc->timer_forward(timr, now);
 
-	remaining = __hrtimer_expires_remaining_adjusted(timer, now);
+	remaining = kc->timer_remaining(timr, now);
 	/* Return 0 only, when the timer is expired and not pending */
 	if (remaining <= 0) {
 		/*
 		 * A single shot SIGEV_NONE timer must return 0, when
 		 * it is expired !
 		 */
-		if ((timr->it_sigev_notify & ~SIGEV_THREAD_ID) != SIGEV_NONE)
+		if (!sig_none)
 			cur_setting->it_value.tv_nsec = 1;
-	} else
+	} else {
 		cur_setting->it_value = ktime_to_timespec64(remaining);
+	}
 }
 
 /* Get the time remaining on a POSIX.1b interval timer. */
@@ -1049,6 +1075,8 @@ static const struct k_clock clock_realtime = {
 	.timer_get	= common_timer_get,
 	.timer_del	= common_timer_del,
 	.timer_rearm	= common_hrtimer_rearm,
+	.timer_forward	= common_hrtimer_forward,
+	.timer_remaining= common_hrtimer_remaining,
 };
 
 static const struct k_clock clock_monotonic = {
@@ -1061,6 +1089,8 @@ static const struct k_clock clock_monotonic = {
 	.timer_get	= common_timer_get,
 	.timer_del	= common_timer_del,
 	.timer_rearm	= common_hrtimer_rearm,
+	.timer_forward	= common_hrtimer_forward,
+	.timer_remaining= common_hrtimer_remaining,
 };
 
 static const struct k_clock clock_monotonic_raw = {
@@ -1088,6 +1118,8 @@ static const struct k_clock clock_tai = {
 	.timer_get	= common_timer_get,
 	.timer_del	= common_timer_del,
 	.timer_rearm	= common_hrtimer_rearm,
+	.timer_forward	= common_hrtimer_forward,
+	.timer_remaining= common_hrtimer_remaining,
 };
 
 static const struct k_clock clock_boottime = {
@@ -1100,6 +1132,8 @@ static const struct k_clock clock_boottime = {
 	.timer_get	= common_timer_get,
 	.timer_del	= common_timer_del,
 	.timer_rearm	= common_hrtimer_rearm,
+	.timer_forward	= common_hrtimer_forward,
+	.timer_remaining= common_hrtimer_remaining,
 };
 
 static const struct k_clock * const posix_clocks[] = {

^ permalink raw reply	[flat|nested] 66+ messages in thread

* [tip:timers/core] posix-timers: Zero settings value in common code
  2017-05-30 21:15 ` [patch 18/26] posix-timers: Zero settings value in common code Thomas Gleixner
@ 2017-06-05  8:21   ` tip-bot for Thomas Gleixner
  2017-06-09 20:12     ` Andrei Vagin
  0 siblings, 1 reply; 66+ messages in thread
From: tip-bot for Thomas Gleixner @ 2017-06-05  8:21 UTC (permalink / raw)
  To: linux-tip-commits; +Cc: peterz, john.stultz, mingo, linux-kernel, tglx, hpa

Commit-ID:  eabdec04385376d560078992710104cc7be2ce1b
Gitweb:     http://git.kernel.org/tip/eabdec04385376d560078992710104cc7be2ce1b
Author:     Thomas Gleixner <tglx@linutronix.de>
AuthorDate: Tue, 30 May 2017 23:15:51 +0200
Committer:  Thomas Gleixner <tglx@linutronix.de>
CommitDate: Sun, 4 Jun 2017 15:40:28 +0200

posix-timers: Zero settings value in common code

Zero out the settings struct in the common code so the callbacks do not
have to do it themself.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: John Stultz <john.stultz@linaro.org>
Link: http://lkml.kernel.org/r/20170530211657.200870713@linutronix.de

---
 kernel/time/posix-cpu-timers.c | 5 +----
 kernel/time/posix-timers.c     | 3 +--
 2 files changed, 2 insertions(+), 6 deletions(-)

diff --git a/kernel/time/posix-cpu-timers.c b/kernel/time/posix-cpu-timers.c
index 96c833a..cb4a4eb 100644
--- a/kernel/time/posix-cpu-timers.c
+++ b/kernel/time/posix-cpu-timers.c
@@ -719,10 +719,8 @@ static void posix_cpu_timer_get(struct k_itimer *timer, struct itimerspec64 *itp
 	 */
 	itp->it_interval = ns_to_timespec64(timer->it.cpu.incr);
 
-	if (timer->it.cpu.expires == 0) {	/* Timer not armed at all.  */
-		itp->it_value.tv_sec = itp->it_value.tv_nsec = 0;
+	if (!timer->it.cpu.expires)
 		return;
-	}
 
 	/*
 	 * Sample the clock to take the difference with the expiry time.
@@ -746,7 +744,6 @@ static void posix_cpu_timer_get(struct k_itimer *timer, struct itimerspec64 *itp
 			 * Call the timer disarmed, nothing else to do.
 			 */
 			timer->it.cpu.expires = 0;
-			itp->it_value = ns_to_timespec64(timer->it.cpu.expires);
 			return;
 		} else {
 			cpu_timer_sample_group(timer->it_clock, p, &now);
diff --git a/kernel/time/posix-timers.c b/kernel/time/posix-timers.c
index 48f6c37..0332f7a 100644
--- a/kernel/time/posix-timers.c
+++ b/kernel/time/posix-timers.c
@@ -645,8 +645,6 @@ common_timer_get(struct k_itimer *timr, struct itimerspec64 *cur_setting)
 	struct timespec64 ts64;
 	bool sig_none;
 
-	memset(cur_setting, 0, sizeof(*cur_setting));
-
 	sig_none = (timr->it_sigev_notify & ~SIGEV_THREAD_ID) != SIGEV_NONE;
 	iv = timr->it_interval;
 
@@ -705,6 +703,7 @@ SYSCALL_DEFINE2(timer_gettime, timer_t, timer_id,
 	if (!timr)
 		return -EINVAL;
 
+	memset(&cur_setting64, 0, sizeof(cur_setting64));
 	kc = timr->kclock;
 	if (WARN_ON_ONCE(!kc || !kc->timer_get))
 		ret = -EINVAL;

^ permalink raw reply	[flat|nested] 66+ messages in thread

* [tip:timers/core] posix-timers: Add cancel/arm callbacks
  2017-05-30 21:15 ` [patch 19/26] posix-timers: Add cancel/arm callbacks Thomas Gleixner
@ 2017-06-05  8:22   ` tip-bot for Thomas Gleixner
  0 siblings, 0 replies; 66+ messages in thread
From: tip-bot for Thomas Gleixner @ 2017-06-05  8:22 UTC (permalink / raw)
  To: linux-tip-commits; +Cc: hpa, peterz, tglx, mingo, linux-kernel, john.stultz

Commit-ID:  525b8ed91671e29e187dfe02d408b11190ccf494
Gitweb:     http://git.kernel.org/tip/525b8ed91671e29e187dfe02d408b11190ccf494
Author:     Thomas Gleixner <tglx@linutronix.de>
AuthorDate: Tue, 30 May 2017 23:15:52 +0200
Committer:  Thomas Gleixner <tglx@linutronix.de>
CommitDate: Sun, 4 Jun 2017 15:40:28 +0200

posix-timers: Add cancel/arm callbacks

Add timer_try_to_cancel() and timer_arm() callbacks to kclock which allow
to make common_timer_set() usable by both hrtimer and alarmtimer based
clocks.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: John Stultz <john.stultz@linaro.org>
Link: http://lkml.kernel.org/r/20170530211657.278022962@linutronix.de

---
 kernel/time/posix-timers.h | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/kernel/time/posix-timers.h b/kernel/time/posix-timers.h
index 3bc5b74..b0ad77e 100644
--- a/kernel/time/posix-timers.h
+++ b/kernel/time/posix-timers.h
@@ -21,6 +21,9 @@ struct k_clock {
 	void	(*timer_rearm)(struct k_itimer *timr);
 	int	(*timer_forward)(struct k_itimer *timr, ktime_t now);
 	ktime_t	(*timer_remaining)(struct k_itimer *timr, ktime_t now);
+	int	(*timer_try_to_cancel)(struct k_itimer *timr);
+	void	(*timer_arm)(struct k_itimer *timr, ktime_t expires,
+			     bool absolute, bool sigev_none);
 };
 
 extern const struct k_clock clock_posix_cpu;

^ permalink raw reply	[flat|nested] 66+ messages in thread

* [tip:timers/core] posix-timers: Make use of cancel/arm callbacks
  2017-05-30 21:15 ` [patch 20/26] posix-timers: Make use of " Thomas Gleixner
@ 2017-06-05  8:22   ` tip-bot for Thomas Gleixner
  0 siblings, 0 replies; 66+ messages in thread
From: tip-bot for Thomas Gleixner @ 2017-06-05  8:22 UTC (permalink / raw)
  To: linux-tip-commits; +Cc: john.stultz, hpa, tglx, linux-kernel, mingo, peterz

Commit-ID:  eae1c4ae275fe3e024454c012a548ee0d700f54c
Gitweb:     http://git.kernel.org/tip/eae1c4ae275fe3e024454c012a548ee0d700f54c
Author:     Thomas Gleixner <tglx@linutronix.de>
AuthorDate: Tue, 30 May 2017 23:15:53 +0200
Committer:  Thomas Gleixner <tglx@linutronix.de>
CommitDate: Sun, 4 Jun 2017 15:40:29 +0200

posix-timers: Make use of cancel/arm callbacks

Replace the hrtimer calls by calls to the new try_to_cancel()/arm() kclock
callbacks and move the hrtimer specific implementation into the
corresponding callback functions.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: John Stultz <john.stultz@linaro.org>
Link: http://lkml.kernel.org/r/20170530211657.355396667@linutronix.de

---
 kernel/time/posix-timers.c | 181 +++++++++++++++++++++++++--------------------
 1 file changed, 100 insertions(+), 81 deletions(-)

diff --git a/kernel/time/posix-timers.c b/kernel/time/posix-timers.c
index 0332f7a..8acc9ee 100644
--- a/kernel/time/posix-timers.c
+++ b/kernel/time/posix-timers.c
@@ -744,25 +744,49 @@ SYSCALL_DEFINE1(timer_getoverrun, timer_t, timer_id)
 	return overrun;
 }
 
+static void common_hrtimer_arm(struct k_itimer *timr, ktime_t expires,
+			       bool absolute, bool sigev_none)
+{
+	struct hrtimer *timer = &timr->it.real.timer;
+	enum hrtimer_mode mode;
+
+	mode = absolute ? HRTIMER_MODE_ABS : HRTIMER_MODE_REL;
+	hrtimer_init(&timr->it.real.timer, timr->it_clock, mode);
+	timr->it.real.timer.function = posix_timer_fn;
+
+	if (!absolute)
+		expires = ktime_add_safe(expires, timer->base->get_time());
+	hrtimer_set_expires(timer, expires);
+
+	if (!sigev_none)
+		hrtimer_start_expires(timer, HRTIMER_MODE_ABS);
+}
+
+static int common_hrtimer_try_to_cancel(struct k_itimer *timr)
+{
+	return hrtimer_try_to_cancel(&timr->it.real.timer);
+}
+
 /* Set a POSIX.1b interval timer. */
-/* timr->it_lock is taken. */
 static int
 common_timer_set(struct k_itimer *timr, int flags,
-		 struct itimerspec64 *new_setting, struct itimerspec64 *old_setting)
+		 struct itimerspec64 *new_setting,
+		 struct itimerspec64 *old_setting)
 {
-	struct hrtimer *timer = &timr->it.real.timer;
-	enum hrtimer_mode mode;
+	const struct k_clock *kc = timr->kclock;
+	bool sigev_none;
+	ktime_t expires;
 
 	if (old_setting)
 		common_timer_get(timr, old_setting);
 
-	/* disable the timer */
+	/* Prevent rearming by clearing the interval */
 	timr->it_interval = 0;
 	/*
-	 * careful here.  If smp we could be in the "fire" routine which will
-	 * be spinning as we hold the lock.  But this is ONLY an SMP issue.
+	 * Careful here. On SMP systems the timer expiry function could be
+	 * active and spinning on timr->it_lock.
 	 */
-	if (hrtimer_try_to_cancel(timer) < 0)
+	if (kc->timer_try_to_cancel(timr) < 0)
 		return TIMER_RETRY;
 
 	timr->it_active = 0;
@@ -770,30 +794,16 @@ common_timer_set(struct k_itimer *timr, int flags,
 		~REQUEUE_PENDING;
 	timr->it_overrun_last = 0;
 
-	/* switch off the timer when it_value is zero */
+	/* Switch off the timer when it_value is zero */
 	if (!new_setting->it_value.tv_sec && !new_setting->it_value.tv_nsec)
 		return 0;
 
-	mode = flags & TIMER_ABSTIME ? HRTIMER_MODE_ABS : HRTIMER_MODE_REL;
-	hrtimer_init(&timr->it.real.timer, timr->it_clock, mode);
-	timr->it.real.timer.function = posix_timer_fn;
-
-	hrtimer_set_expires(timer, timespec64_to_ktime(new_setting->it_value));
-
-	/* Convert interval */
 	timr->it_interval = timespec64_to_ktime(new_setting->it_interval);
+	expires = timespec64_to_ktime(new_setting->it_value);
+	sigev_none = (timr->it_sigev_notify & ~SIGEV_THREAD_ID) == SIGEV_NONE;
 
-	/* SIGEV_NONE timers are not queued ! See common_timer_get */
-	if (((timr->it_sigev_notify & ~SIGEV_THREAD_ID) == SIGEV_NONE)) {
-		/* Setup correct expiry time for relative timers */
-		if (mode == HRTIMER_MODE_REL) {
-			hrtimer_add_expires(timer, timer->base->get_time());
-		}
-		return 0;
-	}
-
-	timr->it_active = 1;
-	hrtimer_start_expires(timer, mode);
+	kc->timer_arm(timr, expires, flags & TIMER_ABSTIME, sigev_none);
+	timr->it_active = !sigev_none;
 	return 0;
 }
 
@@ -847,9 +857,10 @@ retry:
 
 static int common_timer_del(struct k_itimer *timer)
 {
-	timer->it_interval = 0;
+	const struct k_clock *kc = timer->kclock;
 
-	if (hrtimer_try_to_cancel(&timer->it.real.timer) < 0)
+	timer->it_interval = 0;
+	if (kc->timer_try_to_cancel(timer) < 0)
 		return TIMER_RETRY;
 	timer->it_active = 0;
 	return 0;
@@ -1063,76 +1074,84 @@ long clock_nanosleep_restart(struct restart_block *restart_block)
 }
 
 static const struct k_clock clock_realtime = {
-	.clock_getres	= posix_get_hrtimer_res,
-	.clock_get	= posix_clock_realtime_get,
-	.clock_set	= posix_clock_realtime_set,
-	.clock_adj	= posix_clock_realtime_adj,
-	.nsleep		= common_nsleep,
-	.nsleep_restart	= hrtimer_nanosleep_restart,
-	.timer_create	= common_timer_create,
-	.timer_set	= common_timer_set,
-	.timer_get	= common_timer_get,
-	.timer_del	= common_timer_del,
-	.timer_rearm	= common_hrtimer_rearm,
-	.timer_forward	= common_hrtimer_forward,
-	.timer_remaining= common_hrtimer_remaining,
+	.clock_getres		= posix_get_hrtimer_res,
+	.clock_get		= posix_clock_realtime_get,
+	.clock_set		= posix_clock_realtime_set,
+	.clock_adj		= posix_clock_realtime_adj,
+	.nsleep			= common_nsleep,
+	.nsleep_restart		= hrtimer_nanosleep_restart,
+	.timer_create		= common_timer_create,
+	.timer_set		= common_timer_set,
+	.timer_get		= common_timer_get,
+	.timer_del		= common_timer_del,
+	.timer_rearm		= common_hrtimer_rearm,
+	.timer_forward		= common_hrtimer_forward,
+	.timer_remaining	= common_hrtimer_remaining,
+	.timer_try_to_cancel	= common_hrtimer_try_to_cancel,
+	.timer_arm		= common_hrtimer_arm,
 };
 
 static const struct k_clock clock_monotonic = {
-	.clock_getres	= posix_get_hrtimer_res,
-	.clock_get	= posix_ktime_get_ts,
-	.nsleep		= common_nsleep,
-	.nsleep_restart	= hrtimer_nanosleep_restart,
-	.timer_create	= common_timer_create,
-	.timer_set	= common_timer_set,
-	.timer_get	= common_timer_get,
-	.timer_del	= common_timer_del,
-	.timer_rearm	= common_hrtimer_rearm,
-	.timer_forward	= common_hrtimer_forward,
-	.timer_remaining= common_hrtimer_remaining,
+	.clock_getres		= posix_get_hrtimer_res,
+	.clock_get		= posix_ktime_get_ts,
+	.nsleep			= common_nsleep,
+	.nsleep_restart		= hrtimer_nanosleep_restart,
+	.timer_create		= common_timer_create,
+	.timer_set		= common_timer_set,
+	.timer_get		= common_timer_get,
+	.timer_del		= common_timer_del,
+	.timer_rearm		= common_hrtimer_rearm,
+	.timer_forward		= common_hrtimer_forward,
+	.timer_remaining	= common_hrtimer_remaining,
+	.timer_try_to_cancel	= common_hrtimer_try_to_cancel,
+	.timer_arm		= common_hrtimer_arm,
 };
 
 static const struct k_clock clock_monotonic_raw = {
-	.clock_getres	= posix_get_hrtimer_res,
-	.clock_get	= posix_get_monotonic_raw,
+	.clock_getres		= posix_get_hrtimer_res,
+	.clock_get		= posix_get_monotonic_raw,
 };
 
 static const struct k_clock clock_realtime_coarse = {
-	.clock_getres	= posix_get_coarse_res,
-	.clock_get	= posix_get_realtime_coarse,
+	.clock_getres		= posix_get_coarse_res,
+	.clock_get		= posix_get_realtime_coarse,
 };
 
 static const struct k_clock clock_monotonic_coarse = {
-	.clock_getres	= posix_get_coarse_res,
-	.clock_get	= posix_get_monotonic_coarse,
+	.clock_getres		= posix_get_coarse_res,
+	.clock_get		= posix_get_monotonic_coarse,
 };
 
 static const struct k_clock clock_tai = {
-	.clock_getres	= posix_get_hrtimer_res,
-	.clock_get	= posix_get_tai,
-	.nsleep		= common_nsleep,
-	.nsleep_restart	= hrtimer_nanosleep_restart,
-	.timer_create	= common_timer_create,
-	.timer_set	= common_timer_set,
-	.timer_get	= common_timer_get,
-	.timer_del	= common_timer_del,
-	.timer_rearm	= common_hrtimer_rearm,
-	.timer_forward	= common_hrtimer_forward,
-	.timer_remaining= common_hrtimer_remaining,
+	.clock_getres		= posix_get_hrtimer_res,
+	.clock_get		= posix_get_tai,
+	.nsleep			= common_nsleep,
+	.nsleep_restart		= hrtimer_nanosleep_restart,
+	.timer_create		= common_timer_create,
+	.timer_set		= common_timer_set,
+	.timer_get		= common_timer_get,
+	.timer_del		= common_timer_del,
+	.timer_rearm		= common_hrtimer_rearm,
+	.timer_forward		= common_hrtimer_forward,
+	.timer_remaining	= common_hrtimer_remaining,
+	.timer_try_to_cancel	= common_hrtimer_try_to_cancel,
+	.timer_arm		= common_hrtimer_arm,
 };
 
 static const struct k_clock clock_boottime = {
-	.clock_getres	= posix_get_hrtimer_res,
-	.clock_get	= posix_get_boottime,
-	.nsleep		= common_nsleep,
-	.nsleep_restart	= hrtimer_nanosleep_restart,
-	.timer_create	= common_timer_create,
-	.timer_set	= common_timer_set,
-	.timer_get	= common_timer_get,
-	.timer_del	= common_timer_del,
-	.timer_rearm	= common_hrtimer_rearm,
-	.timer_forward	= common_hrtimer_forward,
-	.timer_remaining= common_hrtimer_remaining,
+	.clock_getres		= posix_get_hrtimer_res,
+	.clock_get		= posix_get_boottime,
+	.nsleep			= common_nsleep,
+	.nsleep_restart		= hrtimer_nanosleep_restart,
+	.timer_create		= common_timer_create,
+	.timer_set		= common_timer_set,
+	.timer_get		= common_timer_get,
+	.timer_del		= common_timer_del,
+	.timer_rearm		= common_hrtimer_rearm,
+	.timer_forward		= common_hrtimer_forward,
+	.timer_remaining	= common_hrtimer_remaining,
+	.timer_try_to_cancel	= common_hrtimer_try_to_cancel,
+	.timer_arm		= common_hrtimer_arm,
 };
 
 static const struct k_clock * const posix_clocks[] = {

^ permalink raw reply	[flat|nested] 66+ messages in thread

* [tip:timers/core] alarmtimer: Implement timer_rearm() callback
  2017-05-30 21:15 ` [patch 21/26] alarmtimer: Implement timer_rearm() callback Thomas Gleixner
@ 2017-06-05  8:23   ` tip-bot for Thomas Gleixner
  0 siblings, 0 replies; 66+ messages in thread
From: tip-bot for Thomas Gleixner @ 2017-06-05  8:23 UTC (permalink / raw)
  To: linux-tip-commits; +Cc: hpa, john.stultz, peterz, tglx, mingo, linux-kernel

Commit-ID:  b3db80f77a95a45dbb2136f7b2a364dc797ea914
Gitweb:     http://git.kernel.org/tip/b3db80f77a95a45dbb2136f7b2a364dc797ea914
Author:     Thomas Gleixner <tglx@linutronix.de>
AuthorDate: Tue, 30 May 2017 23:15:54 +0200
Committer:  Thomas Gleixner <tglx@linutronix.de>
CommitDate: Sun, 4 Jun 2017 15:40:30 +0200

alarmtimer: Implement timer_rearm() callback

Preparatory change to utilize the common posix timer mechanisms.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: John Stultz <john.stultz@linaro.org>
Link: http://lkml.kernel.org/r/20170530211657.434598989@linutronix.de

---
 kernel/time/alarmtimer.c | 15 ++++++++++++++-
 1 file changed, 14 insertions(+), 1 deletion(-)

diff --git a/kernel/time/alarmtimer.c b/kernel/time/alarmtimer.c
index 5b8cf4b..be85e3c 100644
--- a/kernel/time/alarmtimer.c
+++ b/kernel/time/alarmtimer.c
@@ -537,6 +537,18 @@ static enum alarmtimer_restart alarm_handle_timer(struct alarm *alarm,
 }
 
 /**
+ * alarm_timer_rearm - Posix timer callback for rearming timer
+ * @timr:	Pointer to the posixtimer data struct
+ */
+static void alarm_timer_rearm(struct k_itimer *timr)
+{
+	struct alarm *alarm = &timr->it.alarm.alarmtimer;
+
+	timr->it_overrun += alarm_forward_now(alarm, timr->it_interval);
+	alarm_start(alarm, alarm->node.expires);
+}
+
+/**
  * alarm_clock_getres - posix getres interface
  * @which_clock: clockid
  * @tp: timespec to fill
@@ -594,7 +606,7 @@ static int alarm_timer_create(struct k_itimer *new_timer)
 
 /**
  * alarm_timer_get - posix timer_get interface
- * @new_timer: k_itimer pointer
+ * @timr: k_itimer pointer
  * @cur_setting: itimerspec data to fill
  *
  * Copies out the current itimerspec data
@@ -863,6 +875,7 @@ const struct k_clock alarm_clock = {
 	.timer_set	= alarm_timer_set,
 	.timer_del	= alarm_timer_del,
 	.timer_get	= alarm_timer_get,
+	.timer_rearm	= alarm_timer_rearm,
 	.nsleep		= alarm_timer_nsleep,
 };
 #endif /* CONFIG_POSIX_TIMERS */

^ permalink raw reply	[flat|nested] 66+ messages in thread

* [tip:timers/core] alarmtimer: Implement forward callback
  2017-05-30 21:15 ` [patch 22/26] alarmtimer: Implement forward callback Thomas Gleixner
@ 2017-06-05  8:24   ` tip-bot for Thomas Gleixner
  0 siblings, 0 replies; 66+ messages in thread
From: tip-bot for Thomas Gleixner @ 2017-06-05  8:24 UTC (permalink / raw)
  To: linux-tip-commits; +Cc: mingo, john.stultz, linux-kernel, tglx, hpa, peterz

Commit-ID:  e7561f1633ac735df48c55ad09a2530e9ab9fab1
Gitweb:     http://git.kernel.org/tip/e7561f1633ac735df48c55ad09a2530e9ab9fab1
Author:     Thomas Gleixner <tglx@linutronix.de>
AuthorDate: Tue, 30 May 2017 23:15:55 +0200
Committer:  Thomas Gleixner <tglx@linutronix.de>
CommitDate: Sun, 4 Jun 2017 15:40:30 +0200

alarmtimer: Implement forward callback

Preparatory change to utilize the common posix timer mechanisms.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: John Stultz <john.stultz@linaro.org>
Link: http://lkml.kernel.org/r/20170530211657.513694229@linutronix.de

---
 kernel/time/alarmtimer.c | 13 +++++++++++++
 1 file changed, 13 insertions(+)

diff --git a/kernel/time/alarmtimer.c b/kernel/time/alarmtimer.c
index be85e3c..6082cf1 100644
--- a/kernel/time/alarmtimer.c
+++ b/kernel/time/alarmtimer.c
@@ -549,6 +549,18 @@ static void alarm_timer_rearm(struct k_itimer *timr)
 }
 
 /**
+ * alarm_timer_forward - Posix timer callback for forwarding timer
+ * @timr:	Pointer to the posixtimer data struct
+ * @now:	Current time to forward the timer against
+ */
+static int alarm_timer_forward(struct k_itimer *timr, ktime_t now)
+{
+	struct alarm *alarm = &timr->it.alarm.alarmtimer;
+
+	return (int) alarm_forward(alarm, timr->it_interval, now);
+}
+
+/**
  * alarm_clock_getres - posix getres interface
  * @which_clock: clockid
  * @tp: timespec to fill
@@ -876,6 +888,7 @@ const struct k_clock alarm_clock = {
 	.timer_del	= alarm_timer_del,
 	.timer_get	= alarm_timer_get,
 	.timer_rearm	= alarm_timer_rearm,
+	.timer_forward	= alarm_timer_forward,
 	.nsleep		= alarm_timer_nsleep,
 };
 #endif /* CONFIG_POSIX_TIMERS */

^ permalink raw reply	[flat|nested] 66+ messages in thread

* [tip:timers/core] alarmtimer: Implement remaining callback
  2017-05-30 21:15 ` [patch 23/26] alarmtimer: Implement remaining callback Thomas Gleixner
@ 2017-06-05  8:24   ` tip-bot for Thomas Gleixner
  0 siblings, 0 replies; 66+ messages in thread
From: tip-bot for Thomas Gleixner @ 2017-06-05  8:24 UTC (permalink / raw)
  To: linux-tip-commits; +Cc: tglx, hpa, peterz, john.stultz, linux-kernel, mingo

Commit-ID:  d653d8457c76da11f047af1f66256ac9b8421b69
Gitweb:     http://git.kernel.org/tip/d653d8457c76da11f047af1f66256ac9b8421b69
Author:     Thomas Gleixner <tglx@linutronix.de>
AuthorDate: Tue, 30 May 2017 23:15:56 +0200
Committer:  Thomas Gleixner <tglx@linutronix.de>
CommitDate: Sun, 4 Jun 2017 15:40:31 +0200

alarmtimer: Implement remaining callback

Preparatory change to utilize the common posix timer mechanisms.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: John Stultz <john.stultz@linaro.org>
Link: http://lkml.kernel.org/r/20170530211657.592676753@linutronix.de

---
 kernel/time/alarmtimer.c | 31 ++++++++++++++++++++++---------
 1 file changed, 22 insertions(+), 9 deletions(-)

diff --git a/kernel/time/alarmtimer.c b/kernel/time/alarmtimer.c
index 6082cf1..02ddc40 100644
--- a/kernel/time/alarmtimer.c
+++ b/kernel/time/alarmtimer.c
@@ -561,6 +561,18 @@ static int alarm_timer_forward(struct k_itimer *timr, ktime_t now)
 }
 
 /**
+ * alarm_timer_remaining - Posix timer callback to retrieve remaining time
+ * @timr:	Pointer to the posixtimer data struct
+ * @now:	Current time to calculate against
+ */
+static ktime_t alarm_timer_remaining(struct k_itimer *timr, ktime_t now)
+{
+	struct alarm *alarm = &timr->it.alarm.alarmtimer;
+
+	return ktime_sub(now, alarm->node.expires);
+}
+
+/**
  * alarm_clock_getres - posix getres interface
  * @which_clock: clockid
  * @tp: timespec to fill
@@ -881,15 +893,16 @@ out:
 }
 
 const struct k_clock alarm_clock = {
-	.clock_getres	= alarm_clock_getres,
-	.clock_get	= alarm_clock_get,
-	.timer_create	= alarm_timer_create,
-	.timer_set	= alarm_timer_set,
-	.timer_del	= alarm_timer_del,
-	.timer_get	= alarm_timer_get,
-	.timer_rearm	= alarm_timer_rearm,
-	.timer_forward	= alarm_timer_forward,
-	.nsleep		= alarm_timer_nsleep,
+	.clock_getres		= alarm_clock_getres,
+	.clock_get		= alarm_clock_get,
+	.timer_create		= alarm_timer_create,
+	.timer_set		= alarm_timer_set,
+	.timer_del		= alarm_timer_del,
+	.timer_get		= alarm_timer_get,
+	.timer_rearm		= alarm_timer_rearm,
+	.timer_forward		= alarm_timer_forward,
+	.timer_remaining	= alarm_timer_remaining,
+	.nsleep			= alarm_timer_nsleep,
 };
 #endif /* CONFIG_POSIX_TIMERS */
 

^ permalink raw reply	[flat|nested] 66+ messages in thread

* [tip:timers/core] alarmtimer: Implement try_to_cancel callback
  2017-05-30 21:15 ` [patch 24/26] alarmtimer: Implement try_to_cancel callback Thomas Gleixner
@ 2017-06-05  8:25   ` tip-bot for Thomas Gleixner
  0 siblings, 0 replies; 66+ messages in thread
From: tip-bot for Thomas Gleixner @ 2017-06-05  8:25 UTC (permalink / raw)
  To: linux-tip-commits; +Cc: john.stultz, hpa, tglx, mingo, linux-kernel, peterz

Commit-ID:  e344c9e76bc6af997926171bfd90d25bbae0a2c5
Gitweb:     http://git.kernel.org/tip/e344c9e76bc6af997926171bfd90d25bbae0a2c5
Author:     Thomas Gleixner <tglx@linutronix.de>
AuthorDate: Tue, 30 May 2017 23:15:57 +0200
Committer:  Thomas Gleixner <tglx@linutronix.de>
CommitDate: Sun, 4 Jun 2017 15:40:31 +0200

alarmtimer: Implement try_to_cancel callback

Preparatory change to utilize the common posix timer mechanisms.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: John Stultz <john.stultz@linaro.org>
Link: http://lkml.kernel.org/r/20170530211657.670026824@linutronix.de

---
 kernel/time/alarmtimer.c | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/kernel/time/alarmtimer.c b/kernel/time/alarmtimer.c
index 02ddc40..374bd85 100644
--- a/kernel/time/alarmtimer.c
+++ b/kernel/time/alarmtimer.c
@@ -573,6 +573,15 @@ static ktime_t alarm_timer_remaining(struct k_itimer *timr, ktime_t now)
 }
 
 /**
+ * alarm_timer_try_to_cancel - Posix timer callback to cancel a timer
+ * @timr:	Pointer to the posixtimer data struct
+ */
+static int alarm_timer_try_to_cancel(struct k_itimer *timr)
+{
+	return alarm_try_to_cancel(&timr->it.alarm.alarmtimer);
+}
+
+/**
  * alarm_clock_getres - posix getres interface
  * @which_clock: clockid
  * @tp: timespec to fill
@@ -902,6 +911,7 @@ const struct k_clock alarm_clock = {
 	.timer_rearm		= alarm_timer_rearm,
 	.timer_forward		= alarm_timer_forward,
 	.timer_remaining	= alarm_timer_remaining,
+	.timer_try_to_cancel	= alarm_timer_try_to_cancel,
 	.nsleep			= alarm_timer_nsleep,
 };
 #endif /* CONFIG_POSIX_TIMERS */

^ permalink raw reply	[flat|nested] 66+ messages in thread

* [tip:timers/core] alarmtimer: Implement arm callback
  2017-05-30 21:15 ` [patch 25/26] alarmtimer: Implement arm callback Thomas Gleixner
@ 2017-06-05  8:25   ` tip-bot for Thomas Gleixner
  0 siblings, 0 replies; 66+ messages in thread
From: tip-bot for Thomas Gleixner @ 2017-06-05  8:25 UTC (permalink / raw)
  To: linux-tip-commits; +Cc: peterz, linux-kernel, john.stultz, tglx, hpa, mingo

Commit-ID:  b3bf6f369d50ece9dec6338741648005d95c19e4
Gitweb:     http://git.kernel.org/tip/b3bf6f369d50ece9dec6338741648005d95c19e4
Author:     Thomas Gleixner <tglx@linutronix.de>
AuthorDate: Tue, 30 May 2017 23:15:58 +0200
Committer:  Thomas Gleixner <tglx@linutronix.de>
CommitDate: Sun, 4 Jun 2017 15:40:31 +0200

alarmtimer: Implement arm callback

Preparatory change to utilize the common posix timer mechanisms.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: John Stultz <john.stultz@linaro.org>
Link: http://lkml.kernel.org/r/20170530211657.747567162@linutronix.de

---
 kernel/time/alarmtimer.c | 22 ++++++++++++++++++++++
 1 file changed, 22 insertions(+)

diff --git a/kernel/time/alarmtimer.c b/kernel/time/alarmtimer.c
index 374bd85..c618a44 100644
--- a/kernel/time/alarmtimer.c
+++ b/kernel/time/alarmtimer.c
@@ -582,6 +582,27 @@ static int alarm_timer_try_to_cancel(struct k_itimer *timr)
 }
 
 /**
+ * alarm_timer_arm - Posix timer callback to arm a timer
+ * @timr:	Pointer to the posixtimer data struct
+ * @expires:	The new expiry time
+ * @absolute:	Expiry value is absolute time
+ * @sigev_none:	Posix timer does not deliver signals
+ */
+static void alarm_timer_arm(struct k_itimer *timr, ktime_t expires,
+			    bool absolute, bool sigev_none)
+{
+	struct alarm *alarm = &timr->it.alarm.alarmtimer;
+	struct alarm_base *base = &alarm_bases[alarm->type];
+
+	if (!absolute)
+		expires = ktime_add_safe(expires, base->gettime());
+	if (sigev_none)
+		alarm->node.expires = expires;
+	else
+		alarm_start(&timr->it.alarm.alarmtimer, expires);
+}
+
+/**
  * alarm_clock_getres - posix getres interface
  * @which_clock: clockid
  * @tp: timespec to fill
@@ -908,6 +929,7 @@ const struct k_clock alarm_clock = {
 	.timer_set		= alarm_timer_set,
 	.timer_del		= alarm_timer_del,
 	.timer_get		= alarm_timer_get,
+	.timer_arm		= alarm_timer_arm,
 	.timer_rearm		= alarm_timer_rearm,
 	.timer_forward		= alarm_timer_forward,
 	.timer_remaining	= alarm_timer_remaining,

^ permalink raw reply	[flat|nested] 66+ messages in thread

* [tip:timers/core] alarmtimer: Switch over to generic set/get/rearm routine
  2017-05-30 21:15 ` [patch 26/26] alarmtimer: Switch over to generic set/get/rearm routine Thomas Gleixner
@ 2017-06-05  8:26   ` tip-bot for Thomas Gleixner
  0 siblings, 0 replies; 66+ messages in thread
From: tip-bot for Thomas Gleixner @ 2017-06-05  8:26 UTC (permalink / raw)
  To: linux-tip-commits; +Cc: hpa, linux-kernel, tglx, mingo, peterz, john.stultz

Commit-ID:  f2c45807d3992fe0f173f34af9c347d907c31686
Gitweb:     http://git.kernel.org/tip/f2c45807d3992fe0f173f34af9c347d907c31686
Author:     Thomas Gleixner <tglx@linutronix.de>
AuthorDate: Tue, 30 May 2017 23:15:59 +0200
Committer:  Thomas Gleixner <tglx@linutronix.de>
CommitDate: Sun, 4 Jun 2017 15:40:32 +0200

alarmtimer: Switch over to generic set/get/rearm routine

All required callbacks are in place. Switch the alarm timer based posix
interval timer callbacks to the common implementation and remove the
incorrect private implementation.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: John Stultz <john.stultz@linaro.org>
Link: http://lkml.kernel.org/r/20170530211657.825471962@linutronix.de

---
 kernel/time/alarmtimer.c   | 121 +++++++--------------------------------------
 kernel/time/posix-timers.c |  12 ++---
 kernel/time/posix-timers.h |   6 +++
 3 files changed, 29 insertions(+), 110 deletions(-)

diff --git a/kernel/time/alarmtimer.c b/kernel/time/alarmtimer.c
index c618a44..d8a7a7e 100644
--- a/kernel/time/alarmtimer.c
+++ b/kernel/time/alarmtimer.c
@@ -515,20 +515,26 @@ static enum alarmtimer_type clock2alarm(clockid_t clockid)
 static enum alarmtimer_restart alarm_handle_timer(struct alarm *alarm,
 							ktime_t now)
 {
-	unsigned long flags;
 	struct k_itimer *ptr = container_of(alarm, struct k_itimer,
-						it.alarm.alarmtimer);
+					    it.alarm.alarmtimer);
 	enum alarmtimer_restart result = ALARMTIMER_NORESTART;
+	unsigned long flags;
+	int si_private = 0;
 
 	spin_lock_irqsave(&ptr->it_lock, flags);
-	if ((ptr->it_sigev_notify & ~SIGEV_THREAD_ID) != SIGEV_NONE) {
-		if (posix_timer_event(ptr, 0))
-			ptr->it_overrun++;
-	}
 
-	/* Re-add periodic timers */
-	if (ptr->it_interval) {
-		ptr->it_overrun += alarm_forward(alarm, now, ptr->it_interval);
+	ptr->it_active = 0;
+	if (ptr->it_interval)
+		si_private = ++ptr->it_requeue_pending;
+
+	if (posix_timer_event(ptr, si_private) && ptr->it_interval) {
+		/*
+		 * Handle ignored signals and rearm the timer. This will go
+		 * away once we handle ignored signals proper.
+		 */
+		ptr->it_overrun += alarm_forward_now(alarm, ptr->it_interval);
+		++ptr->it_requeue_pending;
+		ptr->it_active = 1;
 		result = ALARMTIMER_RESTART;
 	}
 	spin_unlock_irqrestore(&ptr->it_lock, flags);
@@ -659,97 +665,6 @@ static int alarm_timer_create(struct k_itimer *new_timer)
 }
 
 /**
- * alarm_timer_get - posix timer_get interface
- * @timr: k_itimer pointer
- * @cur_setting: itimerspec data to fill
- *
- * Copies out the current itimerspec data
- */
-static void alarm_timer_get(struct k_itimer *timr,
-			    struct itimerspec64 *cur_setting)
-{
-	ktime_t relative_expiry_time =
-		alarm_expires_remaining(&(timr->it.alarm.alarmtimer));
-
-	if (ktime_to_ns(relative_expiry_time) > 0) {
-		cur_setting->it_value = ktime_to_timespec64(relative_expiry_time);
-	} else {
-		cur_setting->it_value.tv_sec = 0;
-		cur_setting->it_value.tv_nsec = 0;
-	}
-
-	cur_setting->it_interval = ktime_to_timespec64(timr->it_interval);
-}
-
-/**
- * alarm_timer_del - posix timer_del interface
- * @timr: k_itimer pointer to be deleted
- *
- * Cancels any programmed alarms for the given timer.
- */
-static int alarm_timer_del(struct k_itimer *timr)
-{
-	if (!rtcdev)
-		return -ENOTSUPP;
-
-	if (alarm_try_to_cancel(&timr->it.alarm.alarmtimer) < 0)
-		return TIMER_RETRY;
-
-	return 0;
-}
-
-/**
- * alarm_timer_set - posix timer_set interface
- * @timr: k_itimer pointer to be deleted
- * @flags: timer flags
- * @new_setting: itimerspec to be used
- * @old_setting: itimerspec being replaced
- *
- * Sets the timer to new_setting, and starts the timer.
- */
-static int alarm_timer_set(struct k_itimer *timr, int flags,
-			   struct itimerspec64 *new_setting,
-			   struct itimerspec64 *old_setting)
-{
-	ktime_t exp;
-
-	if (!rtcdev)
-		return -ENOTSUPP;
-
-	if (flags & ~TIMER_ABSTIME)
-		return -EINVAL;
-
-	if (old_setting)
-		alarm_timer_get(timr, old_setting);
-
-	/* If the timer was already set, cancel it */
-	if (alarm_try_to_cancel(&timr->it.alarm.alarmtimer) < 0)
-		return TIMER_RETRY;
-
-	/* start the timer */
-	timr->it_interval = timespec64_to_ktime(new_setting->it_interval);
-
-	/*
-	 * Rate limit to the tick as a hot fix to prevent DOS. Will be
-	 * mopped up later.
-	 */
-	if (timr->it_interval < TICK_NSEC)
-		timr->it_interval = TICK_NSEC;
-
-	exp = timespec64_to_ktime(new_setting->it_value);
-	/* Convert (if necessary) to absolute time */
-	if (flags != TIMER_ABSTIME) {
-		ktime_t now;
-
-		now = alarm_bases[timr->it.alarm.alarmtimer.type].gettime();
-		exp = ktime_add_safe(now, exp);
-	}
-
-	alarm_start(&timr->it.alarm.alarmtimer, exp);
-	return 0;
-}
-
-/**
  * alarmtimer_nsleep_wakeup - Wakeup function for alarm_timer_nsleep
  * @alarm: ptr to alarm that fired
  *
@@ -926,9 +841,9 @@ const struct k_clock alarm_clock = {
 	.clock_getres		= alarm_clock_getres,
 	.clock_get		= alarm_clock_get,
 	.timer_create		= alarm_timer_create,
-	.timer_set		= alarm_timer_set,
-	.timer_del		= alarm_timer_del,
-	.timer_get		= alarm_timer_get,
+	.timer_set		= common_timer_set,
+	.timer_del		= common_timer_del,
+	.timer_get		= common_timer_get,
 	.timer_arm		= alarm_timer_arm,
 	.timer_rearm		= alarm_timer_rearm,
 	.timer_forward		= alarm_timer_forward,
diff --git a/kernel/time/posix-timers.c b/kernel/time/posix-timers.c
index 8acc9ee..6e7a70b1 100644
--- a/kernel/time/posix-timers.c
+++ b/kernel/time/posix-timers.c
@@ -637,8 +637,7 @@ static int common_hrtimer_forward(struct k_itimer *timr, ktime_t now)
  * it is the same as a requeue pending timer WRT to what we should
  * report.
  */
-static void
-common_timer_get(struct k_itimer *timr, struct itimerspec64 *cur_setting)
+void common_timer_get(struct k_itimer *timr, struct itimerspec64 *cur_setting)
 {
 	const struct k_clock *kc = timr->kclock;
 	ktime_t now, remaining, iv;
@@ -768,10 +767,9 @@ static int common_hrtimer_try_to_cancel(struct k_itimer *timr)
 }
 
 /* Set a POSIX.1b interval timer. */
-static int
-common_timer_set(struct k_itimer *timr, int flags,
-		 struct itimerspec64 *new_setting,
-		 struct itimerspec64 *old_setting)
+int common_timer_set(struct k_itimer *timr, int flags,
+		     struct itimerspec64 *new_setting,
+		     struct itimerspec64 *old_setting)
 {
 	const struct k_clock *kc = timr->kclock;
 	bool sigev_none;
@@ -855,7 +853,7 @@ retry:
 	return error;
 }
 
-static int common_timer_del(struct k_itimer *timer)
+int common_timer_del(struct k_itimer *timer)
 {
 	const struct k_clock *kc = timer->kclock;
 
diff --git a/kernel/time/posix-timers.h b/kernel/time/posix-timers.h
index b0ad77e..b086f5b 100644
--- a/kernel/time/posix-timers.h
+++ b/kernel/time/posix-timers.h
@@ -33,3 +33,9 @@ extern const struct k_clock clock_thread;
 extern const struct k_clock alarm_clock;
 
 int posix_timer_event(struct k_itimer *timr, int si_private);
+
+void common_timer_get(struct k_itimer *timr, struct itimerspec64 *cur_setting);
+int common_timer_set(struct k_itimer *timr, int flags,
+		     struct itimerspec64 *new_setting,
+		     struct itimerspec64 *old_setting);
+int common_timer_del(struct k_itimer *timer);

^ permalink raw reply	[flat|nested] 66+ messages in thread

* Re: [tip:timers/core] posix-timers: Zero settings value in common code
  2017-06-05  8:21   ` [tip:timers/core] " tip-bot for Thomas Gleixner
@ 2017-06-09 20:12     ` Andrei Vagin
  2017-06-12 19:13       ` [tip:timers/core] posix-timers: Zero out oldval itimerspec tip-bot for Thomas Gleixner
  2017-06-12 19:13       ` [tip:timers/core] posix-timers: Handle relative posix-timers correctly tip-bot for Thomas Gleixner
  0 siblings, 2 replies; 66+ messages in thread
From: Andrei Vagin @ 2017-06-09 20:12 UTC (permalink / raw)
  To: tip-bot for Jacob Shin
  Cc: linux-tip-commits, peterz, john.stultz, mingo, linux-kernel,
	tglx, hpa, Cyrill Gorcunov

Hello Thomas,

This patch breaks one of our CRIU tests:
https://github.com/xemul/criu/blob/master/test/zdtm/static/posix_timers.c#L145

python /root/git/main/criu/test/zdtm.py run -t zdtm/static/posix_timers --iter 0

====================== Run zdtm/static/posix_timers in h =======================
Start test
./posix_timers --pidfile=posix_timers.pid --outfile=posix_timers.out
Send the 15 signal to  24
Wait for zdtm/static/posix_timers(24) to die for 0.100000
############## Test zdtm/static/posix_timers FAIL at result check ##############
Test output: ================================
22:39:39.573:    24: ( start) boottime 12 boottime-coarse 12 total_sleep_time 0
22:39:39.602:    24: (   end) boottime 12 boottime-coarse 12 total_sleep_time 0
22:39:39.603:    24: FAIL: posix_timers.c:145: REALTIME (oneshot): timer became periodic
22:39:39.603:    24: FAIL: posix_timers.c:145: MONOTONIC (oneshot): timer became periodic
22:39:39.603:    24: FAIL: posix_timers.c:145: BOOTTIME (oneshot): timer became periodic

 <<< ================================
=== Run 1/1 ================ zdtm/static/posix_timers
##################################### FAIL #####################################


This test sets a timer and then check that it is set correctly. And with this patch,
we see that timer_settime returns incorrect data.


2447  timer_settime(10, 0, {it_interval={tv_sec=0, tv_nsec=0}, it_value={tv_sec=2147483, tv_nsec=647000000}}, NULL) = 0

....

2519  timer_settime(10, 0, {it_interval={tv_sec=0, tv_nsec=0}, it_value={tv_sec=0, tv_nsec=0}},  <unfinished ...>
2509  <... exit_group resumed>)         = ?
2519  <... timer_settime resumed> {it_interval={tv_sec=-1861316067, tv_nsec=18446645490300239488}, it_value={tv_sec=-1852565060, tv_nsec=133}}) = 0

Thanks,
Andrei

On Mon, Jun 05, 2017 at 01:21:46AM -0700, tip-bot for Jacob Shin wrote:
> Commit-ID:  eabdec04385376d560078992710104cc7be2ce1b
> Gitweb:     http://git.kernel.org/tip/eabdec04385376d560078992710104cc7be2ce1b
> Author:     Thomas Gleixner <tglx@linutronix.de>
> AuthorDate: Tue, 30 May 2017 23:15:51 +0200
> Committer:  Thomas Gleixner <tglx@linutronix.de>
> CommitDate: Sun, 4 Jun 2017 15:40:28 +0200
> 
> posix-timers: Zero settings value in common code
> 
> Zero out the settings struct in the common code so the callbacks do not
> have to do it themself.
> 
> Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
> Cc: Peter Zijlstra <peterz@infradead.org>
> Cc: John Stultz <john.stultz@linaro.org>
> Link: http://lkml.kernel.org/r/20170530211657.200870713@linutronix.de
> ---
>  kernel/time/posix-cpu-timers.c | 5 +----
>  kernel/time/posix-timers.c     | 3 +--
>  2 files changed, 2 insertions(+), 6 deletions(-)
> 
> diff --git a/kernel/time/posix-cpu-timers.c b/kernel/time/posix-cpu-timers.c
> index 96c833a..cb4a4eb 100644
> --- a/kernel/time/posix-cpu-timers.c
> +++ b/kernel/time/posix-cpu-timers.c
> @@ -719,10 +719,8 @@ static void posix_cpu_timer_get(struct k_itimer *timer, struct itimerspec64 *itp
>  	 */
>  	itp->it_interval = ns_to_timespec64(timer->it.cpu.incr);
>  
> -	if (timer->it.cpu.expires == 0) {	/* Timer not armed at all.  */
> -		itp->it_value.tv_sec = itp->it_value.tv_nsec = 0;
> +	if (!timer->it.cpu.expires)
>  		return;
> -	}
>  
>  	/*
>  	 * Sample the clock to take the difference with the expiry time.
> @@ -746,7 +744,6 @@ static void posix_cpu_timer_get(struct k_itimer *timer, struct itimerspec64 *itp
>  			 * Call the timer disarmed, nothing else to do.
>  			 */
>  			timer->it.cpu.expires = 0;
> -			itp->it_value = ns_to_timespec64(timer->it.cpu.expires);
>  			return;
>  		} else {
>  			cpu_timer_sample_group(timer->it_clock, p, &now);
> diff --git a/kernel/time/posix-timers.c b/kernel/time/posix-timers.c
> index 48f6c37..0332f7a 100644
> --- a/kernel/time/posix-timers.c
> +++ b/kernel/time/posix-timers.c
> @@ -645,8 +645,6 @@ common_timer_get(struct k_itimer *timr, struct itimerspec64 *cur_setting)
>  	struct timespec64 ts64;
>  	bool sig_none;
>  
> -	memset(cur_setting, 0, sizeof(*cur_setting));
> -
>  	sig_none = (timr->it_sigev_notify & ~SIGEV_THREAD_ID) != SIGEV_NONE;
>  	iv = timr->it_interval;
>  
> @@ -705,6 +703,7 @@ SYSCALL_DEFINE2(timer_gettime, timer_t, timer_id,
>  	if (!timr)
>  		return -EINVAL;
>  
> +	memset(&cur_setting64, 0, sizeof(cur_setting64));
>  	kc = timr->kclock;
>  	if (WARN_ON_ONCE(!kc || !kc->timer_get))
>  		ret = -EINVAL;

^ permalink raw reply	[flat|nested] 66+ messages in thread

* [tip:timers/core] posix-timers: Zero out oldval itimerspec
  2017-06-09 20:12     ` Andrei Vagin
@ 2017-06-12 19:13       ` tip-bot for Thomas Gleixner
  2017-06-12 21:06         ` Andrei Vagin
  2017-06-12 19:13       ` [tip:timers/core] posix-timers: Handle relative posix-timers correctly tip-bot for Thomas Gleixner
  1 sibling, 1 reply; 66+ messages in thread
From: tip-bot for Thomas Gleixner @ 2017-06-12 19:13 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: hpa, linux-kernel, gorcunov, john.stultz, mingo, tglx, avagin, peterz

Commit-ID:  5c7a3a3d20a4e175304c0e23809e3d70be8fed8a
Gitweb:     http://git.kernel.org/tip/5c7a3a3d20a4e175304c0e23809e3d70be8fed8a
Author:     Thomas Gleixner <tglx@linutronix.de>
AuthorDate: Mon, 12 Jun 2017 19:44:09 +0200
Committer:  Thomas Gleixner <tglx@linutronix.de>
CommitDate: Mon, 12 Jun 2017 21:07:40 +0200

posix-timers: Zero out oldval itimerspec

The recent posix timer rework moved the clearing of the itimerspec to the
real syscall implementation, but forgot that the kclock->timer_get() is
used by timer_settime() as well. That results in an uninitialized variable
and bogus values returned to user space.

Add the missing memset to timer_settime().

Fixes: eabdec043853 ("posix-timers: Zero settings value in common code")
Reported-by: Andrei Vagin <avagin@virtuozzo.com>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: John Stultz <john.stultz@linaro.org>
Cc: Cyrill Gorcunov <gorcunov@openvz.org>
Link: http://lkml.kernel.org/r/20170609201156.GB21491@outlook.office365.com
---
 kernel/time/posix-timers.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/kernel/time/posix-timers.c b/kernel/time/posix-timers.c
index b53a0b5..88517dc 100644
--- a/kernel/time/posix-timers.c
+++ b/kernel/time/posix-timers.c
@@ -828,6 +828,8 @@ SYSCALL_DEFINE4(timer_settime, timer_t, timer_id, int, flags,
 	if (!timespec64_valid(&new_spec64.it_interval) ||
 	    !timespec64_valid(&new_spec64.it_value))
 		return -EINVAL;
+	if (rtn)
+		memset(rtn, 0, sizeof(*rtn));
 retry:
 	timr = lock_timer(timer_id, &flag);
 	if (!timr)

^ permalink raw reply	[flat|nested] 66+ messages in thread

* [tip:timers/core] posix-timers: Handle relative posix-timers correctly
  2017-06-09 20:12     ` Andrei Vagin
  2017-06-12 19:13       ` [tip:timers/core] posix-timers: Zero out oldval itimerspec tip-bot for Thomas Gleixner
@ 2017-06-12 19:13       ` tip-bot for Thomas Gleixner
  1 sibling, 0 replies; 66+ messages in thread
From: tip-bot for Thomas Gleixner @ 2017-06-12 19:13 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: avagin, tglx, john.stultz, gorcunov, peterz, hpa, mingo, linux-kernel

Commit-ID:  67edab48caeb75d412706f4b9d3107afd1e07623
Gitweb:     http://git.kernel.org/tip/67edab48caeb75d412706f4b9d3107afd1e07623
Author:     Thomas Gleixner <tglx@linutronix.de>
AuthorDate: Mon, 12 Jun 2017 19:39:49 +0200
Committer:  Thomas Gleixner <tglx@linutronix.de>
CommitDate: Mon, 12 Jun 2017 21:07:41 +0200

posix-timers: Handle relative posix-timers correctly

The recent rework of the posix timer internals broke the magic posix
mechanism, which requires that relative timers are not affected by
modifications of the underlying clock. That means relative CLOCK_REALTIME
timers cannot use CLOCK_REALTIME, because that can be set and adjusted. The
underlying hrtimer switches the clock for these timers to CLOCK_MONOTONIC.

That still works, but reading the remaining time of such a timer has been
broken in the rework. The old code used the hrtimer internals directly and
avoided the posix clock callbacks. Now common_timer_get() uses the
underlying kclock->timer_get() callback, which is still CLOCK_REALTIME
based. So the remaining time of such a timer is calculated against the
wrong time base.

Handle it by switching the k_itimer->kclock pointer according to the
resulting hrtimer mode. k_itimer->it_clock still contains CLOCK_REALTIME
because the timer might be set with ABSTIME later and then it needs to
switch back to the realtime posix clock implementation.

Fixes: eae1c4ae275f ("posix-timers: Make use of cancel/arm callbacks")
Reported-by: Andrei Vagin <avagin@virtuozzo.com>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: John Stultz <john.stultz@linaro.org>
Cc: Cyrill Gorcunov <gorcunov@openvz.org>
Link: http://lkml.kernel.org/r/20170609201156.GB21491@outlook.office365.com
---
 kernel/time/posix-timers.c | 13 +++++++++++++
 1 file changed, 13 insertions(+)

diff --git a/kernel/time/posix-timers.c b/kernel/time/posix-timers.c
index 88517dc..58c0f60 100644
--- a/kernel/time/posix-timers.c
+++ b/kernel/time/posix-timers.c
@@ -72,6 +72,7 @@ static DEFINE_SPINLOCK(hash_lock);
 
 static const struct k_clock * const posix_clocks[];
 static const struct k_clock *clockid_to_kclock(const clockid_t id);
+static const struct k_clock clock_realtime, clock_monotonic;
 
 /*
  * we assume that the new SIGEV_THREAD_ID shares no bits with the other
@@ -750,6 +751,18 @@ static void common_hrtimer_arm(struct k_itimer *timr, ktime_t expires,
 	enum hrtimer_mode mode;
 
 	mode = absolute ? HRTIMER_MODE_ABS : HRTIMER_MODE_REL;
+	/*
+	 * Posix magic: Relative CLOCK_REALTIME timers are not affected by
+	 * clock modifications, so they become CLOCK_MONOTONIC based under the
+	 * hood. See hrtimer_init(). Update timr->kclock, so the generic
+	 * functions which use timr->kclock->clock_get() work.
+	 *
+	 * Note: it_clock stays unmodified, because the next timer_set() might
+	 * use ABSTIME, so it needs to switch back.
+	 */
+	if (timr->it_clock == CLOCK_REALTIME)
+		timr->kclock = absolute ? &clock_realtime : &clock_monotonic;
+
 	hrtimer_init(&timr->it.real.timer, timr->it_clock, mode);
 	timr->it.real.timer.function = posix_timer_fn;
 

^ permalink raw reply	[flat|nested] 66+ messages in thread

* Re: [tip:timers/core] posix-timers: Zero out oldval itimerspec
  2017-06-12 19:13       ` [tip:timers/core] posix-timers: Zero out oldval itimerspec tip-bot for Thomas Gleixner
@ 2017-06-12 21:06         ` Andrei Vagin
  2017-06-12 22:01           ` Thomas Gleixner
  0 siblings, 1 reply; 66+ messages in thread
From: Andrei Vagin @ 2017-06-12 21:06 UTC (permalink / raw)
  To: tip-bot for Thomas Gleixner
  Cc: linux-tip-commits, hpa, linux-kernel, gorcunov, john.stultz,
	mingo, tglx, peterz

On Mon, Jun 12, 2017 at 12:13:15PM -0700, tip-bot for Thomas Gleixner wrote:
> Commit-ID:  5c7a3a3d20a4e175304c0e23809e3d70be8fed8a
> Gitweb:     http://git.kernel.org/tip/5c7a3a3d20a4e175304c0e23809e3d70be8fed8a
> Author:     Thomas Gleixner <tglx@linutronix.de>
> AuthorDate: Mon, 12 Jun 2017 19:44:09 +0200
> Committer:  Thomas Gleixner <tglx@linutronix.de>
> CommitDate: Mon, 12 Jun 2017 21:07:40 +0200
> 
> posix-timers: Zero out oldval itimerspec
> 
> The recent posix timer rework moved the clearing of the itimerspec to the
> real syscall implementation, but forgot that the kclock->timer_get() is
> used by timer_settime() as well. That results in an uninitialized variable
> and bogus values returned to user space.
> 
> Add the missing memset to timer_settime().
> 
> Fixes: eabdec043853 ("posix-timers: Zero settings value in common code")
> Reported-by: Andrei Vagin <avagin@virtuozzo.com>
> Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
> Cc: Peter Zijlstra <peterz@infradead.org>
> Cc: John Stultz <john.stultz@linaro.org>
> Cc: Cyrill Gorcunov <gorcunov@openvz.org>
> Link: http://lkml.kernel.org/r/20170609201156.GB21491@outlook.office365.com
> ---
>  kernel/time/posix-timers.c | 2 ++
>  1 file changed, 2 insertions(+)
> 
> diff --git a/kernel/time/posix-timers.c b/kernel/time/posix-timers.c
> index b53a0b5..88517dc 100644
> --- a/kernel/time/posix-timers.c
> +++ b/kernel/time/posix-timers.c
> @@ -828,6 +828,8 @@ SYSCALL_DEFINE4(timer_settime, timer_t, timer_id, int, flags,
>  	if (!timespec64_valid(&new_spec64.it_interval) ||
>  	    !timespec64_valid(&new_spec64.it_value))
>  		return -EINVAL;
> +	if (rtn)
> +		memset(rtn, 0, sizeof(*rtn));

Maybe we need to call memset after "retry:"?

common_timer_get() is called at the begining of common_timer_set(), then
common_timer_set() can return TIMER_RETRY. common_timer_get() will be
called again and some fields of rtn which have been touched first time
will not be touched.

At the end, rtn will contain data from two executions of
common_timer_get().

Thanks,
Andrei

>  retry:
>  	timr = lock_timer(timer_id, &flag);
>  	if (!timr)

^ permalink raw reply	[flat|nested] 66+ messages in thread

* Re: [tip:timers/core] posix-timers: Zero out oldval itimerspec
  2017-06-12 21:06         ` Andrei Vagin
@ 2017-06-12 22:01           ` Thomas Gleixner
  2017-06-12 22:14             ` Andrei Vagin
  0 siblings, 1 reply; 66+ messages in thread
From: Thomas Gleixner @ 2017-06-12 22:01 UTC (permalink / raw)
  To: Andrei Vagin
  Cc: tip-bot for Thomas Gleixner, linux-tip-commits, hpa,
	linux-kernel, gorcunov, john.stultz, mingo, peterz

On Mon, 12 Jun 2017, Andrei Vagin wrote:
> > diff --git a/kernel/time/posix-timers.c b/kernel/time/posix-timers.c
> > index b53a0b5..88517dc 100644
> > --- a/kernel/time/posix-timers.c
> > +++ b/kernel/time/posix-timers.c
> > @@ -828,6 +828,8 @@ SYSCALL_DEFINE4(timer_settime, timer_t, timer_id, int, flags,
> >  	if (!timespec64_valid(&new_spec64.it_interval) ||
> >  	    !timespec64_valid(&new_spec64.it_value))
> >  		return -EINVAL;
> > +	if (rtn)
> > +		memset(rtn, 0, sizeof(*rtn));
> 
> Maybe we need to call memset after "retry:"?

That would be counter productive.

> common_timer_get() is called at the begining of common_timer_set(), then
> common_timer_set() can return TIMER_RETRY. common_timer_get() will be
> called again and some fields of rtn which have been touched first time
> will not be touched.
> 
> At the end, rtn will contain data from two executions of
> common_timer_get().

No. See the full code sequence:

retry:
        timr = lock_timer(timer_id, &flag);
        if (!timr)
                return -EINVAL;

        kc = clockid_to_kclock(timr->it_clock);
	if (WARN_ON_ONCE(!kc || !kc->timer_set))
                error = -EINVAL;
        else
                error = kc->timer_set(timr, flags, &new_spec64, rtn);

        unlock_timer(timr, flag);
        if (error == TIMER_RETRY) {
                rtn = NULL;     // We already got the old time...
                goto retry;
        }

If you clear it after retry, you'll get all zeros in the retry case. Not
what you really want.

Thanks,

	tglx

^ permalink raw reply	[flat|nested] 66+ messages in thread

* Re: [tip:timers/core] posix-timers: Zero out oldval itimerspec
  2017-06-12 22:01           ` Thomas Gleixner
@ 2017-06-12 22:14             ` Andrei Vagin
  0 siblings, 0 replies; 66+ messages in thread
From: Andrei Vagin @ 2017-06-12 22:14 UTC (permalink / raw)
  To: Thomas Gleixner
  Cc: tip-bot for Thomas Gleixner, linux-tip-commits, hpa,
	linux-kernel, gorcunov, john.stultz, mingo, peterz

On Tue, Jun 13, 2017 at 12:01:17AM +0200, Thomas Gleixner wrote:
> On Mon, 12 Jun 2017, Andrei Vagin wrote:
> > > diff --git a/kernel/time/posix-timers.c b/kernel/time/posix-timers.c
> > > index b53a0b5..88517dc 100644
> > > --- a/kernel/time/posix-timers.c
> > > +++ b/kernel/time/posix-timers.c
> > > @@ -828,6 +828,8 @@ SYSCALL_DEFINE4(timer_settime, timer_t, timer_id, int, flags,
> > >  	if (!timespec64_valid(&new_spec64.it_interval) ||
> > >  	    !timespec64_valid(&new_spec64.it_value))
> > >  		return -EINVAL;
> > > +	if (rtn)
> > > +		memset(rtn, 0, sizeof(*rtn));
> > 
> > Maybe we need to call memset after "retry:"?
> 
> That would be counter productive.
> 
> > common_timer_get() is called at the begining of common_timer_set(), then
> > common_timer_set() can return TIMER_RETRY. common_timer_get() will be
> > called again and some fields of rtn which have been touched first time
> > will not be touched.
> > 
> > At the end, rtn will contain data from two executions of
> > common_timer_get().
> 
> No. See the full code sequence:
> 
> retry:
>         timr = lock_timer(timer_id, &flag);
>         if (!timr)
>                 return -EINVAL;
> 
>         kc = clockid_to_kclock(timr->it_clock);
> 	if (WARN_ON_ONCE(!kc || !kc->timer_set))
>                 error = -EINVAL;
>         else
>                 error = kc->timer_set(timr, flags, &new_spec64, rtn);
> 
>         unlock_timer(timr, flag);
>         if (error == TIMER_RETRY) {
>                 rtn = NULL;     // We already got the old time...
>                 goto retry;
>         }
> 
> If you clear it after retry, you'll get all zeros in the retry case. Not
> what you really want.

Yes, you are right. Sorry for the noise.
> 
> Thanks,
> 
> 	tglx

^ permalink raw reply	[flat|nested] 66+ messages in thread

end of thread, other threads:[~2017-06-12 22:14 UTC | newest]

Thread overview: 66+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-05-30 21:15 [patch 00/26] alarmtimers/posixtimers: Bug fixes and spec conformity changes Thomas Gleixner
2017-05-30 21:15 ` [patch 01/26] alarmtimer: Prevent overflow of relative timers Thomas Gleixner
2017-06-04 13:21   ` [tip:timers/urgent] " tip-bot for Thomas Gleixner
2017-06-04 13:24   ` tip-bot for Thomas Gleixner
2017-05-30 21:15 ` [patch 02/26] alarmtimer: Rate limit periodic intervals Thomas Gleixner
2017-06-04 13:22   ` [tip:timers/urgent] " tip-bot for Thomas Gleixner
2017-06-04 13:25   ` tip-bot for Thomas Gleixner
2017-05-30 21:15 ` [patch 03/26] alarmtimer: Remove pointless config conditional Thomas Gleixner
2017-06-05  8:13   ` [tip:timers/core] " tip-bot for Thomas Gleixner
2017-05-30 21:15 ` [patch 04/26] posix-timers: Remove unused export of posix_timer_event() Thomas Gleixner
2017-06-05  8:13   ` [tip:timers/core] " tip-bot for Thomas Gleixner
2017-05-30 21:15 ` [patch 05/26] posix-clocks: Remove interval timer facility and mmap/fasync callbacks Thomas Gleixner
2017-05-31  9:00   ` Richard Cochran
2017-06-05  8:14   ` [tip:timers/core] " tip-bot for Thomas Gleixner
2017-05-30 21:15 ` [patch 06/26] posix-timers: Avoid gazillions of forward declarations Thomas Gleixner
2017-06-05  8:14   ` [tip:timers/core] " tip-bot for Thomas Gleixner
2017-05-30 21:15 ` [patch 07/26] posix-timers: Cleanup struct k_itimer Thomas Gleixner
2017-06-05  8:15   ` [tip:timers/core] " tip-bot for Thomas Gleixner
2017-05-30 21:15 ` [patch 08/26] posix-timers: Move posix-timer internals to core Thomas Gleixner
2017-05-31 15:37   ` Christoph Hellwig
2017-06-05  8:15   ` [tip:timers/core] " tip-bot for Thomas Gleixner
2017-05-30 21:15 ` [patch 09/26] posix-timers: Unify overrun/requeue_pending handling Thomas Gleixner
2017-06-05  8:16   ` [tip:timers/core] " tip-bot for Thomas Gleixner
2017-05-30 21:15 ` [patch 10/26] posix-timers: Move interval out of the union Thomas Gleixner
2017-06-05  8:17   ` [tip:timers/core] " tip-bot for Thomas Gleixner
2017-05-30 21:15 ` [patch 11/26] posix-timers: Store k_clock pointer in k_itimer Thomas Gleixner
2017-06-05  8:17   ` [tip:timers/core] " tip-bot for Thomas Gleixner
2017-05-30 21:15 ` [patch 12/26] posix-timers: Add timer_rearm() callback Thomas Gleixner
2017-06-05  8:18   ` [tip:timers/core] " tip-bot for Thomas Gleixner
2017-05-30 21:15 ` [patch 13/26] posix-timers: Rename do_schedule_next_timer Thomas Gleixner
2017-05-31 15:39   ` Christoph Hellwig
2017-06-01 20:50     ` Thomas Gleixner
2017-06-02  7:00       ` Christoph Hellwig
2017-06-05  8:18   ` [tip:timers/core] " tip-bot for Thomas Gleixner
2017-05-30 21:15 ` [patch 14/26] posix-timers: Use timer_rearm() callback in posixtimer_rearm() Thomas Gleixner
2017-06-05  8:19   ` [tip:timers/core] " tip-bot for Thomas Gleixner
2017-05-30 21:15 ` [patch 15/26] posix-timers: Add active flag to k_itimer Thomas Gleixner
2017-06-05  8:20   ` [tip:timers/core] " tip-bot for Thomas Gleixner
2017-05-30 21:15 ` [patch 16/26] posix-timers: Add forward/remaining callbacks Thomas Gleixner
2017-06-05  8:20   ` [tip:timers/core] " tip-bot for Thomas Gleixner
2017-05-30 21:15 ` [patch 17/26] posix-timers: Make use of " Thomas Gleixner
2017-06-05  8:21   ` [tip:timers/core] " tip-bot for Thomas Gleixner
2017-05-30 21:15 ` [patch 18/26] posix-timers: Zero settings value in common code Thomas Gleixner
2017-06-05  8:21   ` [tip:timers/core] " tip-bot for Thomas Gleixner
2017-06-09 20:12     ` Andrei Vagin
2017-06-12 19:13       ` [tip:timers/core] posix-timers: Zero out oldval itimerspec tip-bot for Thomas Gleixner
2017-06-12 21:06         ` Andrei Vagin
2017-06-12 22:01           ` Thomas Gleixner
2017-06-12 22:14             ` Andrei Vagin
2017-06-12 19:13       ` [tip:timers/core] posix-timers: Handle relative posix-timers correctly tip-bot for Thomas Gleixner
2017-05-30 21:15 ` [patch 19/26] posix-timers: Add cancel/arm callbacks Thomas Gleixner
2017-06-05  8:22   ` [tip:timers/core] " tip-bot for Thomas Gleixner
2017-05-30 21:15 ` [patch 20/26] posix-timers: Make use of " Thomas Gleixner
2017-06-05  8:22   ` [tip:timers/core] " tip-bot for Thomas Gleixner
2017-05-30 21:15 ` [patch 21/26] alarmtimer: Implement timer_rearm() callback Thomas Gleixner
2017-06-05  8:23   ` [tip:timers/core] " tip-bot for Thomas Gleixner
2017-05-30 21:15 ` [patch 22/26] alarmtimer: Implement forward callback Thomas Gleixner
2017-06-05  8:24   ` [tip:timers/core] " tip-bot for Thomas Gleixner
2017-05-30 21:15 ` [patch 23/26] alarmtimer: Implement remaining callback Thomas Gleixner
2017-06-05  8:24   ` [tip:timers/core] " tip-bot for Thomas Gleixner
2017-05-30 21:15 ` [patch 24/26] alarmtimer: Implement try_to_cancel callback Thomas Gleixner
2017-06-05  8:25   ` [tip:timers/core] " tip-bot for Thomas Gleixner
2017-05-30 21:15 ` [patch 25/26] alarmtimer: Implement arm callback Thomas Gleixner
2017-06-05  8:25   ` [tip:timers/core] " tip-bot for Thomas Gleixner
2017-05-30 21:15 ` [patch 26/26] alarmtimer: Switch over to generic set/get/rearm routine Thomas Gleixner
2017-06-05  8:26   ` [tip:timers/core] " tip-bot for Thomas Gleixner

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.