lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Date:	Wed, 8 Apr 2015 01:45:25 +0000
From:	Naoya Horiguchi <n-horiguchi@...jp.nec.com>
To:	Xie XiuQi <xiexiuqi@...wei.com>
CC:	"rostedt@...dmis.org" <rostedt@...dmis.org>,
	"mingo@...hat.com" <mingo@...hat.com>,
	"akpm@...ux-foundation.org" <akpm@...ux-foundation.org>,
	"kirill.shutemov@...ux.intel.com" <kirill.shutemov@...ux.intel.com>,
	"koct9i@...il.com" <koct9i@...il.com>,
	"hpa@...ux.intel.com" <hpa@...ux.intel.com>,
	"hannes@...xchg.org" <hannes@...xchg.org>,
	"iamjoonsoo.kim@....com" <iamjoonsoo.kim@....com>,
	"luto@...capital.net" <luto@...capital.net>,
	"nasa4836@...il.com" <nasa4836@...il.com>,
	"gong.chen@...ux.intel.com" <gong.chen@...ux.intel.com>,
	"bhelgaas@...gle.com" <bhelgaas@...gle.com>,
	"bp@...e.de" <bp@...e.de>,
	"tony.luck@...el.com" <tony.luck@...el.com>,
	"linux-kernel@...r.kernel.org" <linux-kernel@...r.kernel.org>,
	"linux-mm@...ck.org" <linux-mm@...ck.org>
Subject: Re: [RFC PATCH v3 1/2] memory-failure: export page_type and action
 result

On Tue, Apr 07, 2015 at 07:05:30PM +0800, Xie XiuQi wrote:
> Export 'outcome' and '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@...wei.com>

I made some update on mm/memory-failure.c, so some more rebasing is needed.
Please see mm-memory-failurec-define-page-types-for-action_result-in-one-place-v3
in latest linux-mmotm.

Other than that, this patch looks good to me.

Thanks,
Naoya Horiguchi

> ---
>  include/linux/mm.h  |  34 +++++++++++
>  mm/memory-failure.c | 163 +++++++++++++++++++++-------------------------------
>  2 files changed, 99 insertions(+), 98 deletions(-)
> 
> diff --git a/include/linux/mm.h b/include/linux/mm.h
> index 4a3a385..5d812b0 100644
> --- a/include/linux/mm.h
> +++ b/include/linux/mm.h
> @@ -2114,6 +2114,40 @@ extern void shake_page(struct page *p, int access);
>  extern atomic_long_t num_poisoned_pages;
>  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_page_type {
> +	MF_KERNEL,
> +	MF_KERNEL_HIGH_ORDER,
> +	MF_SLAB,
> +	MF_DIFFERENT_COMPOUND,
> +	MF_POISONED_HUGE,
> +	MF_HUGE,
> +	MF_FREE_HUGE,
> +	MF_UNMAP_FAILED,
> +	MF_DIRTY_SWAPCACHE,
> +	MF_CLEAN_SWAPCACHE,
> +	MF_DIRTY_MLOCKED_LRU,
> +	MF_CLEAN_MLOCKED_LRU,
> +	MF_DIRTY_UNEVICTABLE_LRU,
> +	MF_CLEAN_UNEVICTABLE_LRU,
> +	MF_DIRTY_LRU,
> +	MF_CLEAN_LRU,
> +	MF_TRUNCATED_LRU,
> +	MF_BUDDY,
> +	MF_BUDDY_2ND,
> +	MF_UNKNOWN,
> +};
> +
>  #if defined(CONFIG_TRANSPARENT_HUGEPAGE) || defined(CONFIG_HUGETLBFS)
>  extern void clear_huge_page(struct page *page,
>  			    unsigned long addr,
> diff --git a/mm/memory-failure.c b/mm/memory-failure.c
> index 5074998..34e9c65 100644
> --- a/mm/memory-failure.c
> +++ b/mm/memory-failure.c
> @@ -56,6 +56,7 @@
>  #include <linux/mm_inline.h>
>  #include <linux/kfifo.h>
>  #include "internal.h"
> +#include "ras/ras_event.h"
>  
>  int sysctl_memory_failure_early_kill __read_mostly = 0;
>  
> @@ -503,68 +504,34 @@ static void collect_procs(struct page *page, struct list_head *tokill,
>  	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[] = {
> -	[IGNORED] = "Ignored",
> -	[FAILED] = "Failed",
> -	[DELAYED] = "Delayed",
> -	[RECOVERED] = "Recovered",
> -};
> -
> -enum page_type {
> -	KERNEL,
> -	KERNEL_HIGH_ORDER,
> -	SLAB,
> -	DIFFERENT_COMPOUND,
> -	POISONED_HUGE,
> -	HUGE,
> -	FREE_HUGE,
> -	UNMAP_FAILED,
> -	DIRTY_SWAPCACHE,
> -	CLEAN_SWAPCACHE,
> -	DIRTY_MLOCKED_LRU,
> -	CLEAN_MLOCKED_LRU,
> -	DIRTY_UNEVICTABLE_LRU,
> -	CLEAN_UNEVICTABLE_LRU,
> -	DIRTY_LRU,
> -	CLEAN_LRU,
> -	TRUNCATED_LRU,
> -	BUDDY,
> -	BUDDY_2ND,
> -	UNKNOWN,
> +	[MF_IGNORED] = "Ignored",
> +	[MF_FAILED] = "Failed",
> +	[MF_DELAYED] = "Delayed",
> +	[MF_RECOVERED] = "Recovered",
>  };
>  
>  static const char *action_page_type[] = {
> -	[KERNEL]		= "reserved kernel page",
> -	[KERNEL_HIGH_ORDER]	= "high-order kernel page",
> -	[SLAB]			= "kernel slab page",
> -	[DIFFERENT_COMPOUND]	= "different compound page after locking",
> -	[POISONED_HUGE]		= "huge page already hardware poisoned",
> -	[HUGE]			= "huge page",
> -	[FREE_HUGE]		= "free huge page",
> -	[UNMAP_FAILED]		= "unmapping failed page",
> -	[DIRTY_SWAPCACHE]	= "dirty swapcache page",
> -	[CLEAN_SWAPCACHE]	= "clean swapcache page",
> -	[DIRTY_MLOCKED_LRU]	= "dirty mlocked LRU page",
> -	[CLEAN_MLOCKED_LRU]	= "clean mlocked LRU page",
> -	[DIRTY_UNEVICTABLE_LRU]	= "dirty unevictable LRU page",
> -	[CLEAN_UNEVICTABLE_LRU]	= "clean unevictable LRU page",
> -	[DIRTY_LRU]		= "dirty LRU page",
> -	[CLEAN_LRU]		= "clean LRU page",
> -	[TRUNCATED_LRU]		= "already truncated LRU page",
> -	[BUDDY]			= "free buddy page",
> -	[BUDDY_2ND]		= "free buddy page (2nd try)",
> -	[UNKNOWN]		= "unknown page",
> +	[MF_KERNEL]			= "reserved kernel page",
> +	[MF_KERNEL_HIGH_ORDER]		= "high-order kernel page",
> +	[MF_SLAB]			= "kernel slab page",
> +	[MF_DIFFERENT_COMPOUND]		= "different compound page after locking",
> +	[MF_POISONED_HUGE]		= "huge page already hardware poisoned",
> +	[MF_HUGE]			= "huge page",
> +	[MF_FREE_HUGE]			= "free huge page",
> +	[MF_UNMAP_FAILED]		= "unmapping failed page",
> +	[MF_DIRTY_SWAPCACHE]		= "dirty swapcache page",
> +	[MF_CLEAN_SWAPCACHE]		= "clean swapcache page",
> +	[MF_DIRTY_MLOCKED_LRU]		= "dirty mlocked LRU page",
> +	[MF_CLEAN_MLOCKED_LRU]		= "clean mlocked LRU page",
> +	[MF_DIRTY_UNEVICTABLE_LRU]	= "dirty unevictable LRU page",
> +	[MF_CLEAN_UNEVICTABLE_LRU]	= "clean unevictable LRU page",
> +	[MF_DIRTY_LRU]			= "dirty LRU page",
> +	[MF_CLEAN_LRU]			= "clean LRU page",
> +	[MF_TRUNCATED_LRU]		= "already truncated LRU page",
> +	[MF_BUDDY]			= "free buddy page",
> +	[MF_BUDDY_2ND]			= "free buddy page (2nd try)",
> +	[MF_UNKNOWN]			= "unknown page",
>  };
>  
>  /*
> @@ -598,7 +565,7 @@ static int delete_from_lru_cache(struct page *p)
>   */
>  static int me_kernel(struct page *p, unsigned long pfn)
>  {
> -	return IGNORED;
> +	return MF_IGNORED;
>  }
>  
>  /*
> @@ -607,7 +574,7 @@ static int me_kernel(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);
> -	return FAILED;
> +	return MF_FAILED;
>  }
>  
>  /*
> @@ -616,7 +583,7 @@ static int me_unknown(struct page *p, unsigned long pfn)
>  static int me_pagecache_clean(struct page *p, unsigned long pfn)
>  {
>  	int err;
> -	int ret = FAILED;
> +	int ret = MF_FAILED;
>  	struct address_space *mapping;
>  
>  	delete_from_lru_cache(p);
> @@ -626,7 +593,7 @@ static int me_pagecache_clean(struct page *p, unsigned long pfn)
>  	 * should be the one m_f() holds.
>  	 */
>  	if (PageAnon(p))
> -		return RECOVERED;
> +		return MF_RECOVERED;
>  
>  	/*
>  	 * Now truncate the page in the page cache. This is really
> @@ -640,7 +607,7 @@ static int me_pagecache_clean(struct page *p, unsigned long pfn)
>  		/*
>  		 * Page has been teared down in the meanwhile
>  		 */
> -		return FAILED;
> +		return MF_FAILED;
>  	}
>  
>  	/*
> @@ -657,7 +624,7 @@ static int me_pagecache_clean(struct page *p, unsigned long pfn)
>  				!try_to_release_page(p, GFP_NOIO)) {
>  			pr_info("MCE %#lx: failed to release buffers\n", pfn);
>  		} else {
> -			ret = RECOVERED;
> +			ret = MF_RECOVERED;
>  		}
>  	} else {
>  		/*
> @@ -665,7 +632,7 @@ static int me_pagecache_clean(struct page *p, unsigned long pfn)
>  		 * This fails on dirty or anything with private pages
>  		 */
>  		if (invalidate_inode_page(p))
> -			ret = RECOVERED;
> +			ret = MF_RECOVERED;
>  		else
>  			printk(KERN_INFO "MCE %#lx: Failed to invalidate\n",
>  				pfn);
> @@ -751,9 +718,9 @@ static int me_swapcache_dirty(struct page *p, unsigned long pfn)
>  	ClearPageUptodate(p);
>  
>  	if (!delete_from_lru_cache(p))
> -		return DELAYED;
> +		return MF_DELAYED;
>  	else
> -		return FAILED;
> +		return MF_FAILED;
>  }
>  
>  static int me_swapcache_clean(struct page *p, unsigned long pfn)
> @@ -761,9 +728,9 @@ static int me_swapcache_clean(struct page *p, unsigned long pfn)
>  	delete_from_swap_cache(p);
>  
>  	if (!delete_from_lru_cache(p))
> -		return RECOVERED;
> +		return MF_RECOVERED;
>  	else
> -		return FAILED;
> +		return MF_FAILED;
>  }
>  
>  /*
> @@ -789,9 +756,9 @@ static int me_huge_page(struct page *p, unsigned long pfn)
>  	if (!(page_mapping(hpage) || PageAnon(hpage))) {
>  		res = dequeue_hwpoisoned_huge_page(hpage);
>  		if (!res)
> -			return RECOVERED;
> +			return MF_RECOVERED;
>  	}
> -	return DELAYED;
> +	return MF_DELAYED;
>  }
>  
>  /*
> @@ -826,7 +793,7 @@ static struct page_state {
>  	int type;
>  	int (*action)(struct page *p, unsigned long pfn);
>  } error_states[] = {
> -	{ reserved,	reserved,	KERNEL,	me_kernel },
> +	{ reserved,	reserved,	MF_KERNEL,	me_kernel },
>  	/*
>  	 * free pages are specially detected outside this table:
>  	 * PG_buddy pages only make a small fraction of all free pages.
> @@ -837,31 +804,31 @@ static struct page_state {
>  	 * currently unused objects without touching them. But just
>  	 * treat it as standard kernel for now.
>  	 */
> -	{ slab,		slab,		SLAB,	me_kernel },
> +	{ slab,		slab,		MF_SLAB,	me_kernel },
>  
>  #ifdef CONFIG_PAGEFLAGS_EXTENDED
> -	{ head,		head,		HUGE,		me_huge_page },
> -	{ tail,		tail,		HUGE,		me_huge_page },
> +	{ head,		head,		MF_HUGE,		me_huge_page },
> +	{ tail,		tail,		MF_HUGE,		me_huge_page },
>  #else
> -	{ compound,	compound,	HUGE,		me_huge_page },
> +	{ compound,	compound,	MF_HUGE,		me_huge_page },
>  #endif
>  
> -	{ sc|dirty,	sc|dirty,	DIRTY_SWAPCACHE,	me_swapcache_dirty },
> -	{ sc|dirty,	sc,		CLEAN_SWAPCACHE,	me_swapcache_clean },
> +	{ sc|dirty,	sc|dirty,	MF_DIRTY_SWAPCACHE,	me_swapcache_dirty },
> +	{ sc|dirty,	sc,		MF_CLEAN_SWAPCACHE,	me_swapcache_clean },
>  
> -	{ mlock|dirty,	mlock|dirty,	DIRTY_MLOCKED_LRU,	me_pagecache_dirty },
> -	{ mlock|dirty,	mlock,		CLEAN_MLOCKED_LRU,	me_pagecache_clean },
> +	{ mlock|dirty,	mlock|dirty,	MF_DIRTY_MLOCKED_LRU,	me_pagecache_dirty },
> +	{ mlock|dirty,	mlock,		MF_CLEAN_MLOCKED_LRU,	me_pagecache_clean },
>  
> -	{ unevict|dirty, unevict|dirty,	DIRTY_UNEVICTABLE_LRU,	me_pagecache_dirty },
> -	{ unevict|dirty, unevict,	CLEAN_UNEVICTABLE_LRU,	me_pagecache_clean },
> +	{ unevict|dirty, unevict|dirty,	MF_DIRTY_UNEVICTABLE_LRU,	me_pagecache_dirty },
> +	{ unevict|dirty, unevict,	MF_CLEAN_UNEVICTABLE_LRU,	me_pagecache_clean },
>  
> -	{ lru|dirty,	lru|dirty,	DIRTY_LRU,	me_pagecache_dirty },
> -	{ lru|dirty,	lru,		CLEAN_LRU,	me_pagecache_clean },
> +	{ lru|dirty,	lru|dirty,	MF_DIRTY_LRU,	me_pagecache_dirty },
> +	{ lru|dirty,	lru,		MF_CLEAN_LRU,	me_pagecache_clean },
>  
>  	/*
>  	 * Catchall entry: must be at end.
>  	 */
> -	{ 0,		0,		UNKNOWN,	me_unknown },
> +	{ 0,		0,		MF_UNKNOWN,	me_unknown },
>  };
>  
>  #undef dirty
> @@ -896,13 +863,13 @@ static int page_action(struct page_state *ps, struct page *p,
>  	result = ps->action(p, pfn);
>  
>  	count = page_count(p) - 1;
> -	if (ps->action == me_swapcache_dirty && result == DELAYED)
> +	if (ps->action == me_swapcache_dirty && result == MF_DELAYED)
>  		count--;
>  	if (count != 0) {
>  		printk(KERN_ERR
>  		       "MCE %#lx: %s still referenced by %d users\n",
>  		       pfn, action_page_type[ps->type], count);
> -		result = FAILED;
> +		result = MF_FAILED;
>  	}
>  	action_result(pfn, ps->type, result);
>  
> @@ -911,7 +878,7 @@ static int page_action(struct page_state *ps, struct page *p,
>  	 * 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;
>  }
>  
>  /*
> @@ -1152,7 +1119,7 @@ int memory_failure(unsigned long pfn, int trapno, int flags)
>  	if (!(flags & MF_COUNT_INCREASED) &&
>  		!get_page_unless_zero(hpage)) {
>  		if (is_free_buddy_page(p)) {
> -			action_result(pfn, BUDDY, DELAYED);
> +			action_result(pfn, MF_BUDDY, MF_DELAYED);
>  			return 0;
>  		} else if (PageHuge(hpage)) {
>  			/*
> @@ -1169,12 +1136,12 @@ int memory_failure(unsigned long pfn, int trapno, int flags)
>  			}
>  			set_page_hwpoison_huge_page(hpage);
>  			res = dequeue_hwpoisoned_huge_page(hpage);
> -			action_result(pfn, FREE_HUGE,
> -				      res ? IGNORED : DELAYED);
> +			action_result(pfn, MF_FREE_HUGE,
> +				      res ? MF_IGNORED : MF_DELAYED);
>  			unlock_page(hpage);
>  			return res;
>  		} else {
> -			action_result(pfn, KERNEL_HIGH_ORDER, IGNORED);
> +			action_result(pfn, MF_KERNEL_HIGH_ORDER, MF_IGNORED);
>  			return -EBUSY;
>  		}
>  	}
> @@ -1196,9 +1163,9 @@ int memory_failure(unsigned long pfn, int trapno, int flags)
>  			 */
>  			if (is_free_buddy_page(p)) {
>  				if (flags & MF_COUNT_INCREASED)
> -					action_result(pfn, BUDDY, DELAYED);
> +					action_result(pfn, MF_BUDDY, MF_DELAYED);
>  				else
> -					action_result(pfn, BUDDY_2ND, DELAYED);
> +					action_result(pfn, MF_BUDDY_2ND, MF_DELAYED);
>  				return 0;
>  			}
>  		}
> @@ -1211,7 +1178,7 @@ int memory_failure(unsigned long pfn, int trapno, int flags)
>  	 * If this happens just bail out.
>  	 */
>  	if (compound_head(p) != hpage) {
> -		action_result(pfn, DIFFERENT_COMPOUND, IGNORED);
> +		action_result(pfn, MF_DIFFERENT_COMPOUND, MF_IGNORED);
>  		res = -EBUSY;
>  		goto out;
>  	}
> @@ -1251,7 +1218,7 @@ int memory_failure(unsigned long pfn, int trapno, int flags)
>  	 * on the head page to show that the hugepage is hwpoisoned
>  	 */
>  	if (PageHuge(p) && PageTail(p) && TestSetPageHWPoison(hpage)) {
> -		action_result(pfn, POISONED_HUGE, IGNORED);
> +		action_result(pfn, MF_POISONED_HUGE, MF_IGNORED);
>  		unlock_page(hpage);
>  		put_page(hpage);
>  		return 0;
> @@ -1280,7 +1247,7 @@ int memory_failure(unsigned long pfn, int trapno, int flags)
>  	 */
>  	if (hwpoison_user_mappings(p, pfn, trapno, flags, &hpage)
>  	    != SWAP_SUCCESS) {
> -		action_result(pfn, UNMAP_FAILED, IGNORED);
> +		action_result(pfn, MF_UNMAP_FAILED, MF_IGNORED);
>  		res = -EBUSY;
>  		goto out;
>  	}
> @@ -1289,7 +1256,7 @@ int memory_failure(unsigned long pfn, int trapno, int flags)
>  	 * Torn down by someone else?
>  	 */
>  	if (PageLRU(p) && !PageSwapCache(p) && p->mapping == NULL) {
> -		action_result(pfn, TRUNCATED_LRU, IGNORED);
> +		action_result(pfn, MF_TRUNCATED_LRU, MF_IGNORED);
>  		res = -EBUSY;
>  		goto out;
>  	}
> -- 
> 1.8.3.1
> --
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Powered by blists - more mailing lists