@@ -93,6 +93,7 @@ struct mutex *hugetlb_fault_mutex_table ____cacheline_aligned_in_smp;
93
93
static int hugetlb_acct_memory (struct hstate * h , long delta );
94
94
static void hugetlb_vma_lock_free (struct vm_area_struct * vma );
95
95
static void hugetlb_vma_lock_alloc (struct vm_area_struct * vma );
96
+ static void __hugetlb_vma_unlock_write_free (struct vm_area_struct * vma );
96
97
97
98
static inline bool subpool_is_free (struct hugepage_subpool * spool )
98
99
{
@@ -5188,8 +5189,7 @@ void __unmap_hugepage_range_final(struct mmu_gather *tlb,
5188
5189
* be asynchrously deleted. If the page tables are shared, there
5189
5190
* will be issues when accessed by someone else.
5190
5191
*/
5191
- hugetlb_vma_unlock_write (vma );
5192
- hugetlb_vma_lock_free (vma );
5192
+ __hugetlb_vma_unlock_write_free (vma );
5193
5193
5194
5194
i_mmap_unlock_write (vma -> vm_file -> f_mapping );
5195
5195
}
@@ -6828,6 +6828,30 @@ void hugetlb_vma_lock_release(struct kref *kref)
6828
6828
kfree (vma_lock );
6829
6829
}
6830
6830
6831
+ void __hugetlb_vma_unlock_write_put (struct hugetlb_vma_lock * vma_lock )
6832
+ {
6833
+ struct vm_area_struct * vma = vma_lock -> vma ;
6834
+
6835
+ /*
6836
+ * vma_lock structure may or not be released as a result of put,
6837
+ * it certainly will no longer be attached to vma so clear pointer.
6838
+ * Semaphore synchronizes access to vma_lock->vma field.
6839
+ */
6840
+ vma_lock -> vma = NULL ;
6841
+ vma -> vm_private_data = NULL ;
6842
+ up_write (& vma_lock -> rw_sema );
6843
+ kref_put (& vma_lock -> refs , hugetlb_vma_lock_release );
6844
+ }
6845
+
6846
+ static void __hugetlb_vma_unlock_write_free (struct vm_area_struct * vma )
6847
+ {
6848
+ if (__vma_shareable_flags_pmd (vma )) {
6849
+ struct hugetlb_vma_lock * vma_lock = vma -> vm_private_data ;
6850
+
6851
+ __hugetlb_vma_unlock_write_put (vma_lock );
6852
+ }
6853
+ }
6854
+
6831
6855
static void hugetlb_vma_lock_free (struct vm_area_struct * vma )
6832
6856
{
6833
6857
/*
@@ -6839,14 +6863,8 @@ static void hugetlb_vma_lock_free(struct vm_area_struct *vma)
6839
6863
if (vma -> vm_private_data ) {
6840
6864
struct hugetlb_vma_lock * vma_lock = vma -> vm_private_data ;
6841
6865
6842
- /*
6843
- * vma_lock structure may or not be released, but it
6844
- * certainly will no longer be attached to vma so clear
6845
- * pointer.
6846
- */
6847
- vma_lock -> vma = NULL ;
6848
- kref_put (& vma_lock -> refs , hugetlb_vma_lock_release );
6849
- vma -> vm_private_data = NULL ;
6866
+ down_write (& vma_lock -> rw_sema );
6867
+ __hugetlb_vma_unlock_write_put (vma_lock );
6850
6868
}
6851
6869
}
6852
6870
@@ -6997,6 +7015,10 @@ void hugetlb_vma_lock_release(struct kref *kref)
6997
7015
{
6998
7016
}
6999
7017
7018
+ static void __hugetlb_vma_unlock_write_free (struct vm_area_struct * vma )
7019
+ {
7020
+ }
7021
+
7000
7022
static void hugetlb_vma_lock_free (struct vm_area_struct * vma )
7001
7023
{
7002
7024
}
0 commit comments