From: Kris Pan <kris.pan@intel.com>
To: Jeff Layton <jlayton@kernel.org>, Chuck Lever <cel@kernel.org>
Cc: linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org
Subject: [PATCH] fs/locks: avoid allocation in fcntl_getlk() and fcntl_getlk64()
Date: Fri, 21 Aug 2026 07:40:02 +0800 [thread overview]
Message-ID: <20260820234002.1938998-1-kris.pan@intel.com> (raw)
fcntl_getlk() and fcntl_getlk64() allocate a struct file_lock from
filelock_cache on every call, adding kmem_cache alloc/free overhead to
the F_GETLK hot path.
This was introduced by commit 52306e882f77 ("fs/locks: Use allocation
rather than the stack in fcntl_getlk()") to save stack space, but struct
file_lock has since shrunk to 192 bytes (after the file_lock_core split),
so a stack allocation is fine.
Use locks_init_lock() to initialize a stack-allocated struct file_lock.
The fcntl() -> do_fcntl() -> fcntl_getlk() call chain has a combined
stack frame of under 500 bytes, well within even an 8KB stack.
On a Meteor Lake system, fcntl(F_GETLK) throughput improves from 11.0M
to 12.5M calls/sec (+13.6%), matching the ~11% regression reported by
the kernel test robot for stress-ng lockofd.
Fixes: 52306e882f77 ("fs/locks: Use allocation rather than the stack in fcntl_getlk()")
Reported-by: kernel test robot <lkp@intel.com>
Closes: https://lore.kernel.org/all/20171108072233.GA3816@intel.com/
Signed-off-by: Kris Pan <kris.pan@intel.com>
---
fs/locks.c | 44 ++++++++++++++++++++------------------------
1 file changed, 20 insertions(+), 24 deletions(-)
diff --git a/fs/locks.c b/fs/locks.c
index 6e4ff7fcec053..12f8d569b7749 100644
--- a/fs/locks.c
+++ b/fs/locks.c
@@ -2436,18 +2436,16 @@ static void posix_lock_to_flock64(struct flock64 *flock, struct file_lock *fl)
*/
int fcntl_getlk(struct file *filp, unsigned int cmd, struct flock *flock)
{
- struct file_lock *fl;
+ struct file_lock fl;
int error;
- fl = locks_alloc_lock();
- if (fl == NULL)
- return -ENOMEM;
+ locks_init_lock(&fl);
error = -EINVAL;
if (cmd != F_OFD_GETLK && flock->l_type != F_RDLCK
&& flock->l_type != F_WRLCK)
goto out;
- error = flock_to_posix_lock(filp, fl, flock);
+ error = flock_to_posix_lock(filp, &fl, flock);
if (error)
goto out;
@@ -2456,22 +2454,22 @@ int fcntl_getlk(struct file *filp, unsigned int cmd, struct flock *flock)
if (flock->l_pid != 0)
goto out;
- fl->c.flc_flags |= FL_OFDLCK;
- fl->c.flc_owner = filp;
+ fl.c.flc_flags |= FL_OFDLCK;
+ fl.c.flc_owner = filp;
}
- error = vfs_test_lock(filp, fl);
+ error = vfs_test_lock(filp, &fl);
if (error)
goto out;
- flock->l_type = fl->c.flc_type;
- if (fl->c.flc_type != F_UNLCK) {
- error = posix_lock_to_flock(flock, fl);
+ flock->l_type = fl.c.flc_type;
+ if (fl.c.flc_type != F_UNLCK) {
+ error = posix_lock_to_flock(flock, &fl);
if (error)
goto out;
}
out:
- locks_free_lock(fl);
+ locks_release_private(&fl);
return error;
}
@@ -2644,19 +2642,17 @@ int fcntl_setlk(unsigned int fd, struct file *filp, unsigned int cmd,
*/
int fcntl_getlk64(struct file *filp, unsigned int cmd, struct flock64 *flock)
{
- struct file_lock *fl;
+ struct file_lock fl;
int error;
- fl = locks_alloc_lock();
- if (fl == NULL)
- return -ENOMEM;
+ locks_init_lock(&fl);
error = -EINVAL;
if (cmd != F_OFD_GETLK && flock->l_type != F_RDLCK
&& flock->l_type != F_WRLCK)
goto out;
- error = flock64_to_posix_lock(filp, fl, flock);
+ error = flock64_to_posix_lock(filp, &fl, flock);
if (error)
goto out;
@@ -2665,20 +2661,20 @@ int fcntl_getlk64(struct file *filp, unsigned int cmd, struct flock64 *flock)
if (flock->l_pid != 0)
goto out;
- fl->c.flc_flags |= FL_OFDLCK;
- fl->c.flc_owner = filp;
+ fl.c.flc_flags |= FL_OFDLCK;
+ fl.c.flc_owner = filp;
}
- error = vfs_test_lock(filp, fl);
+ error = vfs_test_lock(filp, &fl);
if (error)
goto out;
- flock->l_type = fl->c.flc_type;
- if (fl->c.flc_type != F_UNLCK)
- posix_lock_to_flock64(flock, fl);
+ flock->l_type = fl.c.flc_type;
+ if (fl.c.flc_type != F_UNLCK)
+ posix_lock_to_flock64(flock, &fl);
out:
- locks_free_lock(fl);
+ locks_release_private(&fl);
return error;
}
--
2.43.0
reply other threads:[~2026-08-20 23:43 UTC|newest]
Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260820234002.1938998-1-kris.pan@intel.com \
--to=kris.pan@intel.com \
--cc=cel@kernel.org \
--cc=jlayton@kernel.org \
--cc=linux-fsdevel@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.