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
This commit is contained in:
parent
e8395e7a1c
commit
fbec56fe6d
@ -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);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user