summaryrefslogtreecommitdiffstats
path: root/sys/kern/tty_cons.c
diff options
context:
space:
mode:
authorjb <jb@FreeBSD.org>2006-11-01 04:54:51 +0000
committerjb <jb@FreeBSD.org>2006-11-01 04:54:51 +0000
commitd2bd8073567b9878a0f047164ede93eea2930207 (patch)
tree4ca8e0db1a4d979ac84b80de999f6b12bfe9e7f3 /sys/kern/tty_cons.c
parent978ee47c81472fd20aa0071b93d9fe4c7c9bbd7e (diff)
downloadFreeBSD-src-d2bd8073567b9878a0f047164ede93eea2930207.zip
FreeBSD-src-d2bd8073567b9878a0f047164ede93eea2930207.tar.gz
Add a cnputs() function to write a string to the console with
a lock to prevent interspersed strings written from different CPUs at the same time. To avoid putting a buffer on the stack or having to malloc one, space is incorporated in the per-cpu structure. The buffer size if 128 bytes; chosen because it's the next power of 2 size up from 80 characters. String writes to the console are buffered up the end of the line or until the buffer fills. Then the buffer is flushed to all console devices. Existing low level console output via cnputc() is unaffected by this change. ithread calls to log() are also unaffected to avoid blocking those threads. A minor change to the behaviour in a panic situation is that console output will still be buffered, but won't be written to a tty as before. This should prevent interspersed panic output as a number of CPUs panic before we end up single threaded running ddb. Reviewed by: scottl, jhb MFC after: 2 weeks
Diffstat (limited to 'sys/kern/tty_cons.c')
-rw-r--r--sys/kern/tty_cons.c25
1 files changed, 25 insertions, 0 deletions
diff --git a/sys/kern/tty_cons.c b/sys/kern/tty_cons.c
index f65f7ad..c0f8692 100644
--- a/sys/kern/tty_cons.c
+++ b/sys/kern/tty_cons.c
@@ -41,6 +41,8 @@ __FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <sys/systm.h>
+#include <sys/lock.h>
+#include <sys/mutex.h>
#include <sys/conf.h>
#include <sys/cons.h>
#include <sys/fcntl.h>
@@ -117,6 +119,8 @@ static u_char console_pausing; /* pause after each line during probe */
static char *console_pausestr=
"<pause; press any key to proceed to next line or '.' to end pause mode>";
struct tty *constty; /* pointer to console "window" tty */
+static struct mtx cnputs_mtx; /* Mutex for cnputs(). */
+static int use_cnputs_mtx = 0; /* != 0 if cnputs_mtx locking reqd. */
static void constty_timeout(void *arg);
@@ -639,6 +643,24 @@ cnputc(int c)
}
}
+void
+cnputs(char *p)
+{
+ int c;
+ int unlock_reqd = 0;
+
+ if (use_cnputs_mtx) {
+ mtx_lock_spin(&cnputs_mtx);
+ unlock_reqd = 1;
+ }
+
+ while ((c = *p++) != '\0')
+ cnputc(c);
+
+ if (unlock_reqd)
+ mtx_unlock_spin(&cnputs_mtx);
+}
+
static int consmsgbuf_size = 8192;
SYSCTL_INT(_kern, OID_AUTO, consmsgbuf_size, CTLFLAG_RW, &consmsgbuf_size, 0,
"");
@@ -708,6 +730,9 @@ cn_drvinit(void *unused)
{
make_dev(&cn_cdevsw, 0, UID_ROOT, GID_WHEEL, 0600, "console");
+
+ mtx_init(&cnputs_mtx, "cnputs_mtx", NULL, MTX_SPIN | MTX_NOWITNESS);
+ use_cnputs_mtx = 1;
}
SYSINIT(cndev, SI_SUB_DRIVERS, SI_ORDER_MIDDLE, cn_drvinit, NULL)
OpenPOWER on IntegriCloud