Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

vfs: only read fops once in fops_get/put

In do_dentry_open() the usage is:
f->f_op = fops_get(inode->i_fop);

In generated asm the compiler emits 2 reads from inode->i_fop instead of
just one.

This popped up due to false-sharing where loads from that offset end up
bouncing a cacheline during parallel open. While this is going to be fixed,
the spurious load does not need to be there.

This makes do_dentry_open() go down from 1177 to 1154 bytes.

fops_put() is patched to maintain some consistency.

No functional changes.

Reviewed-by: Josef Bacik <josef@toxicpanda.com>
Signed-off-by: Mateusz Guzik <mjguzik@gmail.com>
Link: https://lore.kernel.org/r/20240810064753.1211441-1-mjguzik@gmail.com
Signed-off-by: Christian Brauner <brauner@kernel.org>

authored by

Mateusz Guzik and committed by
Christian Brauner
8447d848 193b7279

+11 -4
+11 -4
include/linux/fs.h
··· 2553 2553 struct super_block *sget_dev(struct fs_context *fc, dev_t dev); 2554 2554 2555 2555 /* Alas, no aliases. Too much hassle with bringing module.h everywhere */ 2556 - #define fops_get(fops) \ 2557 - (((fops) && try_module_get((fops)->owner) ? (fops) : NULL)) 2558 - #define fops_put(fops) \ 2559 - do { if (fops) module_put((fops)->owner); } while(0) 2556 + #define fops_get(fops) ({ \ 2557 + const struct file_operations *_fops = (fops); \ 2558 + (((_fops) && try_module_get((_fops)->owner) ? (_fops) : NULL)); \ 2559 + }) 2560 + 2561 + #define fops_put(fops) ({ \ 2562 + const struct file_operations *_fops = (fops); \ 2563 + if (_fops) \ 2564 + module_put((_fops)->owner); \ 2565 + }) 2566 + 2560 2567 /* 2561 2568 * This one is to be used *ONLY* from ->open() instances. 2562 2569 * fops must be non-NULL, pinned down *and* module dependencies