Merge remote-tracking branches 'spi/topic/fsl-espi', 'spi/topic/gpio', 'spi/topic...
[firefly-linux-kernel-4.4.55.git] / mm / rmap.c
index fd3ee7a54a13a52c7d8761ff8e20508f352d083b..068522d8502a58e9465a963e68c37ce4ccf635d7 100644 (file)
--- a/mm/rmap.c
+++ b/mm/rmap.c
@@ -600,8 +600,12 @@ pte_t *__page_check_address(struct page *page, struct mm_struct *mm,
        spinlock_t *ptl;
 
        if (unlikely(PageHuge(page))) {
+               /* when pud is not present, pte will be NULL */
                pte = huge_pte_offset(mm, address);
-               ptl = &mm->page_table_lock;
+               if (!pte)
+                       return NULL;
+
+               ptl = huge_pte_lockptr(page_hstate(page), mm, pte);
                goto check;
        }
 
@@ -665,25 +669,23 @@ int page_referenced_one(struct page *page, struct vm_area_struct *vma,
                        unsigned long *vm_flags)
 {
        struct mm_struct *mm = vma->vm_mm;
+       spinlock_t *ptl;
        int referenced = 0;
 
        if (unlikely(PageTransHuge(page))) {
                pmd_t *pmd;
 
-               spin_lock(&mm->page_table_lock);
                /*
                 * rmap might return false positives; we must filter
                 * these out using page_check_address_pmd().
                 */
                pmd = page_check_address_pmd(page, mm, address,
-                                            PAGE_CHECK_ADDRESS_PMD_FLAG);
-               if (!pmd) {
-                       spin_unlock(&mm->page_table_lock);
+                                            PAGE_CHECK_ADDRESS_PMD_FLAG, &ptl);
+               if (!pmd)
                        goto out;
-               }
 
                if (vma->vm_flags & VM_LOCKED) {
-                       spin_unlock(&mm->page_table_lock);
+                       spin_unlock(ptl);
                        *mapcount = 0;  /* break early from loop */
                        *vm_flags |= VM_LOCKED;
                        goto out;
@@ -692,10 +694,9 @@ int page_referenced_one(struct page *page, struct vm_area_struct *vma,
                /* go ahead even if the pmd is pmd_trans_splitting() */
                if (pmdp_clear_flush_young_notify(vma, address, pmd))
                        referenced++;
-               spin_unlock(&mm->page_table_lock);
+               spin_unlock(ptl);
        } else {
                pte_t *pte;
-               spinlock_t *ptl;
 
                /*
                 * rmap might return false positives; we must filter