alarmtimers/posixtimers: Bug fixes and spec conformity changes
Subsystems (4)
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(-)
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_itimktime_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);
tip-bot for Thomas Gleixner
merge bot[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
@@ -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);
tip-bot for Thomas Gleixner
merge bot[tip:timers/urgent] alarmtimer: Prevent overflow of relative timers
In reply to Thomas Gleixneralarmtimer: 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
@@ -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);
PATCH 2/26 alarmtimer: Rate limit periodic intervals
In reply to Thomas GleixnerThe 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
@@ -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 ) {
tip-bot for Thomas Gleixner
merge bot[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
@@ -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 ) {
tip-bot for Thomas Gleixner
merge bot[tip:timers/urgent] alarmtimer: Rate limit periodic intervals
In reply to Thomas Gleixneralarmtimer: 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
@@ -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 ) {
PATCH 3/26 alarmtimer: Remove pointless config conditional
In reply to Thomas GleixnerHaving 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_hanspin_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++; }
tip-bot for Thomas Gleixner
merge bot[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
@@ -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++; }
PATCH 4/26 posix-timers: Remove unused export of posix_timer_event()
In reply to Thomas GleixnerSince 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
tip-bot for Thomas Gleixner
merge bot[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
@@ -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
PATCH 5/26 posix-clocks: Remove interval timer facility and mmap/fasync callbacks
In reply to Thomas GleixnerThe 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
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_clockneeds.
Quoted 1 line
Signed-off-by Thomas Gleixner <[email protected]>
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
@@ -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
tip-bot for Thomas Gleixner
merge bot[tip:timers/core] posix-clocks: Remove interval timer facility and mmap/fasync callbacks
In reply to Thomas Gleixnerposix-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
@@ -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
PATCH 6/26 posix-timers: Avoid gazillions of forward declarations
In reply to Thomas GleixnerMove 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(clockidreturn 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 kcall_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 restreturn 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]; +}
tip-bot for Thomas Gleixner
merge bot[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
@@ -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]; +}
PATCH 7/26 posix-timers: Cleanup struct k_itimer
In reply to Thomas GleixnerAs 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; };
tip-bot for Thomas Gleixner
merge bot[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
@@ -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; };
PATCH 8/26 posix-timers: Move posix-timer internals to core
In reply to Thomas GleixnerNone 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);
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.
tip-bot for Thomas Gleixner
merge bot[tip:timers/core] posix-timers: Move posix-timer internals to core
In reply to Thomas Gleixnerposix-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
@@ -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
@@ -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 +29 -0
@@ -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);
PATCH 9/26 posix-timers: Unify overrun/requeue_pending handling
In reply to Thomas Gleixnerhrtimer 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_icpu_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 siginunsigned 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)
tip-bot for Thomas Gleixner
merge bot[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
@@ -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
@@ -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)
PATCH 10/26 posix-timers: Move interval out of the union
In reply to Thomas GleixnerPreparatory 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_itimreturn 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 ;
tip-bot for Thomas Gleixner
merge bot[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
@@ -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
@@ -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
@@ -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 ;
PATCH 11/26 posix-timers: Store k_clock pointer in k_itimer
In reply to Thomas GleixnerHaving 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(structif (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_itistatic 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 ;
tip-bot for Thomas Gleixner
merge bot[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
@@ -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
@@ -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
@@ -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 ;
PATCH 12/26 posix-timers: Add timer_rearm() callback
In reply to Thomas GleixnerAdd 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);
tip-bot for Thomas Gleixner
merge bot[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
@@ -1,21 +1,24 @@#define TIMER_RETRY 1struct 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;
PATCH 13/26 posix-timers: Rename do_schedule_next_timer
In reply to Thomas GleixnerThat 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 *tint 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)
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.
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.has 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.hshould probably just move toinclude/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
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.has 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.hshould probably just move toinclude/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
tip-bot for Thomas Gleixner
merge bot[tip:timers/core] posix-timers: Rename do_schedule_next_timer
In reply to Thomas Gleixnerposix-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
@@ -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
@@ -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
@@ -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
@@ -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)
PATCH 14/26 posix-timers: Use timer_rearm() callback in posixtimer_rearm()
In reply to Thomas GleixnerUse 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 *inreturn ;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_threadextern 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);
tip-bot for Thomas Gleixner
merge bot[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
@@ -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
@@ -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
@@ -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);
PATCH 15/26 posix-timers: Add active flag to k_itimer
In reply to Thomas GleixnerKeep 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 *inif (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_itiif (hrtimer_try_to_cancel (&timer->it.real.timer) <0 )return TIMER_RETRY ; + timer->it_active =0 ;return 0 ; }
tip-bot for Thomas Gleixner
merge bot[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
@@ -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
@@ -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 ; }
PATCH 16/26 posix-timers: Add forward/remaining callbacks
In reply to Thomas GleixnerAdd 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);
tip-bot for Thomas Gleixner
merge bot[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
@@ -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;
PATCH 17/26 posix-timers: Make use of forward/remaining callbacks
In reply to Thomas GleixnerReplace 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(timreturn 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(timstatic 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[] = {
tip-bot for Thomas Gleixner
merge bot[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
@@ -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[] = {
PATCH 18/26 posix-timers: Zero settings value in common code
In reply to Thomas GleixnerZero 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 ;
tip-bot for Thomas Gleixner
merge bot[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
@@ -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
@@ -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 ;
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}}) = 0Thanks,
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 +0200posix-timers: Zero settings value in common code
Zero out the settings struct in the common code so the callbacks do not have to do it themself.
Signed-off-by Thomas Gleixner <[email protected]>Cc Peter Zijlstra <[email protected]>Cc John Stultz <[email protected]>--- 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_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@@ -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 ;
tip-bot for Thomas Gleixner
merge bot[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().
--- kernel/time/posix-timers.c | 2 ++ 1 file changed, 2 insertions(+)
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)); retry: timr =lock_timer (timer_id, &flag);if (!timr)
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 +0200posix-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 bytimer_settime()as well. That results in an uninitialized variable and bogus values returned to user space.Add the missing memset to
timer_settime().Fixes eabdec043853 ("posix-timers: Zero settings value in common code")Reported-by Andrei Vagin <[email protected]>Signed-off-by Thomas Gleixner <[email protected]>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
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
-0retry: timr =lock_timer (timer_id, &flag);if (!timr)
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
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 ofcommon_timer_set(), thencommon_timer_set()can returnTIMER_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
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
-0Quoted 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 ofcommon_timer_set(), thencommon_timer_set()can returnTIMER_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
tip-bot for Thomas Gleixner
merge bot[tip:timers/core] posix-timers: Handle relative posix-timers correctly
In reply to Andrei Vaginposix-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.
--- kernel/time/posix-timers.c | 13 +++++++++++++ 1 file changed, 13 insertions(+)
kernel/time/posix-timers.c +13 -0
@@ -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;
PATCH 19/26 posix-timers: Add cancel/arm callbacks
In reply to Thomas GleixnerAdd 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
@@ -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);
tip-bot for Thomas Gleixner
merge bot[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
@@ -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;
PATCH 20/26 posix-timers: Make use of cancel/arm callbacks
In reply to Thomas GleixnerReplace 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
@@ -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[] = {
tip-bot for Thomas Gleixner
merge bot[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
@@ -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[] = {
PATCH 21/26 alarmtimer: Implement timer_rearm() callback
In reply to Thomas GleixnerPreparatory 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 */
tip-bot for Thomas Gleixner
merge bot[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
@@ -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 */
PATCH 22/26 alarmtimer: Implement forward callback
In reply to Thomas GleixnerPreparatory 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 */
tip-bot for Thomas Gleixner
merge bot[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
@@ -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 */
PATCH 23/26 alarmtimer: Implement remaining callback
In reply to Thomas GleixnerPreparatory 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 */
tip-bot for Thomas Gleixner
merge bot[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
@@ -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 */
PATCH 24/26 alarmtimer: Implement try_to_cancel callback
In reply to Thomas GleixnerPreparatory 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 */
tip-bot for Thomas Gleixner
merge bot[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
@@ -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 */
PATCH 25/26 alarmtimer: Implement arm callback
In reply to Thomas GleixnerPreparatory change to utilize the common posix timer mechanisms.
--- kernel/time/alarmtimer.c | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+)
kernel/time/alarmtimer.c +22 -0
@@ -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,
tip-bot for Thomas Gleixner
merge bot[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
@@ -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,
PATCH 26/26 alarmtimer: Switch over to generic set/get/rearm routine
In reply to Thomas GleixnerAll 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_threadextern 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);
tip-bot for Thomas Gleixner
merge bot[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
@@ -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
@@ -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
@@ -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);