提交 c3838353 编写于 作者: A Alexander Aring 提交者: Marcel Holtmann

mac802154: tx: fix synced xmit deadlock

This patch reverts 6001d522 ("mac802154: tx: don't allow if down while
sync tx"). This has side effects with stop callback which flush the
transmit workqueue. The stop callback will wait until the workqueue is
flushed and holding the rtnl lock. That means it can happen that the stop
callback waits forever because it try to lock the rtnl mutex which is
already hold by stop callback.

Cc: Michael Hennerich <michael.hennerich@analog.com>
Signed-off-by: NAlexander Aring <alex.aring@gmail.com>
Signed-off-by: NMarcel Holtmann <marcel@holtmann.org>
上级 818f1f3e
...@@ -18,9 +18,6 @@ drv_xmit_async(struct ieee802154_local *local, struct sk_buff *skb) ...@@ -18,9 +18,6 @@ drv_xmit_async(struct ieee802154_local *local, struct sk_buff *skb)
static inline int static inline int
drv_xmit_sync(struct ieee802154_local *local, struct sk_buff *skb) drv_xmit_sync(struct ieee802154_local *local, struct sk_buff *skb)
{ {
/* don't allow other operations while sync xmit */
ASSERT_RTNL();
might_sleep(); might_sleep();
return local->ops->xmit_sync(&local->hw, skb); return local->ops->xmit_sync(&local->hw, skb);
......
...@@ -38,12 +38,6 @@ void ieee802154_xmit_worker(struct work_struct *work) ...@@ -38,12 +38,6 @@ void ieee802154_xmit_worker(struct work_struct *work)
struct net_device *dev = skb->dev; struct net_device *dev = skb->dev;
int res; int res;
rtnl_lock();
/* check if ifdown occurred while schedule */
if (!netif_running(dev))
goto err_tx;
res = drv_xmit_sync(local, skb); res = drv_xmit_sync(local, skb);
if (res) if (res)
goto err_tx; goto err_tx;
...@@ -53,14 +47,11 @@ void ieee802154_xmit_worker(struct work_struct *work) ...@@ -53,14 +47,11 @@ void ieee802154_xmit_worker(struct work_struct *work)
dev->stats.tx_packets++; dev->stats.tx_packets++;
dev->stats.tx_bytes += skb->len; dev->stats.tx_bytes += skb->len;
rtnl_unlock();
return; return;
err_tx: err_tx:
/* Restart the netif queue on each sub_if_data object. */ /* Restart the netif queue on each sub_if_data object. */
ieee802154_wake_queue(&local->hw); ieee802154_wake_queue(&local->hw);
rtnl_unlock();
kfree_skb(skb); kfree_skb(skb);
netdev_dbg(dev, "transmission failed\n"); netdev_dbg(dev, "transmission failed\n");
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册