On 2015/4/8 9:45, Naoya Horiguchi wrote:
> 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 <[email protected]>
> 
> 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.

OK, I will

> 
> Other than that, this patch looks good to me.

Thanks!

> 
> 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 [email protected]
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