|
@@ -1075,8 +1075,39 @@ int __isolate_lru_page(struct page *page, isolate_mode_t mode, int file)
|
|
|
|
|
|
ret = -EBUSY;
|
|
|
|
|
|
- if ((mode & ISOLATE_CLEAN) && (PageDirty(page) || PageWriteback(page)))
|
|
|
- return ret;
|
|
|
+ /*
|
|
|
+ * To minimise LRU disruption, the caller can indicate that it only
|
|
|
+ * wants to isolate pages it will be able to operate on without
|
|
|
+ * blocking - clean pages for the most part.
|
|
|
+ *
|
|
|
+ * ISOLATE_CLEAN means that only clean pages should be isolated. This
|
|
|
+ * is used by reclaim when it is cannot write to backing storage
|
|
|
+ *
|
|
|
+ * ISOLATE_ASYNC_MIGRATE is used to indicate that it only wants to pages
|
|
|
+ * that it is possible to migrate without blocking
|
|
|
+ */
|
|
|
+ if (mode & (ISOLATE_CLEAN|ISOLATE_ASYNC_MIGRATE)) {
|
|
|
+ /* All the caller can do on PageWriteback is block */
|
|
|
+ if (PageWriteback(page))
|
|
|
+ return ret;
|
|
|
+
|
|
|
+ if (PageDirty(page)) {
|
|
|
+ struct address_space *mapping;
|
|
|
+
|
|
|
+ /* ISOLATE_CLEAN means only clean pages */
|
|
|
+ if (mode & ISOLATE_CLEAN)
|
|
|
+ return ret;
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Only pages without mappings or that have a
|
|
|
+ * ->migratepage callback are possible to migrate
|
|
|
+ * without blocking
|
|
|
+ */
|
|
|
+ mapping = page_mapping(page);
|
|
|
+ if (mapping && !mapping->a_ops->migratepage)
|
|
|
+ return ret;
|
|
|
+ }
|
|
|
+ }
|
|
|
|
|
|
if ((mode & ISOLATE_UNMAPPED) && page_mapped(page))
|
|
|
return ret;
|