etheriwl, etherwpi: limit transmit queue buffer bloat to 48k (at 22Mbit ≅ 20ms)

This commit is contained in:
cinap_lenrek 2017-12-28 01:24:38 +01:00
parent ce9cc8a358
commit d13142b3da
2 changed files with 38 additions and 21 deletions

View file

@ -19,8 +19,12 @@
#include "wifi.h" #include "wifi.h"
enum { enum {
MaxQueue = 24*1024, /* total buffer is 2*MaxQueue: 48k at 22Mbit ≅ 20ms */
Ntxlog = 8, Ntxlog = 8,
Ntx = 1<<Ntxlog, Ntx = 1<<Ntxlog,
Ntxqmax = MaxQueue/1500,
Nrxlog = 8, Nrxlog = 8,
Nrx = 1<<Nrxlog, Nrx = 1<<Nrxlog,
@ -1666,7 +1670,7 @@ static int
txqready(void *arg) txqready(void *arg)
{ {
TXQ *q = arg; TXQ *q = arg;
return q->n < Ntx; return q->n < Ntxqmax;
} }
static char* static char*
@ -1680,11 +1684,11 @@ qcmd(Ctlr *ctlr, uint qid, uint code, uchar *data, int size, Block *block)
ilock(ctlr); ilock(ctlr);
q = &ctlr->tx[qid]; q = &ctlr->tx[qid];
while(q->n >= Ntx && !ctlr->broken){ while(q->n >= Ntxqmax && !ctlr->broken){
iunlock(ctlr); iunlock(ctlr);
qlock(q); qlock(q);
if(!waserror()){ if(!waserror()){
tsleep(q, txqready, q, 10); tsleep(q, txqready, q, 5);
poperror(); poperror();
} }
qunlock(q); qunlock(q);
@ -1929,6 +1933,7 @@ static struct ratetab {
{ 4, 20, RFlagCCK }, { 4, 20, RFlagCCK },
{ 11, 55, RFlagCCK }, { 11, 55, RFlagCCK },
{ 22, 110, RFlagCCK }, { 22, 110, RFlagCCK },
{ 12, 0xd, 0 }, { 12, 0xd, 0 },
{ 18, 0xf, 0 }, { 18, 0xf, 0 },
{ 24, 0x5, 0 }, { 24, 0x5, 0 },
@ -1945,6 +1950,7 @@ static uchar iwlrates[] = {
0x80 | 4, 0x80 | 4,
0x80 | 11, 0x80 | 11,
0x80 | 22, 0x80 | 22,
0x80 | 12, 0x80 | 12,
0x80 | 18, 0x80 | 18,
0x80 | 24, 0x80 | 24,
@ -2026,12 +2032,12 @@ transmit(Wifi *wifi, Wnode *wn, Block *b)
flags |= TFlagFullTxOp; flags |= TFlagFullTxOp;
} }
} }
if(p >= wifi->rates)
rate = p - wifi->rates;
else
rate = 0;
qunlock(ctlr); qunlock(ctlr);
rate = 0;
if(p >= iwlrates && p < &iwlrates[nelem(ratetab)])
rate = p - iwlrates;
/* select first available antenna */ /* select first available antenna */
ant = ctlr->rfcfg.txantmask & 7; ant = ctlr->rfcfg.txantmask & 7;
ant |= (ant == 0); ant |= (ant == 0);
@ -2192,6 +2198,8 @@ iwlattach(Ether *edev)
error("wifi disabled by switch"); error("wifi disabled by switch");
if(ctlr->wifi == nil){ if(ctlr->wifi == nil){
qsetlimit(edev->oq, MaxQueue);
ctlr->wifi = wifiattach(edev, transmit); ctlr->wifi = wifiattach(edev, transmit);
/* tested with 2230, it has transmit issues using higher bit rates */ /* tested with 2230, it has transmit issues using higher bit rates */
if(ctlr->type != Type2030) if(ctlr->type != Type2030)

View file

@ -11,15 +11,20 @@
#include "wifi.h" #include "wifi.h"
enum { enum {
Nrxlog = 6, MaxQueue = 24*1024, /* total buffer is 2*MaxQueue: 48k at 22Mbit ≅ 20ms */
Nrx = 1<<Nrxlog,
Ntx = 256,
Rbufsize = 3*1024, Ntxlog = 8,
Rdscsize = 8, Ntx = 1<<Ntxlog,
Ntxqmax = MaxQueue/1500,
Tdscsize = 64, Nrxlog = 6,
Tcmdsize = 128, Nrx = 1<<Nrxlog,
Rbufsize = 3*1024,
Rdscsize = 8,
Tdscsize = 64,
Tcmdsize = 128,
}; };
/* registers */ /* registers */
@ -956,7 +961,7 @@ static int
txqready(void *arg) txqready(void *arg)
{ {
TXQ *q = arg; TXQ *q = arg;
return q->n < Ntx; return q->n < Ntxqmax;
} }
static char* static char*
@ -971,11 +976,11 @@ qcmd(Ctlr *ctlr, uint qid, uint code, uchar *data, int size, Block *block)
ilock(ctlr); ilock(ctlr);
q = &ctlr->tx[qid]; q = &ctlr->tx[qid];
while(q->n >= Ntx && !ctlr->broken){ while(q->n >= Ntxqmax && !ctlr->broken){
iunlock(ctlr); iunlock(ctlr);
qlock(q); qlock(q);
if(!waserror()){ if(!waserror()){
tsleep(q, txqready, q, 10); tsleep(q, txqready, q, 5);
poperror(); poperror();
} }
qunlock(q); qunlock(q);
@ -1144,6 +1149,7 @@ static uchar wpirates[] = {
0x80 | 72, 0x80 | 72,
0x80 | 96, 0x80 | 96,
0x80 | 108, 0x80 | 108,
0x80 | 2, 0x80 | 2,
0x80 | 4, 0x80 | 4,
0x80 | 11, 0x80 | 11,
@ -1164,6 +1170,7 @@ static struct {
{ 72, 0xb }, { 72, 0xb },
{ 96, 0x1 }, { 96, 0x1 },
{ 108, 0x3 }, { 108, 0x3 },
{ 2, 10 }, { 2, 10 },
{ 4, 20 }, { 4, 20 },
{ 11, 55 }, { 11, 55 },
@ -1436,12 +1443,12 @@ transmit(Wifi *wifi, Wnode *wn, Block *b)
p = wn->actrate; p = wn->actrate;
} }
} }
if(p >= wifi->rates)
rate = p - wifi->rates;
else
rate = 0;
qunlock(ctlr); qunlock(ctlr);
rate = 0;
if(p >= wpirates && p < &wpirates[nelem(ratetab)])
rate = p - wpirates;
memset(p = c, 0, sizeof(c)); memset(p = c, 0, sizeof(c));
put16(p, BLEN(b)), p += 2; put16(p, BLEN(b)), p += 2;
put16(p, 0), p += 2; /* lnext */ put16(p, 0), p += 2; /* lnext */
@ -1582,6 +1589,8 @@ wpiattach(Ether *edev)
error("wifi disabled by switch"); error("wifi disabled by switch");
if(ctlr->wifi == nil){ if(ctlr->wifi == nil){
qsetlimit(edev->oq, MaxQueue);
ctlr->wifi = wifiattach(edev, transmit); ctlr->wifi = wifiattach(edev, transmit);
ctlr->wifi->rates = wpirates; ctlr->wifi->rates = wpirates;
} }