aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorFrancois Romieu <romieu@fr.zoreil.com>2012-01-31 04:47:34 -0500
committerFrancois Romieu <romieu@fr.zoreil.com>2012-01-31 08:32:40 -0500
commit98ddf986fca17840e46e070354b7e2cd2169da15 (patch)
tree520b59064cfb654b15d1491536112d41492f8fa1 /drivers
parentae1f23fb433ac0aaff8aeaa5a7b14348e9aa8277 (diff)
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 Signed-off-by: Francois Romieu <romieu@fr.zoreil.com> Suggested-by: Michał Mirosław <mirqus@gmail.com> Cc: Hayes Wang <hayeswang@realtek.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/net/ethernet/realtek/r8169.c20
1 files changed, 4 insertions, 16 deletions
diff --git a/drivers/net/ethernet/realtek/r8169.c b/drivers/net/ethernet/realtek/r8169.c
index 859554a03a0..118f6f6fcef 100644
--- a/drivers/net/ethernet/realtek/r8169.c
+++ b/drivers/net/ethernet/realtek/r8169.c
@@ -3273,17 +3273,8 @@ out_mod_timer:
3273 3273
3274static void rtl_schedule_task(struct rtl8169_private *tp, enum rtl_flag flag) 3274static void rtl_schedule_task(struct rtl8169_private *tp, enum rtl_flag flag)
3275{ 3275{
3276 spin_lock(&tp->lock);
3277 if (!test_and_set_bit(flag, tp->wk.flags)) 3276 if (!test_and_set_bit(flag, tp->wk.flags))
3278 schedule_work(&tp->wk.work); 3277 schedule_work(&tp->wk.work);
3279 spin_unlock(&tp->lock);
3280}
3281
3282static void rtl_schedule_task_bh(struct rtl8169_private *tp, enum rtl_flag flag)
3283{
3284 local_bh_disable();
3285 rtl_schedule_task(tp, flag);
3286 local_bh_enable();
3287} 3278}
3288 3279
3289static void rtl8169_phy_timer(unsigned long __opaque) 3280static void rtl8169_phy_timer(unsigned long __opaque)
@@ -3291,7 +3282,7 @@ static void rtl8169_phy_timer(unsigned long __opaque)
3291 struct net_device *dev = (struct net_device *)__opaque; 3282 struct net_device *dev = (struct net_device *)__opaque;
3292 struct rtl8169_private *tp = netdev_priv(dev); 3283 struct rtl8169_private *tp = netdev_priv(dev);
3293 3284
3294 rtl_schedule_task_bh(tp, RTL_FLAG_TASK_PHY_PENDING); 3285 rtl_schedule_task(tp, RTL_FLAG_TASK_PHY_PENDING);
3295} 3286}
3296 3287
3297#ifdef CONFIG_NET_POLL_CONTROLLER 3288#ifdef CONFIG_NET_POLL_CONTROLLER
@@ -5635,7 +5626,7 @@ static void rtl8169_pcierr_interrupt(struct net_device *dev)
5635 5626
5636 rtl8169_hw_reset(tp); 5627 rtl8169_hw_reset(tp);
5637 5628
5638 rtl_schedule_task_bh(tp, RTL_FLAG_TASK_RESET_PENDING); 5629 rtl_schedule_task(tp, RTL_FLAG_TASK_RESET_PENDING);
5639} 5630}
5640 5631
5641static void rtl_tx(struct net_device *dev, struct rtl8169_private *tp) 5632static void rtl_tx(struct net_device *dev, struct rtl8169_private *tp)
@@ -5852,7 +5843,7 @@ static void rtl_slow_event_work(struct rtl8169_private *tp)
5852 /* Work around for rx fifo overflow */ 5843 /* Work around for rx fifo overflow */
5853 case RTL_GIGA_MAC_VER_11: 5844 case RTL_GIGA_MAC_VER_11:
5854 netif_stop_queue(dev); 5845 netif_stop_queue(dev);
5855 rtl_schedule_task_bh(tp, RTL_FLAG_TASK_RESET_PENDING); 5846 rtl_schedule_task(tp, RTL_FLAG_TASK_RESET_PENDING);
5856 default: 5847 default:
5857 break; 5848 break;
5858 } 5849 }
@@ -5894,10 +5885,7 @@ static void rtl_task(struct work_struct *work)
5894 for (i = 0; i < ARRAY_SIZE(rtl_work); i++) { 5885 for (i = 0; i < ARRAY_SIZE(rtl_work); i++) {
5895 bool pending; 5886 bool pending;
5896 5887
5897 spin_lock_bh(&tp->lock);
5898 pending = test_and_clear_bit(rtl_work[i].bitnr, tp->wk.flags); 5888 pending = test_and_clear_bit(rtl_work[i].bitnr, tp->wk.flags);
5899 spin_unlock_bh(&tp->lock);
5900
5901 if (pending) 5889 if (pending)
5902 rtl_work[i].action(tp); 5890 rtl_work[i].action(tp);
5903 } 5891 }
@@ -6116,7 +6104,7 @@ static void __rtl8169_resume(struct net_device *dev)
6116 6104
6117 tp->wk.enabled = true; 6105 tp->wk.enabled = true;
6118 6106
6119 rtl_schedule_task_bh(tp, RTL_FLAG_TASK_RESET_PENDING); 6107 rtl_schedule_task(tp, RTL_FLAG_TASK_RESET_PENDING);
6120} 6108}
6121 6109
6122static int rtl8169_resume(struct device *device) 6110static int rtl8169_resume(struct device *device)