Hi,
before looking at this in detail, could please send a properly formatted
patch. the patch you sent is not using the unified option when
generating it. upstream linux-wireless wont accept it otherwise and we
wont either.
also please prefix the email with "mac80211: " so that we know which
subsystem it applies to.
that being said, the bug has been annoying me for eons and i never had
time to fix it so thanks for the time debugging this :)
John
On 11/09/2015 13:33, N.Leiten wrote:
> Fix instability of Ralink WiFi general queue management on high load.
> rt2x00 driver logs in dmesg "Dropping frame due to full queue ..." several
> times and at some point get stuck.
>
> Solutions in patch:
> 1) Increasing number of frames in each TX queue helps with speed and
> decreases queue overflows. Actually 256 frames can be increased to 512 (this
> number of frames used in proprietary drivers for every queue).
> 2) Setting number of frames in TX/RX queues to equal values resolves async
> speed behaviour with better RX on AP-side (uplink from STAs), where it needs
> to be at least equal or better on TX queue on AP (download to STA).
> 3) In rt2x00mac.c additional check for queue full added and reassignment in
> this case, so interface will not drop frame.
> 4) Fixes in queue initialization. Default values for AC_BK, AC_BE, AC_VI,
> AC_VO set from WMM.
>
> Tested on RT3883, RT5350, MT7620 SoCs and on RT3092 pcie interface for 10
> days.
>
> I'm planning to send this patch to mac80211 soon, but need to be sure that it
> works on other Ralink/Mediatek platforms and it's appropriate to do so.
>
>
> Signed-off-by: Nick Leiten <[email protected]>
> diff --git a/package/kernel/mac80211/patches/999-rt2x00-queue-update.patch
> b/package/kernel/mac80211/patches/999-rt2x00-queue-update.patch
> new file mode 100644
> index 0000000..9239bec
> --- /dev/null
> +++ b/package/kernel/mac80211/patches/999-rt2x00-queue-update.patch
> @@ -0,0 +1,142 @@
> +Only in compat-wireless-2015-03-09/drivers/net/wireless/rt2x00: limit
> +diff -c -r
> compat-wireless-2015-03-09-orig/drivers/net/wireless/rt2x00/rt2800mmio.c
> compat-wireless-2015-03-09/drivers/net/wireless/rt2x00/rt2800mmio.c
> +*** compat-wireless-2015-03-09-orig/drivers/net/wireless/rt2x00/rt2800mmio.c
> 2015-06-16 13:02:30.000000000 +0300
> +--- compat-wireless-2015-03-09/drivers/net/wireless/rt2x00/rt2800mmio.c
> 2015-09-04 11:50:09.665148666 +0300
> +***************
> +*** 700,706 ****
> +
> + switch (queue->qid) {
> + case QID_RX:
> +! queue->limit = 128;
> + queue->data_size = AGGREGATION_SIZE;
> + queue->desc_size = RXD_DESC_SIZE;
> + queue->winfo_size = rxwi_size;
> +--- 700,706 ----
> +
> + switch (queue->qid) {
> + case QID_RX:
> +! queue->limit = 256;
> + queue->data_size = AGGREGATION_SIZE;
> + queue->desc_size = RXD_DESC_SIZE;
> + queue->winfo_size = rxwi_size;
> +***************
> +*** 711,717 ****
> + case QID_AC_VI:
> + case QID_AC_BE:
> + case QID_AC_BK:
> +! queue->limit = 64;
> + queue->data_size = AGGREGATION_SIZE;
> + queue->desc_size = TXD_DESC_SIZE;
> + queue->winfo_size = txwi_size;
> +--- 711,717 ----
> + case QID_AC_VI:
> + case QID_AC_BE:
> + case QID_AC_BK:
> +! queue->limit = 256;
> + queue->data_size = AGGREGATION_SIZE;
> + queue->desc_size = TXD_DESC_SIZE;
> + queue->winfo_size = txwi_size;
> +diff -c -r
> compat-wireless-2015-03-09-orig/drivers/net/wireless/rt2x00/rt2x00mac.c
> compat-wireless-2015-03-09/drivers/net/wireless/rt2x00/rt2x00mac.c
> +*** compat-wireless-2015-03-09-orig/drivers/net/wireless/rt2x00/rt2x00mac.c
> 2015-06-16 13:02:30.000000000 +0300
> +--- compat-wireless-2015-03-09/drivers/net/wireless/rt2x00/rt2x00mac.c
> 2015-09-04 11:47:45.845449209 +0300
> +***************
> +*** 26,31 ****
> +--- 26,32 ----
> +
> + #include "rt2x00.h"
> + #include "rt2x00lib.h"
> ++ #include "rt2x00queue.h"
> +
> + static int rt2x00mac_tx_rts_cts(struct rt2x00_dev *rt2x00dev,
> + struct data_queue *queue,
> +***************
> +*** 115,120 ****
> +--- 116,141 ----
> + if (!test_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags))
> + goto exit_free_skb;
> +
> ++ /* Dirty hack for Queue overrun protection,
> ++ * if AC_VO/AC_VI/AC_BE is full, use next queue.
> ++ * if AC_BK is full use previous queue.
> ++ */
> ++ if (qid < 4) {
> ++ queue = rt2x00queue_get_tx_queue(rt2x00dev,qid);
> ++ if (unlikely(rt2x00queue_full(queue))){
> ++ switch(qid){
> ++ case 0: /* QID_AC_VO */
> ++ case 1: /* QID_AC_VI */
> ++ case 2: /* QID_AC_BE */
> ++ qid++;
> ++ break;
> ++ case 3: /* QID_AC_BK */
> ++ qid--;
> ++ break;
> ++ }
> ++ }
> ++ }
> ++
> + /*
> + * Use the ATIM queue if appropriate and present.
> + */
> +diff -c -r
> compat-wireless-2015-03-09-orig/drivers/net/wireless/rt2x00/rt2x00queue.c
> compat-wireless-2015-03-09/drivers/net/wireless/rt2x00/rt2x00queue.c
> +***
> compat-wireless-2015-03-09-orig/drivers/net/wireless/rt2x00/rt2x00queue.c
> 2015-03-10 05:37:16.000000000 +0200
> +--- compat-wireless-2015-03-09/drivers/net/wireless/rt2x00/rt2x00queue.c
> 2015-09-04 11:49:37.911446071 +0300
> +***************
> +*** 1213,1228 ****
> + static void rt2x00queue_init(struct rt2x00_dev *rt2x00dev,
> + struct data_queue *queue, enum data_queue_qid qid)
> + {
> + mutex_init(&queue->status_lock);
> + spin_lock_init(&queue->tx_lock);
> + spin_lock_init(&queue->index_lock);
> +
> + queue->rt2x00dev = rt2x00dev;
> + queue->qid = qid;
> +! queue->txop = 0;
> +! queue->aifs = 2;
> +! queue->cw_min = 5;
> +! queue->cw_max = 10;
> +
> + rt2x00dev->ops->queue_init(queue);
> +
> +--- 1213,1252 ----
> + static void rt2x00queue_init(struct rt2x00_dev *rt2x00dev,
> + struct data_queue *queue, enum data_queue_qid qid)
> + {
> ++ /* Use default values for each queue type */
> ++ unsigned short cwmin = 5, cwmax = 10, aifs = 2, txop = 0;
> ++
> ++ switch (qid) {
> ++ case QID_AC_VO:
> ++ cwmin = 2;
> ++ cwmax = 3;
> ++ txop = 47;
> ++ break;
> ++ case QID_AC_VI:
> ++ cwmin = 3;
> ++ cwmax = 4;
> ++ txop = 94;
> ++ break;
> ++ case QID_AC_BE:
> ++ cwmin = 4;
> ++ aifs = 3;
> ++ break;
> ++ case QID_AC_BK:
> ++ cwmin = 4;
> ++ aifs = 7;
> ++ break;
> ++ }
> ++
> + mutex_init(&queue->status_lock);
> + spin_lock_init(&queue->tx_lock);
> + spin_lock_init(&queue->index_lock);
> +
> + queue->rt2x00dev = rt2x00dev;
> + queue->qid = qid;
> +! queue->txop = txop;
> +! queue->aifs = aifs;
> +! queue->cw_min = cwmin;
> +! queue->cw_max = cwmax;
> +
> + rt2x00dev->ops->queue_init(queue);
> +
> _______________________________________________
> openwrt-devel mailing list
> [email protected]
> https://lists.openwrt.org/cgi-bin/mailman/listinfo/openwrt-devel
>
_______________________________________________
openwrt-devel mailing list
[email protected]
https://lists.openwrt.org/cgi-bin/mailman/listinfo/openwrt-devel