Skip to content

Commit 8d9bfb2

Browse files
mjkravetzakpm00
authored andcommitted
hugetlb: add vma based lock for pmd sharing
Allocate a new hugetlb_vma_lock structure and hang off vm_private_data for synchronization use by vmas that could be involved in pmd sharing. This data structure contains a rw semaphore that is the primary tool used for synchronization. This new structure is ref counted, so that it can exist when NOT attached to a vma. This is only helpful in resolving lock ordering issues where code may need to obtain the vma_lock while there are no guarantees the vma may go away. By obtaining a ref on the structure, it can be guaranteed that at least the rw semaphore will not go away. Only add infrastructure for the new lock here. Actual use will be added in subsequent patches. [[email protected]: fix build issue for missing hugetlb_vma_lock_release] Link: https://lkml.kernel.org/r/YyNUtA1vRASOE4+M@monkey Link: https://lkml.kernel.org/r/[email protected] Signed-off-by: Mike Kravetz <[email protected]> Reviewed-by: Miaohe Lin <[email protected]> Cc: Andrea Arcangeli <[email protected]> Cc: "Aneesh Kumar K.V" <[email protected]> Cc: Axel Rasmussen <[email protected]> Cc: David Hildenbrand <[email protected]> Cc: Davidlohr Bueso <[email protected]> Cc: James Houghton <[email protected]> Cc: "Kirill A. Shutemov" <[email protected]> Cc: Michal Hocko <[email protected]> Cc: Mina Almasry <[email protected]> Cc: Muchun Song <[email protected]> Cc: Naoya Horiguchi <[email protected]> Cc: Pasha Tatashin <[email protected]> Cc: Peter Xu <[email protected]> Cc: Prakash Sangappa <[email protected]> Cc: Sven Schnelle <[email protected]> Signed-off-by: Andrew Morton <[email protected]>
1 parent 12710fd commit 8d9bfb2

File tree

4 files changed

+240
-24
lines changed

4 files changed

+240
-24
lines changed

include/linux/hugetlb.h

Lines changed: 41 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,12 @@ struct file_region {
115115
#endif
116116
};
117117

118+
struct hugetlb_vma_lock {
119+
struct kref refs;
120+
struct rw_semaphore rw_sema;
121+
struct vm_area_struct *vma;
122+
};
123+
118124
extern struct resv_map *resv_map_alloc(void);
119125
void resv_map_release(struct kref *ref);
120126

@@ -127,7 +133,7 @@ struct hugepage_subpool *hugepage_new_subpool(struct hstate *h, long max_hpages,
127133
long min_hpages);
128134
void hugepage_put_subpool(struct hugepage_subpool *spool);
129135

130-
void reset_vma_resv_huge_pages(struct vm_area_struct *vma);
136+
void hugetlb_dup_vma_private(struct vm_area_struct *vma);
131137
void clear_vma_resv_huge_pages(struct vm_area_struct *vma);
132138
int hugetlb_sysctl_handler(struct ctl_table *, int, void *, size_t *, loff_t *);
133139
int hugetlb_overcommit_handler(struct ctl_table *, int, void *, size_t *,
@@ -215,6 +221,14 @@ struct page *follow_huge_pud(struct mm_struct *mm, unsigned long address,
215221
struct page *follow_huge_pgd(struct mm_struct *mm, unsigned long address,
216222
pgd_t *pgd, int flags);
217223

224+
void hugetlb_vma_lock_read(struct vm_area_struct *vma);
225+
void hugetlb_vma_unlock_read(struct vm_area_struct *vma);
226+
void hugetlb_vma_lock_write(struct vm_area_struct *vma);
227+
void hugetlb_vma_unlock_write(struct vm_area_struct *vma);
228+
int hugetlb_vma_trylock_write(struct vm_area_struct *vma);
229+
void hugetlb_vma_assert_locked(struct vm_area_struct *vma);
230+
void hugetlb_vma_lock_release(struct kref *kref);
231+
218232
int pmd_huge(pmd_t pmd);
219233
int pud_huge(pud_t pud);
220234
unsigned long hugetlb_change_protection(struct vm_area_struct *vma,
@@ -226,7 +240,7 @@ void hugetlb_unshare_all_pmds(struct vm_area_struct *vma);
226240

227241
#else /* !CONFIG_HUGETLB_PAGE */
228242

229-
static inline void reset_vma_resv_huge_pages(struct vm_area_struct *vma)
243+
static inline void hugetlb_dup_vma_private(struct vm_area_struct *vma)
230244
{
231245
}
232246

@@ -337,6 +351,31 @@ static inline int prepare_hugepage_range(struct file *file,
337351
return -EINVAL;
338352
}
339353

354+
static inline void hugetlb_vma_lock_read(struct vm_area_struct *vma)
355+
{
356+
}
357+
358+
static inline void hugetlb_vma_unlock_read(struct vm_area_struct *vma)
359+
{
360+
}
361+
362+
static inline void hugetlb_vma_lock_write(struct vm_area_struct *vma)
363+
{
364+
}
365+
366+
static inline void hugetlb_vma_unlock_write(struct vm_area_struct *vma)
367+
{
368+
}
369+
370+
static inline int hugetlb_vma_trylock_write(struct vm_area_struct *vma)
371+
{
372+
return 1;
373+
}
374+
375+
static inline void hugetlb_vma_assert_locked(struct vm_area_struct *vma)
376+
{
377+
}
378+
340379
static inline int pmd_huge(pmd_t pmd)
341380
{
342381
return 0;

kernel/fork.c

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -674,12 +674,10 @@ static __latent_entropy int dup_mmap(struct mm_struct *mm,
674674
}
675675

676676
/*
677-
* Clear hugetlb-related page reserves for children. This only
678-
* affects MAP_PRIVATE mappings. Faults generated by the child
679-
* are not guaranteed to succeed, even if read-only
677+
* Copy/update hugetlb private vma information.
680678
*/
681679
if (is_vm_hugetlb_page(tmp))
682-
reset_vma_resv_huge_pages(tmp);
680+
hugetlb_dup_vma_private(tmp);
683681

684682
/* Link the vma into the MT */
685683
mas.index = tmp->vm_start;

0 commit comments

Comments
 (0)