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 <nicklei...@gmail.com> > 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 > openwrt-devel@lists.openwrt.org > https://lists.openwrt.org/cgi-bin/mailman/listinfo/openwrt-devel > _______________________________________________ openwrt-devel mailing list openwrt-devel@lists.openwrt.org https://lists.openwrt.org/cgi-bin/mailman/listinfo/openwrt-devel