mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-04 10:40:15 +02:00 
			
		
		
		
	mm: compaction: make isolate_lru_page() filter-aware again
Commit 39deaf85 ("mm: compaction: make isolate_lru_page() filter-aware")
noted that compaction does not migrate dirty or writeback pages and that
is was meaningless to pick the page and re-add it to the LRU list.  This
had to be partially reverted because some dirty pages can be migrated by
compaction without blocking.
This patch updates "mm: compaction: make isolate_lru_page" by skipping
over pages that migration has no possibility of migrating to minimise LRU
disruption.
Signed-off-by: Mel Gorman <mgorman@suse.de>
Reviewed-by: Rik van Riel<riel@redhat.com>
Cc: Andrea Arcangeli <aarcange@redhat.com>
Reviewed-by: Minchan Kim <minchan@kernel.org>
Cc: Dave Jones <davej@redhat.com>
Cc: Jan Kara <jack@suse.cz>
Cc: Andy Isaacson <adi@hexapodia.org>
Cc: Nai Xia <nai.xia@gmail.com>
Cc: Johannes Weiner <jweiner@redhat.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
			
			
This commit is contained in:
		
							parent
							
								
									b969c4ab9f
								
							
						
					
					
						commit
						c824493528
					
				
					 3 changed files with 38 additions and 2 deletions
				
			
		| 
						 | 
					@ -177,6 +177,8 @@ struct lruvec {
 | 
				
			||||||
#define ISOLATE_CLEAN		((__force isolate_mode_t)0x4)
 | 
					#define ISOLATE_CLEAN		((__force isolate_mode_t)0x4)
 | 
				
			||||||
/* Isolate unmapped file */
 | 
					/* Isolate unmapped file */
 | 
				
			||||||
#define ISOLATE_UNMAPPED	((__force isolate_mode_t)0x8)
 | 
					#define ISOLATE_UNMAPPED	((__force isolate_mode_t)0x8)
 | 
				
			||||||
 | 
					/* Isolate for asynchronous migration */
 | 
				
			||||||
 | 
					#define ISOLATE_ASYNC_MIGRATE	((__force isolate_mode_t)0x10)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* LRU Isolation modes. */
 | 
					/* LRU Isolation modes. */
 | 
				
			||||||
typedef unsigned __bitwise__ isolate_mode_t;
 | 
					typedef unsigned __bitwise__ isolate_mode_t;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -349,6 +349,9 @@ static isolate_migrate_t isolate_migratepages(struct zone *zone,
 | 
				
			||||||
			continue;
 | 
								continue;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (!cc->sync)
 | 
				
			||||||
 | 
								mode |= ISOLATE_ASYNC_MIGRATE;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		/* Try isolate the page */
 | 
							/* Try isolate the page */
 | 
				
			||||||
		if (__isolate_lru_page(page, mode, 0) != 0)
 | 
							if (__isolate_lru_page(page, mode, 0) != 0)
 | 
				
			||||||
			continue;
 | 
								continue;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										33
									
								
								mm/vmscan.c
									
									
									
									
									
								
							
							
						
						
									
										33
									
								
								mm/vmscan.c
									
									
									
									
									
								
							| 
						 | 
					@ -1075,9 +1075,40 @@ int __isolate_lru_page(struct page *page, isolate_mode_t mode, int file)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	ret = -EBUSY;
 | 
						ret = -EBUSY;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if ((mode & ISOLATE_CLEAN) && (PageDirty(page) || PageWriteback(page)))
 | 
						/*
 | 
				
			||||||
 | 
						 * 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;
 | 
								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))
 | 
						if ((mode & ISOLATE_UNMAPPED) && page_mapped(page))
 | 
				
			||||||
		return ret;
 | 
							return ret;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in a new issue