From: Francois Romieu Date: Tue, 31 Jan 2012 09:47:34 +0000 (+0100) Subject: r8169: bh locking redux and task scheduling. X-Git-Tag: v2.6.39-400.9.0~423^2~19^2~11^2~17 X-Git-Url: https://www.infradead.org/git/?a=commitdiff_plain;h=811a4d89b69dc9a9474fbc93b23d18ee999ae48a;p=users%2Fjedix%2Flinux-maple.git r8169: bh locking redux and task scheduling. - atomic bit operations are globally visible - pending status is always cleared before execution - scheduled works are either idempotent or only required to happen once after a series of originating events, say link events for instance (cherry picked from commit 98ddf986fca17840e46e070354b7e2cd2169da15) Signed-off-by: Francois Romieu Suggested-by: Michał Mirosław Cc: Hayes Wang Signed-off-by: Joe Jin --- diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c index de29b56265a3..07fdfc3e8ea8 100644 --- a/drivers/net/r8169.c +++ b/drivers/net/r8169.c @@ -3271,17 +3271,8 @@ out_mod_timer: static void rtl_schedule_task(struct rtl8169_private *tp, enum rtl_flag flag) { - spin_lock(&tp->lock); if (!test_and_set_bit(flag, tp->wk.flags)) schedule_work(&tp->wk.work); - spin_unlock(&tp->lock); -} - -static void rtl_schedule_task_bh(struct rtl8169_private *tp, enum rtl_flag flag) -{ - local_bh_disable(); - rtl_schedule_task(tp, flag); - local_bh_enable(); } static void rtl8169_phy_timer(unsigned long __opaque) @@ -3289,7 +3280,7 @@ static void rtl8169_phy_timer(unsigned long __opaque) struct net_device *dev = (struct net_device *)__opaque; struct rtl8169_private *tp = netdev_priv(dev); - rtl_schedule_task_bh(tp, RTL_FLAG_TASK_PHY_PENDING); + rtl_schedule_task(tp, RTL_FLAG_TASK_PHY_PENDING); } #ifdef CONFIG_NET_POLL_CONTROLLER @@ -5633,7 +5624,7 @@ static void rtl8169_pcierr_interrupt(struct net_device *dev) rtl8169_hw_reset(tp); - rtl_schedule_task_bh(tp, RTL_FLAG_TASK_RESET_PENDING); + rtl_schedule_task(tp, RTL_FLAG_TASK_RESET_PENDING); } static void rtl_tx(struct net_device *dev, struct rtl8169_private *tp) @@ -5850,7 +5841,7 @@ static void rtl_slow_event_work(struct rtl8169_private *tp) /* Work around for rx fifo overflow */ case RTL_GIGA_MAC_VER_11: netif_stop_queue(dev); - rtl_schedule_task_bh(tp, RTL_FLAG_TASK_RESET_PENDING); + rtl_schedule_task(tp, RTL_FLAG_TASK_RESET_PENDING); default: break; } @@ -5892,10 +5883,7 @@ static void rtl_task(struct work_struct *work) for (i = 0; i < ARRAY_SIZE(rtl_work); i++) { bool pending; - spin_lock_bh(&tp->lock); pending = test_and_clear_bit(rtl_work[i].bitnr, tp->wk.flags); - spin_unlock_bh(&tp->lock); - if (pending) rtl_work[i].action(tp); } @@ -6114,7 +6102,7 @@ static void __rtl8169_resume(struct net_device *dev) tp->wk.enabled = true; - rtl_schedule_task_bh(tp, RTL_FLAG_TASK_RESET_PENDING); + rtl_schedule_task(tp, RTL_FLAG_TASK_RESET_PENDING); } static int rtl8169_resume(struct device *device)