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 <xiexi...@huawei.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 majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Reply via email to