Merge branch 'core-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull locking fixes from Ingo Molnar: "Two fixes from lockdep coverage of seqlocks, which fix deadlocks on lockdep-enabled ARM systems" * 'core-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: sched_clock: Disable seqlock lockdep usage in sched_clock() seqlock: Use raw_ prefix instead of _no_lockdep
This commit is contained in:
commit
9b6c4ea95f
@ -178,7 +178,7 @@ notrace static int __always_inline do_realtime(struct timespec *ts)
|
|||||||
|
|
||||||
ts->tv_nsec = 0;
|
ts->tv_nsec = 0;
|
||||||
do {
|
do {
|
||||||
seq = read_seqcount_begin_no_lockdep(>od->seq);
|
seq = raw_read_seqcount_begin(>od->seq);
|
||||||
mode = gtod->clock.vclock_mode;
|
mode = gtod->clock.vclock_mode;
|
||||||
ts->tv_sec = gtod->wall_time_sec;
|
ts->tv_sec = gtod->wall_time_sec;
|
||||||
ns = gtod->wall_time_snsec;
|
ns = gtod->wall_time_snsec;
|
||||||
@ -198,7 +198,7 @@ notrace static int do_monotonic(struct timespec *ts)
|
|||||||
|
|
||||||
ts->tv_nsec = 0;
|
ts->tv_nsec = 0;
|
||||||
do {
|
do {
|
||||||
seq = read_seqcount_begin_no_lockdep(>od->seq);
|
seq = raw_read_seqcount_begin(>od->seq);
|
||||||
mode = gtod->clock.vclock_mode;
|
mode = gtod->clock.vclock_mode;
|
||||||
ts->tv_sec = gtod->monotonic_time_sec;
|
ts->tv_sec = gtod->monotonic_time_sec;
|
||||||
ns = gtod->monotonic_time_snsec;
|
ns = gtod->monotonic_time_snsec;
|
||||||
@ -214,7 +214,7 @@ notrace static int do_realtime_coarse(struct timespec *ts)
|
|||||||
{
|
{
|
||||||
unsigned long seq;
|
unsigned long seq;
|
||||||
do {
|
do {
|
||||||
seq = read_seqcount_begin_no_lockdep(>od->seq);
|
seq = raw_read_seqcount_begin(>od->seq);
|
||||||
ts->tv_sec = gtod->wall_time_coarse.tv_sec;
|
ts->tv_sec = gtod->wall_time_coarse.tv_sec;
|
||||||
ts->tv_nsec = gtod->wall_time_coarse.tv_nsec;
|
ts->tv_nsec = gtod->wall_time_coarse.tv_nsec;
|
||||||
} while (unlikely(read_seqcount_retry(>od->seq, seq)));
|
} while (unlikely(read_seqcount_retry(>od->seq, seq)));
|
||||||
@ -225,7 +225,7 @@ notrace static int do_monotonic_coarse(struct timespec *ts)
|
|||||||
{
|
{
|
||||||
unsigned long seq;
|
unsigned long seq;
|
||||||
do {
|
do {
|
||||||
seq = read_seqcount_begin_no_lockdep(>od->seq);
|
seq = raw_read_seqcount_begin(>od->seq);
|
||||||
ts->tv_sec = gtod->monotonic_time_coarse.tv_sec;
|
ts->tv_sec = gtod->monotonic_time_coarse.tv_sec;
|
||||||
ts->tv_nsec = gtod->monotonic_time_coarse.tv_nsec;
|
ts->tv_nsec = gtod->monotonic_time_coarse.tv_nsec;
|
||||||
} while (unlikely(read_seqcount_retry(>od->seq, seq)));
|
} while (unlikely(read_seqcount_retry(>od->seq, seq)));
|
||||||
|
@ -117,15 +117,15 @@ static inline unsigned __read_seqcount_begin(const seqcount_t *s)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* read_seqcount_begin_no_lockdep - start seq-read critical section w/o lockdep
|
* raw_read_seqcount_begin - start seq-read critical section w/o lockdep
|
||||||
* @s: pointer to seqcount_t
|
* @s: pointer to seqcount_t
|
||||||
* Returns: count to be passed to read_seqcount_retry
|
* Returns: count to be passed to read_seqcount_retry
|
||||||
*
|
*
|
||||||
* read_seqcount_begin_no_lockdep opens a read critical section of the given
|
* raw_read_seqcount_begin opens a read critical section of the given
|
||||||
* seqcount, but without any lockdep checking. Validity of the critical
|
* seqcount, but without any lockdep checking. Validity of the critical
|
||||||
* section is tested by checking read_seqcount_retry function.
|
* section is tested by checking read_seqcount_retry function.
|
||||||
*/
|
*/
|
||||||
static inline unsigned read_seqcount_begin_no_lockdep(const seqcount_t *s)
|
static inline unsigned raw_read_seqcount_begin(const seqcount_t *s)
|
||||||
{
|
{
|
||||||
unsigned ret = __read_seqcount_begin(s);
|
unsigned ret = __read_seqcount_begin(s);
|
||||||
smp_rmb();
|
smp_rmb();
|
||||||
@ -144,7 +144,7 @@ static inline unsigned read_seqcount_begin_no_lockdep(const seqcount_t *s)
|
|||||||
static inline unsigned read_seqcount_begin(const seqcount_t *s)
|
static inline unsigned read_seqcount_begin(const seqcount_t *s)
|
||||||
{
|
{
|
||||||
seqcount_lockdep_reader_access(s);
|
seqcount_lockdep_reader_access(s);
|
||||||
return read_seqcount_begin_no_lockdep(s);
|
return raw_read_seqcount_begin(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -206,14 +206,26 @@ static inline int read_seqcount_retry(const seqcount_t *s, unsigned start)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
static inline void raw_write_seqcount_begin(seqcount_t *s)
|
||||||
|
{
|
||||||
|
s->sequence++;
|
||||||
|
smp_wmb();
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void raw_write_seqcount_end(seqcount_t *s)
|
||||||
|
{
|
||||||
|
smp_wmb();
|
||||||
|
s->sequence++;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Sequence counter only version assumes that callers are using their
|
* Sequence counter only version assumes that callers are using their
|
||||||
* own mutexing.
|
* own mutexing.
|
||||||
*/
|
*/
|
||||||
static inline void write_seqcount_begin_nested(seqcount_t *s, int subclass)
|
static inline void write_seqcount_begin_nested(seqcount_t *s, int subclass)
|
||||||
{
|
{
|
||||||
s->sequence++;
|
raw_write_seqcount_begin(s);
|
||||||
smp_wmb();
|
|
||||||
seqcount_acquire(&s->dep_map, subclass, 0, _RET_IP_);
|
seqcount_acquire(&s->dep_map, subclass, 0, _RET_IP_);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -225,8 +237,7 @@ static inline void write_seqcount_begin(seqcount_t *s)
|
|||||||
static inline void write_seqcount_end(seqcount_t *s)
|
static inline void write_seqcount_end(seqcount_t *s)
|
||||||
{
|
{
|
||||||
seqcount_release(&s->dep_map, 1, _RET_IP_);
|
seqcount_release(&s->dep_map, 1, _RET_IP_);
|
||||||
smp_wmb();
|
raw_write_seqcount_end(s);
|
||||||
s->sequence++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -74,7 +74,7 @@ unsigned long long notrace sched_clock(void)
|
|||||||
return cd.epoch_ns;
|
return cd.epoch_ns;
|
||||||
|
|
||||||
do {
|
do {
|
||||||
seq = read_seqcount_begin(&cd.seq);
|
seq = raw_read_seqcount_begin(&cd.seq);
|
||||||
epoch_cyc = cd.epoch_cyc;
|
epoch_cyc = cd.epoch_cyc;
|
||||||
epoch_ns = cd.epoch_ns;
|
epoch_ns = cd.epoch_ns;
|
||||||
} while (read_seqcount_retry(&cd.seq, seq));
|
} while (read_seqcount_retry(&cd.seq, seq));
|
||||||
@ -99,10 +99,10 @@ static void notrace update_sched_clock(void)
|
|||||||
cd.mult, cd.shift);
|
cd.mult, cd.shift);
|
||||||
|
|
||||||
raw_local_irq_save(flags);
|
raw_local_irq_save(flags);
|
||||||
write_seqcount_begin(&cd.seq);
|
raw_write_seqcount_begin(&cd.seq);
|
||||||
cd.epoch_ns = ns;
|
cd.epoch_ns = ns;
|
||||||
cd.epoch_cyc = cyc;
|
cd.epoch_cyc = cyc;
|
||||||
write_seqcount_end(&cd.seq);
|
raw_write_seqcount_end(&cd.seq);
|
||||||
raw_local_irq_restore(flags);
|
raw_local_irq_restore(flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user