<feed xmlns='http://www.w3.org/2005/Atom'>
<title>linux/kernel/time/hrtimer.c, branch v5.4</title>
<subtitle>Mirror of https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/
</subtitle>
<id>https://git.shady.money/linux/atom?h=v5.4</id>
<link rel='self' href='https://git.shady.money/linux/atom?h=v5.4'/>
<link rel='alternate' type='text/html' href='https://git.shady.money/linux/'/>
<updated>2019-10-14T13:51:49Z</updated>
<entry>
<title>hrtimer: Annotate lockless access to timer-&gt;base</title>
<updated>2019-10-14T13:51:49Z</updated>
<author>
<name>Eric Dumazet</name>
<email>edumazet@google.com</email>
</author>
<published>2019-10-08T17:32:04Z</published>
<link rel='alternate' type='text/html' href='https://git.shady.money/linux/commit/?id=ff229eee3d897f52bd001c841f2d3cce8853ecdc'/>
<id>urn:sha1:ff229eee3d897f52bd001c841f2d3cce8853ecdc</id>
<content type='text'>
Followup to commit dd2261ed45aa ("hrtimer: Protect lockless access
to timer-&gt;base")

lock_hrtimer_base() fetches timer-&gt;base without lock exclusion.

Compiler is allowed to read timer-&gt;base twice (even if considered dumb)
which could end up trying to lock migration_base and return
&amp;migration_base.

  base = timer-&gt;base;
  if (likely(base != &amp;migration_base)) {

       /* compiler reads timer-&gt;base again, and now (base == &amp;migration_base)

       raw_spin_lock_irqsave(&amp;base-&gt;cpu_base-&gt;lock, *flags);
       if (likely(base == timer-&gt;base))
            return base; /* == &amp;migration_base ! */

Similarly the write sides must use WRITE_ONCE() to avoid store tearing.

Signed-off-by: Eric Dumazet &lt;edumazet@google.com&gt;
Signed-off-by: Thomas Gleixner &lt;tglx@linutronix.de&gt;
Link: https://lkml.kernel.org/r/20191008173204.180879-1-edumazet@google.com

</content>
</entry>
<entry>
<title>hrtimer: Add a missing bracket and hide `migration_base' on !SMP</title>
<updated>2019-09-05T08:39:06Z</updated>
<author>
<name>Sebastian Andrzej Siewior</name>
<email>bigeasy@linutronix.de</email>
</author>
<published>2019-09-04T14:55:27Z</published>
<link rel='alternate' type='text/html' href='https://git.shady.money/linux/commit/?id=5d2295f3a93b04986d069ebeaf5b07725f9096c1'/>
<id>urn:sha1:5d2295f3a93b04986d069ebeaf5b07725f9096c1</id>
<content type='text'>
The recent change to avoid taking the expiry lock when a timer is currently
migrated missed to add a bracket at the end of the if statement leading to
compile errors.  Since that commit the variable `migration_base' is always
used but it is only available on SMP configuration thus leading to another
compile error.  The changelog says "The timer base and base-&gt;cpu_base
cannot be NULL in the code path", so it is safe to limit this check to SMP
configurations only.

Add the missing bracket to the if statement and hide `migration_base'
behind CONFIG_SMP bars.

[ tglx: Mark the functions inline ... ]

Fixes: 68b2c8c1e4210 ("hrtimer: Don't take expiry_lock when timer is currently migrated")
Signed-off-by: Sebastian Andrzej Siewior &lt;bigeasy@linutronix.de&gt;
Signed-off-by: Thomas Gleixner &lt;tglx@linutronix.de&gt;
Link: https://lkml.kernel.org/r/20190904145527.eah7z56ntwobqm6j@linutronix.de

</content>
</entry>
<entry>
<title>hrtimer: Don't take expiry_lock when timer is currently migrated</title>
<updated>2019-08-21T14:10:01Z</updated>
<author>
<name>Julien Grall</name>
<email>julien.grall@arm.com</email>
</author>
<published>2019-08-21T09:24:09Z</published>
<link rel='alternate' type='text/html' href='https://git.shady.money/linux/commit/?id=68b2c8c1e421096f4b46ac2ac502d25ca067a2a6'/>
<id>urn:sha1:68b2c8c1e421096f4b46ac2ac502d25ca067a2a6</id>
<content type='text'>
migration_base is used as a placeholder when an hrtimer is migrated to a
different CPU. In the case that hrtimer_cancel_wait_running() hits a timer
which is currently migrated it would pointlessly acquire the expiry lock of
the migration base, which is even not initialized.

Surely it could be initialized, but there is absolutely no point in
acquiring this lock because the timer is guaranteed not to run it's
callback for which the caller waits to finish on that base. So it would
just do the inc/lock/dec/unlock dance for nothing.

As the base switch is short and non-preemptible, there is no issue when the
wait function returns immediately.

The timer base and base-&gt;cpu_base cannot be NULL in the code path which is
invoking that, so just replace those checks with a check whether base is
migration base.

[ tglx: Updated from RT patch. Massaged changelog. Added comment. ]

Signed-off-by: Julien Grall &lt;julien.grall@arm.com&gt;
Signed-off-by: Thomas Gleixner &lt;tglx@linutronix.de&gt;
Link: https://lkml.kernel.org/r/20190821092409.13225-4-julien.grall@arm.com


</content>
</entry>
<entry>
<title>hrtimer: Protect lockless access to timer-&gt;base</title>
<updated>2019-08-21T14:10:01Z</updated>
<author>
<name>Julien Grall</name>
<email>julien.grall@arm.com</email>
</author>
<published>2019-08-21T09:24:07Z</published>
<link rel='alternate' type='text/html' href='https://git.shady.money/linux/commit/?id=dd2261ed45aaeddeb77768f291d604179bcab096'/>
<id>urn:sha1:dd2261ed45aaeddeb77768f291d604179bcab096</id>
<content type='text'>
The update to timer-&gt;base is protected by the base-&gt;cpu_base-&gt;lock().
However, hrtimer_cancel_wait_running() does access it lockless.  So the
compiler is allowed to refetch timer-&gt;base which can cause havoc when the
timer base is changed concurrently.

Use READ_ONCE() to prevent this.

[ tglx: Adapted from a RT patch ]

Signed-off-by: Julien Grall &lt;julien.grall@arm.com&gt;
Signed-off-by: Thomas Gleixner &lt;tglx@linutronix.de&gt;
Link: https://lkml.kernel.org/r/20190821092409.13225-2-julien.grall@arm.com
</content>
</entry>
<entry>
<title>hrtimer: Improve comments on handling priority inversion against softirq kthread</title>
<updated>2019-08-20T20:05:46Z</updated>
<author>
<name>Frederic Weisbecker</name>
<email>frederic@kernel.org</email>
</author>
<published>2019-08-20T13:12:23Z</published>
<link rel='alternate' type='text/html' href='https://git.shady.money/linux/commit/?id=0bee3b601b77dbe7981b5474ae8758d6bf60177a'/>
<id>urn:sha1:0bee3b601b77dbe7981b5474ae8758d6bf60177a</id>
<content type='text'>
The handling of a priority inversion between timer cancelling and a a not
well defined possible preemption of softirq kthread is not very clear.

Especially in the posix timers side it's unclear why there is a specific RT
wait callback.

All the nice explanations can be found in the initial changelog of
f61eff83cec9 (hrtimer: Prepare support for PREEMPT_RT").

Extract the detailed informations from there and put it into comments.

Signed-off-by: Frederic Weisbecker &lt;frederic@kernel.org&gt;
Signed-off-by: Thomas Gleixner &lt;tglx@linutronix.de&gt;
Link: https://lkml.kernel.org/r/20190820132656.GC2093@lenoir
</content>
</entry>
<entry>
<title>hrtimer: Prepare support for PREEMPT_RT</title>
<updated>2019-08-01T18:51:22Z</updated>
<author>
<name>Anna-Maria Gleixner</name>
<email>anna-maria@linutronix.de</email>
</author>
<published>2019-07-26T18:30:59Z</published>
<link rel='alternate' type='text/html' href='https://git.shady.money/linux/commit/?id=f61eff83cec9cfab31fd30a2ca8856be379cdcd5'/>
<id>urn:sha1:f61eff83cec9cfab31fd30a2ca8856be379cdcd5</id>
<content type='text'>
When PREEMPT_RT is enabled, the soft interrupt thread can be preempted.  If
the soft interrupt thread is preempted in the middle of a timer callback,
then calling hrtimer_cancel() can lead to two issues:

  - If the caller is on a remote CPU then it has to spin wait for the timer
    handler to complete. This can result in unbound priority inversion.

  - If the caller originates from the task which preempted the timer
    handler on the same CPU, then spin waiting for the timer handler to
    complete is never going to end.

To avoid these issues, add a new lock to the timer base which is held
around the execution of the timer callbacks. If hrtimer_cancel() detects
that the timer callback is currently running, it blocks on the expiry
lock. When the callback is finished, the expiry lock is dropped by the
softirq thread which wakes up the waiter and the system makes progress.

This addresses both the priority inversion and the life lock issues.

The same issue can happen in virtual machines when the vCPU which runs a
timer callback is scheduled out. If a second vCPU of the same guest calls
hrtimer_cancel() it will spin wait for the other vCPU to be scheduled back
in. The expiry lock mechanism would avoid that. It'd be trivial to enable
this when paravirt spinlocks are enabled in a guest, but it's not clear
whether this is an actual problem in the wild, so for now it's an RT only
mechanism.

[ tglx: Refactored it for mainline ]

Signed-off-by: Anna-Maria Gleixner &lt;anna-maria@linutronix.de&gt;
Signed-off-by: Sebastian Andrzej Siewior &lt;bigeasy@linutronix.de&gt;
Signed-off-by: Thomas Gleixner &lt;tglx@linutronix.de&gt;
Acked-by: Peter Zijlstra (Intel) &lt;peterz@infradead.org&gt;
Link: https://lkml.kernel.org/r/20190726185753.737767218@linutronix.de



</content>
</entry>
<entry>
<title>hrtimer: Determine hard/soft expiry mode for hrtimer sleepers on RT</title>
<updated>2019-08-01T18:51:22Z</updated>
<author>
<name>Sebastian Andrzej Siewior</name>
<email>bigeasy@linutronix.de</email>
</author>
<published>2019-07-26T18:30:58Z</published>
<link rel='alternate' type='text/html' href='https://git.shady.money/linux/commit/?id=1842f5a427f5323f5c19ab99b55d09b3ab5172a5'/>
<id>urn:sha1:1842f5a427f5323f5c19ab99b55d09b3ab5172a5</id>
<content type='text'>
On PREEMPT_RT enabled kernels hrtimers which are not explicitely marked for
hard interrupt expiry mode are moved into soft interrupt context either for
latency reasons or because the hrtimer callback takes regular spinlocks or
invokes other functions which are not suitable for hard interrupt context
on PREEMPT_RT.

The hrtimer_sleeper callback is RT compatible in hard interrupt context,
but there is a latency concern: Untrusted userspace can spawn many threads
which arm timers for the same expiry time on the same CPU. On expiry that
causes a latency spike due to the wakeup of a gazillion threads.

OTOH, priviledged real-time user space applications rely on the low latency
of hard interrupt wakeups. These syscall related wakeups are all based on
hrtimer sleepers.

If the current task is in a real-time scheduling class, mark the mode for
hard interrupt expiry.

[ tglx: Split out of a larger combo patch. Added changelog ]

Signed-off-by: Sebastian Andrzej Siewior &lt;bigeasy@linutronix.de&gt;
Signed-off-by: Thomas Gleixner &lt;tglx@linutronix.de&gt;
Reviewed-by: Steven Rostedt (VMware) &lt;rostedt@goodmis.org&gt;
Acked-by: Peter Zijlstra (Intel) &lt;peterz@infradead.org&gt;
Link: https://lkml.kernel.org/r/20190726185753.645792403@linutronix.de



</content>
</entry>
<entry>
<title>hrtimer: Move unmarked hrtimers to soft interrupt expiry on RT</title>
<updated>2019-08-01T18:51:21Z</updated>
<author>
<name>Sebastian Andrzej Siewior</name>
<email>bigeasy@linutronix.de</email>
</author>
<published>2019-07-26T18:30:57Z</published>
<link rel='alternate' type='text/html' href='https://git.shady.money/linux/commit/?id=f5c2f0215e36d76fbb9605283dd7535af09f5770'/>
<id>urn:sha1:f5c2f0215e36d76fbb9605283dd7535af09f5770</id>
<content type='text'>
On PREEMPT_RT not all hrtimers can be expired in hard interrupt context
even if that is perfectly fine on a PREEMPT_RT=n kernel, e.g. because they
take regular spinlocks. Also for latency reasons PREEMPT_RT tries to defer
most hrtimers' expiry into softirq context.

hrtimers marked with HRTIMER_MODE_HARD must be kept in hard interrupt
context expiry mode. Add the required logic.

No functional change for PREEMPT_RT=n kernels.

[ tglx: Split out of a larger combo patch. Added changelog ]

Signed-off-by: Sebastian Andrzej Siewior &lt;bigeasy@linutronix.de&gt;
Signed-off-by: Thomas Gleixner &lt;tglx@linutronix.de&gt;
Acked-by: Peter Zijlstra (Intel) &lt;peterz@infradead.org&gt;
Link: https://lkml.kernel.org/r/20190726185753.551967692@linutronix.de



</content>
</entry>
<entry>
<title>hrtimer: Make enqueue mode check work on RT</title>
<updated>2019-08-01T18:51:19Z</updated>
<author>
<name>Thomas Gleixner</name>
<email>tglx@linutronix.de</email>
</author>
<published>2019-07-30T18:15:25Z</published>
<link rel='alternate' type='text/html' href='https://git.shady.money/linux/commit/?id=0ab6a3ddbad40ef5b6b8c2353fd53fa4ecf9c479'/>
<id>urn:sha1:0ab6a3ddbad40ef5b6b8c2353fd53fa4ecf9c479</id>
<content type='text'>
hrtimer_start_range_ns() has a WARN_ONCE() which verifies that a timer
which is marker for softirq expiry is not queued in the hard interrupt base
and vice versa.

When PREEMPT_RT is enabled, timers which are not explicitely marked to
expire in hard interrupt context are deferrred to the soft interrupt. So
the regular check would trigger.

Change the check, so when PREEMPT_RT is enabled, it is verified that the
timers marked for hard interrupt expiry are not tried to be queued for soft
interrupt expiry or any of the unmarked and softirq marked is tried to be
expired in hard interrupt context.

Signed-off-by: Thomas Gleixner &lt;tglx@linutronix.de&gt;


</content>
</entry>
<entry>
<title>hrtimer: Provide hrtimer_sleeper_start_expires()</title>
<updated>2019-08-01T15:43:15Z</updated>
<author>
<name>Thomas Gleixner</name>
<email>tglx@linutronix.de</email>
</author>
<published>2019-07-30T19:03:53Z</published>
<link rel='alternate' type='text/html' href='https://git.shady.money/linux/commit/?id=01656464fce946f70b02a84ab218e562ceb1662e'/>
<id>urn:sha1:01656464fce946f70b02a84ab218e562ceb1662e</id>
<content type='text'>
hrtimer_sleepers will gain a scheduling class dependent treatment on
PREEMPT_RT. Create a wrapper around hrtimer_start_expires() to make that
possible.

Signed-off-by: Thomas Gleixner &lt;tglx@linutronix.de&gt;

</content>
</entry>
</feed>
