Skip to content

Commit cafaee9

Browse files
author
Ian Kent
committed
kernfs: Use a per-fs rwsem to protect per-fs list of kernfs_super_info
JIRA: https://issues.redhat.com/browse/RHEL-52956 Upstream status: Linus Conflicts: There was a reject when applying the single hunk to fs/kernfs/kernfs-internal.h due to the needed RH_KABI_EXTEND() of the previous patch in this series. commit c9f2dfb Author: Imran Khan <imran.f.khan@oracle.com> Date: Thu Mar 9 22:09:31 2023 +1100 kernfs: Use a per-fs rwsem to protect per-fs list of kernfs_super_info. Right now per-fs kernfs_rwsem protects list of kernfs_super_info instances for a kernfs_root. Since kernfs_rwsem is used to synchronize several other operations across kernfs and since most of these operations don't impact kernfs_super_info, we can use a separate per-fs rwsem to synchronize access to list of kernfs_super_info. This helps in reducing contention around kernfs_rwsem and also allows operations that change/access list of kernfs_super_info to proceed without contending for kernfs_rwsem. Signed-off-by: Imran Khan <imran.f.khan@oracle.com> Link: https://lore.kernel.org/r/20230309110932.2889010-3-imran.f.khan@oracle.com Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> Signed-off-by: Ian Kent <ikent@redhat.com>
1 parent 6c3396a commit cafaee9

File tree

4 files changed

+8
-6
lines changed

4 files changed

+8
-6
lines changed

fs/kernfs/dir.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -931,6 +931,7 @@ struct kernfs_root *kernfs_create_root(struct kernfs_syscall_ops *scops,
931931
idr_init(&root->ino_idr);
932932
init_rwsem(&root->kernfs_rwsem);
933933
init_rwsem(&root->kernfs_iattr_rwsem);
934+
init_rwsem(&root->kernfs_supers_rwsem);
934935
INIT_LIST_HEAD(&root->supers);
935936

936937
/*

fs/kernfs/file.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -923,8 +923,8 @@ static void kernfs_notify_workfn(struct work_struct *work)
923923

924924
root = kernfs_root(kn);
925925
/* kick fsnotify */
926-
down_write(&root->kernfs_rwsem);
927926

927+
down_read(&root->kernfs_supers_rwsem);
928928
list_for_each_entry(info, &kernfs_root(kn)->supers, node) {
929929
struct kernfs_node *parent;
930930
struct inode *p_inode = NULL;
@@ -961,7 +961,7 @@ static void kernfs_notify_workfn(struct work_struct *work)
961961
iput(inode);
962962
}
963963

964-
up_write(&root->kernfs_rwsem);
964+
up_read(&root->kernfs_supers_rwsem);
965965
kernfs_put(kn);
966966
goto repeat;
967967
}

fs/kernfs/kernfs-internal.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ struct kernfs_root {
4848
wait_queue_head_t deactivate_waitq;
4949
struct rw_semaphore kernfs_rwsem;
5050
RH_KABI_EXTEND(struct rw_semaphore kernfs_iattr_rwsem)
51+
RH_KABI_EXTEND(struct rw_semaphore kernfs_supers_rwsem)
5152
};
5253

5354
/* +1 to avoid triggering overflow warning when negating it */

fs/kernfs/mount.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -347,9 +347,9 @@ int kernfs_get_tree(struct fs_context *fc)
347347
}
348348
sb->s_flags |= SB_ACTIVE;
349349

350-
down_write(&root->kernfs_rwsem);
350+
down_write(&root->kernfs_supers_rwsem);
351351
list_add(&info->node, &info->root->supers);
352-
up_write(&root->kernfs_rwsem);
352+
up_write(&root->kernfs_supers_rwsem);
353353
}
354354

355355
fc->root = dget(sb->s_root);
@@ -376,9 +376,9 @@ void kernfs_kill_sb(struct super_block *sb)
376376
struct kernfs_super_info *info = kernfs_info(sb);
377377
struct kernfs_root *root = info->root;
378378

379-
down_write(&root->kernfs_rwsem);
379+
down_write(&root->kernfs_supers_rwsem);
380380
list_del(&info->node);
381-
up_write(&root->kernfs_rwsem);
381+
up_write(&root->kernfs_supers_rwsem);
382382

383383
/*
384384
* Remove the superblock from fs_supers/s_instances

0 commit comments

Comments
 (0)