Skip to content

Commit c20b99e

Browse files
KAGA-KOKOFrederic Weisbecker
authored andcommitted
posix-cpu-timers: Simplify posix_cpu_timer_set()
Avoid the late sighand lock/unlock dance when a timer is not armed to enforce reevaluation of the timer base so that the process wide CPU timer sampling can be disabled. Do it right at the point where the arming decision is made which already has sighand locked. Signed-off-by: Thomas Gleixner <[email protected]> Signed-off-by: Frederic Weisbecker <[email protected]> Reviewed-by: Anna-Maria Behnsen <[email protected]> Acked-by: Peter Zijlstra (Intel) <[email protected]>
1 parent 286bfac commit c20b99e

File tree

1 file changed

+17
-27
lines changed

1 file changed

+17
-27
lines changed

kernel/time/posix-cpu-timers.c

Lines changed: 17 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -705,10 +705,16 @@ static int posix_cpu_timer_set(struct k_itimer *timer, int timer_flags,
705705
/*
706706
* Arm the timer if it is not disabled, the new expiry value has
707707
* not yet expired and the timer requires signal delivery.
708-
* SIGEV_NONE timers are never armed.
708+
* SIGEV_NONE timers are never armed. In case the timer is not
709+
* armed, enforce the reevaluation of the timer base so that the
710+
* process wide cputime counter can be disabled eventually.
709711
*/
710-
if (!sigev_none && new_expires && now < new_expires)
711-
arm_timer(timer, p);
712+
if (likely(!sigev_none)) {
713+
if (new_expires && now < new_expires)
714+
arm_timer(timer, p);
715+
else
716+
trigger_base_recalc_expires(timer, p);
717+
}
712718

713719
unlock_task_sighand(p, &flags);
714720
/*
@@ -727,30 +733,14 @@ static int posix_cpu_timer_set(struct k_itimer *timer, int timer_flags,
727733
timer->it_overrun_last = 0;
728734
timer->it_overrun = -1;
729735

730-
if (!sigev_none && now >= new_expires) {
731-
if (new_expires != 0) {
732-
/*
733-
* The designated time already passed, so we notify
734-
* immediately, even if the thread never runs to
735-
* accumulate more time on this clock.
736-
*/
737-
cpu_timer_fire(timer);
738-
}
739-
740-
/*
741-
* Make sure we don't keep around the process wide cputime
742-
* counter or the tick dependency if they are not necessary.
743-
*/
744-
sighand = lock_task_sighand(p, &flags);
745-
if (!sighand)
746-
goto out;
747-
748-
if (!cpu_timer_queued(ctmr))
749-
trigger_base_recalc_expires(timer, p);
750-
751-
unlock_task_sighand(p, &flags);
752-
}
753-
out:
736+
/*
737+
* If the new expiry time was already in the past the timer was not
738+
* queued. Fire it immediately even if the thread never runs to
739+
* accumulate more time on this clock.
740+
*/
741+
if (!sigev_none && new_expires && now >= new_expires)
742+
cpu_timer_fire(timer);
743+
out:
754744
rcu_read_unlock();
755745
if (old)
756746
old->it_interval = ns_to_timespec64(old_incr);

0 commit comments

Comments
 (0)