diff options
| author | David S. Miller <davem@davemloft.net> | 2008-11-11 15:43:02 -0800 | 
|---|---|---|
| committer | David S. Miller <davem@davemloft.net> | 2008-11-11 15:43:02 -0800 | 
| commit | 7e452baf6b96b5aeba097afd91501d33d390cc97 (patch) | |
| tree | 9b0e062d3677d50d731ffd0fba47423bfdee9253 /kernel/hrtimer.c | |
| parent | 3ac38c3a2e7dac3f8f35a56eb85c27881a4c3833 (diff) | |
| parent | f21f237cf55494c3a4209de323281a3b0528da10 (diff) | |
| download | olio-linux-3.10-7e452baf6b96b5aeba097afd91501d33d390cc97.tar.xz olio-linux-3.10-7e452baf6b96b5aeba097afd91501d33d390cc97.zip  | |
Merge branch 'master' of master.kernel.org:/pub/scm/linux/kernel/git/davem/net-2.6
Conflicts:
	drivers/message/fusion/mptlan.c
	drivers/net/sfc/ethtool.c
	net/mac80211/debugfs_sta.c
Diffstat (limited to 'kernel/hrtimer.c')
| -rw-r--r-- | kernel/hrtimer.c | 17 | 
1 files changed, 16 insertions, 1 deletions
diff --git a/kernel/hrtimer.c b/kernel/hrtimer.c index 2b465dfde42..95d3949f2ae 100644 --- a/kernel/hrtimer.c +++ b/kernel/hrtimer.c @@ -1209,6 +1209,7 @@ static void run_hrtimer_pending(struct hrtimer_cpu_base *cpu_base)  		enum hrtimer_restart (*fn)(struct hrtimer *);  		struct hrtimer *timer;  		int restart; +		int emulate_hardirq_ctx = 0;  		timer = list_entry(cpu_base->cb_pending.next,  				   struct hrtimer, cb_entry); @@ -1217,10 +1218,24 @@ static void run_hrtimer_pending(struct hrtimer_cpu_base *cpu_base)  		timer_stats_account_hrtimer(timer);  		fn = timer->function; +		/* +		 * A timer might have been added to the cb_pending list +		 * when it was migrated during a cpu-offline operation. +		 * Emulate hardirq context for such timers. +		 */ +		if (timer->cb_mode == HRTIMER_CB_IRQSAFE_PERCPU || +		    timer->cb_mode == HRTIMER_CB_IRQSAFE_UNLOCKED) +			emulate_hardirq_ctx = 1; +  		__remove_hrtimer(timer, timer->base, HRTIMER_STATE_CALLBACK, 0);  		spin_unlock_irq(&cpu_base->lock); -		restart = fn(timer); +		if (unlikely(emulate_hardirq_ctx)) { +			local_irq_disable(); +			restart = fn(timer); +			local_irq_enable(); +		} else +			restart = fn(timer);  		spin_lock_irq(&cpu_base->lock);  |