@@ -255,6 +255,152 @@ static inline struct hugepage_subpool *subpool_vma(struct vm_area_struct *vma)
255255 return subpool_inode (file_inode (vma -> vm_file ));
256256}
257257
258+ /*
259+ * hugetlb vma_lock helper routines
260+ */
261+ static bool __vma_shareable_lock (struct vm_area_struct * vma )
262+ {
263+ return vma -> vm_flags & (VM_MAYSHARE | VM_SHARED ) &&
264+ vma -> vm_private_data ;
265+ }
266+
267+ void hugetlb_vma_lock_read (struct vm_area_struct * vma )
268+ {
269+ if (__vma_shareable_lock (vma )) {
270+ struct hugetlb_vma_lock * vma_lock = vma -> vm_private_data ;
271+
272+ down_read (& vma_lock -> rw_sema );
273+ }
274+ }
275+
276+ void hugetlb_vma_unlock_read (struct vm_area_struct * vma )
277+ {
278+ if (__vma_shareable_lock (vma )) {
279+ struct hugetlb_vma_lock * vma_lock = vma -> vm_private_data ;
280+
281+ up_read (& vma_lock -> rw_sema );
282+ }
283+ }
284+
285+ void hugetlb_vma_lock_write (struct vm_area_struct * vma )
286+ {
287+ if (__vma_shareable_lock (vma )) {
288+ struct hugetlb_vma_lock * vma_lock = vma -> vm_private_data ;
289+
290+ down_write (& vma_lock -> rw_sema );
291+ }
292+ }
293+
294+ void hugetlb_vma_unlock_write (struct vm_area_struct * vma )
295+ {
296+ if (__vma_shareable_lock (vma )) {
297+ struct hugetlb_vma_lock * vma_lock = vma -> vm_private_data ;
298+
299+ up_write (& vma_lock -> rw_sema );
300+ }
301+ }
302+
303+ int hugetlb_vma_trylock_write (struct vm_area_struct * vma )
304+ {
305+ struct hugetlb_vma_lock * vma_lock = vma -> vm_private_data ;
306+
307+ if (!__vma_shareable_lock (vma ))
308+ return 1 ;
309+
310+ return down_write_trylock (& vma_lock -> rw_sema );
311+ }
312+
313+ void hugetlb_vma_assert_locked (struct vm_area_struct * vma )
314+ {
315+ if (__vma_shareable_lock (vma )) {
316+ struct hugetlb_vma_lock * vma_lock = vma -> vm_private_data ;
317+
318+ lockdep_assert_held (& vma_lock -> rw_sema );
319+ }
320+ }
321+
322+ void hugetlb_vma_lock_release (struct kref * kref )
323+ {
324+ struct hugetlb_vma_lock * vma_lock = container_of (kref ,
325+ struct hugetlb_vma_lock , refs );
326+
327+ kfree (vma_lock );
328+ }
329+
330+ static void __hugetlb_vma_unlock_write_put (struct hugetlb_vma_lock * vma_lock )
331+ {
332+ struct vm_area_struct * vma = vma_lock -> vma ;
333+
334+ /*
335+ * vma_lock structure may or not be released as a result of put,
336+ * it certainly will no longer be attached to vma so clear pointer.
337+ * Semaphore synchronizes access to vma_lock->vma field.
338+ */
339+ vma_lock -> vma = NULL ;
340+ vma -> vm_private_data = NULL ;
341+ up_write (& vma_lock -> rw_sema );
342+ kref_put (& vma_lock -> refs , hugetlb_vma_lock_release );
343+ }
344+
345+ static void __hugetlb_vma_unlock_write_free (struct vm_area_struct * vma )
346+ {
347+ if (__vma_shareable_lock (vma )) {
348+ struct hugetlb_vma_lock * vma_lock = vma -> vm_private_data ;
349+
350+ __hugetlb_vma_unlock_write_put (vma_lock );
351+ }
352+ }
353+
354+ static void hugetlb_vma_lock_free (struct vm_area_struct * vma )
355+ {
356+ /*
357+ * Only present in sharable vmas.
358+ */
359+ if (!vma || !__vma_shareable_lock (vma ))
360+ return ;
361+
362+ if (vma -> vm_private_data ) {
363+ struct hugetlb_vma_lock * vma_lock = vma -> vm_private_data ;
364+
365+ down_write (& vma_lock -> rw_sema );
366+ __hugetlb_vma_unlock_write_put (vma_lock );
367+ }
368+ }
369+
370+ static void hugetlb_vma_lock_alloc (struct vm_area_struct * vma )
371+ {
372+ struct hugetlb_vma_lock * vma_lock ;
373+
374+ /* Only establish in (flags) sharable vmas */
375+ if (!vma || !(vma -> vm_flags & VM_MAYSHARE ))
376+ return ;
377+
378+ /* Should never get here with non-NULL vm_private_data */
379+ if (vma -> vm_private_data )
380+ return ;
381+
382+ vma_lock = kmalloc (sizeof (* vma_lock ), GFP_KERNEL );
383+ if (!vma_lock ) {
384+ /*
385+ * If we can not allocate structure, then vma can not
386+ * participate in pmd sharing. This is only a possible
387+ * performance enhancement and memory saving issue.
388+ * However, the lock is also used to synchronize page
389+ * faults with truncation. If the lock is not present,
390+ * unlikely races could leave pages in a file past i_size
391+ * until the file is removed. Warn in the unlikely case of
392+ * allocation failure.
393+ */
394+ pr_warn_once ("HugeTLB: unable to allocate vma specific lock\n" );
395+ return ;
396+ }
397+
398+ kref_init (& vma_lock -> refs );
399+ init_rwsem (& vma_lock -> rw_sema );
400+ vma_lock -> vma = vma ;
401+ vma -> vm_private_data = vma_lock ;
402+ }
403+
258404/* Helper that removes a struct file_region from the resv_map cache and returns
259405 * it for use.
260406 */
@@ -6613,7 +6759,8 @@ bool hugetlb_reserve_pages(struct inode *inode,
66136759 }
66146760
66156761 /*
6616- * vma specific semaphore used for pmd sharing synchronization
6762+ * vma specific semaphore used for pmd sharing and fault/truncation
6763+ * synchronization
66176764 */
66186765 hugetlb_vma_lock_alloc (vma );
66196766
@@ -6869,149 +7016,6 @@ void adjust_range_if_pmd_sharing_possible(struct vm_area_struct *vma,
68697016 * end = ALIGN (* end , PUD_SIZE );
68707017}
68717018
6872- static bool __vma_shareable_flags_pmd (struct vm_area_struct * vma )
6873- {
6874- return vma -> vm_flags & (VM_MAYSHARE | VM_SHARED ) &&
6875- vma -> vm_private_data ;
6876- }
6877-
6878- void hugetlb_vma_lock_read (struct vm_area_struct * vma )
6879- {
6880- if (__vma_shareable_flags_pmd (vma )) {
6881- struct hugetlb_vma_lock * vma_lock = vma -> vm_private_data ;
6882-
6883- down_read (& vma_lock -> rw_sema );
6884- }
6885- }
6886-
6887- void hugetlb_vma_unlock_read (struct vm_area_struct * vma )
6888- {
6889- if (__vma_shareable_flags_pmd (vma )) {
6890- struct hugetlb_vma_lock * vma_lock = vma -> vm_private_data ;
6891-
6892- up_read (& vma_lock -> rw_sema );
6893- }
6894- }
6895-
6896- void hugetlb_vma_lock_write (struct vm_area_struct * vma )
6897- {
6898- if (__vma_shareable_flags_pmd (vma )) {
6899- struct hugetlb_vma_lock * vma_lock = vma -> vm_private_data ;
6900-
6901- down_write (& vma_lock -> rw_sema );
6902- }
6903- }
6904-
6905- void hugetlb_vma_unlock_write (struct vm_area_struct * vma )
6906- {
6907- if (__vma_shareable_flags_pmd (vma )) {
6908- struct hugetlb_vma_lock * vma_lock = vma -> vm_private_data ;
6909-
6910- up_write (& vma_lock -> rw_sema );
6911- }
6912- }
6913-
6914- int hugetlb_vma_trylock_write (struct vm_area_struct * vma )
6915- {
6916- struct hugetlb_vma_lock * vma_lock = vma -> vm_private_data ;
6917-
6918- if (!__vma_shareable_flags_pmd (vma ))
6919- return 1 ;
6920-
6921- return down_write_trylock (& vma_lock -> rw_sema );
6922- }
6923-
6924- void hugetlb_vma_assert_locked (struct vm_area_struct * vma )
6925- {
6926- if (__vma_shareable_flags_pmd (vma )) {
6927- struct hugetlb_vma_lock * vma_lock = vma -> vm_private_data ;
6928-
6929- lockdep_assert_held (& vma_lock -> rw_sema );
6930- }
6931- }
6932-
6933- void hugetlb_vma_lock_release (struct kref * kref )
6934- {
6935- struct hugetlb_vma_lock * vma_lock = container_of (kref ,
6936- struct hugetlb_vma_lock , refs );
6937-
6938- kfree (vma_lock );
6939- }
6940-
6941- static void __hugetlb_vma_unlock_write_put (struct hugetlb_vma_lock * vma_lock )
6942- {
6943- struct vm_area_struct * vma = vma_lock -> vma ;
6944-
6945- /*
6946- * vma_lock structure may or not be released as a result of put,
6947- * it certainly will no longer be attached to vma so clear pointer.
6948- * Semaphore synchronizes access to vma_lock->vma field.
6949- */
6950- vma_lock -> vma = NULL ;
6951- vma -> vm_private_data = NULL ;
6952- up_write (& vma_lock -> rw_sema );
6953- kref_put (& vma_lock -> refs , hugetlb_vma_lock_release );
6954- }
6955-
6956- static void __hugetlb_vma_unlock_write_free (struct vm_area_struct * vma )
6957- {
6958- if (__vma_shareable_flags_pmd (vma )) {
6959- struct hugetlb_vma_lock * vma_lock = vma -> vm_private_data ;
6960-
6961- __hugetlb_vma_unlock_write_put (vma_lock );
6962- }
6963- }
6964-
6965- static void hugetlb_vma_lock_free (struct vm_area_struct * vma )
6966- {
6967- /*
6968- * Only present in sharable vmas.
6969- */
6970- if (!vma || !__vma_shareable_flags_pmd (vma ))
6971- return ;
6972-
6973- if (vma -> vm_private_data ) {
6974- struct hugetlb_vma_lock * vma_lock = vma -> vm_private_data ;
6975-
6976- down_write (& vma_lock -> rw_sema );
6977- __hugetlb_vma_unlock_write_put (vma_lock );
6978- }
6979- }
6980-
6981- static void hugetlb_vma_lock_alloc (struct vm_area_struct * vma )
6982- {
6983- struct hugetlb_vma_lock * vma_lock ;
6984-
6985- /* Only establish in (flags) sharable vmas */
6986- if (!vma || !(vma -> vm_flags & VM_MAYSHARE ))
6987- return ;
6988-
6989- /* Should never get here with non-NULL vm_private_data */
6990- if (vma -> vm_private_data )
6991- return ;
6992-
6993- vma_lock = kmalloc (sizeof (* vma_lock ), GFP_KERNEL );
6994- if (!vma_lock ) {
6995- /*
6996- * If we can not allocate structure, then vma can not
6997- * participate in pmd sharing. This is only a possible
6998- * performance enhancement and memory saving issue.
6999- * However, the lock is also used to synchronize page
7000- * faults with truncation. If the lock is not present,
7001- * unlikely races could leave pages in a file past i_size
7002- * until the file is removed. Warn in the unlikely case of
7003- * allocation failure.
7004- */
7005- pr_warn_once ("HugeTLB: unable to allocate vma specific lock\n" );
7006- return ;
7007- }
7008-
7009- kref_init (& vma_lock -> refs );
7010- init_rwsem (& vma_lock -> rw_sema );
7011- vma_lock -> vma = vma ;
7012- vma -> vm_private_data = vma_lock ;
7013- }
7014-
70157019/*
70167020 * Search for a shareable pmd page for hugetlb. In any case calls pmd_alloc()
70177021 * and returns the corresponding pte. While this is not necessary for the
@@ -7100,47 +7104,6 @@ int huge_pmd_unshare(struct mm_struct *mm, struct vm_area_struct *vma,
71007104
71017105#else /* !CONFIG_ARCH_WANT_HUGE_PMD_SHARE */
71027106
7103- void hugetlb_vma_lock_read (struct vm_area_struct * vma )
7104- {
7105- }
7106-
7107- void hugetlb_vma_unlock_read (struct vm_area_struct * vma )
7108- {
7109- }
7110-
7111- void hugetlb_vma_lock_write (struct vm_area_struct * vma )
7112- {
7113- }
7114-
7115- void hugetlb_vma_unlock_write (struct vm_area_struct * vma )
7116- {
7117- }
7118-
7119- int hugetlb_vma_trylock_write (struct vm_area_struct * vma )
7120- {
7121- return 1 ;
7122- }
7123-
7124- void hugetlb_vma_assert_locked (struct vm_area_struct * vma )
7125- {
7126- }
7127-
7128- void hugetlb_vma_lock_release (struct kref * kref )
7129- {
7130- }
7131-
7132- static void __hugetlb_vma_unlock_write_free (struct vm_area_struct * vma )
7133- {
7134- }
7135-
7136- static void hugetlb_vma_lock_free (struct vm_area_struct * vma )
7137- {
7138- }
7139-
7140- static void hugetlb_vma_lock_alloc (struct vm_area_struct * vma )
7141- {
7142- }
7143-
71447107pte_t * huge_pmd_share (struct mm_struct * mm , struct vm_area_struct * vma ,
71457108 unsigned long addr , pud_t * pud )
71467109{
0 commit comments