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