~kris/9p

9hist

1d4bb27834523e4f5c839bb2c04d03c408d404f7 — David du Colombier 24 years ago b61ca91
Plan 9 from Bell Labs 2002-07-14
3 files changed, 154 insertions(+), 32 deletions(-)

M ip/tcp.c
M pc/etherga620.c
M port/qio.c
M ip/tcp.c => ip/tcp.c +1 -1
@@ 576,7 576,7 @@ static void
tcpcreate(Conv *c)
{
	c->rq = qopen(QMAX, Qcoalesce, tcpacktimer, c);
	c->wq = qopen(4*QMAX, Qkick, tcpkick, c);
	c->wq = qopen((3*QMAX)/2, Qkick, tcpkick, c);
}

static void

M pc/etherga620.c => pc/etherga620.c +142 -29
@@ 24,13 24,6 @@
#include "etherif.h"
#include "etherga620fw.h"

enum {					/* Compile-time options */
	DoMhcCheck	= 1,
	DoCoalUpdateOnly= 1,
	DoHardwareCksum	= 0,
	DoCountTicks	= 1,
};

enum {
	Mhc		= 0x0040,	/* Miscellaneous Host Control */
	Mlc		= 0x0044,	/* Miscellaneous Local Control */


@@ 259,9 252,6 @@ typedef struct Ctlr {

	uchar	ea[Eaddrlen];

	int	interrupts;
	uvlong	ticks;

	int*	nic;
	Gib*	gib;



@@ 284,6 274,17 @@ typedef struct Ctlr {
	int	epi[2];			/* Event Producer Index */
	int	rrrpi[2];		/* Receive Return Ring Producer Index */
	int	sci[3];			/* Send Consumer Index ([2] is host) */

	int	interrupts;		/* statistics */
	uvlong	ticks;

	int	coalupdateonly;		/* tuning */
	int	hardwarecksum;
	int	rct;			/* Receive Coalesce Ticks */
	int	sct;			/* Send Coalesce Ticks */
	int	st;			/* Stat Ticks */
	int	smcbd;			/* Send Max. Coalesced BDs */
	int	rmcbd;			/* Receive Max. Coalesced BDs */
} Ctlr;

static Ctlr* ctlrhead;


@@ 342,7 343,13 @@ ga620ifstat(Ether* edev, void* a, long n, ulong offset)
	}

	l += snprint(p+l, READSTR-l, "interrupts: %ud\n", ctlr->interrupts);
	snprint(p+l, READSTR-l, "ticks: %llud\n", ctlr->ticks);
	l += snprint(p+l, READSTR-l, "ticks: %llud\n", ctlr->ticks);
	l += snprint(p+l, READSTR-l, "coalupdateonly: %d\n", ctlr->coalupdateonly);
	l += snprint(p+l, READSTR-l, "hardwarecksum: %d\n", ctlr->hardwarecksum);
	l += snprint(p+l, READSTR-l, "rct: %d\n", ctlr->rct);
	l += snprint(p+l, READSTR-l, "sct: %d\n", ctlr->sct);
	l += snprint(p+l, READSTR-l, "smcbd: %d\n", ctlr->smcbd);
	snprint(p+l, READSTR-l, "rmcbd: %d\n", ctlr->rmcbd);

	n = readstr(offset, a, n, p);
	free(p);


@@ 350,6 357,111 @@ ga620ifstat(Ether* edev, void* a, long n, ulong offset)
	return n;
}

static long
ga620ctl(Ether* edev, void* buf, long n)
{
	char *p;
	Cmdbuf *cb;
	Ctlr *ctlr;
	int control, i, r;

	ctlr = edev->ctlr;
	if(ctlr == nil)
		error(Enonexist);
	r = 0;
	cb = parsecmd(buf, n);
	if(cb->nf < 2)
		r = -1;
	else if(cistrcmp(cb->f[0], "coalupdateonly") == 0){
		if(cistrcmp(cb->f[1], "off") == 0){
			control = ctlr->gib->srcb.control;
			control &= ~CoalUpdateOnly;
			ctlr->gib->srcb.control = control;
		}
		else if(cistrcmp(cb->f[1], "on") == 0){
			control = ctlr->gib->srcb.control;
			control |= CoalUpdateOnly;
			ctlr->gib->srcb.control = control;
		}
		else
			r = -1;
	}
	else if(cistrcmp(cb->f[0], "hardwarecksum") == 0){
		if(cistrcmp(cb->f[1], "off") == 0){
			control = ctlr->gib->srcb.control;
			control &= ~(TcpUdpCksum|NoPseudoHdrCksum);
			ctlr->gib->srcb.control = control;

			control = ctlr->gib->rsrcb.control;
			control &= ~(TcpUdpCksum|NoPseudoHdrCksum);
			ctlr->gib->rsrcb.control = control;
		}
		else if(cistrcmp(cb->f[1], "on") == 0){
			control = ctlr->gib->srcb.control;
			control |= (TcpUdpCksum|NoPseudoHdrCksum);
			ctlr->gib->srcb.control = control;

			control = ctlr->gib->rsrcb.control;
			control |= (TcpUdpCksum|NoPseudoHdrCksum);
			ctlr->gib->rsrcb.control = control;
		}
		else
			r = -1;
	}
	else if(cistrcmp(cb->f[0], "rct") == 0){
		i = strtol(cb->f[1], &p, 0);
		if(i < 0 || p == cb->f[1])
			r = -1;
		else{
			ctlr->rct = i;
			csr32w(ctlr, Rct, ctlr->rct);
		}
	}
	else if(cistrcmp(cb->f[0], "sct") == 0){
		i = strtol(cb->f[1], &p, 0);
		if(i < 0 || p == cb->f[1])
			r = -1;
		else{
			ctlr->sct = i;
			csr32w(ctlr, Sct, ctlr->sct);
		}
	}
	else if(cistrcmp(cb->f[0], "st") == 0){
		i = strtol(cb->f[1], &p, 0);
		if(i < 0 || p == cb->f[1])
			r = -1;
		else{
			ctlr->st = i;
			csr32w(ctlr, St, ctlr->st);
		}
	}
	else if(cistrcmp(cb->f[0], "smcbd") == 0){
		i = strtol(cb->f[1], &p, 0);
		if(i < 0 || p == cb->f[1])
			r = -1;
		else{
			ctlr->smcbd = i;
			csr32w(ctlr, SmcBD, ctlr->smcbd);
		}
	}
	else if(cistrcmp(cb->f[0], "rmcbd") == 0){
		i = strtol(cb->f[1], &p, 0);
		if(i < 0 || p == cb->f[1])
			r = -1;
		else{
			ctlr->rmcbd = i;
			csr32w(ctlr, RmcBD, ctlr->rmcbd);
		}
	}
	else
		r = -1;

	free(cb);
	if(r == 0)
		return n;
	return r;
}

static void
ga620transmit(Ether* edev)
{


@@ 494,12 606,9 @@ ga620interrupt(Ureg*, void* arg)
	edev = arg;
	ctlr = edev->ctlr;

	if(DoMhcCheck){
		if(!(csr32r(ctlr, Mhc) & Is))
			return;
	}
	if(DoCountTicks)
		rdtsc(&tsc0);
	if(!(csr32r(ctlr, Mhc) & Is))
		return;
	rdtsc(&tsc0);

	ctlr->interrupts++;
	csr32w(ctlr, Hi, 1);


@@ 518,10 627,8 @@ ga620interrupt(Ureg*, void* arg)

	csr32w(ctlr, Hi, 0);

	if(DoCountTicks){
		rdtsc(&tsc1);
		ctlr->ticks += tsc1-tsc0;
	}
	rdtsc(&tsc1);
	ctlr->ticks += tsc1-tsc0;
}

static void


@@ 627,11 734,11 @@ ga620init(Ether* edev)
	 */
	ctlr->sr = malign(sizeof(Sbd)*Nsr);
	sethost64(&ctlr->gib->srcb.addr, ctlr->sr);
	if(DoHardwareCksum)
	if(ctlr->hardwarecksum)
		flags = TcpUdpCksum|NoPseudoHdrCksum|HostRing;
	else 
		flags = HostRing;
	if(DoCoalUpdateOnly) 
	if(ctlr->coalupdateonly) 
		flags |= CoalUpdateOnly;
	ctlr->gib->srcb.control = (Nsr<<16)|flags;
	sethost64(&ctlr->gib->scp, ctlr->sci);


@@ 643,7 750,7 @@ ga620init(Ether* edev)
	 */
	ctlr->rsr = malign(sizeof(Rbd)*Nrsr);
	sethost64(&ctlr->gib->rsrcb.addr, ctlr->rsr);
	if(DoHardwareCksum)
	if(ctlr->hardwarecksum)
		flags = TcpUdpCksum|NoPseudoHdrCksum;
	else
		flags = 0;


@@ 695,11 802,16 @@ ga620init(Ether* edev)
	 * These defaults are based on the tuning hints in the Alteon
	 * Host/NIC Software Interface Definition and example software.
	 */
	csr32w(ctlr, Rct, 120);
	csr32w(ctlr, Sct, 400);
	csr32w(ctlr, St, 1000000);
	csr32w(ctlr, SmcBD, 60);
	csr32w(ctlr, RmcBD, 25);
	ctlr->rct = 100;
	csr32w(ctlr, Rct, ctlr->rct);
	ctlr->sct = 0;
	csr32w(ctlr, Sct, ctlr->sct);
	ctlr->st = 1000000;
	csr32w(ctlr, St, ctlr->st);
	ctlr->smcbd = Nsr/4;
	csr32w(ctlr, SmcBD, ctlr->smcbd);
	ctlr->rmcbd = 6;
	csr32w(ctlr, RmcBD, ctlr->rmcbd);

	/*
	 * Enable DMA Assist Logic.


@@ 1064,6 1176,7 @@ ga620pnp(Ether* edev)
	edev->transmit = ga620transmit;
	edev->interrupt = ga620interrupt;
	edev->ifstat = ga620ifstat;
	edev->ctl = ga620ctl;
	edev->shutdown = ga620shutdown;

	edev->arg = edev;

M port/qio.c => port/qio.c +11 -2
@@ 460,8 460,17 @@ qdiscard(Queue *q, int len)
		}
	}

	/* if writer flow controlled, restart */
	if((q->state & Qflow) && q->len < q->limit/2){
	/*
	 *  if writer flow controlled, restart
	 *
	 *  This used to be
	 *	q->len < q->limit/2
	 *  but it slows down tcp too much for certain write sizes.
	 *  I really don't understand it completely.  It may be
	 *  due to the queue draining so fast that the transmission
	 *  stalls waiting for the app to produce more data.  - presotto
	 */
	if((q->state & Qflow) && q->len < q->limit){
		q->state &= ~Qflow;
		dowakeup = 1;
	} else