Turn console printf buffering into a kernel option and only on

by default for sun4v where it is absolutely required.

This change moves the buffer from struct pcpu to the stack to avoid
using the critical section which created a LOR in a couple of cases
due to interaction with the tty code and kqueue. The LOR can't be
fixed with the critical section and the pcpu buffer can't be used
without the critical section.

Putting the buffer on the stack was my initial solution, but it was
pointed out that the stress on the stack might cause problems
depending on the call path. We don't have a way of creating tests
for those possible cases, so it's best to leave this as an option
for the time being. In time we may get enough data to enable this
option more generally.
This commit is contained in:
John Birrell 2006-11-30 04:17:05 +00:00
parent b3ef1381d4
commit e0b651251d
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=164760
9 changed files with 27 additions and 24 deletions

View File

@ -185,7 +185,6 @@ ASSYM(PC_CURTHREAD, offsetof(struct pcpu, pc_curthread));
ASSYM(PC_FPCURTHREAD, offsetof(struct pcpu, pc_fpcurthread));
ASSYM(PC_IDLETHREAD, offsetof(struct pcpu, pc_idlethread));
ASSYM(PC_CURPCB, offsetof(struct pcpu, pc_curpcb));
ASSYM(PC_CONS_BUFR, offsetof(struct pcpu, pc_cons_bufr));
ASSYM(PC_CPUID, offsetof(struct pcpu, pc_cpuid));
ASSYM(PC_SCRATCH_RSP, offsetof(struct pcpu, pc_scratch_rsp));
ASSYM(PC_CURPMAP, offsetof(struct pcpu, pc_curpmap));

View File

@ -69,7 +69,6 @@ ASSYM(PCB_R12, offsetof(struct pcb, un_32.pcb32_r12));
ASSYM(PCB_PC, offsetof(struct pcb, un_32.pcb32_pc));
ASSYM(PCB_SP, offsetof(struct pcb, un_32.pcb32_sp));
ASSYM(PC_CONS_BUFR, offsetof(struct pcpu, pc_cons_bufr));
ASSYM(PC_CURPCB, offsetof(struct pcpu, pc_curpcb));
ASSYM(PC_CURTHREAD, offsetof(struct pcpu, pc_curthread));
ASSYM(M_LEN, offsetof(struct mbuf, m_len));

View File

@ -709,6 +709,9 @@ SC_PIXEL_MODE opt_syscons.h
SC_RENDER_DEBUG opt_syscons.h
SC_TWOBUTTON_MOUSE opt_syscons.h
# options for printf
PRINTF_BUFR_SIZE opt_printf.h
# kbd options
KBD_DISABLE_KEYMAP_LOAD opt_kbd.h
KBD_INSTALL_CDEV opt_kbd.h

View File

@ -195,7 +195,6 @@ ASSYM(PC_COMMON_TSSD, offsetof(struct pcpu, pc_common_tssd));
ASSYM(PC_TSS_GDT, offsetof(struct pcpu, pc_tss_gdt));
ASSYM(PC_FSGS_GDT, offsetof(struct pcpu, pc_fsgs_gdt));
ASSYM(PC_CURRENTLDT, offsetof(struct pcpu, pc_currentldt));
ASSYM(PC_CONS_BUFR, offsetof(struct pcpu, pc_cons_bufr));
ASSYM(PC_CPUID, offsetof(struct pcpu, pc_cpuid));
ASSYM(PC_CURPMAP, offsetof(struct pcpu, pc_curpmap));
ASSYM(PC_PRIVATE_TSS, offsetof(struct pcpu, pc_private_tss));

View File

@ -38,6 +38,7 @@
__FBSDID("$FreeBSD$");
#include "opt_ddb.h"
#include "opt_printf.h"
#include <sys/param.h>
#include <sys/systm.h>
@ -291,18 +292,24 @@ printf(const char *fmt, ...)
va_list ap;
struct putchar_arg pca;
int retval;
critical_enter();
#ifdef PRINTF_BUFR_SIZE
char bufr[PRINTF_BUFR_SIZE];
#endif
va_start(ap, fmt);
pca.tty = NULL;
pca.flags = TOCONS | TOLOG;
pca.pri = -1;
pca.p_bufr = (char *) PCPU_PTR(cons_bufr);
#ifdef PRINTF_BUFR_SIZE
pca.p_bufr = bufr;
pca.p_next = pca.p_bufr;
pca.n_bufr = PCPU_CONS_BUFR;
pca.remain = PCPU_CONS_BUFR;
pca.n_bufr = sizeof(bufr);
pca.remain = sizeof(bufr);
*pca.p_next = '\0';
#else
/* Don't buffer console output. */
pca.p_bufr = NULL;
#endif
retval = kvprintf(fmt, putchar, &pca, 10, ap);
va_end(ap);
@ -314,8 +321,6 @@ printf(const char *fmt, ...)
if (!panicstr)
msgbuftrigger = 1;
critical_exit();
return (retval);
}
@ -324,17 +329,23 @@ vprintf(const char *fmt, va_list ap)
{
struct putchar_arg pca;
int retval;
critical_enter();
#ifdef PRINTF_BUFR_SIZE
char bufr[PRINTF_BUFR_SIZE];
#endif
pca.tty = NULL;
pca.flags = TOCONS | TOLOG;
pca.pri = -1;
pca.p_bufr = (char *) PCPU_PTR(cons_bufr);
#ifdef PRINTF_BUFR_SIZE
pca.p_bufr = bufr;
pca.p_next = pca.p_bufr;
pca.n_bufr = PCPU_CONS_BUFR;
pca.remain = PCPU_CONS_BUFR;
pca.n_bufr = sizeof(bufr);
pca.remain = sizeof(bufr);
*pca.p_next = '\0';
#else
/* Don't buffer console output. */
pca.p_bufr = NULL;
#endif
retval = kvprintf(fmt, putchar, &pca, 10, ap);
@ -345,8 +356,6 @@ vprintf(const char *fmt, va_list ap)
if (!panicstr)
msgbuftrigger = 1;
critical_exit();
return (retval);
}

View File

@ -55,7 +55,6 @@
#include <machine/pmap.h>
#include <machine/sigframe.h>
ASSYM(PC_CONS_BUFR, offsetof(struct pcpu, pc_cons_bufr));
ASSYM(PC_CURTHREAD, offsetof(struct pcpu, pc_curthread));
ASSYM(PC_CURPCB, offsetof(struct pcpu, pc_curpcb));
ASSYM(PC_CURPMAP, offsetof(struct pcpu, pc_curpmap));

View File

@ -198,7 +198,6 @@ ASSYM(HASH_ENTRY_SHIFT, HASH_ENTRY_SHIFT);
ASSYM(V_INTR, offsetof(struct vmmeter, v_intr));
ASSYM(PC_CONS_BUFR, offsetof(struct pcpu, pc_cons_bufr));
ASSYM(PC_CURTHREAD, offsetof(struct pcpu, pc_curthread));
ASSYM(PC_CURPCB, offsetof(struct pcpu, pc_curpcb));
ASSYM(PC_CPUID, offsetof(struct pcpu, pc_cpuid));

View File

@ -59,6 +59,7 @@ options _KPOSIX_PRIORITY_SCHEDULING # POSIX P1003_1B real-time extensions
options AHC_REG_PRETTY_PRINT # Print register bitfields in debug
# output. Adds ~128k to driver.
options ADAPTIVE_GIANT # Giant mutex is adaptive.
options PRINTF_BUFR_SIZE=128 # Prevent printf output being interspersed.
# Debugging for use in -current
options KDB # Enable kernel debugger support.

View File

@ -48,9 +48,6 @@
struct pcb;
struct thread;
/* Size of the per-cpu console buffer for printf(). */
#define PCPU_CONS_BUFR 128
/*
* This structure maps out the global data that needs to be kept on a
* per-cpu basis. The members are accessed via the PCPU_GET/SET/PTR
@ -74,8 +71,6 @@ struct pcpu {
int pc_ktr_idx; /* Index into trace table */
char *pc_ktr_buf;
#endif
char pc_cons_bufr[PCPU_CONS_BUFR];
/* Console buffer */
PCPU_MD_FIELDS;
struct vmmeter pc_cnt; /* VM stats counters */
struct device *pc_device;