History

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

Linus Torvalds committed 12 years ago

Commit 9b6c4ea2 parents 93a11c8 7a06c413 files · +26 −15Browse files

Unified · Split

3 files
  1. arch/x86/vdso/vclock_gettime.c +4 −4
  2. include/linux/seqlock.h +19 −8
  3. kernel/time/sched_clock.c +3 −3
arch/x86/vdso/vclock_gettime.c+4−4
@@ -178,7 +178,7 @@ notrace static int __always_inline do_realtime(struct timespec *ts) · 177 unmodified lines
178 178
179 ts->tv_nsec = 0;179 ts->tv_nsec = 0;
180 do {180 do {
181 seq = read_seqcount_begin_no_lockdep(&gtod->seq);181 seq = raw_read_seqcount_begin(&gtod->seq);
182 mode = gtod->clock.vclock_mode;182 mode = gtod->clock.vclock_mode;
183 ts->tv_sec = gtod->wall_time_sec;183 ts->tv_sec = gtod->wall_time_sec;
184 ns = gtod->wall_time_snsec;184 ns = gtod->wall_time_snsec;
@@ -198,7 +198,7 @@ notrace static int do_monotonic(struct timespec *ts) · 13 unmodified lines
198 198
199 ts->tv_nsec = 0;199 ts->tv_nsec = 0;
200 do {200 do {
201 seq = read_seqcount_begin_no_lockdep(&gtod->seq);201 seq = raw_read_seqcount_begin(&gtod->seq);
202 mode = gtod->clock.vclock_mode;202 mode = gtod->clock.vclock_mode;
203 ts->tv_sec = gtod->monotonic_time_sec;203 ts->tv_sec = gtod->monotonic_time_sec;
204 ns = gtod->monotonic_time_snsec;204 ns = gtod->monotonic_time_snsec;
@@ -214,7 +214,7 @@ notrace static int do_realtime_coarse(struct timespec *ts) · 9 unmodified lines
214{214{
215 unsigned long seq;215 unsigned long seq;
216 do {216 do {
217 seq = read_seqcount_begin_no_lockdep(&gtod->seq);217 seq = raw_read_seqcount_begin(&gtod->seq);
218 ts->tv_sec = gtod->wall_time_coarse.tv_sec;218 ts->tv_sec = gtod->wall_time_coarse.tv_sec;
219 ts->tv_nsec = gtod->wall_time_coarse.tv_nsec;219 ts->tv_nsec = gtod->wall_time_coarse.tv_nsec;
220 } while (unlikely(read_seqcount_retry(&gtod->seq, seq)));220 } while (unlikely(read_seqcount_retry(&gtod->seq, seq)));
@@ -225,7 +225,7 @@ notrace static int do_monotonic_coarse(struct timespec *ts) · 4 unmodified lines
225{225{
226 unsigned long seq;226 unsigned long seq;
227 do {227 do {
228 seq = read_seqcount_begin_no_lockdep(&gtod->seq);228 seq = raw_read_seqcount_begin(&gtod->seq);
229 ts->tv_sec = gtod->monotonic_time_coarse.tv_sec;229 ts->tv_sec = gtod->monotonic_time_coarse.tv_sec;
230 ts->tv_nsec = gtod->monotonic_time_coarse.tv_nsec;230 ts->tv_nsec = gtod->monotonic_time_coarse.tv_nsec;
231 } while (unlikely(read_seqcount_retry(&gtod->seq, seq)));231 } while (unlikely(read_seqcount_retry(&gtod->seq, seq)));
include/linux/seqlock.h+19−8
@@ -117,15 +117,15 @@ repeat: · 116 unmodified lines
117}117}
118 118
119/**119/**
120 * read_seqcount_begin_no_lockdep - start seq-read critical section w/o lockdep120 * raw_read_seqcount_begin - start seq-read critical section w/o lockdep
121 * @s: pointer to seqcount_t121 * @s: pointer to seqcount_t
122 * Returns: count to be passed to read_seqcount_retry122 * Returns: count to be passed to read_seqcount_retry
123 *123 *
124 * read_seqcount_begin_no_lockdep opens a read critical section of the given124 * raw_read_seqcount_begin opens a read critical section of the given
125 * seqcount, but without any lockdep checking. Validity of the critical125 * seqcount, but without any lockdep checking. Validity of the critical
126 * section is tested by checking read_seqcount_retry function.126 * section is tested by checking read_seqcount_retry function.
127 */127 */
128static inline unsigned read_seqcount_begin_no_lockdep(const seqcount_t *s)128static inline unsigned raw_read_seqcount_begin(const seqcount_t *s)
129{129{
130 unsigned ret = __read_seqcount_begin(s);130 unsigned ret = __read_seqcount_begin(s);
131 smp_rmb();131 smp_rmb();
@@ -144,7 +144,7 @@ static inline unsigned read_seqcount_begin_no_lockdep(const seqcount_t *s) · 12 unmodified lines
144static inline unsigned read_seqcount_begin(const seqcount_t *s)144static inline unsigned read_seqcount_begin(const seqcount_t *s)
145{145{
146 seqcount_lockdep_reader_access(s);146 seqcount_lockdep_reader_access(s);
147 return read_seqcount_begin_no_lockdep(s);147 return raw_read_seqcount_begin(s);
148}148}
149 149
150/**150/**
@@ -206,14 +206,26 @@ static inline int read_seqcount_retry(const seqcount_t *s, unsigned start) · 55 unmodified lines
206}206}
207 207
208 208
209
210static inline void raw_write_seqcount_begin(seqcount_t *s)
211{
212 s->sequence++;
213 smp_wmb();
214}
215
216static inline void raw_write_seqcount_end(seqcount_t *s)
217{
218 smp_wmb();
219 s->sequence++;
220}
221
209/*222/*
210 * Sequence counter only version assumes that callers are using their223 * Sequence counter only version assumes that callers are using their
211 * own mutexing.224 * own mutexing.
212 */225 */
213static inline void write_seqcount_begin_nested(seqcount_t *s, int subclass)226static inline void write_seqcount_begin_nested(seqcount_t *s, int subclass)
214{227{
215 s->sequence++;228 raw_write_seqcount_begin(s);
216 smp_wmb();
217 seqcount_acquire(&s->dep_map, subclass, 0, _RET_IP_);229 seqcount_acquire(&s->dep_map, subclass, 0, _RET_IP_);
218}230}
219 231
@@ -225,8 +237,7 @@ static inline void write_seqcount_begin(seqcount_t *s) · 5 unmodified lines
225static inline void write_seqcount_end(seqcount_t *s)237static inline void write_seqcount_end(seqcount_t *s)
226{238{
227 seqcount_release(&s->dep_map, 1, _RET_IP_);239 seqcount_release(&s->dep_map, 1, _RET_IP_);
228 smp_wmb();240 raw_write_seqcount_end(s);
229 s->sequence++;
230}241}
231 242
232/**243/**
kernel/time/sched_clock.c+3−3
@@ -74,7 +74,7 @@ unsigned long long notrace sched_clock(void) · 73 unmodified lines
74 return cd.epoch_ns;74 return cd.epoch_ns;
75 75
76 do {76 do {
77 seq = read_seqcount_begin(&cd.seq);77 seq = raw_read_seqcount_begin(&cd.seq);
78 epoch_cyc = cd.epoch_cyc;78 epoch_cyc = cd.epoch_cyc;
79 epoch_ns = cd.epoch_ns;79 epoch_ns = cd.epoch_ns;
80 } while (read_seqcount_retry(&cd.seq, seq));80 } while (read_seqcount_retry(&cd.seq, seq));
@@ -99,10 +99,10 @@ static void notrace update_sched_clock(void) · 18 unmodified lines
99 cd.mult, cd.shift);99 cd.mult, cd.shift);
100 100
101 raw_local_irq_save(flags);101 raw_local_irq_save(flags);
102 write_seqcount_begin(&cd.seq);102 raw_write_seqcount_begin(&cd.seq);
103 cd.epoch_ns = ns;103 cd.epoch_ns = ns;
104 cd.epoch_cyc = cyc;104 cd.epoch_cyc = cyc;
105 write_seqcount_end(&cd.seq);105 raw_write_seqcount_end(&cd.seq);
106 raw_local_irq_restore(flags);106 raw_local_irq_restore(flags);
107}107}
108 108