From 511cd4dc31b14ba392858a523bb3a4cbf37044e8 Mon Sep 17 00:00:00 2001 From: cinap_lenrek Date: Fri, 10 Jan 2025 22:50:24 +0000 Subject: [PATCH] devether: handle input queue size for bypass mode when the interface is bypassed, use a fixed large receive queue (1MB) and ignore speed/link state changes. also, zap the mac table when the link state changes. --- sys/src/9/port/devether.c | 51 ++++++++++++++++++++++++++------------- sys/src/9/port/netif.c | 18 ++++++++------ 2 files changed, 44 insertions(+), 25 deletions(-) diff --git a/sys/src/9/port/devether.c b/sys/src/9/port/devether.c index 316d30fde..317452a2d 100644 --- a/sys/src/9/port/devether.c +++ b/sys/src/9/port/devether.c @@ -21,6 +21,9 @@ static Ether *etherprobe(int cardno, int ctlrno, char *conf); static void dmatproxy(Block*, int, uchar*, DMAT*); +static int etheroqsize(Ether*); +static int etheriqsize(Ether*); + Chan* etherattach(char* spec) { @@ -88,10 +91,17 @@ static void etherclose(Chan* chan) { Ether *ether = etherxx[chan->dev]; + Netfile *f; - if(NETTYPE(chan->qid.path) == Ndataqid && ether->f[NETID(chan->qid.path)]->bridge) - memset(ether->mactab, 0, sizeof(ether->mactab)); - + if(NETTYPE(chan->qid.path) == Ndataqid){ + f = ether->f[NETID(chan->qid.path)]; + if(f->bridge || f->bypass) + memset(ether->mactab, 0, sizeof(ether->mactab)); + if(f->bypass){ + qsetlimit(ether->oq, etheroqsize(ether)); + netifsetlimit(ether, etheriqsize(ether)); + } + } netifclose(ether, chan); } @@ -295,8 +305,14 @@ etherwrite(Chan* chan, void* buf, long n, vlong) if(NETTYPE(chan->qid.path) != Ndataqid) { nn = netifwrite(ether, chan, buf, n); - if(nn >= 0) + if(nn >= 0){ + /* ignore mbps and use large input queue size when bypassed */ + if(ether->f[NETID(chan->qid.path)]->bypass){ + qflush(ether->oq); + netifsetlimit(ether, MB); + } return nn; + } cb = parsecmd(buf, n); if(cb->f[0] && strcmp(cb->f[0], "nonblocking") == 0){ if(cb->nf <= 1) @@ -380,7 +396,7 @@ addethercard(char* t, int (*r)(Ether*)) } static int -etherqueuesize(Ether *ether) +etheroqsize(Ether *ether) { int b, q; @@ -392,6 +408,12 @@ etherqueuesize(Ether *ether) return q; } +static int +etheriqsize(Ether *ether) +{ + return etheroqsize(ether) * 2; +} + static Ether* etherprobe(int cardno, int ctlrno, char *conf) { @@ -445,7 +467,7 @@ Nope: print("#l%d: %s: %dMbps port 0x%lluX irq %d ea %E\n", ctlrno, ether->type, ether->mbps, (uvlong)ether->port, ether->irq, ether->ea); - q = etherqueuesize(ether); + q = etheroqsize(ether); if(ether->oq == nil){ ether->oq = qopen(q, Qmsg, 0, 0); if(ether->oq == nil) @@ -453,7 +475,7 @@ Nope: } else { qsetlimit(ether->oq, q); } - netifinit(ether, ether->name, Ntypes, q*2); + netifinit(ether, ether->name, Ntypes, etheriqsize(ether)); ether->alen = Eaddrlen; memmove(ether->addr, ether->ea, Eaddrlen); memset(ether->bcast, 0xFF, Eaddrlen); @@ -464,17 +486,13 @@ Nope: void ethersetspeed(Ether *ether, int mbps) { - int q; - if(ether->mbps == mbps) return; ether->mbps = mbps; - - if(mbps <= 0 || ether->f == nil || ether->oq == nil) + if(mbps <= 0 || ether->f == nil || ether->oq == nil || ether->bypass) return; - q = etherqueuesize(ether); - qsetlimit(ether->oq, q); - netifsetlimit(ether, q*2); + qsetlimit(ether->oq, etheroqsize(ether)); + netifsetlimit(ether, etheriqsize(ether)); } void @@ -484,10 +502,9 @@ ethersetlink(Ether *ether, int link) if(!!ether->link == link) return; ether->link = link; - - if(ether->f == nil) + if(ether->f == nil || ether->bypass) return; - + memset(ether->mactab, 0, sizeof(ether->mactab)); if(link) print("#l%d: %s: link up: %dMbps\n", ether->ctlrno, ether->type, ether->mbps); diff --git a/sys/src/9/port/netif.c b/sys/src/9/port/netif.c index 0239fa201..0e1d2dfcd 100644 --- a/sys/src/9/port/netif.c +++ b/sys/src/9/port/netif.c @@ -39,14 +39,16 @@ netifsetlimit(Netif *nif, int limit) int i; qlock(nif); - nif->limit = limit; - for(i = 0; i < nif->nfile; i++){ - f = nif->f[i]; - if(f == nil) - continue; - qlock(f); - qsetlimit(f->in, nif->limit); - qunlock(f); + if(nif->limit != limit){ + nif->limit = limit; + for(i = 0; i < nif->nfile; i++){ + f = nif->f[i]; + if(f == nil) + continue; + qlock(f); + qsetlimit(f->in, nif->limit); + qunlock(f); + } } qunlock(nif); }