summaryrefslogtreecommitdiffstats
path: root/sys/kern
diff options
context:
space:
mode:
authortjr <tjr@FreeBSD.org>2002-12-13 09:59:40 +0000
committertjr <tjr@FreeBSD.org>2002-12-13 09:59:40 +0000
commitbcd327d9a44f1ca6c358929cb93dd40acf3d7295 (patch)
tree48b504971d855aed854c98ac4ba5826748b47684 /sys/kern
parent33cac8d3682293ff210e1d5f6d0006c02cc2d93f (diff)
downloadFreeBSD-src-bcd327d9a44f1ca6c358929cb93dd40acf3d7295.zip
FreeBSD-src-bcd327d9a44f1ca6c358929cb93dd40acf3d7295.tar.gz
Drop filedesc lock and acquire Giant around calls to malloc() and free().
These call uma_large_malloc() and uma_large_free() which require Giant. Fixes panic when descriptor table is larger than KMEM_ZMAX bytes noticed by kkenn. Reviewed by: jhb
Diffstat (limited to 'sys/kern')
-rw-r--r--sys/kern/kern_descrip.c19
1 files changed, 18 insertions, 1 deletions
diff --git a/sys/kern/kern_descrip.c b/sys/kern/kern_descrip.c
index 852cd39..27e0bcc 100644
--- a/sys/kern/kern_descrip.c
+++ b/sys/kern/kern_descrip.c
@@ -1056,7 +1056,13 @@ fdalloc(td, want, result)
while (nfiles < want)
nfiles <<= 1;
FILEDESC_UNLOCK(fdp);
+ /*
+ * XXX malloc() calls uma_large_malloc() for sizes larger
+ * than KMEM_ZMAX bytes. uma_large_malloc() requires Giant.
+ */
+ mtx_lock(&Giant);
newofile = malloc(nfiles * OFILESIZE, M_FILEDESC, M_WAITOK);
+ mtx_unlock(&Giant);
/*
* Deal with file-table extend race that might have
@@ -1064,7 +1070,12 @@ fdalloc(td, want, result)
*/
FILEDESC_LOCK(fdp);
if (fdp->fd_nfiles >= nfiles) {
+ /* XXX uma_large_free() needs Giant. */
+ FILEDESC_UNLOCK(fdp);
+ mtx_lock(&Giant);
free(newofile, M_FILEDESC);
+ mtx_unlock(&Giant);
+ FILEDESC_LOCK(fdp);
continue;
}
newofileflags = (char *) &newofile[nfiles];
@@ -1087,8 +1098,14 @@ fdalloc(td, want, result)
fdp->fd_ofileflags = newofileflags;
fdp->fd_nfiles = nfiles;
fdexpand++;
- if (oldofile != NULL)
+ if (oldofile != NULL) {
+ /* XXX uma_large_free() needs Giant. */
+ FILEDESC_UNLOCK(fdp);
+ mtx_lock(&Giant);
free(oldofile, M_FILEDESC);
+ mtx_unlock(&Giant);
+ FILEDESC_LOCK(fdp);
+ }
}
return (0);
}
OpenPOWER on IntegriCloud