mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-04 02:30:34 +02:00 
			
		
		
		
	memory-failure: export page_type and action result
Export 'outcome' and 'action_page_type' to mm.h, so we could use this emnus outside. This patch is preparation for adding trace events for memory-failure recovery action. Signed-off-by: Xie XiuQi <xiexiuqi@huawei.com> Acked-by: Naoya Horiguchi <n-horiguchi@ah.jp.nec.com> Cc: Chen Gong <gong.chen@linux.intel.com> Cc: Jim Davis <jim.epost@gmail.com> Cc: Steven Rostedt <rostedt@goodmis.org> Cc: Tony Luck <tony.luck@intel.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
							
								
									eb3c24f305
								
							
						
					
					
						commit
						cc637b1704
					
				
					 2 changed files with 101 additions and 101 deletions
				
			
		| 
						 | 
					@ -2153,6 +2153,40 @@ extern void shake_page(struct page *p, int access);
 | 
				
			||||||
extern atomic_long_t num_poisoned_pages;
 | 
					extern atomic_long_t num_poisoned_pages;
 | 
				
			||||||
extern int soft_offline_page(struct page *page, int flags);
 | 
					extern int soft_offline_page(struct page *page, int flags);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Error handlers for various types of pages.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					enum mf_outcome {
 | 
				
			||||||
 | 
						MF_IGNORED,	/* Error: cannot be handled */
 | 
				
			||||||
 | 
						MF_FAILED,	/* Error: handling failed */
 | 
				
			||||||
 | 
						MF_DELAYED,	/* Will be handled later */
 | 
				
			||||||
 | 
						MF_RECOVERED,	/* Successfully recovered */
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					enum mf_action_page_type {
 | 
				
			||||||
 | 
						MF_MSG_KERNEL,
 | 
				
			||||||
 | 
						MF_MSG_KERNEL_HIGH_ORDER,
 | 
				
			||||||
 | 
						MF_MSG_SLAB,
 | 
				
			||||||
 | 
						MF_MSG_DIFFERENT_COMPOUND,
 | 
				
			||||||
 | 
						MF_MSG_POISONED_HUGE,
 | 
				
			||||||
 | 
						MF_MSG_HUGE,
 | 
				
			||||||
 | 
						MF_MSG_FREE_HUGE,
 | 
				
			||||||
 | 
						MF_MSG_UNMAP_FAILED,
 | 
				
			||||||
 | 
						MF_MSG_DIRTY_SWAPCACHE,
 | 
				
			||||||
 | 
						MF_MSG_CLEAN_SWAPCACHE,
 | 
				
			||||||
 | 
						MF_MSG_DIRTY_MLOCKED_LRU,
 | 
				
			||||||
 | 
						MF_MSG_CLEAN_MLOCKED_LRU,
 | 
				
			||||||
 | 
						MF_MSG_DIRTY_UNEVICTABLE_LRU,
 | 
				
			||||||
 | 
						MF_MSG_CLEAN_UNEVICTABLE_LRU,
 | 
				
			||||||
 | 
						MF_MSG_DIRTY_LRU,
 | 
				
			||||||
 | 
						MF_MSG_CLEAN_LRU,
 | 
				
			||||||
 | 
						MF_MSG_TRUNCATED_LRU,
 | 
				
			||||||
 | 
						MF_MSG_BUDDY,
 | 
				
			||||||
 | 
						MF_MSG_BUDDY_2ND,
 | 
				
			||||||
 | 
						MF_MSG_UNKNOWN,
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#if defined(CONFIG_TRANSPARENT_HUGEPAGE) || defined(CONFIG_HUGETLBFS)
 | 
					#if defined(CONFIG_TRANSPARENT_HUGEPAGE) || defined(CONFIG_HUGETLBFS)
 | 
				
			||||||
extern void clear_huge_page(struct page *page,
 | 
					extern void clear_huge_page(struct page *page,
 | 
				
			||||||
			    unsigned long addr,
 | 
								    unsigned long addr,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -504,68 +504,34 @@ static void collect_procs(struct page *page, struct list_head *tokill,
 | 
				
			||||||
	kfree(tk);
 | 
						kfree(tk);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*
 | 
					 | 
				
			||||||
 * Error handlers for various types of pages.
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
enum outcome {
 | 
					 | 
				
			||||||
	IGNORED,	/* Error: cannot be handled */
 | 
					 | 
				
			||||||
	FAILED,		/* Error: handling failed */
 | 
					 | 
				
			||||||
	DELAYED,	/* Will be handled later */
 | 
					 | 
				
			||||||
	RECOVERED,	/* Successfully recovered */
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static const char *action_name[] = {
 | 
					static const char *action_name[] = {
 | 
				
			||||||
	[IGNORED] = "Ignored",
 | 
						[MF_IGNORED] = "Ignored",
 | 
				
			||||||
	[FAILED] = "Failed",
 | 
						[MF_FAILED] = "Failed",
 | 
				
			||||||
	[DELAYED] = "Delayed",
 | 
						[MF_DELAYED] = "Delayed",
 | 
				
			||||||
	[RECOVERED] = "Recovered",
 | 
						[MF_RECOVERED] = "Recovered",
 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
enum action_page_type {
 | 
					 | 
				
			||||||
	MSG_KERNEL,
 | 
					 | 
				
			||||||
	MSG_KERNEL_HIGH_ORDER,
 | 
					 | 
				
			||||||
	MSG_SLAB,
 | 
					 | 
				
			||||||
	MSG_DIFFERENT_COMPOUND,
 | 
					 | 
				
			||||||
	MSG_POISONED_HUGE,
 | 
					 | 
				
			||||||
	MSG_HUGE,
 | 
					 | 
				
			||||||
	MSG_FREE_HUGE,
 | 
					 | 
				
			||||||
	MSG_UNMAP_FAILED,
 | 
					 | 
				
			||||||
	MSG_DIRTY_SWAPCACHE,
 | 
					 | 
				
			||||||
	MSG_CLEAN_SWAPCACHE,
 | 
					 | 
				
			||||||
	MSG_DIRTY_MLOCKED_LRU,
 | 
					 | 
				
			||||||
	MSG_CLEAN_MLOCKED_LRU,
 | 
					 | 
				
			||||||
	MSG_DIRTY_UNEVICTABLE_LRU,
 | 
					 | 
				
			||||||
	MSG_CLEAN_UNEVICTABLE_LRU,
 | 
					 | 
				
			||||||
	MSG_DIRTY_LRU,
 | 
					 | 
				
			||||||
	MSG_CLEAN_LRU,
 | 
					 | 
				
			||||||
	MSG_TRUNCATED_LRU,
 | 
					 | 
				
			||||||
	MSG_BUDDY,
 | 
					 | 
				
			||||||
	MSG_BUDDY_2ND,
 | 
					 | 
				
			||||||
	MSG_UNKNOWN,
 | 
					 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static const char * const action_page_types[] = {
 | 
					static const char * const action_page_types[] = {
 | 
				
			||||||
	[MSG_KERNEL]			= "reserved kernel page",
 | 
						[MF_MSG_KERNEL]			= "reserved kernel page",
 | 
				
			||||||
	[MSG_KERNEL_HIGH_ORDER]		= "high-order kernel page",
 | 
						[MF_MSG_KERNEL_HIGH_ORDER]	= "high-order kernel page",
 | 
				
			||||||
	[MSG_SLAB]			= "kernel slab page",
 | 
						[MF_MSG_SLAB]			= "kernel slab page",
 | 
				
			||||||
	[MSG_DIFFERENT_COMPOUND]	= "different compound page after locking",
 | 
						[MF_MSG_DIFFERENT_COMPOUND]	= "different compound page after locking",
 | 
				
			||||||
	[MSG_POISONED_HUGE]		= "huge page already hardware poisoned",
 | 
						[MF_MSG_POISONED_HUGE]		= "huge page already hardware poisoned",
 | 
				
			||||||
	[MSG_HUGE]			= "huge page",
 | 
						[MF_MSG_HUGE]			= "huge page",
 | 
				
			||||||
	[MSG_FREE_HUGE]			= "free huge page",
 | 
						[MF_MSG_FREE_HUGE]		= "free huge page",
 | 
				
			||||||
	[MSG_UNMAP_FAILED]		= "unmapping failed page",
 | 
						[MF_MSG_UNMAP_FAILED]		= "unmapping failed page",
 | 
				
			||||||
	[MSG_DIRTY_SWAPCACHE]		= "dirty swapcache page",
 | 
						[MF_MSG_DIRTY_SWAPCACHE]	= "dirty swapcache page",
 | 
				
			||||||
	[MSG_CLEAN_SWAPCACHE]		= "clean swapcache page",
 | 
						[MF_MSG_CLEAN_SWAPCACHE]	= "clean swapcache page",
 | 
				
			||||||
	[MSG_DIRTY_MLOCKED_LRU]		= "dirty mlocked LRU page",
 | 
						[MF_MSG_DIRTY_MLOCKED_LRU]	= "dirty mlocked LRU page",
 | 
				
			||||||
	[MSG_CLEAN_MLOCKED_LRU]		= "clean mlocked LRU page",
 | 
						[MF_MSG_CLEAN_MLOCKED_LRU]	= "clean mlocked LRU page",
 | 
				
			||||||
	[MSG_DIRTY_UNEVICTABLE_LRU]	= "dirty unevictable LRU page",
 | 
						[MF_MSG_DIRTY_UNEVICTABLE_LRU]	= "dirty unevictable LRU page",
 | 
				
			||||||
	[MSG_CLEAN_UNEVICTABLE_LRU]	= "clean unevictable LRU page",
 | 
						[MF_MSG_CLEAN_UNEVICTABLE_LRU]	= "clean unevictable LRU page",
 | 
				
			||||||
	[MSG_DIRTY_LRU]			= "dirty LRU page",
 | 
						[MF_MSG_DIRTY_LRU]		= "dirty LRU page",
 | 
				
			||||||
	[MSG_CLEAN_LRU]			= "clean LRU page",
 | 
						[MF_MSG_CLEAN_LRU]		= "clean LRU page",
 | 
				
			||||||
	[MSG_TRUNCATED_LRU]		= "already truncated LRU page",
 | 
						[MF_MSG_TRUNCATED_LRU]		= "already truncated LRU page",
 | 
				
			||||||
	[MSG_BUDDY]			= "free buddy page",
 | 
						[MF_MSG_BUDDY]			= "free buddy page",
 | 
				
			||||||
	[MSG_BUDDY_2ND]			= "free buddy page (2nd try)",
 | 
						[MF_MSG_BUDDY_2ND]		= "free buddy page (2nd try)",
 | 
				
			||||||
	[MSG_UNKNOWN]			= "unknown page",
 | 
						[MF_MSG_UNKNOWN]		= "unknown page",
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*
 | 
					/*
 | 
				
			||||||
| 
						 | 
					@ -599,7 +565,7 @@ static int delete_from_lru_cache(struct page *p)
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
static int me_kernel(struct page *p, unsigned long pfn)
 | 
					static int me_kernel(struct page *p, unsigned long pfn)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	return IGNORED;
 | 
						return MF_IGNORED;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*
 | 
					/*
 | 
				
			||||||
| 
						 | 
					@ -608,7 +574,7 @@ static int me_kernel(struct page *p, unsigned long pfn)
 | 
				
			||||||
static int me_unknown(struct page *p, unsigned long pfn)
 | 
					static int me_unknown(struct page *p, unsigned long pfn)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	printk(KERN_ERR "MCE %#lx: Unknown page state\n", pfn);
 | 
						printk(KERN_ERR "MCE %#lx: Unknown page state\n", pfn);
 | 
				
			||||||
	return FAILED;
 | 
						return MF_FAILED;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*
 | 
					/*
 | 
				
			||||||
| 
						 | 
					@ -617,7 +583,7 @@ static int me_unknown(struct page *p, unsigned long pfn)
 | 
				
			||||||
static int me_pagecache_clean(struct page *p, unsigned long pfn)
 | 
					static int me_pagecache_clean(struct page *p, unsigned long pfn)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	int err;
 | 
						int err;
 | 
				
			||||||
	int ret = FAILED;
 | 
						int ret = MF_FAILED;
 | 
				
			||||||
	struct address_space *mapping;
 | 
						struct address_space *mapping;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	delete_from_lru_cache(p);
 | 
						delete_from_lru_cache(p);
 | 
				
			||||||
| 
						 | 
					@ -627,7 +593,7 @@ static int me_pagecache_clean(struct page *p, unsigned long pfn)
 | 
				
			||||||
	 * should be the one m_f() holds.
 | 
						 * should be the one m_f() holds.
 | 
				
			||||||
	 */
 | 
						 */
 | 
				
			||||||
	if (PageAnon(p))
 | 
						if (PageAnon(p))
 | 
				
			||||||
		return RECOVERED;
 | 
							return MF_RECOVERED;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/*
 | 
						/*
 | 
				
			||||||
	 * Now truncate the page in the page cache. This is really
 | 
						 * Now truncate the page in the page cache. This is really
 | 
				
			||||||
| 
						 | 
					@ -641,7 +607,7 @@ static int me_pagecache_clean(struct page *p, unsigned long pfn)
 | 
				
			||||||
		/*
 | 
							/*
 | 
				
			||||||
		 * Page has been teared down in the meanwhile
 | 
							 * Page has been teared down in the meanwhile
 | 
				
			||||||
		 */
 | 
							 */
 | 
				
			||||||
		return FAILED;
 | 
							return MF_FAILED;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/*
 | 
						/*
 | 
				
			||||||
| 
						 | 
					@ -658,7 +624,7 @@ static int me_pagecache_clean(struct page *p, unsigned long pfn)
 | 
				
			||||||
				!try_to_release_page(p, GFP_NOIO)) {
 | 
									!try_to_release_page(p, GFP_NOIO)) {
 | 
				
			||||||
			pr_info("MCE %#lx: failed to release buffers\n", pfn);
 | 
								pr_info("MCE %#lx: failed to release buffers\n", pfn);
 | 
				
			||||||
		} else {
 | 
							} else {
 | 
				
			||||||
			ret = RECOVERED;
 | 
								ret = MF_RECOVERED;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	} else {
 | 
						} else {
 | 
				
			||||||
		/*
 | 
							/*
 | 
				
			||||||
| 
						 | 
					@ -666,7 +632,7 @@ static int me_pagecache_clean(struct page *p, unsigned long pfn)
 | 
				
			||||||
		 * This fails on dirty or anything with private pages
 | 
							 * This fails on dirty or anything with private pages
 | 
				
			||||||
		 */
 | 
							 */
 | 
				
			||||||
		if (invalidate_inode_page(p))
 | 
							if (invalidate_inode_page(p))
 | 
				
			||||||
			ret = RECOVERED;
 | 
								ret = MF_RECOVERED;
 | 
				
			||||||
		else
 | 
							else
 | 
				
			||||||
			printk(KERN_INFO "MCE %#lx: Failed to invalidate\n",
 | 
								printk(KERN_INFO "MCE %#lx: Failed to invalidate\n",
 | 
				
			||||||
				pfn);
 | 
									pfn);
 | 
				
			||||||
| 
						 | 
					@ -752,9 +718,9 @@ static int me_swapcache_dirty(struct page *p, unsigned long pfn)
 | 
				
			||||||
	ClearPageUptodate(p);
 | 
						ClearPageUptodate(p);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (!delete_from_lru_cache(p))
 | 
						if (!delete_from_lru_cache(p))
 | 
				
			||||||
		return DELAYED;
 | 
							return MF_DELAYED;
 | 
				
			||||||
	else
 | 
						else
 | 
				
			||||||
		return FAILED;
 | 
							return MF_FAILED;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int me_swapcache_clean(struct page *p, unsigned long pfn)
 | 
					static int me_swapcache_clean(struct page *p, unsigned long pfn)
 | 
				
			||||||
| 
						 | 
					@ -762,9 +728,9 @@ static int me_swapcache_clean(struct page *p, unsigned long pfn)
 | 
				
			||||||
	delete_from_swap_cache(p);
 | 
						delete_from_swap_cache(p);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (!delete_from_lru_cache(p))
 | 
						if (!delete_from_lru_cache(p))
 | 
				
			||||||
		return RECOVERED;
 | 
							return MF_RECOVERED;
 | 
				
			||||||
	else
 | 
						else
 | 
				
			||||||
		return FAILED;
 | 
							return MF_FAILED;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*
 | 
					/*
 | 
				
			||||||
| 
						 | 
					@ -794,9 +760,9 @@ static int me_huge_page(struct page *p, unsigned long pfn)
 | 
				
			||||||
	if (!(page_mapping(hpage) || PageAnon(hpage))) {
 | 
						if (!(page_mapping(hpage) || PageAnon(hpage))) {
 | 
				
			||||||
		res = dequeue_hwpoisoned_huge_page(hpage);
 | 
							res = dequeue_hwpoisoned_huge_page(hpage);
 | 
				
			||||||
		if (!res)
 | 
							if (!res)
 | 
				
			||||||
			return RECOVERED;
 | 
								return MF_RECOVERED;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return DELAYED;
 | 
						return MF_DELAYED;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*
 | 
					/*
 | 
				
			||||||
| 
						 | 
					@ -828,10 +794,10 @@ static int me_huge_page(struct page *p, unsigned long pfn)
 | 
				
			||||||
static struct page_state {
 | 
					static struct page_state {
 | 
				
			||||||
	unsigned long mask;
 | 
						unsigned long mask;
 | 
				
			||||||
	unsigned long res;
 | 
						unsigned long res;
 | 
				
			||||||
	enum action_page_type type;
 | 
						enum mf_action_page_type type;
 | 
				
			||||||
	int (*action)(struct page *p, unsigned long pfn);
 | 
						int (*action)(struct page *p, unsigned long pfn);
 | 
				
			||||||
} error_states[] = {
 | 
					} error_states[] = {
 | 
				
			||||||
	{ reserved,	reserved,	MSG_KERNEL,	me_kernel },
 | 
						{ reserved,	reserved,	MF_MSG_KERNEL,	me_kernel },
 | 
				
			||||||
	/*
 | 
						/*
 | 
				
			||||||
	 * free pages are specially detected outside this table:
 | 
						 * free pages are specially detected outside this table:
 | 
				
			||||||
	 * PG_buddy pages only make a small fraction of all free pages.
 | 
						 * PG_buddy pages only make a small fraction of all free pages.
 | 
				
			||||||
| 
						 | 
					@ -842,31 +808,31 @@ static struct page_state {
 | 
				
			||||||
	 * currently unused objects without touching them. But just
 | 
						 * currently unused objects without touching them. But just
 | 
				
			||||||
	 * treat it as standard kernel for now.
 | 
						 * treat it as standard kernel for now.
 | 
				
			||||||
	 */
 | 
						 */
 | 
				
			||||||
	{ slab,		slab,		MSG_SLAB,	me_kernel },
 | 
						{ slab,		slab,		MF_MSG_SLAB,	me_kernel },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifdef CONFIG_PAGEFLAGS_EXTENDED
 | 
					#ifdef CONFIG_PAGEFLAGS_EXTENDED
 | 
				
			||||||
	{ head,		head,		MSG_HUGE,		me_huge_page },
 | 
						{ head,		head,		MF_MSG_HUGE,		me_huge_page },
 | 
				
			||||||
	{ tail,		tail,		MSG_HUGE,		me_huge_page },
 | 
						{ tail,		tail,		MF_MSG_HUGE,		me_huge_page },
 | 
				
			||||||
#else
 | 
					#else
 | 
				
			||||||
	{ compound,	compound,	MSG_HUGE,		me_huge_page },
 | 
						{ compound,	compound,	MF_MSG_HUGE,		me_huge_page },
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	{ sc|dirty,	sc|dirty,	MSG_DIRTY_SWAPCACHE,	me_swapcache_dirty },
 | 
						{ sc|dirty,	sc|dirty,	MF_MSG_DIRTY_SWAPCACHE,	me_swapcache_dirty },
 | 
				
			||||||
	{ sc|dirty,	sc,		MSG_CLEAN_SWAPCACHE,	me_swapcache_clean },
 | 
						{ sc|dirty,	sc,		MF_MSG_CLEAN_SWAPCACHE,	me_swapcache_clean },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	{ mlock|dirty,	mlock|dirty,	MSG_DIRTY_MLOCKED_LRU,	me_pagecache_dirty },
 | 
						{ mlock|dirty,	mlock|dirty,	MF_MSG_DIRTY_MLOCKED_LRU,	me_pagecache_dirty },
 | 
				
			||||||
	{ mlock|dirty,	mlock,		MSG_CLEAN_MLOCKED_LRU,	me_pagecache_clean },
 | 
						{ mlock|dirty,	mlock,		MF_MSG_CLEAN_MLOCKED_LRU,	me_pagecache_clean },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	{ unevict|dirty, unevict|dirty,	MSG_DIRTY_UNEVICTABLE_LRU,	me_pagecache_dirty },
 | 
						{ unevict|dirty, unevict|dirty,	MF_MSG_DIRTY_UNEVICTABLE_LRU,	me_pagecache_dirty },
 | 
				
			||||||
	{ unevict|dirty, unevict,	MSG_CLEAN_UNEVICTABLE_LRU,	me_pagecache_clean },
 | 
						{ unevict|dirty, unevict,	MF_MSG_CLEAN_UNEVICTABLE_LRU,	me_pagecache_clean },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	{ lru|dirty,	lru|dirty,	MSG_DIRTY_LRU,	me_pagecache_dirty },
 | 
						{ lru|dirty,	lru|dirty,	MF_MSG_DIRTY_LRU,	me_pagecache_dirty },
 | 
				
			||||||
	{ lru|dirty,	lru,		MSG_CLEAN_LRU,	me_pagecache_clean },
 | 
						{ lru|dirty,	lru,		MF_MSG_CLEAN_LRU,	me_pagecache_clean },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/*
 | 
						/*
 | 
				
			||||||
	 * Catchall entry: must be at end.
 | 
						 * Catchall entry: must be at end.
 | 
				
			||||||
	 */
 | 
						 */
 | 
				
			||||||
	{ 0,		0,		MSG_UNKNOWN,	me_unknown },
 | 
						{ 0,		0,		MF_MSG_UNKNOWN,	me_unknown },
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#undef dirty
 | 
					#undef dirty
 | 
				
			||||||
| 
						 | 
					@ -886,7 +852,7 @@ static struct page_state {
 | 
				
			||||||
 * "Dirty/Clean" indication is not 100% accurate due to the possibility of
 | 
					 * "Dirty/Clean" indication is not 100% accurate due to the possibility of
 | 
				
			||||||
 * setting PG_dirty outside page lock. See also comment above set_page_dirty().
 | 
					 * setting PG_dirty outside page lock. See also comment above set_page_dirty().
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
static void action_result(unsigned long pfn, enum action_page_type type, int result)
 | 
					static void action_result(unsigned long pfn, enum mf_action_page_type type, int result)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	pr_err("MCE %#lx: recovery action for %s: %s\n",
 | 
						pr_err("MCE %#lx: recovery action for %s: %s\n",
 | 
				
			||||||
		pfn, action_page_types[type], action_name[result]);
 | 
							pfn, action_page_types[type], action_name[result]);
 | 
				
			||||||
| 
						 | 
					@ -901,13 +867,13 @@ static int page_action(struct page_state *ps, struct page *p,
 | 
				
			||||||
	result = ps->action(p, pfn);
 | 
						result = ps->action(p, pfn);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	count = page_count(p) - 1;
 | 
						count = page_count(p) - 1;
 | 
				
			||||||
	if (ps->action == me_swapcache_dirty && result == DELAYED)
 | 
						if (ps->action == me_swapcache_dirty && result == MF_DELAYED)
 | 
				
			||||||
		count--;
 | 
							count--;
 | 
				
			||||||
	if (count != 0) {
 | 
						if (count != 0) {
 | 
				
			||||||
		printk(KERN_ERR
 | 
							printk(KERN_ERR
 | 
				
			||||||
		       "MCE %#lx: %s still referenced by %d users\n",
 | 
							       "MCE %#lx: %s still referenced by %d users\n",
 | 
				
			||||||
		       pfn, action_page_types[ps->type], count);
 | 
							       pfn, action_page_types[ps->type], count);
 | 
				
			||||||
		result = FAILED;
 | 
							result = MF_FAILED;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	action_result(pfn, ps->type, result);
 | 
						action_result(pfn, ps->type, result);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -916,7 +882,7 @@ static int page_action(struct page_state *ps, struct page *p,
 | 
				
			||||||
	 * Could adjust zone counters here to correct for the missing page.
 | 
						 * Could adjust zone counters here to correct for the missing page.
 | 
				
			||||||
	 */
 | 
						 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return (result == RECOVERED || result == DELAYED) ? 0 : -EBUSY;
 | 
						return (result == MF_RECOVERED || result == MF_DELAYED) ? 0 : -EBUSY;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
| 
						 | 
					@ -1136,7 +1102,7 @@ int memory_failure(unsigned long pfn, int trapno, int flags)
 | 
				
			||||||
	 */
 | 
						 */
 | 
				
			||||||
	if (!(flags & MF_COUNT_INCREASED) && !get_hwpoison_page(p)) {
 | 
						if (!(flags & MF_COUNT_INCREASED) && !get_hwpoison_page(p)) {
 | 
				
			||||||
		if (is_free_buddy_page(p)) {
 | 
							if (is_free_buddy_page(p)) {
 | 
				
			||||||
			action_result(pfn, MSG_BUDDY, DELAYED);
 | 
								action_result(pfn, MF_MSG_BUDDY, MF_DELAYED);
 | 
				
			||||||
			return 0;
 | 
								return 0;
 | 
				
			||||||
		} else if (PageHuge(hpage)) {
 | 
							} else if (PageHuge(hpage)) {
 | 
				
			||||||
			/*
 | 
								/*
 | 
				
			||||||
| 
						 | 
					@ -1153,12 +1119,12 @@ int memory_failure(unsigned long pfn, int trapno, int flags)
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			set_page_hwpoison_huge_page(hpage);
 | 
								set_page_hwpoison_huge_page(hpage);
 | 
				
			||||||
			res = dequeue_hwpoisoned_huge_page(hpage);
 | 
								res = dequeue_hwpoisoned_huge_page(hpage);
 | 
				
			||||||
			action_result(pfn, MSG_FREE_HUGE,
 | 
								action_result(pfn, MF_MSG_FREE_HUGE,
 | 
				
			||||||
				      res ? IGNORED : DELAYED);
 | 
									      res ? MF_IGNORED : MF_DELAYED);
 | 
				
			||||||
			unlock_page(hpage);
 | 
								unlock_page(hpage);
 | 
				
			||||||
			return res;
 | 
								return res;
 | 
				
			||||||
		} else {
 | 
							} else {
 | 
				
			||||||
			action_result(pfn, MSG_KERNEL_HIGH_ORDER, IGNORED);
 | 
								action_result(pfn, MF_MSG_KERNEL_HIGH_ORDER, MF_IGNORED);
 | 
				
			||||||
			return -EBUSY;
 | 
								return -EBUSY;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					@ -1203,10 +1169,10 @@ int memory_failure(unsigned long pfn, int trapno, int flags)
 | 
				
			||||||
			 */
 | 
								 */
 | 
				
			||||||
			if (is_free_buddy_page(p)) {
 | 
								if (is_free_buddy_page(p)) {
 | 
				
			||||||
				if (flags & MF_COUNT_INCREASED)
 | 
									if (flags & MF_COUNT_INCREASED)
 | 
				
			||||||
					action_result(pfn, MSG_BUDDY, DELAYED);
 | 
										action_result(pfn, MF_MSG_BUDDY, MF_DELAYED);
 | 
				
			||||||
				else
 | 
									else
 | 
				
			||||||
					action_result(pfn, MSG_BUDDY_2ND,
 | 
										action_result(pfn, MF_MSG_BUDDY_2ND,
 | 
				
			||||||
						      DELAYED);
 | 
											      MF_DELAYED);
 | 
				
			||||||
				return 0;
 | 
									return 0;
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
| 
						 | 
					@ -1219,7 +1185,7 @@ int memory_failure(unsigned long pfn, int trapno, int flags)
 | 
				
			||||||
	 * If this happens just bail out.
 | 
						 * If this happens just bail out.
 | 
				
			||||||
	 */
 | 
						 */
 | 
				
			||||||
	if (PageCompound(p) && compound_head(p) != orig_head) {
 | 
						if (PageCompound(p) && compound_head(p) != orig_head) {
 | 
				
			||||||
		action_result(pfn, MSG_DIFFERENT_COMPOUND, IGNORED);
 | 
							action_result(pfn, MF_MSG_DIFFERENT_COMPOUND, MF_IGNORED);
 | 
				
			||||||
		res = -EBUSY;
 | 
							res = -EBUSY;
 | 
				
			||||||
		goto out;
 | 
							goto out;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					@ -1259,7 +1225,7 @@ int memory_failure(unsigned long pfn, int trapno, int flags)
 | 
				
			||||||
	 * on the head page to show that the hugepage is hwpoisoned
 | 
						 * on the head page to show that the hugepage is hwpoisoned
 | 
				
			||||||
	 */
 | 
						 */
 | 
				
			||||||
	if (PageHuge(p) && PageTail(p) && TestSetPageHWPoison(hpage)) {
 | 
						if (PageHuge(p) && PageTail(p) && TestSetPageHWPoison(hpage)) {
 | 
				
			||||||
		action_result(pfn, MSG_POISONED_HUGE, IGNORED);
 | 
							action_result(pfn, MF_MSG_POISONED_HUGE, MF_IGNORED);
 | 
				
			||||||
		unlock_page(hpage);
 | 
							unlock_page(hpage);
 | 
				
			||||||
		put_page(hpage);
 | 
							put_page(hpage);
 | 
				
			||||||
		return 0;
 | 
							return 0;
 | 
				
			||||||
| 
						 | 
					@ -1288,7 +1254,7 @@ int memory_failure(unsigned long pfn, int trapno, int flags)
 | 
				
			||||||
	 */
 | 
						 */
 | 
				
			||||||
	if (hwpoison_user_mappings(p, pfn, trapno, flags, &hpage)
 | 
						if (hwpoison_user_mappings(p, pfn, trapno, flags, &hpage)
 | 
				
			||||||
	    != SWAP_SUCCESS) {
 | 
						    != SWAP_SUCCESS) {
 | 
				
			||||||
		action_result(pfn, MSG_UNMAP_FAILED, IGNORED);
 | 
							action_result(pfn, MF_MSG_UNMAP_FAILED, MF_IGNORED);
 | 
				
			||||||
		res = -EBUSY;
 | 
							res = -EBUSY;
 | 
				
			||||||
		goto out;
 | 
							goto out;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					@ -1297,7 +1263,7 @@ int memory_failure(unsigned long pfn, int trapno, int flags)
 | 
				
			||||||
	 * Torn down by someone else?
 | 
						 * Torn down by someone else?
 | 
				
			||||||
	 */
 | 
						 */
 | 
				
			||||||
	if (PageLRU(p) && !PageSwapCache(p) && p->mapping == NULL) {
 | 
						if (PageLRU(p) && !PageSwapCache(p) && p->mapping == NULL) {
 | 
				
			||||||
		action_result(pfn, MSG_TRUNCATED_LRU, IGNORED);
 | 
							action_result(pfn, MF_MSG_TRUNCATED_LRU, MF_IGNORED);
 | 
				
			||||||
		res = -EBUSY;
 | 
							res = -EBUSY;
 | 
				
			||||||
		goto out;
 | 
							goto out;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in a new issue