Skip to contentSkip to conversation

alarmtimers/posixtimers: Bug fixes and spec conformity changes

PATCH In review Thomas Gleixner 5 participants 66 messages May 30, 2017 – Jun 12, 2017

Subsystems (4)
lore
Share & tools
lore
#0 lore raw

cover alarmtimers/posixtimers: Bug fixes and spec conformity changes

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(-)
#1 lore raw

PATCH 1/26 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.

---
 kernel/time/alarmtimer.c |    6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)
kernel/time/alarmtimer.c +3 -3
@@ -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);
#2 lore raw

[tip:timers/urgent] alarmtimer: Prevent overflow of relative timers

alarmtimer: Prevent overflow of relative timers
Commit-ID:  ecd7d6ff04a59478c41987051dd8f15258cea6af
Gitweb:     http://git.kernel.org/tip/ecd7d6ff04a59478c41987051dd8f15258cea6af
Author:     Thomas Gleixner <[email protected]>
AuthorDate: Tue, 30 May 2017 23:15:34 +0200
Committer:  Thomas Gleixner <[email protected]>
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.

---
 kernel/time/alarmtimer.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)
kernel/time/alarmtimer.c +3 -3
index 5cb5b00..2b2e032 100644
@@ -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);
#3 lore raw

[tip:timers/urgent] alarmtimer: Prevent overflow of relative timers

In reply to Thomas Gleixner
alarmtimer: Prevent overflow of relative timers
Commit-ID:  f4781e76f90df7aec400635d73ea4c35ee1d4765
Gitweb:     http://git.kernel.org/tip/f4781e76f90df7aec400635d73ea4c35ee1d4765
Author:     Thomas Gleixner <[email protected]>
AuthorDate: Tue, 30 May 2017 23:15:34 +0200
Committer:  Thomas Gleixner <[email protected]>
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.

---
 kernel/time/alarmtimer.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)
kernel/time/alarmtimer.c +3 -3
index 5cb5b00..2b2e032 100644
@@ -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);
#4 lore raw

PATCH 2/26 alarmtimer: Rate limit periodic intervals

In reply to Thomas Gleixner

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.

Cc Dmitry Vyukov <[email protected]>
Cc Kostya Serebryany <[email protected]>
Cc syzkaller <[email protected]>
---
 kernel/time/alarmtimer.c |    8 ++++++++
 1 file changed, 8 insertions(+)
kernel/time/alarmtimer.c +8 -0
@@ -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) {
#5 lore raw

[tip:timers/urgent] alarmtimer: Rate limit periodic intervals

alarmtimer: Rate limit periodic intervals
Commit-ID:  a90b040d8a7a206dd1863c60a47ace5319c99321
Gitweb:     http://git.kernel.org/tip/a90b040d8a7a206dd1863c60a47ace5319c99321
Author:     Thomas Gleixner <[email protected]>
AuthorDate: Tue, 30 May 2017 23:15:35 +0200
Committer:  Thomas Gleixner <[email protected]>
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.

---
 kernel/time/alarmtimer.c | 8 ++++++++
 1 file changed, 8 insertions(+)
kernel/time/alarmtimer.c +8 -0
index 2b2e032..ee2f420 100644
@@ -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) {
#6 lore raw

[tip:timers/urgent] alarmtimer: Rate limit periodic intervals

In reply to Thomas Gleixner
alarmtimer: Rate limit periodic intervals
Commit-ID:  ff86bf0c65f14346bf2440534f9ba5ac232c39a0
Gitweb:     http://git.kernel.org/tip/ff86bf0c65f14346bf2440534f9ba5ac232c39a0
Author:     Thomas Gleixner <[email protected]>
AuthorDate: Tue, 30 May 2017 23:15:35 +0200
Committer:  Thomas Gleixner <[email protected]>
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.

---
 kernel/time/alarmtimer.c | 8 ++++++++
 1 file changed, 8 insertions(+)
kernel/time/alarmtimer.c +8 -0
index 2b2e032..ee2f420 100644
@@ -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) {
#7 lore raw

PATCH 3/26 alarmtimer: Remove pointless config conditional

In reply to Thomas Gleixner

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

---
 kernel/time/alarmtimer.c |    3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)
kernel/time/alarmtimer.c +1 -2
@@ -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++;
 	}
 
#8 lore raw

[tip:timers/core] alarmtimer: Remove pointless config conditional

alarmtimer: Remove pointless config conditional
Commit-ID:  18c700c4e3d0a37c43a2df8b8f740121d4dac645
Gitweb:     http://git.kernel.org/tip/18c700c4e3d0a37c43a2df8b8f740121d4dac645
Author:     Thomas Gleixner <[email protected]>
AuthorDate: Tue, 30 May 2017 23:15:36 +0200
Committer:  Thomas Gleixner <[email protected]>
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.

---
 kernel/time/alarmtimer.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)
kernel/time/alarmtimer.c +1 -2
index e645dcc..2a8675f 100644
@@ -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++;
 	}
 
#9 lore raw

PATCH 4/26 posix-timers: Remove unused export of posix_timer_event()

In reply to Thomas Gleixner

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

---
 kernel/time/posix-timers.c |    1 -
 1 file changed, 1 deletion(-)
kernel/time/posix-timers.c +0 -1
@@ -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
#10 lore raw

[tip:timers/core] posix-timers: Remove unused export of posix_timer_event()

posix-timers: Remove unused export of posix_timer_event()
Commit-ID:  a81129e5a189973abd661704b261f8aad9325407
Gitweb:     http://git.kernel.org/tip/a81129e5a189973abd661704b261f8aad9325407
Author:     Thomas Gleixner <[email protected]>
AuthorDate: Tue, 30 May 2017 23:15:37 +0200
Committer:  Thomas Gleixner <[email protected]>
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.

---
 kernel/time/posix-timers.c | 1 -
 1 file changed, 1 deletion(-)
kernel/time/posix-timers.c +0 -1
index 0c0cccf..44d4865 100644
@@ -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
#11 lore raw

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

In reply to Thomas Gleixner

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.

---
 include/linux/posix-clock.h |   22 --------
 kernel/time/posix-clock.c   |  113 --------------------------------------------
 2 files changed, 135 deletions(-)
include/linux/posix-clock.h +0 -22
@@ -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,
kernel/time/posix-clock.c +0 -113

134 lines not on this page · raw message

Acked-by on v1 5/26
#12 lore raw

Re: [patch 05/26] posix-clocks: Remove interval timer facility and mmap/fasync callbacks

Quoted 11 lines · Thomas Gleixner

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.

Quoted 1 line

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/[email protected]/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<---

Documentation/ptp/ptp.txt +1 -4
index ae8fef8..11e904e 100644
@@ -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
 
#13 lore raw

[tip:timers/core] posix-clocks: Remove interval timer facility and mmap/fasync callbacks

In reply to Thomas Gleixner
posix-clocks: Remove interval timer facility and mmap/fasync callbacks
Commit-ID:  3a06c7ac24f9f24ec059cd77c2dbdf7fbfd0aaaf
Gitweb:     http://git.kernel.org/tip/3a06c7ac24f9f24ec059cd77c2dbdf7fbfd0aaaf
Author:     Thomas Gleixner <[email protected]>
AuthorDate: Tue, 30 May 2017 23:15:38 +0200
Committer:  Thomas Gleixner <[email protected]>
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.

---
 include/linux/posix-clock.h |  22 ---------
 kernel/time/posix-clock.c   | 113 --------------------------------------------
 2 files changed, 135 deletions(-)
include/linux/posix-clock.h +0 -22
index 83b22ae..38d8225 100644
@@ -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,
kernel/time/posix-clock.c +0 -113

134 lines not on this page · raw message

#14 lore raw

PATCH 6/26 posix-timers: Avoid gazillions of forward declarations

In reply to Thomas Gleixner

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

---
 kernel/time/posix-timers.c |  190 +++++++++++++++++++++------------------------
 1 file changed, 89 insertions(+), 101 deletions(-)
kernel/time/posix-timers.c +89 -101
@@ -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];
+}
#15 lore raw

[tip:timers/core] posix-timers: Avoid gazillions of forward declarations

posix-timers: Avoid gazillions of forward declarations
Commit-ID:  6631fa12c105e326bbe5fb215eb216e86c90d1ba
Gitweb:     http://git.kernel.org/tip/6631fa12c105e326bbe5fb215eb216e86c90d1ba
Author:     Thomas Gleixner <[email protected]>
AuthorDate: Tue, 30 May 2017 23:15:39 +0200
Committer:  Thomas Gleixner <[email protected]>
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.

---
 kernel/time/posix-timers.c | 190 +++++++++++++++++++++------------------------
 1 file changed, 89 insertions(+), 101 deletions(-)
kernel/time/posix-timers.c +89 -101
index 44d4865..b60b655 100644
@@ -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];
+}
#16 lore raw

PATCH 7/26 posix-timers: Cleanup struct k_itimer

In reply to Thomas Gleixner

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

---
 include/linux/posix-timers.h |   61 ++++++++++++++++++++++++++++---------------
 1 file changed, 40 insertions(+), 21 deletions(-)
include/linux/posix-timers.h +40 -21
@@ -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;
 };
 
#17 lore raw

[tip:timers/core] posix-timers: Cleanup struct k_itimer

posix-timers: Cleanup struct k_itimer
Commit-ID:  03676b41a8ffcbb1f6d9eb6ca754b2bfa431fd59
Gitweb:     http://git.kernel.org/tip/03676b41a8ffcbb1f6d9eb6ca754b2bfa431fd59
Author:     Thomas Gleixner <[email protected]>
AuthorDate: Tue, 30 May 2017 23:15:40 +0200
Committer:  Thomas Gleixner <[email protected]>
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.

---
 include/linux/posix-timers.h | 61 +++++++++++++++++++++++++++++---------------
 1 file changed, 40 insertions(+), 21 deletions(-)
include/linux/posix-timers.h +40 -21
index 8929f7e..e06062c 100644
@@ -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;
 };
 
#18 lore raw

PATCH 8/26 posix-timers: Move posix-timer internals to core

In reply to Thomas Gleixner

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

---
 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(-)
include/linux/posix-timers.h +0 -11
@@ -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);
kernel/time/alarmtimer.c +2 -0
@@ -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>
 
kernel/time/posix-clock.c +2 -0
@@ -25,6 +25,8 @@
 #include <linux/syscalls.h>
 #include <linux/uaccess.h>
 
+#include "posix-timers.h"
+
 static void delete_clock(struct kref *kref);
 
 /*
kernel/time/posix-cpu-timers.c +2 -0
@@ -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
kernel/time/posix-timers.c +1 -0
@@ -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
kernel/time/posix-timers.h new file +9 -0
@@ -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);
#19 lore raw

Re: [patch 08/26] posix-timers: Move posix-timer internals to core

Quoted 2 lines · Thomas Gleixner

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.

#20 lore raw

[tip:timers/core] posix-timers: Move posix-timer internals to core

In reply to Thomas Gleixner
posix-timers: Move posix-timer internals to core
Commit-ID:  bab0aae9dcba9466dcc968b8bd21914f8f691631
Gitweb:     http://git.kernel.org/tip/bab0aae9dcba9466dcc968b8bd21914f8f691631
Author:     Thomas Gleixner <[email protected]>
AuthorDate: Tue, 30 May 2017 23:15:41 +0200
Committer:  Thomas Gleixner <[email protected]>
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.

---
 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(-)
include/linux/posix-timers.h +0 -30
index e06062c..a372e7e 100644
@@ -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);
kernel/time/alarmtimer.c +2 -0
index 2a8675f..36855d6 100644
@@ -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>
 
kernel/time/posix-clock.c +2 -0
index bd4fb78..17cdc55 100644
@@ -25,6 +25,8 @@
 #include <linux/syscalls.h>
 #include <linux/uaccess.h>
 
+#include "posix-timers.h"
+
 static void delete_clock(struct kref *kref);
 
 /*
kernel/time/posix-cpu-timers.c +2 -0
index c994347..a77a792 100644
@@ -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
kernel/time/posix-timers.c +1 -0
index b60b655..dee6a0d 100644
@@ -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
kernel/time/posix-timers.h new file +29 -0
new file mode 100644
index 0000000..ad2dbd2
@@ -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);
#21 lore raw

PATCH 9/26 posix-timers: Unify overrun/requeue_pending handling

In reply to Thomas Gleixner

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.

---
 kernel/time/posix-cpu-timers.c |   18 +++++++-----------
 kernel/time/posix-timers.c     |   15 ++++++++-------
 2 files changed, 15 insertions(+), 18 deletions(-)
kernel/time/posix-cpu-timers.c +7 -11
@@ -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;
 }
 
 /**
kernel/time/posix-timers.c +8 -7
@@ -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)
#22 lore raw

[tip:timers/core] posix-timers: Unify overrun/requeue_pending handling

posix-timers: Unify overrun/requeue_pending handling
Commit-ID:  af888d677a3f4473c198b4720319dd037f398b51
Gitweb:     http://git.kernel.org/tip/af888d677a3f4473c198b4720319dd037f398b51
Author:     Thomas Gleixner <[email protected]>
AuthorDate: Tue, 30 May 2017 23:15:42 +0200
Committer:  Thomas Gleixner <[email protected]>
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.

---
 kernel/time/posix-cpu-timers.c | 18 +++++++-----------
 kernel/time/posix-timers.c     | 15 ++++++++-------
 2 files changed, 15 insertions(+), 18 deletions(-)
kernel/time/posix-cpu-timers.c +7 -11
index a77a792..1683e50 100644
@@ -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;
 }
 
 /**
kernel/time/posix-timers.c +8 -7
index dee6a0d..79a00e0 100644
@@ -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)
#23 lore raw

PATCH 10/26 posix-timers: Move interval out of the union

In reply to Thomas Gleixner

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.

---
 include/linux/posix-timers.h |    4 ++--
 kernel/time/alarmtimer.c     |   13 ++++++-------
 kernel/time/posix-timers.c   |   20 ++++++++++----------
 3 files changed, 18 insertions(+), 19 deletions(-)
include/linux/posix-timers.h +2 -2
@@ -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;
kernel/time/alarmtimer.c +6 -7
@@ -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 */
kernel/time/posix-timers.c +10 -10
@@ -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;
#24 lore raw

[tip:timers/core] posix-timers: Move interval out of the union

posix-timers: Move interval out of the union
Commit-ID:  80105cd0e62ba8a2caf8eebd52f42952c7c04046
Gitweb:     http://git.kernel.org/tip/80105cd0e62ba8a2caf8eebd52f42952c7c04046
Author:     Thomas Gleixner <[email protected]>
AuthorDate: Tue, 30 May 2017 23:15:43 +0200
Committer:  Thomas Gleixner <[email protected]>
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.

---
 include/linux/posix-timers.h |  4 ++--
 kernel/time/alarmtimer.c     | 13 ++++++-------
 kernel/time/posix-timers.c   | 20 ++++++++++----------
 3 files changed, 18 insertions(+), 19 deletions(-)
include/linux/posix-timers.h +2 -2
index a372e7e..908048f 100644
@@ -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;
kernel/time/alarmtimer.c +6 -7
index 36855d6..5b8cf4b 100644
@@ -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 */
kernel/time/posix-timers.c +10 -10
index 79a00e0..7dd992c 100644
@@ -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;
#25 lore raw

PATCH 11/26 posix-timers: Store k_clock pointer in k_itimer

In reply to Thomas Gleixner

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.

---
 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(-)
include/linux/posix-timers.h +2 -0
@@ -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;
kernel/time/posix-cpu-timers.c +2 -0
@@ -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();
kernel/time/posix-timers.c +4 -3
@@ -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;
#26 lore raw

[tip:timers/core] posix-timers: Store k_clock pointer in k_itimer

posix-timers: Store k_clock pointer in k_itimer
Commit-ID:  d97bb75ddd2f38068df01da8abf26df78756253c
Gitweb:     http://git.kernel.org/tip/d97bb75ddd2f38068df01da8abf26df78756253c
Author:     Thomas Gleixner <[email protected]>
AuthorDate: Tue, 30 May 2017 23:15:44 +0200
Committer:  Thomas Gleixner <[email protected]>
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.

---
 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(-)
include/linux/posix-timers.h +2 -0
index 908048f..8f9cca3 100644
@@ -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;
kernel/time/posix-cpu-timers.c +2 -0
index 1683e50..0123ece 100644
@@ -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();
kernel/time/posix-timers.c +4 -3
index 7dd992c..eb007e1 100644
@@ -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;
#27 lore raw

PATCH 12/26 posix-timers: Add timer_rearm() callback

In reply to Thomas Gleixner

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

---
 include/linux/posix-timers.h |   36 ++++++++++++++++++++----------------
 1 file changed, 20 insertions(+), 16 deletions(-)
include/linux/posix-timers.h +20 -16
@@ -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);
#28 lore raw

[tip:timers/core] posix-timers: Add timer_rearm() callback

posix-timers: Add timer_rearm() callback
Commit-ID:  30802945893bc944b5971b408b37511a03b54e5c
Gitweb:     http://git.kernel.org/tip/30802945893bc944b5971b408b37511a03b54e5c
Author:     Thomas Gleixner <[email protected]>
AuthorDate: Tue, 30 May 2017 23:15:45 +0200
Committer:  Thomas Gleixner <[email protected]>
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.

---
 kernel/time/posix-timers.h | 33 ++++++++++++++++++---------------
 1 file changed, 18 insertions(+), 15 deletions(-)
kernel/time/posix-timers.h +18 -15
index ad2dbd2..02ffd1b 100644
@@ -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;
#29 lore raw

PATCH 13/26 posix-timers: Rename do_schedule_next_timer

In reply to Thomas Gleixner

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

---
 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(-)
include/asm-generic/siginfo.h +1 -1
@@ -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);
 
kernel/signal.c +1 -1
@@ -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
kernel/time/posix-cpu-timers.c +1 -1
@@ -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)
kernel/time/posix-timers.c +5 -5
@@ -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)
#30 lore raw

Re: [patch 13/26] posix-timers: Rename do_schedule_next_timer

Quoted 2 lines · Thomas Gleixner

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.

#31 lore raw

Re: [patch 13/26] posix-timers: Rename do_schedule_next_timer

Quoted 9 lines · Christoph Hellwig
Quoted 2 lines · Thomas Gleixner

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

#32 lore raw

Re: [patch 13/26] posix-timers: Rename do_schedule_next_timer

Quoted 6 lines · Thomas Gleixner
Quoted 4 lines · Christoph Hellwig
Quoted 2 lines · Thomas Gleixner

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

Quoted 7 lines
Quoted 5 lines

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

#33 lore raw

[tip:timers/core] posix-timers: Rename do_schedule_next_timer

In reply to Thomas Gleixner
posix-timers: Rename do_schedule_next_timer
Commit-ID:  96fe3b072f134e4993f829d599eaa1e0eb5a10e5
Gitweb:     http://git.kernel.org/tip/96fe3b072f134e4993f829d599eaa1e0eb5a10e5
Author:     Thomas Gleixner <[email protected]>
AuthorDate: Tue, 30 May 2017 23:15:46 +0200
Committer:  Thomas Gleixner <[email protected]>
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().

---
 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(-)
include/linux/posix-timers.h +1 -1
index 8f9cca3..771e5f7 100644
@@ -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
kernel/signal.c +1 -1
index 1f85c84..d031cd2 100644
@@ -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
kernel/time/posix-cpu-timers.c +1 -1
index 0123ece..1ba576d 100644
@@ -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)
kernel/time/posix-timers.c +5 -5
index eb007e1..036b7e7 100644
@@ -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)
#34 lore raw

PATCH 14/26 posix-timers: Use timer_rearm() callback in posixtimer_rearm()

In reply to Thomas Gleixner

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.

---
 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(-)
kernel/time/posix-cpu-timers.c +5 -2
@@ -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 = {
kernel/time/posix-timers.c +6 -6
@@ -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[] = {
kernel/time/posix-timers.h +0 -2
@@ -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);
#35 lore raw

[tip:timers/core] posix-timers: Use timer_rearm() callback in posixtimer_rearm()

posix-timers: Use timer_rearm() callback in posixtimer_rearm()
Commit-ID:  f37fb0aa4f453c7c785bbcecc4991ac48c5c0e51
Gitweb:     http://git.kernel.org/tip/f37fb0aa4f453c7c785bbcecc4991ac48c5c0e51
Author:     Thomas Gleixner <[email protected]>
AuthorDate: Tue, 30 May 2017 23:15:47 +0200
Committer:  Thomas Gleixner <[email protected]>
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.

---
 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(-)
kernel/time/posix-cpu-timers.c +5 -2
index 1ba576d..96c833a 100644
@@ -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 = {
kernel/time/posix-timers.c +6 -6
index 036b7e7..b12582a 100644
@@ -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[] = {
kernel/time/posix-timers.h +0 -2
index 02ffd1b..1f6f6f9 100644
@@ -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);
#36 lore raw

PATCH 15/26 posix-timers: Add active flag to k_itimer

In reply to Thomas Gleixner

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.

---
 include/linux/posix-timers.h |    2 ++
 kernel/time/posix-timers.c   |    8 +++++++-
 2 files changed, 9 insertions(+), 1 deletion(-)
include/linux/posix-timers.h +2 -0
@@ -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;
kernel/time/posix-timers.c +7 -1
@@ -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;
 }
 
#37 lore raw

[tip:timers/core] posix-timers: Add active flag to k_itimer

posix-timers: Add active flag to k_itimer
Commit-ID:  21e55c1f83880a56360287c00f2b5cd5e5a4a912
Gitweb:     http://git.kernel.org/tip/21e55c1f83880a56360287c00f2b5cd5e5a4a912
Author:     Thomas Gleixner <[email protected]>
AuthorDate: Tue, 30 May 2017 23:15:48 +0200
Committer:  Thomas Gleixner <[email protected]>
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.

---
 include/linux/posix-timers.h | 2 ++
 kernel/time/posix-timers.c   | 8 +++++++-
 2 files changed, 9 insertions(+), 1 deletion(-)
include/linux/posix-timers.h +2 -0
index 771e5f7..667095d 100644
@@ -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;
kernel/time/posix-timers.c +7 -1
index b12582a..795215b 100644
@@ -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;
 }
 
#38 lore raw

PATCH 16/26 posix-timers: Add forward/remaining callbacks

In reply to Thomas Gleixner

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

---
 include/linux/posix-timers.h |    2 ++
 1 file changed, 2 insertions(+)
include/linux/posix-timers.h +2 -0
@@ -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);
#39 lore raw

[tip:timers/core] posix-timers: Add forward/remaining callbacks

posix-timers: Add forward/remaining callbacks
Commit-ID:  63841b2a6969501de183efafc14d20175e402804
Gitweb:     http://git.kernel.org/tip/63841b2a6969501de183efafc14d20175e402804
Author:     Thomas Gleixner <[email protected]>
AuthorDate: Tue, 30 May 2017 23:15:49 +0200
Committer:  Thomas Gleixner <[email protected]>
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.

---
 kernel/time/posix-timers.h | 2 ++
 1 file changed, 2 insertions(+)
kernel/time/posix-timers.h +2 -0
index 1f6f6f9..3bc5b74 100644
@@ -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;
#40 lore raw

PATCH 17/26 posix-timers: Make use of forward/remaining callbacks

In reply to Thomas Gleixner

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

---
 kernel/time/posix-timers.c |   64 ++++++++++++++++++++++++++++++++++-----------
 1 file changed, 49 insertions(+), 15 deletions(-)
kernel/time/posix-timers.c +49 -15
@@ -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[] = {
#41 lore raw

[tip:timers/core] posix-timers: Make use of forward/remaining callbacks

posix-timers: Make use of forward/remaining callbacks
Commit-ID:  91d57bae08689199c8acc77a8b3b41150cafab1c
Gitweb:     http://git.kernel.org/tip/91d57bae08689199c8acc77a8b3b41150cafab1c
Author:     Thomas Gleixner <[email protected]>
AuthorDate: Tue, 30 May 2017 23:15:50 +0200
Committer:  Thomas Gleixner <[email protected]>
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.

---
 kernel/time/posix-timers.c | 64 +++++++++++++++++++++++++++++++++++-----------
 1 file changed, 49 insertions(+), 15 deletions(-)
kernel/time/posix-timers.c +49 -15
index 795215b..48f6c37 100644
@@ -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[] = {
#42 lore raw

PATCH 18/26 posix-timers: Zero settings value in common code

In reply to Thomas Gleixner

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

---
 kernel/time/posix-cpu-timers.c |    5 +----
 kernel/time/posix-timers.c     |    3 +--
 2 files changed, 2 insertions(+), 6 deletions(-)
kernel/time/posix-cpu-timers.c +1 -4
@@ -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);
kernel/time/posix-timers.c +1 -2
@@ -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;
#43 lore raw

[tip:timers/core] posix-timers: Zero settings value in common code

posix-timers: Zero settings value in common code
Commit-ID:  eabdec04385376d560078992710104cc7be2ce1b
Gitweb:     http://git.kernel.org/tip/eabdec04385376d560078992710104cc7be2ce1b
Author:     Thomas Gleixner <[email protected]>
AuthorDate: Tue, 30 May 2017 23:15:51 +0200
Committer:  Thomas Gleixner <[email protected]>
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.

---
 kernel/time/posix-cpu-timers.c | 5 +----
 kernel/time/posix-timers.c     | 3 +--
 2 files changed, 2 insertions(+), 6 deletions(-)
kernel/time/posix-cpu-timers.c +1 -4
index 96c833a..cb4a4eb 100644
@@ -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);
kernel/time/posix-timers.c +1 -2
index 48f6c37..0332f7a 100644
@@ -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;
#44 lore raw

Re: [tip:timers/core] posix-timers: Zero settings value in common code

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

Quoted 66 lines · tip-bot for Jacob Shin
Commit-ID:  eabdec04385376d560078992710104cc7be2ce1b
Gitweb:     http://git.kernel.org/tip/eabdec04385376d560078992710104cc7be2ce1b
Author:     Thomas Gleixner <[email protected]>
AuthorDate: Tue, 30 May 2017 23:15:51 +0200
Committer:  Thomas Gleixner <[email protected]>
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.

---
 kernel/time/posix-cpu-timers.c | 5 +----
 kernel/time/posix-timers.c     | 3 +--
 2 files changed, 2 insertions(+), 6 deletions(-)
kernel/time/posix-cpu-timers.c +1 -4
index 96c833a..cb4a4eb 100644
@@ -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);
kernel/time/posix-timers.c +1 -2
index 48f6c37..0332f7a 100644
@@ -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;
#45 lore raw

[tip:timers/core] posix-timers: Zero out oldval itimerspec

posix-timers: Zero out oldval itimerspec
Commit-ID:  5c7a3a3d20a4e175304c0e23809e3d70be8fed8a
Gitweb:     http://git.kernel.org/tip/5c7a3a3d20a4e175304c0e23809e3d70be8fed8a
Author:     Thomas Gleixner <[email protected]>
AuthorDate: Mon, 12 Jun 2017 19:44:09 +0200
Committer:  Thomas Gleixner <[email protected]>
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")
Cc Peter Zijlstra <[email protected]>
Cc John Stultz <[email protected]>
Cc Cyrill Gorcunov <[email protected]>
---
 kernel/time/posix-timers.c | 2 ++
 1 file changed, 2 insertions(+)
kernel/time/posix-timers.c +2 -0
index b53a0b5..88517dc 100644
@@ -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)
#46 lore raw

Re: [tip:timers/core] posix-timers: Zero out oldval itimerspec

Quoted 32 lines · tip-bot for Thomas Gleixner
Commit-ID:  5c7a3a3d20a4e175304c0e23809e3d70be8fed8a
Gitweb:     http://git.kernel.org/tip/5c7a3a3d20a4e175304c0e23809e3d70be8fed8a
Author:     Thomas Gleixner <[email protected]>
AuthorDate: Mon, 12 Jun 2017 19:44:09 +0200
Committer:  Thomas Gleixner <[email protected]>
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")
Cc Peter Zijlstra <[email protected]>
Cc John Stultz <[email protected]>
Cc Cyrill Gorcunov <[email protected]>
---
 kernel/time/posix-timers.c | 2 ++
 1 file changed, 2 insertions(+)
kernel/time/posix-timers.c +0 -0
index b53a0b5..88517dc 100644

kernel/time/posix-timers.c SYSCALL_DEFINE4(timer_settime, timer_t, timer_id, int, flags, · line 832

Quoted 5 lines
kernel/time/posix-timers.c +2 -0
@@ -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

Quoted 3 lines
kernel/time/posix-timers.c +0 -0
 retry:
 	timr = lock_timer(timer_id, &flag);
 	if (!timr)
#47 lore raw

Re: [tip:timers/core] posix-timers: Zero out oldval itimerspec

Quoted 4 lines · Andrei Vagin
Quoted 4 lines
kernel/time/posix-timers.c +0 -0
index b53a0b5..88517dc 100644
Quoted 8 lines

kernel/time/posix-timers.c SYSCALL_DEFINE4(timer_settime, timer_t, timer_id, int, flags, · line 832

Quoted 6 lines
kernel/time/posix-timers.c +2 -0
@@ -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.

Quoted 7 lines

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

#48 lore raw

Re: [tip:timers/core] posix-timers: Zero out oldval itimerspec

Quoted 43 lines · Thomas Gleixner
Quoted 4 lines · Andrei Vagin
Quoted 4 lines
kernel/time/posix-timers.c +0 -0
index b53a0b5..88517dc 100644
Quoted 8 lines

kernel/time/posix-timers.c SYSCALL_DEFINE4(timer_settime, timer_t, timer_id, int, flags, · line 832

Quoted 6 lines
kernel/time/posix-timers.c +2 -0
@@ -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.

Quoted 7 lines

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;
        }
Quoted 2 lines

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.

Quoted 4 lines

Thanks,

tglx

#49 lore raw

[tip:timers/core] posix-timers: Handle relative posix-timers correctly

In reply to Andrei Vagin
posix-timers: Handle relative posix-timers correctly
Commit-ID:  67edab48caeb75d412706f4b9d3107afd1e07623
Gitweb:     http://git.kernel.org/tip/67edab48caeb75d412706f4b9d3107afd1e07623
Author:     Thomas Gleixner <[email protected]>
AuthorDate: Mon, 12 Jun 2017 19:39:49 +0200
Committer:  Thomas Gleixner <[email protected]>
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")
Cc Peter Zijlstra <[email protected]>
Cc John Stultz <[email protected]>
Cc Cyrill Gorcunov <[email protected]>
---
 kernel/time/posix-timers.c | 13 +++++++++++++
 1 file changed, 13 insertions(+)
kernel/time/posix-timers.c +13 -0
index 88517dc..58c0f60 100644
@@ -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;
 
#50 lore raw

PATCH 19/26 posix-timers: Add cancel/arm callbacks

In reply to Thomas Gleixner

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.

---
 include/linux/posix-timers.h |    3 +++
 1 file changed, 3 insertions(+)
include/linux/posix-timers.h +3 -0
Index: 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);
#51 lore raw

[tip:timers/core] posix-timers: Add cancel/arm callbacks

posix-timers: Add cancel/arm callbacks
Commit-ID:  525b8ed91671e29e187dfe02d408b11190ccf494
Gitweb:     http://git.kernel.org/tip/525b8ed91671e29e187dfe02d408b11190ccf494
Author:     Thomas Gleixner <[email protected]>
AuthorDate: Tue, 30 May 2017 23:15:52 +0200
Committer:  Thomas Gleixner <[email protected]>
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.

---
 kernel/time/posix-timers.h | 3 +++
 1 file changed, 3 insertions(+)
kernel/time/posix-timers.h +3 -0
index 3bc5b74..b0ad77e 100644
@@ -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;
#52 lore raw

PATCH 20/26 posix-timers: Make use of cancel/arm callbacks

In reply to Thomas Gleixner

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.

---
 kernel/time/posix-timers.c |  181 ++++++++++++++++++++++++---------------------
 1 file changed, 100 insertions(+), 81 deletions(-)
kernel/time/posix-timers.c +100 -81
Index: 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[] = {
#53 lore raw

[tip:timers/core] posix-timers: Make use of cancel/arm callbacks

posix-timers: Make use of cancel/arm callbacks
Commit-ID:  eae1c4ae275fe3e024454c012a548ee0d700f54c
Gitweb:     http://git.kernel.org/tip/eae1c4ae275fe3e024454c012a548ee0d700f54c
Author:     Thomas Gleixner <[email protected]>
AuthorDate: Tue, 30 May 2017 23:15:53 +0200
Committer:  Thomas Gleixner <[email protected]>
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.

---
 kernel/time/posix-timers.c | 181 +++++++++++++++++++++++++--------------------
 1 file changed, 100 insertions(+), 81 deletions(-)
kernel/time/posix-timers.c +100 -81
index 0332f7a..8acc9ee 100644
@@ -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[] = {
#54 lore raw

PATCH 21/26 alarmtimer: Implement timer_rearm() callback

In reply to Thomas Gleixner

Preparatory change to utilize the common posix timer mechanisms.

---
 kernel/time/alarmtimer.c |   15 ++++++++++++++-
 1 file changed, 14 insertions(+), 1 deletion(-)
kernel/time/alarmtimer.c +14 -1
@@ -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 */
#55 lore raw

[tip:timers/core] alarmtimer: Implement timer_rearm() callback

alarmtimer: Implement timer_rearm() callback
Commit-ID:  b3db80f77a95a45dbb2136f7b2a364dc797ea914
Gitweb:     http://git.kernel.org/tip/b3db80f77a95a45dbb2136f7b2a364dc797ea914
Author:     Thomas Gleixner <[email protected]>
AuthorDate: Tue, 30 May 2017 23:15:54 +0200
Committer:  Thomas Gleixner <[email protected]>
CommitDate: Sun, 4 Jun 2017 15:40:30 +0200

alarmtimer: Implement timer_rearm() callback

Preparatory change to utilize the common posix timer mechanisms.

---
 kernel/time/alarmtimer.c | 15 ++++++++++++++-
 1 file changed, 14 insertions(+), 1 deletion(-)
kernel/time/alarmtimer.c +14 -1
index 5b8cf4b..be85e3c 100644
@@ -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 */
#56 lore raw

PATCH 22/26 alarmtimer: Implement forward callback

In reply to Thomas Gleixner

Preparatory change to utilize the common posix timer mechanisms.

---
 kernel/time/alarmtimer.c |   13 +++++++++++++
 1 file changed, 13 insertions(+)
kernel/time/alarmtimer.c +13 -0
@@ -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 */
#57 lore raw

[tip:timers/core] alarmtimer: Implement forward callback

alarmtimer: Implement forward callback
Commit-ID:  e7561f1633ac735df48c55ad09a2530e9ab9fab1
Gitweb:     http://git.kernel.org/tip/e7561f1633ac735df48c55ad09a2530e9ab9fab1
Author:     Thomas Gleixner <[email protected]>
AuthorDate: Tue, 30 May 2017 23:15:55 +0200
Committer:  Thomas Gleixner <[email protected]>
CommitDate: Sun, 4 Jun 2017 15:40:30 +0200

alarmtimer: Implement forward callback

Preparatory change to utilize the common posix timer mechanisms.

---
 kernel/time/alarmtimer.c | 13 +++++++++++++
 1 file changed, 13 insertions(+)
kernel/time/alarmtimer.c +13 -0
index be85e3c..6082cf1 100644
@@ -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 */
#58 lore raw

PATCH 23/26 alarmtimer: Implement remaining callback

In reply to Thomas Gleixner

Preparatory change to utilize the common posix timer mechanisms.

---
 kernel/time/alarmtimer.c |   31 ++++++++++++++++++++++---------
 1 file changed, 22 insertions(+), 9 deletions(-)
kernel/time/alarmtimer.c +22 -9
@@ -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 */
 
#59 lore raw

[tip:timers/core] alarmtimer: Implement remaining callback

alarmtimer: Implement remaining callback
Commit-ID:  d653d8457c76da11f047af1f66256ac9b8421b69
Gitweb:     http://git.kernel.org/tip/d653d8457c76da11f047af1f66256ac9b8421b69
Author:     Thomas Gleixner <[email protected]>
AuthorDate: Tue, 30 May 2017 23:15:56 +0200
Committer:  Thomas Gleixner <[email protected]>
CommitDate: Sun, 4 Jun 2017 15:40:31 +0200

alarmtimer: Implement remaining callback

Preparatory change to utilize the common posix timer mechanisms.

---
 kernel/time/alarmtimer.c | 31 ++++++++++++++++++++++---------
 1 file changed, 22 insertions(+), 9 deletions(-)
kernel/time/alarmtimer.c +22 -9
index 6082cf1..02ddc40 100644
@@ -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 */
 
#60 lore raw

PATCH 24/26 alarmtimer: Implement try_to_cancel callback

In reply to Thomas Gleixner

Preparatory change to utilize the common posix timer mechanisms.

---
 kernel/time/alarmtimer.c |   10 ++++++++++
 1 file changed, 10 insertions(+)
kernel/time/alarmtimer.c +10 -0
@@ -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 */
#61 lore raw

[tip:timers/core] alarmtimer: Implement try_to_cancel callback

alarmtimer: Implement try_to_cancel callback
Commit-ID:  e344c9e76bc6af997926171bfd90d25bbae0a2c5
Gitweb:     http://git.kernel.org/tip/e344c9e76bc6af997926171bfd90d25bbae0a2c5
Author:     Thomas Gleixner <[email protected]>
AuthorDate: Tue, 30 May 2017 23:15:57 +0200
Committer:  Thomas Gleixner <[email protected]>
CommitDate: Sun, 4 Jun 2017 15:40:31 +0200

alarmtimer: Implement try_to_cancel callback

Preparatory change to utilize the common posix timer mechanisms.

---
 kernel/time/alarmtimer.c | 10 ++++++++++
 1 file changed, 10 insertions(+)
kernel/time/alarmtimer.c +10 -0
index 02ddc40..374bd85 100644
@@ -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 */
#62 lore raw

PATCH 25/26 alarmtimer: Implement arm callback

In reply to Thomas Gleixner

Preparatory change to utilize the common posix timer mechanisms.

---
 kernel/time/alarmtimer.c |   22 ++++++++++++++++++++++
 1 file changed, 22 insertions(+)
kernel/time/alarmtimer.c +22 -0
Index: 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,
#63 lore raw

[tip:timers/core] alarmtimer: Implement arm callback

alarmtimer: Implement arm callback
Commit-ID:  b3bf6f369d50ece9dec6338741648005d95c19e4
Gitweb:     http://git.kernel.org/tip/b3bf6f369d50ece9dec6338741648005d95c19e4
Author:     Thomas Gleixner <[email protected]>
AuthorDate: Tue, 30 May 2017 23:15:58 +0200
Committer:  Thomas Gleixner <[email protected]>
CommitDate: Sun, 4 Jun 2017 15:40:31 +0200

alarmtimer: Implement arm callback

Preparatory change to utilize the common posix timer mechanisms.

---
 kernel/time/alarmtimer.c | 22 ++++++++++++++++++++++
 1 file changed, 22 insertions(+)
kernel/time/alarmtimer.c +22 -0
index 374bd85..c618a44 100644
@@ -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,
#64 lore raw

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

In reply to Thomas Gleixner

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.

---
 kernel/time/alarmtimer.c   |  121 ++++++---------------------------------------
 kernel/time/posix-timers.c |   12 +---
 kernel/time/posix-timers.h |    6 ++
 3 files changed, 29 insertions(+), 110 deletions(-)
kernel/time/alarmtimer.c +18 -103
@@ -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,
kernel/time/posix-timers.c +5 -7
@@ -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;
 
kernel/time/posix-timers.h +6 -0
@@ -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);
#65 lore raw

[tip:timers/core] alarmtimer: Switch over to generic set/get/rearm routine

alarmtimer: Switch over to generic set/get/rearm routine
Commit-ID:  f2c45807d3992fe0f173f34af9c347d907c31686
Gitweb:     http://git.kernel.org/tip/f2c45807d3992fe0f173f34af9c347d907c31686
Author:     Thomas Gleixner <[email protected]>
AuthorDate: Tue, 30 May 2017 23:15:59 +0200
Committer:  Thomas Gleixner <[email protected]>
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.

---
 kernel/time/alarmtimer.c   | 121 +++++++--------------------------------------
 kernel/time/posix-timers.c |  12 ++---
 kernel/time/posix-timers.h |   6 +++
 3 files changed, 29 insertions(+), 110 deletions(-)
kernel/time/alarmtimer.c +18 -103
index c618a44..d8a7a7e 100644
@@ -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,
kernel/time/posix-timers.c +5 -7
index 8acc9ee..6e7a70b1 100644
@@ -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;
 
kernel/time/posix-timers.h +6 -0
index b0ad77e..b086f5b 100644
@@ -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);