Commit 284efb47 authored by Lorenzo Bianconi's avatar Lorenzo Bianconi Committed by Felix Fietkau

mt76: mt76u: rely on a dedicated stats workqueue

rate controller and throughput are very sensitive to tx status timing.
In order to improve performances when the system is heavily loaded,
substitute stat_work delayed_work with a regular work_struct and create
a mt76u dedicated workqueue for tx status reporting
Signed-off-by: default avatarLorenzo Bianconi <lorenzo@kernel.org>
Signed-off-by: default avatarFelix Fietkau <nbd@nbd.name>
parent 80df01f4
......@@ -387,7 +387,8 @@ struct mt76_usb {
};
struct tasklet_struct rx_tasklet;
struct delayed_work stat_work;
struct workqueue_struct *stat_wq;
struct work_struct stat_work;
u8 out_ep[__MT_EP_OUT_MAX];
u8 in_ep[__MT_EP_IN_MAX];
......@@ -823,6 +824,7 @@ int mt76u_vendor_request(struct mt76_dev *dev, u8 req,
void mt76u_single_wr(struct mt76_dev *dev, const u8 req,
const u16 offset, const u32 val);
int mt76u_init(struct mt76_dev *dev, struct usb_interface *intf);
void mt76u_deinit(struct mt76_dev *dev);
int mt76u_alloc_queues(struct mt76_dev *dev);
void mt76u_stop_tx(struct mt76_dev *dev);
void mt76u_stop_rx(struct mt76_dev *dev);
......
......@@ -273,6 +273,7 @@ static int mt76x0u_probe(struct usb_interface *usb_intf,
err:
usb_set_intfdata(usb_intf, NULL);
usb_put_dev(interface_to_usbdev(usb_intf));
mt76u_deinit(&dev->mt76);
ieee80211_free_hw(mdev->hw);
return ret;
......@@ -292,6 +293,7 @@ static void mt76x0_disconnect(struct usb_interface *usb_intf)
usb_set_intfdata(usb_intf, NULL);
usb_put_dev(interface_to_usbdev(usb_intf));
mt76u_deinit(&dev->mt76);
ieee80211_free_hw(dev->mt76.hw);
}
......
......@@ -73,6 +73,7 @@ static int mt76x2u_probe(struct usb_interface *intf,
err:
ieee80211_free_hw(mt76_hw(dev));
mt76u_deinit(&dev->mt76);
usb_set_intfdata(intf, NULL);
usb_put_dev(udev);
......@@ -88,6 +89,7 @@ static void mt76x2u_disconnect(struct usb_interface *intf)
set_bit(MT76_REMOVED, &dev->mt76.state);
ieee80211_unregister_hw(hw);
mt76x2u_cleanup(dev);
mt76u_deinit(&dev->mt76);
ieee80211_free_hw(hw);
usb_set_intfdata(intf, NULL);
......
......@@ -697,10 +697,7 @@ static void mt76u_tx_tasklet(unsigned long data)
mt76_txq_schedule(dev, i);
if (!test_and_set_bit(MT76_READING_STATS, &dev->state))
ieee80211_queue_delayed_work(dev->hw,
&dev->usb.stat_work,
msecs_to_jiffies(10));
queue_work(dev->usb.stat_wq, &dev->usb.stat_work);
if (wake)
ieee80211_wake_queue(dev->hw, i);
}
......@@ -713,7 +710,7 @@ static void mt76u_tx_status_data(struct work_struct *work)
u8 update = 1;
u16 count = 0;
usb = container_of(work, struct mt76_usb, stat_work.work);
usb = container_of(work, struct mt76_usb, stat_work);
dev = container_of(usb, struct mt76_dev, usb);
while (true) {
......@@ -726,8 +723,7 @@ static void mt76u_tx_status_data(struct work_struct *work)
}
if (count && test_bit(MT76_STATE_RUNNING, &dev->state))
ieee80211_queue_delayed_work(dev->hw, &usb->stat_work,
msecs_to_jiffies(10));
queue_work(usb->stat_wq, &usb->stat_work);
else
clear_bit(MT76_READING_STATS, &dev->state);
}
......@@ -908,7 +904,7 @@ void mt76u_stop_tx(struct mt76_dev *dev)
}
}
cancel_delayed_work_sync(&dev->usb.stat_work);
cancel_work_sync(&dev->usb.stat_work);
clear_bit(MT76_READING_STATS, &dev->state);
mt76_tx_status_check(dev, NULL, true);
......@@ -959,9 +955,13 @@ int mt76u_init(struct mt76_dev *dev,
tasklet_init(&usb->rx_tasklet, mt76u_rx_tasklet, (unsigned long)dev);
tasklet_init(&dev->tx_tasklet, mt76u_tx_tasklet, (unsigned long)dev);
INIT_DELAYED_WORK(&usb->stat_work, mt76u_tx_status_data);
INIT_WORK(&usb->stat_work, mt76u_tx_status_data);
skb_queue_head_init(&dev->rx_skb[MT_RXQ_MAIN]);
usb->stat_wq = alloc_workqueue("mt76u", WQ_UNBOUND, 0);
if (!usb->stat_wq)
return -ENOMEM;
mutex_init(&usb->mcu.mutex);
mutex_init(&usb->usb_ctrl_mtx);
......@@ -976,5 +976,14 @@ int mt76u_init(struct mt76_dev *dev,
}
EXPORT_SYMBOL_GPL(mt76u_init);
void mt76u_deinit(struct mt76_dev *dev)
{
if (dev->usb.stat_wq) {
destroy_workqueue(dev->usb.stat_wq);
dev->usb.stat_wq = NULL;
}
}
EXPORT_SYMBOL_GPL(mt76u_deinit);
MODULE_AUTHOR("Lorenzo Bianconi <lorenzo.bianconi83@gmail.com>");
MODULE_LICENSE("Dual BSD/GPL");
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment