Don't acquire Giant before calling closef() in close() (and elsewhere);

instead acquire it conditionally in closef() if it is required for
advisory locking.  This removes Giant from the close() path of sockets
and pipes (and any other objects that don't acquire Giant in their
fo_close path, such as kqueues).  Giant will still be acquired twice for
vnodes -- once for advisory lock teardown, and a second time in the
fo_close method.  Both Poul-Henning and I believe that the advisory lock
teardown code can be moved into the vn_closefile path shortly.

This trims a percent or two off the cost of most non-vnode close
operations on SMP, but has a fairly minimal impact on UP where the cost
of a single mutex operation is pretty low.
This commit is contained in:
Robert Watson 2004-11-28 14:37:17 +00:00
parent 969c9e889c
commit 1a1238a112
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=138156

View File

@ -732,9 +732,7 @@ do_dup(td, type, old, new, retval)
if (delfp != NULL) {
knote_fdclose(td, new);
FILEDESC_UNLOCK(fdp);
mtx_lock(&Giant);
(void) closef(delfp, td);
mtx_unlock(&Giant);
if (holdleaders) {
FILEDESC_LOCK_FAST(fdp);
fdp->fd_holdleaderscount--;
@ -1000,12 +998,10 @@ close(td, uap)
error = 0;
holdleaders = 0;
fdp = td->td_proc->p_fd;
mtx_lock(&Giant);
FILEDESC_LOCK(fdp);
if ((unsigned)fd >= fdp->fd_nfiles ||
(fp = fdp->fd_ofiles[fd]) == NULL) {
FILEDESC_UNLOCK(fdp);
mtx_unlock(&Giant);
return (EBADF);
}
fdp->fd_ofiles[fd] = NULL;
@ -1031,7 +1027,6 @@ close(td, uap)
FILEDESC_UNLOCK(fdp);
error = closef(fp, td);
mtx_unlock(&Giant);
if (holdleaders) {
FILEDESC_LOCK_FAST(fdp);
fdp->fd_holdleaderscount--;
@ -1862,8 +1857,11 @@ fdcheckstd(td)
/*
* Internal form of close.
* Decrement reference count on file structure.
* Note: td may be NULL when closing a file
* that was being passed in a message.
* Note: td may be NULL when closing a file that was being passed in a
* message.
*
* XXXRW: Giant is not required for the caller, but often will be held; this
* makes it moderately likely the Giant will be recursed in the VFS case.
*/
int
closef(fp, td)
@ -1884,6 +1882,7 @@ closef(fp, td)
* aren't passed with the descriptor.
*/
if (fp->f_type == DTYPE_VNODE) {
mtx_lock(&Giant);
if ((td->td_proc->p_leader->p_flag & P_ADVLOCK) != 0) {
lf.l_whence = SEEK_SET;
lf.l_start = 0;
@ -1927,6 +1926,7 @@ closef(fp, td)
}
FILEDESC_UNLOCK(fdp);
}
mtx_unlock(&Giant);
}
return (fdrop(fp, td));
}