Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys - Introduce a sysctl to control the default tty queue si...



details:   https://anonhg.NetBSD.org/src/rev/768873d5f6ae
branches:  trunk
changeset: 769804:768873d5f6ae
user:      christos <christos%NetBSD.org@localhost>
date:      Sat Sep 24 00:05:38 2011 +0000

description:
- Introduce a sysctl to control the default tty queue size kern.tty.qsize,
  which defaults to 1024 as before.
- Add two ioctls TIOC{G,S}QSIZE to read and adjust the queue size on
  individual ptys.

NB: ttys (and ptys) still silently (or beepingly (IMAXBEL)) drop
    characters if the queue size is exceeded. I.e. you can appear
    to succeed writing to the {p,t}ty, but not all characters will
    have made it if the queue overflows.  CVS:

diffstat:

 sys/kern/tty.c      |  108 +++++++++++++++++++++++++++++++++++++++++++++++----
 sys/kern/tty_subr.c |    8 +-
 sys/sys/tty.h       |   17 ++++---
 sys/sys/ttycom.h    |    4 +-
 4 files changed, 115 insertions(+), 22 deletions(-)

diffs (295 lines):

diff -r 55af97365b84 -r 768873d5f6ae sys/kern/tty.c
--- a/sys/kern/tty.c    Fri Sep 23 23:57:06 2011 +0000
+++ b/sys/kern/tty.c    Sat Sep 24 00:05:38 2011 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: tty.c,v 1.247 2011/09/23 15:29:08 christos Exp $       */
+/*     $NetBSD: tty.c,v 1.248 2011/09/24 00:05:38 christos Exp $       */
 
 /*-
  * Copyright (c) 2008 The NetBSD Foundation, Inc.
@@ -63,7 +63,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: tty.c,v 1.247 2011/09/23 15:29:08 christos Exp $");
+__KERNEL_RCSID(0, "$NetBSD: tty.c,v 1.248 2011/09/24 00:05:38 christos Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -91,6 +91,7 @@
 #include <sys/intr.h>
 #include <sys/ioctl_compat.h>
 #include <sys/module.h>
+#include <sys/bitops.h>
 
 static int     ttnread(struct tty *);
 static void    ttyblock(struct tty *);
@@ -207,12 +208,77 @@
 
 static kauth_listener_t tty_listener;
 
-static struct sysctllog *kern_tkstat_sysctllog;
+#define        TTY_MINQSIZE    0x00400
+#define        TTY_MAXQSIZE    0x10000
+int tty_qsize = TTY_MINQSIZE;
+
+static int
+tty_get_qsize(int *qsize, int newsize)
+{
+       newsize = 1 << ilog2(newsize);  /* Make it a power of two */ 
+
+       if (newsize < TTY_MINQSIZE || newsize > TTY_MAXQSIZE)
+               return EINVAL;
+
+       *qsize = newsize;
+       return 0;
+}
 
 static void
-sysctl_kern_tkstat_setup(void)
+tty_set_qsize(struct tty *tp, int newsize)
 {
+       struct clist rawq, canq, outq;
+       struct clist orawq, ocanq, ooutq;
 
+       clalloc(&rawq, newsize, 1);
+       clalloc(&canq, newsize, 1);
+       clalloc(&outq, newsize, 0);
+
+       mutex_spin_enter(&tty_lock);
+
+       orawq = tp->t_rawq;
+       ocanq = tp->t_canq;
+       ooutq = tp->t_outq;
+
+       tp->t_qsize = newsize;
+       tp->t_rawq = rawq;
+       tp->t_canq = canq;
+       tp->t_outq = outq;
+
+       ttsetwater(tp);
+
+       mutex_spin_exit(&tty_lock);
+
+       clfree(&orawq);
+       clfree(&ocanq);
+       clfree(&ooutq);
+}
+
+static int
+sysctl_kern_tty_qsize(SYSCTLFN_ARGS)
+{
+       int newsize;
+       int error;
+       struct sysctlnode node;
+       node = *rnode;
+       node.sysctl_data = &newsize;
+
+       newsize = tty_qsize;
+       error = sysctl_lookup(SYSCTLFN_CALL(&node));
+       if (error || newp == NULL)
+               return error;
+
+
+       return tty_get_qsize(&tty_qsize, newsize);
+}
+
+static void
+sysctl_kern_tty_setup(void)
+{
+       const struct sysctlnode *rnode, *cnode;
+       struct sysctllog *kern_tkstat_sysctllog, *kern_tty_sysctllog;
+
+       kern_tkstat_sysctllog = NULL;
        sysctl_createv(&kern_tkstat_sysctllog, 0, NULL, NULL,
                       CTLFLAG_PERMANENT,
                       CTLTYPE_NODE, "kern", NULL,
@@ -250,6 +316,19 @@
                       SYSCTL_DESCR("Number of raw tty input characters"),
                       NULL, 0, &tk_rawcc, 0,
                       CTL_KERN, KERN_TKSTAT, KERN_TKSTAT_RAWCC, CTL_EOL);
+
+       kern_tty_sysctllog = NULL;
+       sysctl_createv(&kern_tty_sysctllog, 0, NULL, &rnode,
+                      CTLFLAG_PERMANENT,
+                      CTLTYPE_NODE, "tty", NULL,
+                      NULL, 0, NULL, 0,
+                      CTL_KERN, CTL_CREATE, CTL_EOL);
+       sysctl_createv(&kern_tty_sysctllog, 0, &rnode, &cnode,
+                      CTLFLAG_PERMANENT | CTLFLAG_READWRITE,
+                      CTLTYPE_INT, "qsize",
+                      SYSCTL_DESCR("TTY input and output queue size"),
+                      sysctl_kern_tty_qsize, 0, &tty_qsize, 0,
+                      CTL_CREATE, CTL_EOL);
 }
 
 int
@@ -319,6 +398,8 @@
                tp->t_flags = 0;
        }
        mutex_spin_exit(&tty_lock);
+       if (tp->t_qsize != tty_qsize)
+               tty_set_qsize(tp, tty_qsize);
        return (0);
 }
 
@@ -856,6 +937,7 @@
        case  TIOCSTAT:
        case  TIOCSTI:
        case  TIOCSWINSZ:
+       case  TIOCSQSIZE:
        case  TIOCLBIC:
        case  TIOCLBIS:
        case  TIOCLSET:
@@ -974,6 +1056,9 @@
        case TIOCGWINSZ:                /* get window size */
                *(struct winsize *)data = tp->t_winsize;
                break;
+       case TIOCGQSIZE:
+               *(int *)data = tp->t_qsize;
+               break;
        case FIOGETOWN:
                mutex_enter(proc_lock);
                if (tp->t_session != NULL && !isctty(p, tp)) {
@@ -1262,6 +1347,11 @@
                }
                mutex_spin_exit(&tty_lock);
                break;
+       case TIOCSQSIZE:
+               if ((error = tty_get_qsize(&s, *(int *)data)) == 0 &&
+                   s != tp->t_qsize)
+                       tty_set_qsize(tp, s);
+               return error;
        default:
                /* We may have to load the compat module for this. */
                for (;;) {
@@ -2694,15 +2784,15 @@
        tp = kmem_zalloc(sizeof(*tp), KM_SLEEP);
        callout_init(&tp->t_rstrt_ch, 0);
        callout_setfunc(&tp->t_rstrt_ch, ttrstrt, tp);
-       /* XXX: default to 1024 chars for now */
-       clalloc(&tp->t_rawq, 1024, 1);
+       tp->t_qsize = tty_qsize;
+       clalloc(&tp->t_rawq, tp->t_qsize, 1);
        cv_init(&tp->t_rawcv, "ttyraw");
        cv_init(&tp->t_rawcvf, "ttyrawf");
-       clalloc(&tp->t_canq, 1024, 1);
+       clalloc(&tp->t_canq, tp->t_qsize, 1);
        cv_init(&tp->t_cancv, "ttycan");
        cv_init(&tp->t_cancvf, "ttycanf");
        /* output queue doesn't need quoting */
-       clalloc(&tp->t_outq, 1024, 0);
+       clalloc(&tp->t_outq, tp->t_qsize, 0);
        cv_init(&tp->t_outcv, "ttyout");
        cv_init(&tp->t_outcvf, "ttyoutf");
        /* Set default line discipline. */
@@ -2817,7 +2907,7 @@
        tty_listener = kauth_listen_scope(KAUTH_SCOPE_DEVICE,
            tty_listener_cb, NULL);
 
-       sysctl_kern_tkstat_setup();
+       sysctl_kern_tty_setup();
 }
 
 /*
diff -r 55af97365b84 -r 768873d5f6ae sys/kern/tty_subr.c
--- a/sys/kern/tty_subr.c       Fri Sep 23 23:57:06 2011 +0000
+++ b/sys/kern/tty_subr.c       Sat Sep 24 00:05:38 2011 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: tty_subr.c,v 1.39 2009/11/14 13:18:41 dsl Exp $        */
+/*     $NetBSD: tty_subr.c,v 1.40 2011/09/24 00:05:38 christos Exp $   */
 
 /*
  * Copyright (c) 1993, 1994 Theo de Raadt
@@ -29,7 +29,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: tty_subr.c,v 1.39 2009/11/14 13:18:41 dsl Exp $");
+__KERNEL_RCSID(0, "$NetBSD: tty_subr.c,v 1.40 2011/09/24 00:05:38 christos Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -263,7 +263,7 @@
 #if defined(DIAGNOSTIC) || 1
                        printf("putc: required clalloc\n");
 #endif
-                       if (clalloc(clp, 1024, 1)) {
+                       if (clalloc(clp, clp->c_cn, 1)) {
 out:
                                splx(s);
                                return -1;
@@ -352,7 +352,7 @@
 #if defined(DIAGNOSTIC) || 1
                        printf("b_to_q: required clalloc\n");
 #endif
-                       if (clalloc(clp, 1024, 1))
+                       if (clalloc(clp, clp->c_cn, 1))
                                goto out;
                }
                clp->c_cf = clp->c_cl = clp->c_cs;
diff -r 55af97365b84 -r 768873d5f6ae sys/sys/tty.h
--- a/sys/sys/tty.h     Fri Sep 23 23:57:06 2011 +0000
+++ b/sys/sys/tty.h     Sat Sep 24 00:05:38 2011 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: tty.h,v 1.89 2011/09/23 15:29:09 christos Exp $        */
+/*     $NetBSD: tty.h,v 1.90 2011/09/24 00:05:38 christos Exp $        */
 
 /*-
  * Copyright (c) 2008 The NetBSD Foundation, Inc.
@@ -126,6 +126,7 @@
        int     t_state;                /* Device and driver (TS*) state. */
        int     t_wopen;                /* Processes waiting for open. */
        int     t_flags;                /* Tty flags. */
+       int     t_qsize;                /* Tty character queue size */
        struct  pgrp *t_pgrp;           /* Foreground process group. */
        struct  session *t_session;     /* Enclosing session. */
        struct  selinfo t_rsel;         /* Tty read/oob select. */
@@ -141,8 +142,8 @@
        void    *t_sc;                  /* XXX: net/if_sl.c:sl_softc. */
        short   t_column;               /* Tty output column. */
        short   t_rocount, t_rocol;     /* Tty. */
-       short   t_hiwat;                /* High water mark. */
-       short   t_lowat;                /* Low water mark. */
+       int     t_hiwat;                /* High water mark. */
+       int     t_lowat;                /* Low water mark. */
        short   t_gen;                  /* Generation number. */
        sigset_t t_sigs[TTYSIG_COUNT];  /* Pending signals */
        int     t_sigcount;             /* # pending signals */
@@ -162,13 +163,13 @@
 
 #define        TTMASK  15
 #define        OBUFSIZ 100
-#define        TTYHOG  1024
+#define        TTYHOG  tp->t_qsize
 
 #ifdef _KERNEL
-#define        TTMAXHIWAT      roundup(2048, TTROUND)
-#define        TTMINHIWAT      roundup(100, TTROUND)
-#define        TTMAXLOWAT      256
-#define        TTMINLOWAT      32
+#define        TTMAXHIWAT      roundup(tp->t_qsize << 1, 64)
+#define        TTMINHIWAT      roundup(tp->t_qsize >> 3, 64)
+#define        TTMAXLOWAT      (tp->t_qsize >> 2)
+#define        TTMINLOWAT      (tp->t_qsize >> 5)
 #define        TTROUND         64
 #endif /* _KERNEL */
 
diff -r 55af97365b84 -r 768873d5f6ae sys/sys/ttycom.h
--- a/sys/sys/ttycom.h  Fri Sep 23 23:57:06 2011 +0000
+++ b/sys/sys/ttycom.h  Sat Sep 24 00:05:38 2011 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: ttycom.h,v 1.18 2005/12/11 12:25:21 christos Exp $     */
+/*     $NetBSD: ttycom.h,v 1.19 2011/09/24 00:05:39 christos Exp $     */
 
 /*-
  * Copyright (c) 1982, 1986, 1990, 1993, 1994
@@ -153,6 +153,8 @@
 #define TIOCGRANTPT     _IO('t', 71)                   /* grantpt(3) */
 #define TIOCPTSNAME     _IOR('t', 72, struct ptmget)   /* ptsname(3) */
 
+#define TIOCSQSIZE      _IOW('t', 128, int)    /* set queue size */
+#define TIOCGQSIZE      _IOR('t', 129, int)    /* get queue size */
 
 #define        TTYDISC         0               /* termios tty line discipline */
 #define        TABLDISC        3               /* tablet discipline */



Home | Main Index | Thread Index | Old Index