]> git.proxmox.com Git - mirror_ubuntu-jammy-kernel.git/commitdiff
hrtimer: Use sequence counter with associated raw spinlock
authorAhmed S. Darwish <a.darwish@linutronix.de>
Mon, 20 Jul 2020 15:55:30 +0000 (17:55 +0200)
committerPeter Zijlstra <peterz@infradead.org>
Wed, 29 Jul 2020 14:14:29 +0000 (16:14 +0200)
A sequence counter write side critical section must be protected by some
form of locking to serialize writers. A plain seqcount_t does not
contain the information of which lock must be held when entering a write
side critical section.

Use the new seqcount_raw_spinlock_t data type, which allows to associate
a raw spinlock with the sequence counter. This enables lockdep to verify
that the raw spinlock used for writer serialization is held when the
write side critical section is entered.

If lockdep is disabled this lock association is compiled out and has
neither storage size nor runtime overhead.

Signed-off-by: Ahmed S. Darwish <a.darwish@linutronix.de>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Link: https://lkml.kernel.org/r/20200720155530.1173732-25-a.darwish@linutronix.de
include/linux/hrtimer.h
kernel/time/hrtimer.c

index 15c8ac3136780fdc177fbc6f7c7342dfd79fcdcb..25993b86ac5cacc1cbb651f8227e25d00adf531b 100644 (file)
@@ -159,7 +159,7 @@ struct hrtimer_clock_base {
        struct hrtimer_cpu_base *cpu_base;
        unsigned int            index;
        clockid_t               clockid;
-       seqcount_t              seq;
+       seqcount_raw_spinlock_t seq;
        struct hrtimer          *running;
        struct timerqueue_head  active;
        ktime_t                 (*get_time)(void);
index d89da1c7e005a68f4f18c06187086132df5eb2ba..c4038511d5c9e3fad13f06dd04fd7ce24f7a653a 100644 (file)
@@ -135,7 +135,11 @@ static const int hrtimer_clock_to_base_table[MAX_CLOCKS] = {
  * timer->base->cpu_base
  */
 static struct hrtimer_cpu_base migration_cpu_base = {
-       .clock_base = { { .cpu_base = &migration_cpu_base, }, },
+       .clock_base = { {
+               .cpu_base = &migration_cpu_base,
+               .seq      = SEQCNT_RAW_SPINLOCK_ZERO(migration_cpu_base.seq,
+                                                    &migration_cpu_base.lock),
+       }, },
 };
 
 #define migration_base migration_cpu_base.clock_base[0]
@@ -1998,8 +2002,11 @@ int hrtimers_prepare_cpu(unsigned int cpu)
        int i;
 
        for (i = 0; i < HRTIMER_MAX_CLOCK_BASES; i++) {
-               cpu_base->clock_base[i].cpu_base = cpu_base;
-               timerqueue_init_head(&cpu_base->clock_base[i].active);
+               struct hrtimer_clock_base *clock_b = &cpu_base->clock_base[i];
+
+               clock_b->cpu_base = cpu_base;
+               seqcount_raw_spinlock_init(&clock_b->seq, &cpu_base->lock);
+               timerqueue_init_head(&clock_b->active);
        }
 
        cpu_base->cpu = cpu;