]> git.karo-electronics.de Git - mv-sheeva.git/blobdiff - include/linux/mm.h
thp: alter compound get_page/put_page
[mv-sheeva.git] / include / linux / mm.h
index 3b1754ad8785cb4dfe9910de1757927c06729203..a2718e1ed585eee46b3cfcada4ef8d4b196040ed 100644 (file)
@@ -353,9 +353,29 @@ static inline int page_count(struct page *page)
 
 static inline void get_page(struct page *page)
 {
-       page = compound_head(page);
-       VM_BUG_ON(atomic_read(&page->_count) == 0);
+       /*
+        * Getting a normal page or the head of a compound page
+        * requires to already have an elevated page->_count. Only if
+        * we're getting a tail page, the elevated page->_count is
+        * required only in the head page, so for tail pages the
+        * bugcheck only verifies that the page->_count isn't
+        * negative.
+        */
+       VM_BUG_ON(atomic_read(&page->_count) < !PageTail(page));
        atomic_inc(&page->_count);
+       /*
+        * Getting a tail page will elevate both the head and tail
+        * page->_count(s).
+        */
+       if (unlikely(PageTail(page))) {
+               /*
+                * This is safe only because
+                * __split_huge_page_refcount can't run under
+                * get_page().
+                */
+               VM_BUG_ON(atomic_read(&page->first_page->_count) <= 0);
+               atomic_inc(&page->first_page->_count);
+       }
 }
 
 static inline struct page *virt_to_head_page(const void *x)