Skip to content

Commit c0390d5

Browse files
committed
fs: pack struct file
Now that we shrunk struct file to 192 bytes aka 3 cachelines reorder struct file to not leave any holes or have members cross cachelines. Add a short comment to each of the fields and mark the cachelines. It's possible that we may have to tweak this based on profiling in the future. So far I had Jens test this comparing io_uring with non-fixed and fixed files and it improved performance. The layout is a combination of Jens' and my changes. Link: https: //lore.kernel.org/r/20240824-peinigen-hocken-7384b977c643@brauner Signed-off-by: Christian Brauner <[email protected]>
1 parent a55d1cb commit c0390d5

File tree

1 file changed

+51
-40
lines changed

1 file changed

+51
-40
lines changed

include/linux/fs.h

Lines changed: 51 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -987,52 +987,63 @@ static inline int ra_has_index(struct file_ra_state *ra, pgoff_t index)
987987
index < ra->start + ra->size);
988988
}
989989

990-
/*
991-
* f_{lock,count,pos_lock} members can be highly contended and share
992-
* the same cacheline. f_{lock,mode} are very frequently used together
993-
* and so share the same cacheline as well. The read-mostly
994-
* f_{path,inode,op} are kept on a separate cacheline.
990+
/**
991+
* struct file - Represents a file
992+
* @f_count: reference count
993+
* @f_lock: Protects f_ep, f_flags. Must not be taken from IRQ context.
994+
* @f_mode: FMODE_* flags often used in hotpaths
995+
* @f_op: file operations
996+
* @f_mapping: Contents of a cacheable, mappable object.
997+
* @private_data: filesystem or driver specific data
998+
* @f_inode: cached inode
999+
* @f_flags: file flags
1000+
* @f_iocb_flags: iocb flags
1001+
* @f_cred: stashed credentials of creator/opener
1002+
* @f_path: path of the file
1003+
* @f_pos_lock: lock protecting file position
1004+
* @f_pos: file position
1005+
* @f_version: file version
1006+
* @f_security: LSM security context of this file
1007+
* @f_owner: file owner
1008+
* @f_wb_err: writeback error
1009+
* @f_sb_err: per sb writeback errors
1010+
* @f_ep: link of all epoll hooks for this file
1011+
* @f_task_work: task work entry point
1012+
* @f_llist: work queue entrypoint
1013+
* @f_ra: file's readahead state
9951014
*/
9961015
struct file {
997-
union {
998-
/* fput() uses task work when closing and freeing file (default). */
999-
struct callback_head f_task_work;
1000-
/* fput() must use workqueue (most kernel threads). */
1001-
struct llist_node f_llist;
1002-
/* Invalid after last fput(). */
1003-
struct file_ra_state f_ra;
1004-
};
1005-
/*
1006-
* Protects f_ep, f_flags.
1007-
* Must not be taken from IRQ context.
1008-
*/
1009-
spinlock_t f_lock;
1010-
fmode_t f_mode;
1011-
atomic_long_t f_count;
1012-
struct mutex f_pos_lock;
1013-
loff_t f_pos;
1014-
unsigned int f_flags;
1015-
unsigned int f_iocb_flags;
1016-
struct fown_struct *f_owner;
1017-
const struct cred *f_cred;
1018-
struct path f_path;
1019-
struct inode *f_inode; /* cached value */
1016+
atomic_long_t f_count;
1017+
spinlock_t f_lock;
1018+
fmode_t f_mode;
10201019
const struct file_operations *f_op;
1021-
1022-
u64 f_version;
1020+
struct address_space *f_mapping;
1021+
void *private_data;
1022+
struct inode *f_inode;
1023+
unsigned int f_flags;
1024+
unsigned int f_iocb_flags;
1025+
const struct cred *f_cred;
1026+
/* --- cacheline 1 boundary (64 bytes) --- */
1027+
struct path f_path;
1028+
struct mutex f_pos_lock;
1029+
loff_t f_pos;
1030+
u64 f_version;
1031+
/* --- cacheline 2 boundary (128 bytes) --- */
10231032
#ifdef CONFIG_SECURITY
1024-
void *f_security;
1033+
void *f_security;
10251034
#endif
1026-
/* needed for tty driver, and maybe others */
1027-
void *private_data;
1028-
1035+
struct fown_struct *f_owner;
1036+
errseq_t f_wb_err;
1037+
errseq_t f_sb_err;
10291038
#ifdef CONFIG_EPOLL
1030-
/* Used by fs/eventpoll.c to link all the hooks to this file */
1031-
struct hlist_head *f_ep;
1032-
#endif /* #ifdef CONFIG_EPOLL */
1033-
struct address_space *f_mapping;
1034-
errseq_t f_wb_err;
1035-
errseq_t f_sb_err; /* for syncfs */
1039+
struct hlist_head *f_ep;
1040+
#endif
1041+
union {
1042+
struct callback_head f_task_work;
1043+
struct llist_node f_llist;
1044+
struct file_ra_state f_ra;
1045+
};
1046+
/* --- cacheline 3 boundary (192 bytes) --- */
10361047
} __randomize_layout
10371048
__attribute__((aligned(4))); /* lest something weird decides that 2 is OK */
10381049

0 commit comments

Comments
 (0)