Skip to content

Commit

Permalink
vfs: only read fops once in fops_get/put
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Mateusz Guzik authored and Christian Brauner committed Aug 30, 2024
1 parent 193b727 commit 8447d84
Showing 1 changed file with 11 additions and 4 deletions.
15 changes: 11 additions & 4 deletions include/linux/fs.h
Original file line number Diff line number Diff line change
Expand Up @@ -2553,10 +2553,17 @@ struct super_block *sget(struct file_system_type *type,
struct super_block *sget_dev(struct fs_context *fc, dev_t dev);

/* Alas, no aliases. Too much hassle with bringing module.h everywhere */
#define fops_get(fops) \
(((fops) && try_module_get((fops)->owner) ? (fops) : NULL))
#define fops_put(fops) \
do { if (fops) module_put((fops)->owner); } while(0)
#define fops_get(fops) ({ \
const struct file_operations *_fops = (fops); \
(((_fops) && try_module_get((_fops)->owner) ? (_fops) : NULL)); \
})

#define fops_put(fops) ({ \
const struct file_operations *_fops = (fops); \
if (_fops) \
module_put((_fops)->owner); \
})

/*
* This one is to be used *ONLY* from ->open() instances.
* fops must be non-NULL, pinned down *and* module dependencies
Expand Down

0 comments on commit 8447d84

Please sign in to comment.