diff options
author | Reece R. Pollack | 2013-06-11 13:01:39 -0500 |
---|---|---|
committer | Murali Karicheri | 2014-12-03 10:29:50 -0600 |
commit | 90df6850f2b660501f4afe1175d08f829de54ccc (patch) | |
tree | ff93737404a778a4d50ecb288ba403c8e4e60fdd /drivers/net/ethernet/ti/keystone_ethss.c | |
parent | 1a6ae2b73feefc6cdb40b508a51d594f88ccb22b (diff) | |
download | linux-90df6850f2b660501f4afe1175d08f829de54ccc.tar.gz linux-90df6850f2b660501f4afe1175d08f829de54ccc.tar.xz linux-90df6850f2b660501f4afe1175d08f829de54ccc.zip |
net: keystone: Fix "scheduling while atomic" crash in cpsw_timer
Modification of statistics counters needs to be atomic, but a mutex
cannot be acquired from within a timer (softirq context). This patch
changes the mutex to a spinlock, and uses spin_lock_bh() to properly
synchronize the accesses.
Signed-off-by: Reece R. Pollack <x0183204@ti.com>
Diffstat (limited to 'drivers/net/ethernet/ti/keystone_ethss.c')
-rw-r--r-- | drivers/net/ethernet/ti/keystone_ethss.c | 16 |
1 files changed, 8 insertions, 8 deletions
diff --git a/drivers/net/ethernet/ti/keystone_ethss.c b/drivers/net/ethernet/ti/keystone_ethss.c index fb12fd070aa..896e036a6b1 100644 --- a/drivers/net/ethernet/ti/keystone_ethss.c +++ b/drivers/net/ethernet/ti/keystone_ethss.c | |||
@@ -253,7 +253,7 @@ struct cpsw_priv { | |||
253 | struct kobject tx_pri_kobj; | 253 | struct kobject tx_pri_kobj; |
254 | struct kobject pvlan_kobj; | 254 | struct kobject pvlan_kobj; |
255 | struct kobject stats_kobj; | 255 | struct kobject stats_kobj; |
256 | struct mutex hw_stats_lock; | 256 | spinlock_t hw_stats_lock; |
257 | }; | 257 | }; |
258 | 258 | ||
259 | struct cpsw_intf { | 259 | struct cpsw_intf { |
@@ -1127,9 +1127,9 @@ static ssize_t cpsw_stats_mod_store(struct cpsw_priv *cpsw_dev, | |||
1127 | return -EINVAL; | 1127 | return -EINVAL; |
1128 | 1128 | ||
1129 | stat_mod = (int)(attr->context); | 1129 | stat_mod = (int)(attr->context); |
1130 | mutex_lock(&cpsw_dev->hw_stats_lock); | 1130 | spin_lock_bh(&cpsw_dev->hw_stats_lock); |
1131 | cpsw_reset_mod_stats(cpsw_dev, stat_mod); | 1131 | cpsw_reset_mod_stats(cpsw_dev, stat_mod); |
1132 | mutex_unlock(&cpsw_dev->hw_stats_lock); | 1132 | spin_unlock_bh(&cpsw_dev->hw_stats_lock); |
1133 | return count; | 1133 | return count; |
1134 | } | 1134 | } |
1135 | 1135 | ||
@@ -1291,9 +1291,9 @@ static void keystone_get_ethtool_stats(struct net_device *ndev, | |||
1291 | struct ethtool_stats *stats, | 1291 | struct ethtool_stats *stats, |
1292 | uint64_t *data) | 1292 | uint64_t *data) |
1293 | { | 1293 | { |
1294 | mutex_lock(&priv->hw_stats_lock); | 1294 | spin_lock_bh(&priv->hw_stats_lock); |
1295 | cpsw_update_stats(priv, data); | 1295 | cpsw_update_stats(priv, data); |
1296 | mutex_unlock(&priv->hw_stats_lock); | 1296 | spin_unlock_bh(&priv->hw_stats_lock); |
1297 | 1297 | ||
1298 | return; | 1298 | return; |
1299 | } | 1299 | } |
@@ -1785,9 +1785,9 @@ static void cpsw_timer(unsigned long arg) | |||
1785 | netif_stop_queue(cpsw_intf->ndev); | 1785 | netif_stop_queue(cpsw_intf->ndev); |
1786 | } | 1786 | } |
1787 | 1787 | ||
1788 | mutex_lock(&cpsw_dev->hw_stats_lock); | 1788 | spin_lock_bh(&cpsw_dev->hw_stats_lock); |
1789 | cpsw_update_stats(cpsw_dev, NULL); | 1789 | cpsw_update_stats(cpsw_dev, NULL); |
1790 | mutex_unlock(&cpsw_dev->hw_stats_lock); | 1790 | spin_unlock_bh(&cpsw_dev->hw_stats_lock); |
1791 | 1791 | ||
1792 | cpsw_intf->timer.expires = jiffies + (HZ/10); | 1792 | cpsw_intf->timer.expires = jiffies + (HZ/10); |
1793 | add_timer(&cpsw_intf->timer); | 1793 | add_timer(&cpsw_intf->timer); |
@@ -2209,7 +2209,7 @@ static int cpsw_probe(struct netcp_device *netcp_device, | |||
2209 | NULL, cpsw_dev->intf_tx_queues, | 2209 | NULL, cpsw_dev->intf_tx_queues, |
2210 | 1, 0); | 2210 | 1, 0); |
2211 | /* init the hw stats lock */ | 2211 | /* init the hw stats lock */ |
2212 | mutex_init(&cpsw_dev->hw_stats_lock); | 2212 | spin_lock_init(&cpsw_dev->hw_stats_lock); |
2213 | 2213 | ||
2214 | ret = cpsw_create_sysfs_entries(cpsw_dev); | 2214 | ret = cpsw_create_sysfs_entries(cpsw_dev); |
2215 | if (ret) | 2215 | if (ret) |