We should never start a transmission after the queue has been stopped. But because it might work we don't kill the function here but rather warn loudly the user that something is wrong. Signed-off-by: Miquel Raynal <miquel.raynal@xxxxxxxxxxx> --- net/mac802154/ieee802154_i.h | 8 ++++++++ net/mac802154/tx.c | 2 ++ net/mac802154/util.c | 18 ++++++++++++++++++ 3 files changed, 28 insertions(+) diff --git a/net/mac802154/ieee802154_i.h b/net/mac802154/ieee802154_i.h index b55fdefb0b34..cb61a4abaf37 100644 --- a/net/mac802154/ieee802154_i.h +++ b/net/mac802154/ieee802154_i.h @@ -178,6 +178,14 @@ bool ieee802154_queue_is_held(struct ieee802154_local *local); */ void ieee802154_stop_queue(struct ieee802154_local *local); +/** + * ieee802154_queue_is_stopped - check whether ieee802154 queue was stopped + * @local: main mac object + * + * Goes through all the interfaces and indicates if they are all stopped or not. + */ +bool ieee802154_queue_is_stopped(struct ieee802154_local *local); + /* MIB callbacks */ void mac802154_dev_set_page_channel(struct net_device *dev, u8 page, u8 chan); diff --git a/net/mac802154/tx.c b/net/mac802154/tx.c index a8a83f0167bf..021dddfea542 100644 --- a/net/mac802154/tx.c +++ b/net/mac802154/tx.c @@ -124,6 +124,8 @@ bool ieee802154_queue_is_held(struct ieee802154_local *local) static netdev_tx_t ieee802154_hot_tx(struct ieee802154_local *local, struct sk_buff *skb) { + WARN_ON_ONCE(ieee802154_queue_is_stopped(local)); + return ieee802154_tx(local, skb); } diff --git a/net/mac802154/util.c b/net/mac802154/util.c index 847e0864b575..cfd17a7db532 100644 --- a/net/mac802154/util.c +++ b/net/mac802154/util.c @@ -44,6 +44,24 @@ void ieee802154_stop_queue(struct ieee802154_local *local) rcu_read_unlock(); } +bool ieee802154_queue_is_stopped(struct ieee802154_local *local) +{ + struct ieee802154_sub_if_data *sdata; + bool stopped = true; + + rcu_read_lock(); + list_for_each_entry_rcu(sdata, &local->interfaces, list) { + if (!sdata->dev) + continue; + + if (!netif_queue_stopped(sdata->dev)) + stopped = false; + } + rcu_read_unlock(); + + return stopped; +} + enum hrtimer_restart ieee802154_xmit_ifs_timer(struct hrtimer *timer) { struct ieee802154_local *local = -- 2.27.0