Skip to content

Commit

Permalink
mt76: mt76u: rely on a dedicated stats workqueue
Browse files Browse the repository at this point in the history
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: Lorenzo Bianconi <lorenzo@kernel.org>
Signed-off-by: Felix Fietkau <nbd@nbd.name>
  • Loading branch information
Lorenzo Bianconi authored and Felix Fietkau committed Nov 20, 2019
1 parent 80df01f commit 284efb4
Show file tree
Hide file tree
Showing 4 changed files with 25 additions and 10 deletions.
4 changes: 3 additions & 1 deletion drivers/net/wireless/mediatek/mt76/mt76.h
Original file line number Diff line number Diff line change
Expand Up @@ -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];
Expand Down Expand Up @@ -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);
Expand Down
2 changes: 2 additions & 0 deletions drivers/net/wireless/mediatek/mt76/mt76x0/usb.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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);
}

Expand Down
2 changes: 2 additions & 0 deletions drivers/net/wireless/mediatek/mt76/mt76x2/usb.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand All @@ -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);
Expand Down
27 changes: 18 additions & 9 deletions drivers/net/wireless/mediatek/mt76/usb.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
Expand All @@ -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) {
Expand All @@ -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);
}
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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);
Expand All @@ -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");

0 comments on commit 284efb4

Please sign in to comment.