kfree(balloon_mapping);
}
+/*
+ * __balloon_page_flags - helper to perform balloon @page ->flags tests.
+ *
+ * As balloon pages are got from Buddy, and we do not play with page->flags
+ * at driver level (exception made when we get the page lock for compaction),
+ * therefore we can safely identify a ballooned page by checking if the
+ * NR_PAGEFLAGS rightmost bits from the page->flags are all cleared.
+ * This approach also helps on skipping ballooned pages that are locked for
+ * compaction or release, thus mitigating their racy check at
+ * balloon_page_movable()
+ */
+#define BALLOON_PAGE_FLAGS_MASK ((1UL << NR_PAGEFLAGS) - 1)
+static inline bool __balloon_page_flags(struct page *page)
+{
+ return page->flags & BALLOON_PAGE_FLAGS_MASK ? false : true;
+}
+
/*
* __is_movable_balloon_page - helper to perform @page mapping->flags tests
*/
* Before dereferencing and testing mapping->flags, lets make sure
* this is not a page that uses ->mapping in a different way
*/
- if (!PageSlab(page) && !PageSwapCache(page) && !PageAnon(page) &&
- !page_mapped(page))
+ if (__balloon_page_flags(page) && !page_mapped(page) &&
+ page_count(page) == 1)
return __is_movable_balloon_page(page);
return false;