diff options
author | rwatson <rwatson@FreeBSD.org> | 2004-07-22 18:35:43 +0000 |
---|---|---|
committer | rwatson <rwatson@FreeBSD.org> | 2004-07-22 18:35:43 +0000 |
commit | 861b3c44169cf75066afaaa69d2ec46483eac929 (patch) | |
tree | f7e2beb855def63afc1059aa39f7053e07c81046 /sys/kern | |
parent | d37648bc1fa202ca6ba0cfb549bdd91c0e4d916c (diff) | |
download | FreeBSD-src-861b3c44169cf75066afaaa69d2ec46483eac929.zip FreeBSD-src-861b3c44169cf75066afaaa69d2ec46483eac929.tar.gz |
Push acquisition of Giant from fdrop_closed() into fo_close() so that
individual file object implementations can optionally acquire Giant if
they require it:
- soo_close(): depends on debug.mpsafenet
- pipe_close(): Giant not acquired
- kqueue_close(): Giant required
- vn_close(): Giant required
- cryptof_close(): Giant required (conservative)
Notes:
Giant is still acquired in close() even when closing MPSAFE objects
due to kqueue requiring Giant in the calling closef() code.
Microbenchmarks indicate that this removal of Giant cuts 3%-3% off
of pipe create/destroy pairs from user space with SMP compiled into
the kernel.
The cryptodev and opencrypto code appears MPSAFE, but I'm unable to
test it extensively and so have left Giant over fo_close(). It can
probably be removed given some testing and review.
Diffstat (limited to 'sys/kern')
-rw-r--r-- | sys/kern/kern_descrip.c | 2 | ||||
-rw-r--r-- | sys/kern/kern_event.c | 3 | ||||
-rw-r--r-- | sys/kern/sys_socket.c | 2 | ||||
-rw-r--r-- | sys/kern/vfs_vnops.c | 8 |
4 files changed, 9 insertions, 6 deletions
diff --git a/sys/kern/kern_descrip.c b/sys/kern/kern_descrip.c index e8ba4fe..2953752 100644 --- a/sys/kern/kern_descrip.c +++ b/sys/kern/kern_descrip.c @@ -2070,13 +2070,11 @@ fdrop_locked(fp, td) FILE_UNLOCK(fp); if (fp->f_count < 0) panic("fdrop: count < 0"); - mtx_lock(&Giant); if (fp->f_ops != &badfileops) error = fo_close(fp, td); else error = 0; ffree(fp); - mtx_unlock(&Giant); return (error); } diff --git a/sys/kern/kern_event.c b/sys/kern/kern_event.c index 29491d7..4d3870e 100644 --- a/sys/kern/kern_event.c +++ b/sys/kern/kern_event.c @@ -906,7 +906,7 @@ kqueue_close(struct file *fp, struct thread *td) struct knote **knp, *kn, *kn0; int i; - GIANT_REQUIRED; + mtx_lock(&Giant); FILEDESC_LOCK(fdp); for (i = 0; i < fdp->fd_knlistsize; i++) { @@ -957,6 +957,7 @@ kqueue_close(struct file *fp, struct thread *td) free(kq, M_KQUEUE); fp->f_data = NULL; + mtx_unlock(&Giant); return (0); } diff --git a/sys/kern/sys_socket.c b/sys/kern/sys_socket.c index e59823c..e1de4b7 100644 --- a/sys/kern/sys_socket.c +++ b/sys/kern/sys_socket.c @@ -262,11 +262,13 @@ soo_close(fp, td) int error = 0; struct socket *so; + NET_LOCK_GIANT(); so = fp->f_data; fp->f_ops = &badfileops; fp->f_data = NULL; if (so) error = soclose(so); + NET_UNLOCK_GIANT(); return (error); } diff --git a/sys/kern/vfs_vnops.c b/sys/kern/vfs_vnops.c index 319835d..107feeb 100644 --- a/sys/kern/vfs_vnops.c +++ b/sys/kern/vfs_vnops.c @@ -915,11 +915,11 @@ vn_closefile(fp, td) { struct vnode *vp; struct flock lf; - - GIANT_REQUIRED; + int error; vp = fp->f_vnode; + mtx_lock(&Giant); if (fp->f_type == DTYPE_VNODE && fp->f_flag & FHASLOCK) { lf.l_whence = SEEK_SET; lf.l_start = 0; @@ -930,7 +930,9 @@ vn_closefile(fp, td) fp->f_ops = &badfileops; - return (vn_close(vp, fp->f_flag, fp->f_cred, td)); + error = vn_close(vp, fp->f_flag, fp->f_cred, td); + mtx_unlock(&Giant); + return (error); } /* |