1 From 934111e7a727890ecb6b9b72c66c105c21ea23ea Mon Sep 17 00:00:00 2001
2 From: Thomas Gleixner <tglx@linutronix.de>
3 Date: Thu, 14 Feb 2013 22:36:59 +0100
4 Subject: [PATCH 007/366] timekeeping: Split jiffies seqlock
6 Replace jiffies_lock seqlock with a simple seqcounter and a rawlock so
7 it can be taken in atomic context on RT.
9 Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
11 kernel/time/jiffies.c | 7 ++++---
12 kernel/time/tick-common.c | 10 ++++++----
13 kernel/time/tick-sched.c | 19 ++++++++++++-------
14 kernel/time/timekeeping.c | 6 ++++--
15 kernel/time/timekeeping.h | 3 ++-
16 5 files changed, 28 insertions(+), 17 deletions(-)
18 diff --git a/kernel/time/jiffies.c b/kernel/time/jiffies.c
19 index 347fecf..2ede474 100644
20 --- a/kernel/time/jiffies.c
21 +++ b/kernel/time/jiffies.c
22 @@ -74,7 +74,8 @@ static struct clocksource clocksource_jiffies = {
26 -__cacheline_aligned_in_smp DEFINE_SEQLOCK(jiffies_lock);
27 +__cacheline_aligned_in_smp DEFINE_RAW_SPINLOCK(jiffies_lock);
28 +__cacheline_aligned_in_smp seqcount_t jiffies_seq;
30 #if (BITS_PER_LONG < 64)
31 u64 get_jiffies_64(void)
32 @@ -83,9 +84,9 @@ u64 get_jiffies_64(void)
36 - seq = read_seqbegin(&jiffies_lock);
37 + seq = read_seqcount_begin(&jiffies_seq);
39 - } while (read_seqretry(&jiffies_lock, seq));
40 + } while (read_seqcount_retry(&jiffies_seq, seq));
43 EXPORT_SYMBOL(get_jiffies_64);
44 diff --git a/kernel/time/tick-common.c b/kernel/time/tick-common.c
45 index 4fcd99e..5a47f2e 100644
46 --- a/kernel/time/tick-common.c
47 +++ b/kernel/time/tick-common.c
48 @@ -79,13 +79,15 @@ int tick_is_oneshot_available(void)
49 static void tick_periodic(int cpu)
51 if (tick_do_timer_cpu == cpu) {
52 - write_seqlock(&jiffies_lock);
53 + raw_spin_lock(&jiffies_lock);
54 + write_seqcount_begin(&jiffies_seq);
56 /* Keep track of the next tick event */
57 tick_next_period = ktime_add(tick_next_period, tick_period);
60 - write_sequnlock(&jiffies_lock);
61 + write_seqcount_end(&jiffies_seq);
62 + raw_spin_unlock(&jiffies_lock);
66 @@ -157,9 +159,9 @@ void tick_setup_periodic(struct clock_event_device *dev, int broadcast)
70 - seq = read_seqbegin(&jiffies_lock);
71 + seq = read_seqcount_begin(&jiffies_seq);
72 next = tick_next_period;
73 - } while (read_seqretry(&jiffies_lock, seq));
74 + } while (read_seqcount_retry(&jiffies_seq, seq));
76 clockevents_switch_state(dev, CLOCK_EVT_STATE_ONESHOT);
78 diff --git a/kernel/time/tick-sched.c b/kernel/time/tick-sched.c
79 index 22c57e1..9579f79 100644
80 --- a/kernel/time/tick-sched.c
81 +++ b/kernel/time/tick-sched.c
82 @@ -62,7 +62,8 @@ static void tick_do_update_jiffies64(ktime_t now)
85 /* Reevalute with jiffies_lock held */
86 - write_seqlock(&jiffies_lock);
87 + raw_spin_lock(&jiffies_lock);
88 + write_seqcount_begin(&jiffies_seq);
90 delta = ktime_sub(now, last_jiffies_update);
91 if (delta.tv64 >= tick_period.tv64) {
92 @@ -85,10 +86,12 @@ static void tick_do_update_jiffies64(ktime_t now)
93 /* Keep the tick_next_period variable up to date */
94 tick_next_period = ktime_add(last_jiffies_update, tick_period);
96 - write_sequnlock(&jiffies_lock);
97 + write_seqcount_end(&jiffies_seq);
98 + raw_spin_unlock(&jiffies_lock);
101 - write_sequnlock(&jiffies_lock);
102 + write_seqcount_end(&jiffies_seq);
103 + raw_spin_unlock(&jiffies_lock);
107 @@ -99,12 +102,14 @@ static ktime_t tick_init_jiffy_update(void)
111 - write_seqlock(&jiffies_lock);
112 + raw_spin_lock(&jiffies_lock);
113 + write_seqcount_begin(&jiffies_seq);
114 /* Did we start the jiffies update yet ? */
115 if (last_jiffies_update.tv64 == 0)
116 last_jiffies_update = tick_next_period;
117 period = last_jiffies_update;
118 - write_sequnlock(&jiffies_lock);
119 + write_seqcount_end(&jiffies_seq);
120 + raw_spin_unlock(&jiffies_lock);
124 @@ -578,10 +583,10 @@ static ktime_t tick_nohz_stop_sched_tick(struct tick_sched *ts,
126 /* Read jiffies and the time when jiffies were updated last */
128 - seq = read_seqbegin(&jiffies_lock);
129 + seq = read_seqcount_begin(&jiffies_seq);
130 basemono = last_jiffies_update.tv64;
132 - } while (read_seqretry(&jiffies_lock, seq));
133 + } while (read_seqcount_retry(&jiffies_seq, seq));
134 ts->last_jiffies = basejiff;
136 if (rcu_needs_cpu(basemono, &next_rcu) ||
137 diff --git a/kernel/time/timekeeping.c b/kernel/time/timekeeping.c
138 index 9a1092b..a963d9e 100644
139 --- a/kernel/time/timekeeping.c
140 +++ b/kernel/time/timekeeping.c
141 @@ -2072,8 +2072,10 @@ EXPORT_SYMBOL(hardpps);
143 void xtime_update(unsigned long ticks)
145 - write_seqlock(&jiffies_lock);
146 + raw_spin_lock(&jiffies_lock);
147 + write_seqcount_begin(&jiffies_seq);
149 - write_sequnlock(&jiffies_lock);
150 + write_seqcount_end(&jiffies_seq);
151 + raw_spin_unlock(&jiffies_lock);
154 diff --git a/kernel/time/timekeeping.h b/kernel/time/timekeeping.h
155 index 704f595..763a3e5 100644
156 --- a/kernel/time/timekeeping.h
157 +++ b/kernel/time/timekeeping.h
158 @@ -19,7 +19,8 @@ extern void timekeeping_resume(void);
159 extern void do_timer(unsigned long ticks);
160 extern void update_wall_time(void);
162 -extern seqlock_t jiffies_lock;
163 +extern raw_spinlock_t jiffies_lock;
164 +extern seqcount_t jiffies_seq;
166 #define CS_NAME_LEN 32