Commit af5a06b5 authored by Ahmed S. Darwish's avatar Ahmed S. Darwish Committed by Peter Zijlstra
Browse files

hrtimer: Use sequence counter with associated raw spinlock



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: default avatarAhmed S. Darwish <a.darwish@linutronix.de>
Signed-off-by: default avatarPeter Zijlstra (Intel) <peterz@infradead.org>
Link: https://lkml.kernel.org/r/20200720155530.1173732-25-a.darwish@linutronix.de
parent 5c73b9a2
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -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);
+10 −3
Original line number Diff line number Diff line
@@ -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;