From 84d2b7df26aaa4c58367dd2ba8a64bf84a7bb069 Mon Sep 17 00:00:00 2001 From: Robert Watson Date: Mon, 19 Sep 2005 16:51:43 +0000 Subject: Add GIANT_REQUIRED and WITNESS sleep warnings to uprintf() and tprintf(), as they both interact with the tty code (!MPSAFE) and may sleep if the tty buffer is full (per comment). Modify all consumers of uprintf() and tprintf() to hold Giant around calls into these functions. In most cases, this means adding an acquisition of Giant immediately around the function. In some cases (nfs_timer()), it means acquiring Giant higher up in the callout. With these changes, UFS no longer panics on SMP when either blocks are exhausted or inodes are exhausted under load due to races in the tty code when running without Giant. NB: Some reduction in calls to uprintf() in the svr4 code is probably desirable. NB: In the case of nfs_timer(), calling uprintf() while holding a mutex, or even in a callout at all, is a bad idea, and will generate warnings and potential upset. This needs to be fixed, but was a problem before this change. NB: uprintf()/tprintf() sleeping is generally a bad ideas, as is having non-MPSAFE tty code. MFC after: 1 week --- sys/kern/imgact_elf.c | 6 ++++++ sys/kern/subr_prf.c | 8 ++++++++ 2 files changed, 14 insertions(+) (limited to 'sys/kern') diff --git a/sys/kern/imgact_elf.c b/sys/kern/imgact_elf.c index b469898359cb..77ec406556d8 100644 --- a/sys/kern/imgact_elf.c +++ b/sys/kern/imgact_elf.c @@ -380,7 +380,9 @@ __elfN(load_section)(struct proc *p, struct vmspace *vmspace, */ if ((off_t)filsz + offset > object->un_pager.vnp.vnp_size || filsz > memsz) { + mtx_lock(&Giant); uprintf("elf_load_section: truncated ELF file\n"); + mtx_unlock(&Giant); return (ENOEXEC); } @@ -698,8 +700,10 @@ __CONCAT(exec_, __elfN(imgact))(struct image_params *imgp) brand_info = __elfN(get_brandinfo)(hdr, interp); if (brand_info == NULL) { + mtx_lock(&Giant); uprintf("ELF binary type \"%u\" not known.\n", hdr->e_ident[EI_OSABI]); + mtx_unlock(&Giant); error = ENOEXEC; goto fail; } @@ -840,7 +844,9 @@ __CONCAT(exec_, __elfN(imgact))(struct image_params *imgp) error = __elfN(load_file)(imgp->proc, interp, &addr, &imgp->entry_addr, sv->sv_pagesize); if (error != 0) { + mtx_lock(&Giant); uprintf("ELF interpreter %s not found\n", interp); + mtx_unlock(&Giant); goto fail; } } diff --git a/sys/kern/subr_prf.c b/sys/kern/subr_prf.c index 91418229ae72..a457ee92c43e 100644 --- a/sys/kern/subr_prf.c +++ b/sys/kern/subr_prf.c @@ -129,6 +129,10 @@ uprintf(const char *fmt, ...) struct putchar_arg pca; int retval; + GIANT_REQUIRED; + + WITNESS_WARN(WARN_GIANTOK | WARN_SLEEPOK, NULL, "uprintf"); + if (td == NULL || td == PCPU_GET(idlethread)) return (0); @@ -165,6 +169,10 @@ tprintf(struct proc *p, int pri, const char *fmt, ...) struct putchar_arg pca; struct session *sess = NULL; + GIANT_REQUIRED; + + WITNESS_WARN(WARN_GIANTOK | WARN_SLEEPOK, NULL, "tprintf"); + if (pri != -1) flags |= TOLOG; if (p != NULL) { -- cgit v1.3