aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/softirq.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/softirq.c')
-rw-r--r--kernel/softirq.c23
1 files changed, 14 insertions, 9 deletions
diff --git a/kernel/softirq.c b/kernel/softirq.c
index b5197dcb0dad..ca25e6e704a2 100644
--- a/kernel/softirq.c
+++ b/kernel/softirq.c
@@ -127,8 +127,7 @@ static inline void __local_bh_disable(unsigned long ip, unsigned int cnt)
127 127
128void local_bh_disable(void) 128void local_bh_disable(void)
129{ 129{
130 __local_bh_disable((unsigned long)__builtin_return_address(0), 130 __local_bh_disable(_RET_IP_, SOFTIRQ_DISABLE_OFFSET);
131 SOFTIRQ_DISABLE_OFFSET);
132} 131}
133 132
134EXPORT_SYMBOL(local_bh_disable); 133EXPORT_SYMBOL(local_bh_disable);
@@ -139,7 +138,7 @@ static void __local_bh_enable(unsigned int cnt)
139 WARN_ON_ONCE(!irqs_disabled()); 138 WARN_ON_ONCE(!irqs_disabled());
140 139
141 if (softirq_count() == cnt) 140 if (softirq_count() == cnt)
142 trace_softirqs_on((unsigned long)__builtin_return_address(0)); 141 trace_softirqs_on(_RET_IP_);
143 sub_preempt_count(cnt); 142 sub_preempt_count(cnt);
144} 143}
145 144
@@ -184,7 +183,7 @@ static inline void _local_bh_enable_ip(unsigned long ip)
184 183
185void local_bh_enable(void) 184void local_bh_enable(void)
186{ 185{
187 _local_bh_enable_ip((unsigned long)__builtin_return_address(0)); 186 _local_bh_enable_ip(_RET_IP_);
188} 187}
189EXPORT_SYMBOL(local_bh_enable); 188EXPORT_SYMBOL(local_bh_enable);
190 189
@@ -195,8 +194,12 @@ void local_bh_enable_ip(unsigned long ip)
195EXPORT_SYMBOL(local_bh_enable_ip); 194EXPORT_SYMBOL(local_bh_enable_ip);
196 195
197/* 196/*
198 * We restart softirq processing for at most 2 ms, 197 * We restart softirq processing for at most MAX_SOFTIRQ_RESTART times,
199 * and if need_resched() is not set. 198 * but break the loop if need_resched() is set or after 2 ms.
199 * The MAX_SOFTIRQ_TIME provides a nice upper bound in most cases, but in
200 * certain cases, such as stop_machine(), jiffies may cease to
201 * increment and so we need the MAX_SOFTIRQ_RESTART limit as
202 * well to make sure we eventually return from this method.
200 * 203 *
201 * These limits have been established via experimentation. 204 * These limits have been established via experimentation.
202 * The two things to balance is latency against fairness - 205 * The two things to balance is latency against fairness -
@@ -204,6 +207,7 @@ EXPORT_SYMBOL(local_bh_enable_ip);
204 * should not be able to lock up the box. 207 * should not be able to lock up the box.
205 */ 208 */
206#define MAX_SOFTIRQ_TIME msecs_to_jiffies(2) 209#define MAX_SOFTIRQ_TIME msecs_to_jiffies(2)
210#define MAX_SOFTIRQ_RESTART 10
207 211
208asmlinkage void __do_softirq(void) 212asmlinkage void __do_softirq(void)
209{ 213{
@@ -212,6 +216,7 @@ asmlinkage void __do_softirq(void)
212 unsigned long end = jiffies + MAX_SOFTIRQ_TIME; 216 unsigned long end = jiffies + MAX_SOFTIRQ_TIME;
213 int cpu; 217 int cpu;
214 unsigned long old_flags = current->flags; 218 unsigned long old_flags = current->flags;
219 int max_restart = MAX_SOFTIRQ_RESTART;
215 220
216 /* 221 /*
217 * Mask out PF_MEMALLOC s current task context is borrowed for the 222 * Mask out PF_MEMALLOC s current task context is borrowed for the
@@ -223,8 +228,7 @@ asmlinkage void __do_softirq(void)
223 pending = local_softirq_pending(); 228 pending = local_softirq_pending();
224 account_irq_enter_time(current); 229 account_irq_enter_time(current);
225 230
226 __local_bh_disable((unsigned long)__builtin_return_address(0), 231 __local_bh_disable(_RET_IP_, SOFTIRQ_OFFSET);
227 SOFTIRQ_OFFSET);
228 lockdep_softirq_enter(); 232 lockdep_softirq_enter();
229 233
230 cpu = smp_processor_id(); 234 cpu = smp_processor_id();
@@ -265,7 +269,8 @@ restart:
265 269
266 pending = local_softirq_pending(); 270 pending = local_softirq_pending();
267 if (pending) { 271 if (pending) {
268 if (time_before(jiffies, end) && !need_resched()) 272 if (time_before(jiffies, end) && !need_resched() &&
273 --max_restart)
269 goto restart; 274 goto restart;
270 275
271 wakeup_softirqd(); 276 wakeup_softirqd();