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.

kernfs: Introduce interface to access global kernfs_open_file_mutex.

This allows to change underlying mutex locking, without needing to change
the users of the lock. For example next patch modifies this interface to
use hashed mutexes in place of a single global kernfs_open_file_mutex.

Acked-by: Tejun Heo <tj@kernel.org>
Signed-off-by: Imran Khan <imran.f.khan@oracle.com>
Link: https://lore.kernel.org/r/20220615021059.862643-4-imran.f.khan@oracle.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

authored by

Imran Khan and committed by
Greg Kroah-Hartman
41448c61 b8f35fa1

+38 -18
+38 -18
fs/kernfs/file.c
··· 49 49 50 50 static LLIST_HEAD(kernfs_notify_list); 51 51 52 + static inline struct mutex *kernfs_open_file_mutex_ptr(struct kernfs_node *kn) 53 + { 54 + return &kernfs_open_file_mutex; 55 + } 56 + 57 + static inline struct mutex *kernfs_open_file_mutex_lock(struct kernfs_node *kn) 58 + { 59 + struct mutex *lock; 60 + 61 + lock = kernfs_open_file_mutex_ptr(kn); 62 + 63 + mutex_lock(lock); 64 + 65 + return lock; 66 + } 67 + 52 68 /** 53 69 * kernfs_deref_open_node - Get kernfs_open_node corresponding to @kn. 54 70 * ··· 95 79 * @kn: target kernfs_node. 96 80 * 97 81 * Fetch and return ->attr.open of @kn when caller holds the 98 - * kernfs_open_file_mutex. 82 + * kernfs_open_file_mutex_ptr(kn). 99 83 * 100 - * Update of ->attr.open happens under kernfs_open_file_mutex. So when 84 + * Update of ->attr.open happens under kernfs_open_file_mutex_ptr(kn). So when 101 85 * the caller guarantees that this mutex is being held, other updaters can't 102 86 * change ->attr.open and this means that we can safely deref ->attr.open 103 87 * outside RCU read-side critical section. ··· 108 92 kernfs_deref_open_node_protected(struct kernfs_node *kn) 109 93 { 110 94 return rcu_dereference_protected(kn->attr.open, 111 - lockdep_is_held(&kernfs_open_file_mutex)); 95 + lockdep_is_held(kernfs_open_file_mutex_ptr(kn))); 112 96 } 113 97 114 98 static struct kernfs_open_file *kernfs_of(struct file *file) ··· 590 574 struct kernfs_open_file *of) 591 575 { 592 576 struct kernfs_open_node *on, *new_on = NULL; 577 + struct mutex *mutex = NULL; 593 578 594 - mutex_lock(&kernfs_open_file_mutex); 579 + mutex = kernfs_open_file_mutex_lock(kn); 595 580 on = kernfs_deref_open_node_protected(kn); 596 581 597 582 if (on) { 598 583 list_add_tail(&of->list, &on->files); 599 - mutex_unlock(&kernfs_open_file_mutex); 584 + mutex_unlock(mutex); 600 585 return 0; 601 586 } else { 602 587 /* not there, initialize a new one */ 603 588 new_on = kmalloc(sizeof(*new_on), GFP_KERNEL); 604 589 if (!new_on) { 605 - mutex_unlock(&kernfs_open_file_mutex); 590 + mutex_unlock(mutex); 606 591 return -ENOMEM; 607 592 } 608 593 atomic_set(&new_on->event, 1); ··· 612 595 list_add_tail(&of->list, &new_on->files); 613 596 rcu_assign_pointer(kn->attr.open, new_on); 614 597 } 615 - mutex_unlock(&kernfs_open_file_mutex); 598 + mutex_unlock(mutex); 616 599 617 600 return 0; 618 601 } ··· 634 617 struct kernfs_open_file *of) 635 618 { 636 619 struct kernfs_open_node *on; 620 + struct mutex *mutex = NULL; 637 621 638 - mutex_lock(&kernfs_open_file_mutex); 622 + mutex = kernfs_open_file_mutex_lock(kn); 639 623 640 624 on = kernfs_deref_open_node_protected(kn); 641 625 if (!on) { 642 - mutex_unlock(&kernfs_open_file_mutex); 626 + mutex_unlock(mutex); 643 627 return; 644 628 } 645 629 ··· 652 634 kfree_rcu(on, rcu_head); 653 635 } 654 636 655 - mutex_unlock(&kernfs_open_file_mutex); 637 + mutex_unlock(mutex); 656 638 } 657 639 658 640 static int kernfs_fop_open(struct inode *inode, struct file *file) ··· 790 772 /* 791 773 * @of is guaranteed to have no other file operations in flight and 792 774 * we just want to synchronize release and drain paths. 793 - * @kernfs_open_file_mutex is enough. @of->mutex can't be used 775 + * @kernfs_open_file_mutex_ptr(kn) is enough. @of->mutex can't be used 794 776 * here because drain path may be called from places which can 795 777 * cause circular dependency. 796 778 */ 797 - lockdep_assert_held(&kernfs_open_file_mutex); 779 + lockdep_assert_held(kernfs_open_file_mutex_ptr(kn)); 798 780 799 781 if (!of->released) { 800 782 /* ··· 811 793 { 812 794 struct kernfs_node *kn = inode->i_private; 813 795 struct kernfs_open_file *of = kernfs_of(filp); 796 + struct mutex *mutex = NULL; 814 797 815 798 if (kn->flags & KERNFS_HAS_RELEASE) { 816 - mutex_lock(&kernfs_open_file_mutex); 799 + mutex = kernfs_open_file_mutex_lock(kn); 817 800 kernfs_release_file(kn, of); 818 - mutex_unlock(&kernfs_open_file_mutex); 801 + mutex_unlock(mutex); 819 802 } 820 803 821 804 kernfs_unlink_open_file(kn, of); ··· 831 812 { 832 813 struct kernfs_open_node *on; 833 814 struct kernfs_open_file *of; 815 + struct mutex *mutex = NULL; 834 816 835 817 if (!(kn->flags & (KERNFS_HAS_MMAP | KERNFS_HAS_RELEASE))) 836 818 return; ··· 841 821 * ->attr.open at this point of time. This check allows early bail out 842 822 * if ->attr.open is already NULL. kernfs_unlink_open_file makes 843 823 * ->attr.open NULL only while holding kernfs_open_file_mutex so below 844 - * check under kernfs_open_file_mutex will ensure bailing out if 824 + * check under kernfs_open_file_mutex_ptr(kn) will ensure bailing out if 845 825 * ->attr.open became NULL while waiting for the mutex. 846 826 */ 847 827 if (!rcu_access_pointer(kn->attr.open)) 848 828 return; 849 829 850 - mutex_lock(&kernfs_open_file_mutex); 830 + mutex = kernfs_open_file_mutex_lock(kn); 851 831 on = kernfs_deref_open_node_protected(kn); 852 832 if (!on) { 853 - mutex_unlock(&kernfs_open_file_mutex); 833 + mutex_unlock(mutex); 854 834 return; 855 835 } 856 836 ··· 864 844 kernfs_release_file(kn, of); 865 845 } 866 846 867 - mutex_unlock(&kernfs_open_file_mutex); 847 + mutex_unlock(mutex); 868 848 } 869 849 870 850 /*