mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-14 15:54:15 +08:00
net: mac802154: Add a warning in the hot path
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. Set a flag when the queue should remain stopped. Reset this flag when the queue actually gets restarded. Just check this value to know if a transmission is legitimate, warn if it is not. Turn the flags variable into an unsigned long to allow the use of atomic helpers on it. Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com> Acked-by: Alexander Aring <aahringo@redhat.com> Link: https://lore.kernel.org/r/20220519150516.443078-11-miquel.raynal@bootlin.com Signed-off-by: Stefan Schmidt <stefan@datenfreihafen.org>
This commit is contained in:
parent
ddd9ee7cda
commit
2b13db13af
@ -166,11 +166,14 @@ wpan_phy_cca_cmp(const struct wpan_phy_cca *a, const struct wpan_phy_cca *b)
|
||||
* level setting.
|
||||
* @WPAN_PHY_FLAG_CCA_MODE: Indicates that transceiver will support cca mode
|
||||
* setting.
|
||||
* @WPAN_PHY_FLAG_STATE_QUEUE_STOPPED: Indicates that the transmit queue was
|
||||
* temporarily stopped.
|
||||
*/
|
||||
enum wpan_phy_flags {
|
||||
WPAN_PHY_FLAG_TXPOWER = BIT(1),
|
||||
WPAN_PHY_FLAG_CCA_ED_LEVEL = BIT(2),
|
||||
WPAN_PHY_FLAG_CCA_MODE = BIT(3),
|
||||
WPAN_PHY_FLAG_STATE_QUEUE_STOPPED = BIT(4),
|
||||
};
|
||||
|
||||
struct wpan_phy {
|
||||
@ -182,7 +185,7 @@ struct wpan_phy {
|
||||
*/
|
||||
const void *privid;
|
||||
|
||||
u32 flags;
|
||||
unsigned long flags;
|
||||
|
||||
/*
|
||||
* This is a PIB according to 802.15.4-2011.
|
||||
|
@ -123,9 +123,13 @@ static int ieee802154_sync_queue(struct ieee802154_local *local)
|
||||
|
||||
int ieee802154_sync_and_hold_queue(struct ieee802154_local *local)
|
||||
{
|
||||
ieee802154_hold_queue(local);
|
||||
int ret;
|
||||
|
||||
return ieee802154_sync_queue(local);
|
||||
ieee802154_hold_queue(local);
|
||||
ret = ieee802154_sync_queue(local);
|
||||
set_bit(WPAN_PHY_FLAG_STATE_QUEUE_STOPPED, &local->phy->flags);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ieee802154_mlme_op_pre(struct ieee802154_local *local)
|
||||
@ -172,9 +176,19 @@ int ieee802154_mlme_tx_one(struct ieee802154_local *local, struct sk_buff *skb)
|
||||
return ret;
|
||||
}
|
||||
|
||||
static bool ieee802154_queue_is_stopped(struct ieee802154_local *local)
|
||||
{
|
||||
return test_bit(WPAN_PHY_FLAG_STATE_QUEUE_STOPPED, &local->phy->flags);
|
||||
}
|
||||
|
||||
static netdev_tx_t
|
||||
ieee802154_hot_tx(struct ieee802154_local *local, struct sk_buff *skb)
|
||||
{
|
||||
/* Warn if the net interface tries to transmit frames while the
|
||||
* ieee802154 core assumes the queue is stopped.
|
||||
*/
|
||||
WARN_ON_ONCE(ieee802154_queue_is_stopped(local));
|
||||
|
||||
return ieee802154_tx(local, skb);
|
||||
}
|
||||
|
||||
|
@ -29,6 +29,7 @@ static void ieee802154_wake_queue(struct ieee802154_hw *hw)
|
||||
struct ieee802154_sub_if_data *sdata;
|
||||
|
||||
rcu_read_lock();
|
||||
clear_bit(WPAN_PHY_FLAG_STATE_QUEUE_STOPPED, &local->phy->flags);
|
||||
list_for_each_entry_rcu(sdata, &local->interfaces, list) {
|
||||
if (!sdata->dev)
|
||||
continue;
|
||||
|
Loading…
Reference in New Issue
Block a user