diff options
-rw-r--r-- | sys/kern/subr_clist.c | 191 | ||||
-rw-r--r-- | sys/kern/tty.c | 43 | ||||
-rw-r--r-- | sys/kern/tty_subr.c | 191 | ||||
-rw-r--r-- | sys/net/if_ppp.c | 22 | ||||
-rw-r--r-- | sys/net/if_sl.c | 41 | ||||
-rw-r--r-- | sys/sys/tty.h | 15 |
6 files changed, 339 insertions, 164 deletions
diff --git a/sys/kern/subr_clist.c b/sys/kern/subr_clist.c index 46a8f1e..a261533 100644 --- a/sys/kern/subr_clist.c +++ b/sys/kern/subr_clist.c @@ -6,7 +6,7 @@ * of this software, nor does the author assume any responsibility * for damages incurred with its use. * - * $Id: tty_subr.c,v 1.7 1994/09/25 19:33:50 phk Exp $ + * $Id: tty_subr.c,v 1.8 1994/10/30 19:43:49 bde Exp $ */ /* @@ -22,17 +22,25 @@ struct cblock *cfreelist = 0; int cfreecount = 0; +static int cslushcount; +static int ctotcount; #ifndef INITIAL_CBLOCKS -#define INITIAL_CBLOCKS 50 +#define INITIAL_CBLOCKS 50 #endif -#define MBUF_DIAG -#ifdef MBUF_DIAG -void -print_nblocks() +static void cblock_alloc_cblocks __P((int number)); +static void cblock_free_cblocks __P((int number)); + +#define CBLOCK_DIAG +#ifdef CBLOCK_DIAG +static void +cbstat() { - printf("There are currently %d bytes in cblocks\n", cfreecount); + printf( + "tot = %d (active = %d, free = %d (reserved = %d, slush = %d))\n", + ctotcount * CBSIZE, ctotcount * CBSIZE - cfreecount, cfreecount, + cfreecount - cslushcount * CBSIZE, cslushcount * CBSIZE); } #endif @@ -44,10 +52,13 @@ clist_init() { /* * Allocate an initial base set of cblocks as a 'slush'. - * We allocate more with each ttyopen(). + * We allocate non-slush cblocks with each initial ttyopen() and + * deallocate them with each ttyclose(). + * We should adjust the slush allocation. This can't be done in + * the i/o routines because they are sometimes called from + * interrupt handlers when it may be unsafe to call malloc(). */ - cblock_alloc_cblocks(INITIAL_CBLOCKS); - return; + cblock_alloc_cblocks(cslushcount = INITIAL_CBLOCKS); } /* @@ -60,10 +71,8 @@ cblock_alloc() struct cblock *cblockp; cblockp = cfreelist; - if (!cblockp) { - /* XXX should syslog a message that we're out! */ - return (0); - } + if (cblockp == NULL) + panic("clist reservation botch"); cfreelist = cblockp->c_next; cblockp->c_next = NULL; cfreecount -= CBSIZE; @@ -80,13 +89,12 @@ cblock_free(cblockp) cblockp->c_next = cfreelist; cfreelist = cblockp; cfreecount += CBSIZE; - return; } /* * Allocate some cblocks for the cfreelist queue. */ -void +static void cblock_alloc_cblocks(number) int number; { @@ -94,36 +102,66 @@ cblock_alloc_cblocks(number) struct cblock *tmp; for (i = 0; i < number; ++i) { - tmp = malloc(sizeof(struct cblock), M_TTYS, M_NOWAIT); - if (!tmp) { - printf("cblock_alloc_cblocks: could not malloc cblock"); - break; - } + tmp = malloc(sizeof(struct cblock), M_TTYS, M_WAITOK); bzero((char *)tmp, sizeof(struct cblock)); cblock_free(tmp); } - return; + ctotcount += number; +} + +/* + * Set the cblock allocation policy for a a clist. + * Must be called at spltty(). + */ +void +clist_alloc_cblocks(clistp, ccmax, ccreserved) + struct clist *clistp; + int ccmax; + int ccreserved; +{ + int dcbr; + + clistp->c_cbmax = roundup(ccmax, CBSIZE) / CBSIZE; + dcbr = roundup(ccreserved, CBSIZE) / CBSIZE - clistp->c_cbreserved; + if (dcbr >= 0) + cblock_alloc_cblocks(dcbr); + else { + if (clistp->c_cbreserved + dcbr < clistp->c_cbcount) + dcbr = clistp->c_cbcount - clistp->c_cbreserved; + cblock_free_cblocks(-dcbr); + } + clistp->c_cbreserved += dcbr; } /* * Free some cblocks from the cfreelist queue back to the * system malloc pool. */ -void +static void cblock_free_cblocks(number) int number; { int i; - struct cblock *tmp; - for (i = 0; i < number; ++i) { - tmp = cblock_alloc(); - if (tmp == NULL) - return; - free(tmp, M_TTYS); - } + for (i = 0; i < number; ++i) + free(cblock_alloc(), M_TTYS); + ctotcount -= number; } +/* + * Free the cblocks reserved for a clist. + * Must be called at spltty(). + */ +void +clist_free_cblocks(clistp) + struct clist *clistp; +{ + if (clistp->c_cbcount != 0) + panic("freeing active clist cblocks"); + cblock_free_cblocks(clistp->c_cbreserved); + clistp->c_cbmax = 0; + clistp->c_cbreserved = 0; +} /* * Get a character from the head of a clist. @@ -168,6 +206,8 @@ getc(clistp) clistp->c_cf = clistp->c_cl = NULL; } cblock_free(cblockp); + if (--clistp->c_cbcount >= clistp->c_cbreserved) + ++cslushcount; } } @@ -217,6 +257,8 @@ q_to_b(clistp, dest, amount) clistp->c_cf = clistp->c_cl = NULL; } cblock_free(cblockp); + if (--clistp->c_cbcount >= clistp->c_cbreserved) + ++cslushcount; } } @@ -260,11 +302,12 @@ ndflush(clistp, amount) clistp->c_cf = clistp->c_cl = NULL; } cblock_free(cblockp); + if (--clistp->c_cbcount >= clistp->c_cbreserved) + ++cslushcount; } } splx(s); - return; } /* @@ -281,28 +324,30 @@ putc(chr, clistp) s = spltty(); - cblockp = (struct cblock *)((long)clistp->c_cl & ~CROUND); - if (clistp->c_cl == NULL) { + if (clistp->c_cbreserved < 1) + panic("putc to a clist with no reserved cblocks"); cblockp = cblock_alloc(); - if (cblockp) { - clistp->c_cf = clistp->c_cl = cblockp->c_info; - clistp->c_cc = 0; - } else { - splx(s); - return (-1); - } + clistp->c_cbcount = 1; + clistp->c_cf = clistp->c_cl = cblockp->c_info; + clistp->c_cc = 0; } else { + cblockp = (struct cblock *)((long)clistp->c_cl & ~CROUND); if (((long)clistp->c_cl & CROUND) == 0) { struct cblock *prev = (cblockp - 1); - cblockp = cblock_alloc(); - if (cblockp) { - prev->c_next = cblockp; - clistp->c_cl = cblockp->c_info; - } else { - splx(s); - return (-1); + + if (clistp->c_cbcount >= clistp->c_cbreserved) { + if (clistp->c_cbcount >= clistp->c_cbmax + || cslushcount <= 0) { + splx(s); + return (-1); + } + --cslushcount; } + cblockp = cblock_alloc(); + clistp->c_cbcount++; + prev->c_next = cblockp; + clistp->c_cl = cblockp->c_info; } } @@ -337,6 +382,13 @@ b_to_q(src, amount, clistp) int startbit, endbit, num_between, numc; int s; + /* + * Avoid allocating an initial cblock and then not using it. + * c_cc == 0 must imply c_cbount == 0. + */ + if (amount <= 0) + return (amount); + s = spltty(); /* @@ -344,14 +396,12 @@ b_to_q(src, amount, clistp) * then get one. */ if (clistp->c_cl == NULL) { + if (clistp->c_cbreserved < 1) + panic("b_to_q to a clist with no reserved cblocks"); cblockp = cblock_alloc(); - if (cblockp) { - clistp->c_cf = clistp->c_cl = cblockp->c_info; - clistp->c_cc = 0; - } else { - splx(s); - return (amount); - } + clistp->c_cbcount = 1; + clistp->c_cf = clistp->c_cl = cblockp->c_info; + clistp->c_cc = 0; } else { cblockp = (struct cblock *)((long)clistp->c_cl & ~CROUND); } @@ -362,14 +412,19 @@ b_to_q(src, amount, clistp) */ if (((long)clistp->c_cl & CROUND) == 0) { struct cblock *prev = cblockp - 1; - cblockp = cblock_alloc(); - if (cblockp) { - prev->c_next = cblockp; - clistp->c_cl = cblockp->c_info; - } else { - splx(s); - return (amount); + + if (clistp->c_cbcount >= clistp->c_cbreserved) { + if (clistp->c_cbcount >= clistp->c_cbmax + || cslushcount <= 0) { + splx(s); + return (amount); + } + --cslushcount; } + cblockp = cblock_alloc(); + clistp->c_cbcount++; + prev->c_next = cblockp; + clistp->c_cl = cblockp->c_info; } /* @@ -515,6 +570,8 @@ unputc(clistp) */ clistp->c_cl = (char *)(cbp+1); cblock_free(cblockp); + if (--clistp->c_cbcount >= clistp->c_cbreserved) + ++cslushcount; cbp->c_next = NULL; } } @@ -526,6 +583,8 @@ unputc(clistp) if ((clistp->c_cc == 0) && clistp->c_cl) { cblockp = (struct cblock *)((long)clistp->c_cl & ~CROUND); cblock_free(cblockp); + if (--clistp->c_cbcount >= clistp->c_cbreserved) + ++cslushcount; clistp->c_cf = clistp->c_cl = NULL; } @@ -546,19 +605,25 @@ catq(src_clistp, dest_clistp) s = spltty(); /* * If the destination clist is empty (has no cblocks atttached), + * and there are no possible complications with the resource counters, * then we simply assign the current clist to the destination. */ - if (!dest_clistp->c_cf) { + if (!dest_clistp->c_cf + && src_clistp->c_cbcount <= src_clistp->c_cbmax + && src_clistp->c_cbcount <= dest_clistp->c_cbmax) { dest_clistp->c_cf = src_clistp->c_cf; dest_clistp->c_cl = src_clistp->c_cl; src_clistp->c_cf = src_clistp->c_cl = NULL; dest_clistp->c_cc = src_clistp->c_cc; src_clistp->c_cc = 0; + dest_clistp->c_cbcount = src_clistp->c_cbcount; + src_clistp->c_cbcount = 0; splx(s); return; } + splx(s); /* @@ -567,6 +632,4 @@ catq(src_clistp, dest_clistp) */ while ((chr = getc(src_clistp)) != -1) putc(chr, dest_clistp); - - return; } diff --git a/sys/kern/tty.c b/sys/kern/tty.c index dca12f9..d15110f 100644 --- a/sys/kern/tty.c +++ b/sys/kern/tty.c @@ -36,7 +36,7 @@ * SUCH DAMAGE. * * @(#)tty.c 8.8 (Berkeley) 1/21/94 - * $Id: tty.c,v 1.13 1994/11/01 22:23:29 bde Exp $ + * $Id: tty.c,v 1.14 1994/11/26 18:54:25 bde Exp $ */ #include <sys/param.h> @@ -72,10 +72,6 @@ char ttybuf[] = "ttybuf"; char ttyin[] = "ttyin"; char ttyout[] = "ttyout"; -#ifndef CBLOCKS_PER_TTY -#define CBLOCKS_PER_TTY 10 -#endif - /* * Table with character classes and parity. The 8th bit indicates parity, * the 7th bit indicates the character is an alphameric or underscore (for @@ -169,12 +165,17 @@ ttyopen(device, tp) if (!ISSET(tp->t_state, TS_ISOPEN)) { SET(tp->t_state, TS_ISOPEN); bzero(&tp->t_winsize, sizeof(tp->t_winsize)); - /* - * Add some cblocks to the clistfree pool. - */ - cblock_alloc_cblocks(CBLOCKS_PER_TTY); } CLR(tp->t_state, TS_WOPEN); + + /* + * Initialize or restore a cblock allocation policy suitable for + * the standard line discipline. + */ + clist_alloc_cblocks(&tp->t_canq, TTYHOG, 512); + clist_alloc_cblocks(&tp->t_outq, TTMAXHIWAT + 200, 512); + clist_alloc_cblocks(&tp->t_rawq, TTYHOG, 512); + splx(s); return (0); } @@ -189,23 +190,22 @@ ttyclose(tp) register struct tty *tp; { extern struct tty *constty; /* Temporary virtual console. */ + int s; + s = spltty(); if (constty == tp) constty = NULL; ttyflush(tp, FREAD | FWRITE); + clist_free_cblocks(&tp->t_canq); + clist_free_cblocks(&tp->t_outq); + clist_free_cblocks(&tp->t_rawq); tp->t_gen++; tp->t_pgrp = NULL; tp->t_session = NULL; - /* - * If the tty has not already been closed, free the cblocks - * that were allocated in ttyopen() back to the system malloc - * pool. - */ - if (ISSET(tp->t_state, (TS_ISOPEN|TS_WOPEN))) - cblock_free_cblocks(CBLOCKS_PER_TTY); tp->t_state = 0; + splx(s); return (0); } @@ -1209,9 +1209,16 @@ ttypend(tp) CLR(tp->t_lflag, PENDIN); SET(tp->t_state, TS_TYPEN); + /* + * XXX this assumes too much about clist internals. It may even + * fail if the cblock slush pool is empty. We can't allocate more + * cblocks here because we are called from an interrupt handler + * and clist_alloc_cblocks() can wait. + */ tq = tp->t_rawq; - tp->t_rawq.c_cc = 0; - tp->t_rawq.c_cf = tp->t_rawq.c_cl = 0; + bzero(&tp->t_rawq, sizeof tp->t_rawq); + tp->t_rawq.c_cbmax = tq.c_cbmax; + tp->t_rawq.c_cbreserved = tq.c_cbreserved; while ((c = getc(&tq)) >= 0) ttyinput(c, tp); CLR(tp->t_state, TS_TYPEN); diff --git a/sys/kern/tty_subr.c b/sys/kern/tty_subr.c index 46a8f1e..a261533 100644 --- a/sys/kern/tty_subr.c +++ b/sys/kern/tty_subr.c @@ -6,7 +6,7 @@ * of this software, nor does the author assume any responsibility * for damages incurred with its use. * - * $Id: tty_subr.c,v 1.7 1994/09/25 19:33:50 phk Exp $ + * $Id: tty_subr.c,v 1.8 1994/10/30 19:43:49 bde Exp $ */ /* @@ -22,17 +22,25 @@ struct cblock *cfreelist = 0; int cfreecount = 0; +static int cslushcount; +static int ctotcount; #ifndef INITIAL_CBLOCKS -#define INITIAL_CBLOCKS 50 +#define INITIAL_CBLOCKS 50 #endif -#define MBUF_DIAG -#ifdef MBUF_DIAG -void -print_nblocks() +static void cblock_alloc_cblocks __P((int number)); +static void cblock_free_cblocks __P((int number)); + +#define CBLOCK_DIAG +#ifdef CBLOCK_DIAG +static void +cbstat() { - printf("There are currently %d bytes in cblocks\n", cfreecount); + printf( + "tot = %d (active = %d, free = %d (reserved = %d, slush = %d))\n", + ctotcount * CBSIZE, ctotcount * CBSIZE - cfreecount, cfreecount, + cfreecount - cslushcount * CBSIZE, cslushcount * CBSIZE); } #endif @@ -44,10 +52,13 @@ clist_init() { /* * Allocate an initial base set of cblocks as a 'slush'. - * We allocate more with each ttyopen(). + * We allocate non-slush cblocks with each initial ttyopen() and + * deallocate them with each ttyclose(). + * We should adjust the slush allocation. This can't be done in + * the i/o routines because they are sometimes called from + * interrupt handlers when it may be unsafe to call malloc(). */ - cblock_alloc_cblocks(INITIAL_CBLOCKS); - return; + cblock_alloc_cblocks(cslushcount = INITIAL_CBLOCKS); } /* @@ -60,10 +71,8 @@ cblock_alloc() struct cblock *cblockp; cblockp = cfreelist; - if (!cblockp) { - /* XXX should syslog a message that we're out! */ - return (0); - } + if (cblockp == NULL) + panic("clist reservation botch"); cfreelist = cblockp->c_next; cblockp->c_next = NULL; cfreecount -= CBSIZE; @@ -80,13 +89,12 @@ cblock_free(cblockp) cblockp->c_next = cfreelist; cfreelist = cblockp; cfreecount += CBSIZE; - return; } /* * Allocate some cblocks for the cfreelist queue. */ -void +static void cblock_alloc_cblocks(number) int number; { @@ -94,36 +102,66 @@ cblock_alloc_cblocks(number) struct cblock *tmp; for (i = 0; i < number; ++i) { - tmp = malloc(sizeof(struct cblock), M_TTYS, M_NOWAIT); - if (!tmp) { - printf("cblock_alloc_cblocks: could not malloc cblock"); - break; - } + tmp = malloc(sizeof(struct cblock), M_TTYS, M_WAITOK); bzero((char *)tmp, sizeof(struct cblock)); cblock_free(tmp); } - return; + ctotcount += number; +} + +/* + * Set the cblock allocation policy for a a clist. + * Must be called at spltty(). + */ +void +clist_alloc_cblocks(clistp, ccmax, ccreserved) + struct clist *clistp; + int ccmax; + int ccreserved; +{ + int dcbr; + + clistp->c_cbmax = roundup(ccmax, CBSIZE) / CBSIZE; + dcbr = roundup(ccreserved, CBSIZE) / CBSIZE - clistp->c_cbreserved; + if (dcbr >= 0) + cblock_alloc_cblocks(dcbr); + else { + if (clistp->c_cbreserved + dcbr < clistp->c_cbcount) + dcbr = clistp->c_cbcount - clistp->c_cbreserved; + cblock_free_cblocks(-dcbr); + } + clistp->c_cbreserved += dcbr; } /* * Free some cblocks from the cfreelist queue back to the * system malloc pool. */ -void +static void cblock_free_cblocks(number) int number; { int i; - struct cblock *tmp; - for (i = 0; i < number; ++i) { - tmp = cblock_alloc(); - if (tmp == NULL) - return; - free(tmp, M_TTYS); - } + for (i = 0; i < number; ++i) + free(cblock_alloc(), M_TTYS); + ctotcount -= number; } +/* + * Free the cblocks reserved for a clist. + * Must be called at spltty(). + */ +void +clist_free_cblocks(clistp) + struct clist *clistp; +{ + if (clistp->c_cbcount != 0) + panic("freeing active clist cblocks"); + cblock_free_cblocks(clistp->c_cbreserved); + clistp->c_cbmax = 0; + clistp->c_cbreserved = 0; +} /* * Get a character from the head of a clist. @@ -168,6 +206,8 @@ getc(clistp) clistp->c_cf = clistp->c_cl = NULL; } cblock_free(cblockp); + if (--clistp->c_cbcount >= clistp->c_cbreserved) + ++cslushcount; } } @@ -217,6 +257,8 @@ q_to_b(clistp, dest, amount) clistp->c_cf = clistp->c_cl = NULL; } cblock_free(cblockp); + if (--clistp->c_cbcount >= clistp->c_cbreserved) + ++cslushcount; } } @@ -260,11 +302,12 @@ ndflush(clistp, amount) clistp->c_cf = clistp->c_cl = NULL; } cblock_free(cblockp); + if (--clistp->c_cbcount >= clistp->c_cbreserved) + ++cslushcount; } } splx(s); - return; } /* @@ -281,28 +324,30 @@ putc(chr, clistp) s = spltty(); - cblockp = (struct cblock *)((long)clistp->c_cl & ~CROUND); - if (clistp->c_cl == NULL) { + if (clistp->c_cbreserved < 1) + panic("putc to a clist with no reserved cblocks"); cblockp = cblock_alloc(); - if (cblockp) { - clistp->c_cf = clistp->c_cl = cblockp->c_info; - clistp->c_cc = 0; - } else { - splx(s); - return (-1); - } + clistp->c_cbcount = 1; + clistp->c_cf = clistp->c_cl = cblockp->c_info; + clistp->c_cc = 0; } else { + cblockp = (struct cblock *)((long)clistp->c_cl & ~CROUND); if (((long)clistp->c_cl & CROUND) == 0) { struct cblock *prev = (cblockp - 1); - cblockp = cblock_alloc(); - if (cblockp) { - prev->c_next = cblockp; - clistp->c_cl = cblockp->c_info; - } else { - splx(s); - return (-1); + + if (clistp->c_cbcount >= clistp->c_cbreserved) { + if (clistp->c_cbcount >= clistp->c_cbmax + || cslushcount <= 0) { + splx(s); + return (-1); + } + --cslushcount; } + cblockp = cblock_alloc(); + clistp->c_cbcount++; + prev->c_next = cblockp; + clistp->c_cl = cblockp->c_info; } } @@ -337,6 +382,13 @@ b_to_q(src, amount, clistp) int startbit, endbit, num_between, numc; int s; + /* + * Avoid allocating an initial cblock and then not using it. + * c_cc == 0 must imply c_cbount == 0. + */ + if (amount <= 0) + return (amount); + s = spltty(); /* @@ -344,14 +396,12 @@ b_to_q(src, amount, clistp) * then get one. */ if (clistp->c_cl == NULL) { + if (clistp->c_cbreserved < 1) + panic("b_to_q to a clist with no reserved cblocks"); cblockp = cblock_alloc(); - if (cblockp) { - clistp->c_cf = clistp->c_cl = cblockp->c_info; - clistp->c_cc = 0; - } else { - splx(s); - return (amount); - } + clistp->c_cbcount = 1; + clistp->c_cf = clistp->c_cl = cblockp->c_info; + clistp->c_cc = 0; } else { cblockp = (struct cblock *)((long)clistp->c_cl & ~CROUND); } @@ -362,14 +412,19 @@ b_to_q(src, amount, clistp) */ if (((long)clistp->c_cl & CROUND) == 0) { struct cblock *prev = cblockp - 1; - cblockp = cblock_alloc(); - if (cblockp) { - prev->c_next = cblockp; - clistp->c_cl = cblockp->c_info; - } else { - splx(s); - return (amount); + + if (clistp->c_cbcount >= clistp->c_cbreserved) { + if (clistp->c_cbcount >= clistp->c_cbmax + || cslushcount <= 0) { + splx(s); + return (amount); + } + --cslushcount; } + cblockp = cblock_alloc(); + clistp->c_cbcount++; + prev->c_next = cblockp; + clistp->c_cl = cblockp->c_info; } /* @@ -515,6 +570,8 @@ unputc(clistp) */ clistp->c_cl = (char *)(cbp+1); cblock_free(cblockp); + if (--clistp->c_cbcount >= clistp->c_cbreserved) + ++cslushcount; cbp->c_next = NULL; } } @@ -526,6 +583,8 @@ unputc(clistp) if ((clistp->c_cc == 0) && clistp->c_cl) { cblockp = (struct cblock *)((long)clistp->c_cl & ~CROUND); cblock_free(cblockp); + if (--clistp->c_cbcount >= clistp->c_cbreserved) + ++cslushcount; clistp->c_cf = clistp->c_cl = NULL; } @@ -546,19 +605,25 @@ catq(src_clistp, dest_clistp) s = spltty(); /* * If the destination clist is empty (has no cblocks atttached), + * and there are no possible complications with the resource counters, * then we simply assign the current clist to the destination. */ - if (!dest_clistp->c_cf) { + if (!dest_clistp->c_cf + && src_clistp->c_cbcount <= src_clistp->c_cbmax + && src_clistp->c_cbcount <= dest_clistp->c_cbmax) { dest_clistp->c_cf = src_clistp->c_cf; dest_clistp->c_cl = src_clistp->c_cl; src_clistp->c_cf = src_clistp->c_cl = NULL; dest_clistp->c_cc = src_clistp->c_cc; src_clistp->c_cc = 0; + dest_clistp->c_cbcount = src_clistp->c_cbcount; + src_clistp->c_cbcount = 0; splx(s); return; } + splx(s); /* @@ -567,6 +632,4 @@ catq(src_clistp, dest_clistp) */ while ((chr = getc(src_clistp)) != -1) putc(chr, dest_clistp); - - return; } diff --git a/sys/net/if_ppp.c b/sys/net/if_ppp.c index fac8eca..826bcc6 100644 --- a/sys/net/if_ppp.c +++ b/sys/net/if_ppp.c @@ -69,7 +69,7 @@ * Paul Mackerras (paulus@cs.anu.edu.au). */ -/* $Id: if_ppp.c,v 1.6 1994/11/01 22:18:34 wollman Exp $ */ +/* $Id: if_ppp.c,v 1.7 1994/11/23 08:29:44 ugen Exp $ */ /* from if_sl.c,v 1.11 84/10/04 12:54:47 rick Exp */ #include "ppp.h" @@ -127,6 +127,7 @@ #define CCOUNT(q) ((q)->c_cc) #define PPP_HIWAT 400 /* Don't start a new packet if HIWAT on que */ +#define PPP_MAXMTU 16384 /* Largest MTU we allow */ struct ppp_softc ppp_softc[NPPP]; @@ -319,6 +320,15 @@ pppopen(dev, tp) tp->t_sc = (caddr_t) sc; ttyflush(tp, FREAD | FWRITE); + /* + * XXX we fudge t_canq to avoid providing pppselect() and FIONREAD. + * I hope one char is enough. The following actually gives CBSIZE + * chars. + */ + clist_alloc_cblocks(&tp->t_canq, 1, 1); + clist_alloc_cblocks(&tp->t_outq, sc->sc_if.if_mtu + PPP_HIWAT, + sc->sc_if.if_mtu + PPP_HIWAT); + clist_alloc_cblocks(&tp->t_rawq, 0, 0); return (0); } @@ -339,6 +349,7 @@ pppclose(tp, flag) ttywflush(tp); s = splimp(); /* paranoid; splnet probably ok */ + clist_free_cblocks(&tp->t_outq); tp->t_line = 0; sc = (struct ppp_softc *)tp->t_sc; if (sc != NULL) { @@ -1494,7 +1505,14 @@ pppioctl(ifp, cmd, data) case SIOCSIFMTU: if (error = suser(p->p_ucred, &p->p_acflag)) return (error); - sc->sc_if.if_mtu = ifr->ifr_mtu; + if (ifr->ifr_mtu > PPP_MAXMTU) + error = EINVAL; + else { + sc->sc_if.if_mtu = ifr->ifr_mtu; + clist_alloc_cblocks(&((struct tty *) sc->sc_devp)->t_outq, + sc->sc_if.if_mtu + PPP_HIWAT, + sc->sc_if.if_mtu + PPP_HIWAT); + } break; case SIOCGIFMTU: diff --git a/sys/net/if_sl.c b/sys/net/if_sl.c index 61b2be2..915bc4b 100644 --- a/sys/net/if_sl.c +++ b/sys/net/if_sl.c @@ -31,7 +31,7 @@ * SUCH DAMAGE. * * @(#)if_sl.c 8.6 (Berkeley) 2/1/94 - * $Id: if_sl.c,v 1.8 1994/10/05 21:22:45 wollman Exp $ + * $Id: if_sl.c,v 1.9 1994/10/08 01:40:22 phk Exp $ */ /* @@ -127,7 +127,8 @@ Huh? Slip without inet? * role in interactive performance than the MTU. The MTU can be changed * at any time to suit the specific environment with ifconfig(8), and * its maximum value is defined as SLTMAX. SLTMAX must not be so large - * that it would overflow the stack if BPF is configured. + * that it would overflow the stack if BPF is configured (XXX; if_ppp.c + * handles this better). * * SLIP_HIWAT is the amount of data that will be queued 'downstream' * of us (i.e., in clists waiting to be picked up by the tty output @@ -155,13 +156,10 @@ Huh? Slip without inet? #ifndef SLMTU #define SLMTU 552 /* default MTU */ #endif -#define SLTMAX 1500 /* maximum MTU */ +#define SLTMAX 1500 /* maximum MTU */ #define SLIP_HIWAT roundup(50,CBSIZE) #define CLISTRESERVE 1024 /* Can't let clists get too low */ -/* add this many cblocks to the pool */ -#define CLISTEXTRA ((SLRMAX+SLTMAX) / CBSIZE) - /* * SLIP ABORT ESCAPE MECHANISM: * (inspired by HAYES modem escape arrangement) @@ -276,7 +274,21 @@ slopen(dev, tp) sc->sc_if.if_baudrate = tp->t_ospeed; ttyflush(tp, FREAD | FWRITE); - cblock_alloc_cblocks(CLISTEXTRA); + /* + * We don't use t_canq or t_rawq, so reduce their + * cblock resources to 0. Reserve enough cblocks + * for t_outq to guarantee that we can fit a full + * packet if the SLIP_HIWAT check allows slstart() + * to loop. Use the same value for the cblock + * limit since the reserved blocks should always + * be enough. Reserving cblocks probably makes + * the CLISTRESERVE check unnecessary and wasteful. + */ + clist_alloc_cblocks(&tp->t_canq, 0, 0); + clist_alloc_cblocks(&tp->t_outq, + sc->sc_if.if_mtu + SLIP_HIWAT, + sc->sc_if.if_mtu + SLIP_HIWAT); + clist_alloc_cblocks(&tp->t_rawq, 0, 0); return (0); } @@ -296,7 +308,13 @@ slclose(tp,flag) int s; ttywflush(tp); + /* + * XXX the placement of the following spl is misleading. tty + * interrupts must be blocked across line discipline switches + * and throughout closes to avoid races. + */ s = splimp(); /* actually, max(spltty, splnet) */ + clist_free_cblocks(&tp->t_outq); tp->t_line = 0; sc = (struct sl_softc *)tp->t_sc; if (sc != NULL) { @@ -307,7 +325,6 @@ slclose(tp,flag) sc->sc_ep = 0; sc->sc_mp = 0; sc->sc_buf = 0; - cblock_free_cblocks(CLISTEXTRA); } splx(s); return 0; @@ -863,10 +880,14 @@ slioctl(ifp, cmd, data) /* * Set the interface MTU. */ - if (ifr->ifr_mtu > SLTMAX) { + if (ifr->ifr_mtu > SLTMAX) error = EINVAL; - } else { + else { ifp->if_mtu = ifr->ifr_mtu; + clist_alloc_cblocks( + &sl_softc[ifp->if_unit].sc_ttyp->t_outq, + ifp->if_mtu + SLIP_HIWAT, + ifp->if_mtu + SLIP_HIWAT); } break; diff --git a/sys/sys/tty.h b/sys/sys/tty.h index 5899625..275c7f9 100644 --- a/sys/sys/tty.h +++ b/sys/sys/tty.h @@ -36,11 +36,11 @@ * SUCH DAMAGE. * * @(#)tty.h 8.6 (Berkeley) 1/21/94 - * $Id: tty.h,v 1.5 1994/09/13 16:03:35 davidg Exp $ + * $Id: tty.h,v 1.6 1994/10/02 17:25:02 phk Exp $ */ #ifndef _SYS_TTY_H_ -#define _SYS_TTY_H_ +#define _SYS_TTY_H_ #include <sys/termios.h> #include <sys/select.h> /* For struct selinfo. */ @@ -51,6 +51,9 @@ */ struct clist { int c_cc; /* Number of characters in the clist. */ + int c_cbcount; /* Number of cblocks. */ + int c_cbmax; /* Max # cblocks allowed for this clist. */ + int c_cbreserved; /* # cblocks reserved for this clist. */ char *c_cf; /* Pointer to the first cblock. */ char *c_cl; /* Pointer to the last cblock. */ }; @@ -179,10 +182,10 @@ extern struct ttychars ttydefaults; /* Symbolic sleep message strings. */ extern char ttyin[], ttyout[], ttopen[], ttclos[], ttybg[], ttybuf[]; -void cblock_alloc_cblocks __P((int)); -void cblock_free_cblocks __P((int)); int b_to_q __P((char *cp, int cc, struct clist *q)); void catq __P((struct clist *from, struct clist *to)); +void clist_alloc_cblocks __P((struct clist *q, int ccmax, int ccres)); +void clist_free_cblocks __P((struct clist *q)); /* void clist_init __P((void)); */ /* defined in systm.h for main() */ int getc __P((struct clist *q)); void ndflush __P((struct clist *q, int cc)); @@ -220,6 +223,6 @@ int ttysleep __P((struct tty *tp, void *chan, int pri, char *wmesg, int timeout)); int ttywait __P((struct tty *tp)); int ttywflush __P((struct tty *tp)); -#endif +#endif /* KERNEL */ -#endif +#endif /* !_SYS_TTY_H_ */ |