aboutsummaryrefslogtreecommitdiffstats
path: root/include/linux/mm.h
diff options
context:
space:
mode:
authorDan Murphy <dmurphy@ti.com>2012-02-02 14:16:57 -0600
committerDan Murphy <dmurphy@ti.com>2012-02-02 14:19:13 -0600
commit04cc23436ebc4f0caf088a97ef9404ea71acfdd1 (patch)
tree9994f9a05d68e47e51368017288c157936e9e1cd /include/linux/mm.h
parent50725abe80c6893a7134977c8b576a0ec4eef5a5 (diff)
parent235eae6e5e402f5f723203e4444f10c16c7c3be3 (diff)
downloadkernel_samsung_espresso10-04cc23436ebc4f0caf088a97ef9404ea71acfdd1.zip
kernel_samsung_espresso10-04cc23436ebc4f0caf088a97ef9404ea71acfdd1.tar.gz
kernel_samsung_espresso10-04cc23436ebc4f0caf088a97ef9404ea71acfdd1.tar.bz2
Merge branch 'linux-3.0.18' into p-android-omap-3.0
Conflicts: arch/arm/mach-omap2/smartreflex.c drivers/i2c/busses/i2c-omap.c drivers/usb/host/ehci.h drivers/usb/musb/musb_core.c fs/proc/base.c Signed-off-by: Dan Murphy <dmurphy@ti.com>
Diffstat (limited to 'include/linux/mm.h')
-rw-r--r--include/linux/mm.h67
1 files changed, 33 insertions, 34 deletions
diff --git a/include/linux/mm.h b/include/linux/mm.h
index 07890ac..f59179b 100644
--- a/include/linux/mm.h
+++ b/include/linux/mm.h
@@ -355,36 +355,50 @@ static inline struct page *compound_head(struct page *page)
return page;
}
+/*
+ * The atomic page->_mapcount, starts from -1: so that transitions
+ * both from it and to it can be tracked, using atomic_inc_and_test
+ * and atomic_add_negative(-1).
+ */
+static inline void reset_page_mapcount(struct page *page)
+{
+ atomic_set(&(page)->_mapcount, -1);
+}
+
+static inline int page_mapcount(struct page *page)
+{
+ return atomic_read(&(page)->_mapcount) + 1;
+}
+
static inline int page_count(struct page *page)
{
return atomic_read(&compound_head(page)->_count);
}
+static inline void get_huge_page_tail(struct page *page)
+{
+ /*
+ * __split_huge_page_refcount() cannot run
+ * from under us.
+ */
+ VM_BUG_ON(page_mapcount(page) < 0);
+ VM_BUG_ON(atomic_read(&page->_count) != 0);
+ atomic_inc(&page->_mapcount);
+}
+
+extern bool __get_page_tail(struct page *page);
+
static inline void get_page(struct page *page)
{
+ if (unlikely(PageTail(page)))
+ if (likely(__get_page_tail(page)))
+ return;
/*
* 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.
+ * requires to already have an elevated page->_count.
*/
- VM_BUG_ON(atomic_read(&page->_count) < !PageTail(page));
+ VM_BUG_ON(atomic_read(&page->_count) <= 0);
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)
@@ -803,21 +817,6 @@ static inline pgoff_t page_index(struct page *page)
}
/*
- * The atomic page->_mapcount, like _count, starts from -1:
- * so that transitions both from it and to it can be tracked,
- * using atomic_inc_and_test and atomic_add_negative(-1).
- */
-static inline void reset_page_mapcount(struct page *page)
-{
- atomic_set(&(page)->_mapcount, -1);
-}
-
-static inline int page_mapcount(struct page *page)
-{
- return atomic_read(&(page)->_mapcount) + 1;
-}
-
-/*
* Return true if this page is mapped into pagetables.
*/
static inline int page_mapped(struct page *page)