Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 19 Nov 2023 22:25:51 GMT
From:      Mateusz Guzik <mjg@FreeBSD.org>
To:        src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org
Subject:   git: 305a2676ae93 - main - vfs: dodge locking for lseek(fd, 0, SEEK_CUR)
Message-ID:  <202311192225.3AJMPprx019359@gitrepo.freebsd.org>

next in thread | raw e-mail | index | archive | help
The branch main has been updated by mjg:

URL: https://cgit.FreeBSD.org/src/commit/?id=305a2676ae93fb50a623024d51039415521cb2da

commit 305a2676ae93fb50a623024d51039415521cb2da
Author:     Mateusz Guzik <mjg@FreeBSD.org>
AuthorDate: 2023-11-19 22:23:20 +0000
Commit:     Mateusz Guzik <mjg@FreeBSD.org>
CommitDate: 2023-11-19 22:25:45 +0000

    vfs: dodge locking for lseek(fd, 0, SEEK_CUR)
    
    It is very common and according to dtrace while running poudriere almost
    all calls with SEEK_CUR pass 0.
---
 sys/kern/vfs_vnops.c | 27 ++++++++++++++++++++++++++-
 1 file changed, 26 insertions(+), 1 deletion(-)

diff --git a/sys/kern/vfs_vnops.c b/sys/kern/vfs_vnops.c
index f81516608eeb..4669296750e4 100644
--- a/sys/kern/vfs_vnops.c
+++ b/sys/kern/vfs_vnops.c
@@ -828,6 +828,13 @@ foffset_unlock(struct file *fp, off_t val, int flags)
 	sleepq_broadcast(&fp->f_vnread_flags, SLEEPQ_SLEEP, 0, 0);
 	sleepq_release(&fp->f_vnread_flags);
 }
+
+static off_t
+foffset_read(struct file *fp)
+{
+
+	return (atomic_load_long(&fp->f_offset));
+}
 #else
 off_t
 foffset_lock(struct file *fp, int flags)
@@ -876,6 +883,13 @@ foffset_unlock(struct file *fp, off_t val, int flags)
 	}
 	mtx_unlock(mtxp);
 }
+
+static off_t
+foffset_read(struct file *fp)
+{
+
+	return (foffset_lock(fp, FOF_NOLOCK));
+}
 #endif
 
 void
@@ -2647,8 +2661,19 @@ vn_seek(struct file *fp, off_t offset, int whence, struct thread *td)
 
 	cred = td->td_ucred;
 	vp = fp->f_vnode;
-	foffset = foffset_lock(fp, 0);
 	noneg = (vp->v_type != VCHR);
+	/*
+	 * Try to dodge locking for common case of querying the offset.
+	 */
+	if (whence == L_INCR && offset == 0) {
+		foffset = foffset_read(fp);
+		if (__predict_false(foffset < 0 && noneg)) {
+			return (EOVERFLOW);
+		}
+		td->td_uretoff.tdu_off = foffset;
+		return (0);
+	}
+	foffset = foffset_lock(fp, 0);
 	error = 0;
 	switch (whence) {
 	case L_INCR:



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202311192225.3AJMPprx019359>