From 00cfabff6e3a5c4a50984c6de1336fb8fa59729d Mon Sep 17 00:00:00 2001 From: David du Colombier <0intro@gmail.com> Date: Fri, 14 Feb 2003 00:00:00 +0000 Subject: [PATCH] Plan 9 from Bell Labs 2003-02-14 --- ip/ip.c | 5 ++++ ip/tcp.c | 58 +++++++++++++++++++++++++------------------ pc/devarch.c | 67 +++++++++++++++++++++++--------------------------- port/devproc.c | 16 ++++++++++++ port/proc.c | 3 ++- 5 files changed, 88 insertions(+), 61 deletions(-) diff --git a/ip/ip.c b/ip/ip.c index 213c5911395da1108b04a13473371b9b03dff2f4..2e15afde1344997cdb2b6d6ef5a24c69788b9534 100644 --- a/ip/ip.c +++ b/ip/ip.c @@ -231,6 +231,7 @@ ipoput4(Fs *f, Block *bp, int gating, int ttl, int tos) int lid, len, seglen, chunk, dlen, blklen, offset, medialen; Route *r, *sr; IP *ip; + Proto *pr; ip = f->ip; @@ -262,6 +263,10 @@ ipoput4(Fs *f, Block *bp, int gating, int ttl, int tos) if(r == nil){ ip->stats[OutNoRoutes]++; netlog(f, Logip, "no interface %V\n", eh->dst); + if(!gating){ + freeblist(bp); + error("no route"); + } goto free; } diff --git a/ip/tcp.c b/ip/tcp.c index 31069fdb2c7d137413811ea2aa694b6524a9df48..9c737c6d2966b34b7d6af1a77420fd07ef980eb3 100644 --- a/ip/tcp.c +++ b/ip/tcp.c @@ -1319,27 +1319,30 @@ tcphangup(Conv *s) if(waserror()) return commonerror(); if(s->raddr != 0) { - seg.flags = RST | ACK; - seg.ack = tcb->rcv.nxt; - tcb->rcv.una = 0; - seg.seq = tcb->snd.ptr; - seg.wnd = 0; - seg.urg = 0; - seg.mss = 0; - seg.ws = 0; - switch(s->ipversion) { - case V4: - tcb->protohdr.tcp4hdr.vihl = IP_VER4; - hbp = htontcp4(&seg, nil, &tcb->protohdr.tcp4hdr, tcb); - ipoput4(s->p->f, hbp, 0, s->ttl, s->tos); - break; - case V6: - tcb->protohdr.tcp6hdr.vcf[0] = IP_VER6; - hbp = htontcp6(&seg, nil, &tcb->protohdr.tcp6hdr, tcb); - ipoput6(s->p->f, hbp, 0, s->ttl, s->tos); - break; - default: - panic("tcphangup: version %d", s->ipversion); + if(!waserror()){ + seg.flags = RST | ACK; + seg.ack = tcb->rcv.nxt; + tcb->rcv.una = 0; + seg.seq = tcb->snd.ptr; + seg.wnd = 0; + seg.urg = 0; + seg.mss = 0; + seg.ws = 0; + switch(s->ipversion) { + case V4: + tcb->protohdr.tcp4hdr.vihl = IP_VER4; + hbp = htontcp4(&seg, nil, &tcb->protohdr.tcp4hdr, tcb); + ipoput4(s->p->f, hbp, 0, s->ttl, s->tos); + break; + case V6: + tcb->protohdr.tcp6hdr.vcf[0] = IP_VER6; + hbp = htontcp6(&seg, nil, &tcb->protohdr.tcp6hdr, tcb); + ipoput6(s->p->f, hbp, 0, s->ttl, s->tos); + break; + default: + panic("tcphangup: version %d", s->ipversion); + } + poperror(); } } localclose(s, nil); @@ -2408,6 +2411,11 @@ tcpoutput(Conv *s) tpriv = s->p->priv; version = s->ipversion; + if(waserror()){ + localclose(s, up->errstr); + return; + } + for(msgs = 0; msgs < 100; msgs++) { tcb = (Tcpctl*)s->ptcl; @@ -2415,7 +2423,7 @@ tcpoutput(Conv *s) case Listen: case Closed: case Finwait2: - return; + goto out; } /* force an ack when a window has opened up */ @@ -2542,7 +2550,7 @@ tcpoutput(Conv *s) hbp = htontcp4(&seg, bp, &tcb->protohdr.tcp4hdr, tcb); if(hbp == nil) { freeblist(bp); - return; + goto out; } break; case V6: @@ -2550,7 +2558,7 @@ tcpoutput(Conv *s) hbp = htontcp6(&seg, bp, &tcb->protohdr.tcp6hdr, tcb); if(hbp == nil) { freeblist(bp); - return; + goto out; } break; default: @@ -2596,6 +2604,8 @@ tcpoutput(Conv *s) qlock(s); } } +out: + poperror(); } /* diff --git a/pc/devarch.c b/pc/devarch.c index 39917be5fffc0cfbba2f26e0350fff49f57bceb9..fba008061d3ce732fd153f3bf4f0c7fd158d9d4d 100644 --- a/pc/devarch.c +++ b/pc/devarch.c @@ -110,9 +110,9 @@ ioinit(void) ioalloc(0x10000, 1, 0, "dummy"); /* * Someone needs to explain why this was here... - */ ioalloc(0x0fff, 1, 0, "dummy"); // i82557 is at 0x1000, the dummy // entry is needed for swappable devs. + */ if ((excluded = getconf("ioexclude")) != nil) { char *s; @@ -391,8 +391,7 @@ archread(Chan *c, void *a, long n, vlong offset) break; } - /* allocate a buffer to avoid page faults in the loop */ - if((buf = malloc(n+1)) == nil) /* +1 for the NUL */ + if((buf = malloc(n)) == nil) error(Enomem); p = buf; n = n/Linelen; @@ -404,7 +403,7 @@ archread(Chan *c, void *a, long n, vlong offset) continue; if(strcmp(m->tag, "dummy") == 0) break; - snprint(p, Linelen+1, "%8lux %8lux %-12.12s\n", m->start, m->end-1, m->tag); + sprint(p, "%8lux %8lux %-12.12s\n", m->start, m->end-1, m->tag); p += Linelen; n--; } @@ -624,9 +623,11 @@ cpuidprint(void) * figure out: * - cpu type * - whether or not we have a TSC (cycle counter) - * - whether or not is supports page size extensions + * - whether or not it supports page size extensions + * (if so turn it on) + * - whether or not it supports machine check exceptions * (if so turn it on) - * - whether or not is supports machine check exceptions + * - whether or not it supports the page global flag * (if so turn it on) */ int @@ -669,11 +670,11 @@ cpuidentify(void) guesscpuhz(t->aalcycles); /* - * If machine check exception or page size extensions are supported - * enable them in CR4 and clear any other set extensions. + * If machine check exception, page size extensions or page global bit + * are supported enable them in CR4 and clear any other set extensions. * If machine check was enabled clear out any lingering status. */ - if(m->cpuiddx & 0x88){ + if(m->cpuiddx & 0x2088){ cr4 = 0; if(m->cpuiddx & 0x08) cr4 |= 0x10; /* page size extensions */ @@ -688,38 +689,32 @@ cpuidentify(void) rdmsr(0x01, &mct); } } + + /* + * Detect whether the chip supports the global bit + * in page directory and page table entries. When set + * in a particular entry, it means ``don't bother removing + * this from the TLB when CR3 changes.'' + * + * We flag all kernel pages with this bit. Doing so lessens the + * overhead of switching processes on bare hardware, + * even more so on VMware. See mmu.c:/^memglobal. + * + * For future reference, should we ever need to do a + * full TLB flush, it can be accomplished by clearing + * the PGE bit in CR4, writing to CR3, and then + * restoring the PGE bit. + */ + if(m->cpuiddx & 0x2000){ + cr4 |= 0x80; /* page global enable bit */ + m->havepge = 1; + } + putcr4(cr4); if(m->cpuiddx & 0x80) rdmsr(0x01, &mct); } - /* - * Detect whether the chip supports the global bit - * in page directory and page table entries. When set - * in a particular entry, it means ``don't bother removing - * this from the TLB when CR3 changes.'' - * - * We flag all kernel pages with this bit. Doing so lessens the - * overhead of switching processes on bare hardware, - * even more so on VMware. See mmu.c:/^memglobal. - * - * This feature exists on Intel Pentium Pro and later - * processors. Presumably the AMD processors have - * a similar notion, but I can't find it in the meager - * documentation I've tried. - * - * For future reference, should we ever need to do a - * full TLB flush, it can be accomplished by clearing - * the PGE bit in CR4, writing to CR3, and then - * restoring the PGE bit. - */ - if(tab==x86intel && t->family >= 6){ - cr4 = getcr4(); - cr4 |= 0x80; /* page global enable bit */ - putcr4(cr4); - m->havepge = 1; - } - cputype = t; return t->family; } diff --git a/port/devproc.c b/port/devproc.c index 5ec84cc1c0ef6a9a27b1687c905e3eb35863888d..22481649b6e993b621ebe0c3b4474d2fd867c2bd 100644 --- a/port/devproc.c +++ b/port/devproc.c @@ -45,6 +45,8 @@ enum CMstop, CMwaitstop, CMwired, + CMfair, + CMunfair, }; #define STATSIZE (2*KNAMELEN+12+9*12) @@ -91,6 +93,8 @@ Cmdtab proccmd[] = { CMstop, "stop", 1, CMwaitstop, "waitstop", 1, CMwired, "wired", 2, + CMfair, "fair", 1, + CMunfair, "unfair", 1, }; /* Segment type from portdat.h */ @@ -118,6 +122,8 @@ Segment* txt2data(Proc*, Segment*); int procstopped(void*); void mntscan(Mntwalk*, Proc*); +extern int unfair; + static int procgen(Chan *c, char *name, Dirtab *tab, int, int s, Dir *dp) { @@ -1191,6 +1197,16 @@ procctlreq(Proc *p, char *va, int n) case CMwired: procwired(p, atoi(cb->f[1])); break; + case CMfair: + if(!iseve()) + error(Eperm); + unfair = 0; + break; + case CMunfair: + if(!iseve()) + error(Eperm); + unfair = 1; + break; } poperror(); diff --git a/port/proc.c b/port/proc.c index 27e3322a5b776311f66119c488e0685957375393..8d999a68590729d5d7802be1f3ba305dacd36ef2 100644 --- a/port/proc.c +++ b/port/proc.c @@ -9,6 +9,7 @@ int nrdy; Ref noteidalloc; long delayedscheds; /* statistics */ +int unfair; /* unfair scheduling */ static Ref pidalloc; @@ -228,7 +229,7 @@ loop: */ spllo(); for(;;){ - if((++(m->fairness) & 0x3) == 0){ + if(!unfair && (++(m->fairness) & 0x3) == 0){ /* * once in a while, run process that's been waiting longest * regardless of movetime