lkml.org 
[lkml]   [2009]   [Dec]   [1]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Date
    From
    Subject[PATCH 09/24] HWPOISON: introduce delete_from_lru_cache()
    Introduce delete_from_lru_cache() to
    - clear PG_active, PG_unevictable to avoid complains at unpoison time
    - move the isolate_lru_page() call back to the handlers instead of the
    entrance of __memory_failure(), this is more hwpoison filter friendly

    CC: Andi Kleen <andi@firstfloor.org>
    Signed-off-by: Wu Fengguang <fengguang.wu@intel.com>
    ---
    mm/memory-failure.c | 45 ++++++++++++++++++++++++++++++++++--------
    1 file changed, 37 insertions(+), 8 deletions(-)

    --- linux-mm.orig/mm/memory-failure.c 2009-11-30 11:12:41.000000000 +0800
    +++ linux-mm/mm/memory-failure.c 2009-11-30 20:04:43.000000000 +0800
    @@ -328,6 +328,30 @@ static const char *action_name[] = {
    };

    /*
    + * XXX: It is possible that a page is isolated from LRU cache,
    + * and then kept in swap cache or failed to remove from page cache.
    + * The page count will stop it from being freed by unpoison.
    + * Stress tests should be aware of this memory leak problem.
    + */
    +static int delete_from_lru_cache(struct page *p)
    +{
    + if (!isolate_lru_page(p)) {
    + /*
    + * Clear sensible page flags, so that the buddy system won't
    + * complain when the page is unpoison-and-freed.
    + */
    + ClearPageActive(p);
    + ClearPageUnevictable(p);
    + /*
    + * drop the page count elevated by isolate_lru_page()
    + */
    + page_cache_release(p);
    + return 0;
    + }
    + return -EIO;
    +}
    +
    +/*
    * Error hit kernel page.
    * Do nothing, try to be lucky and not touch this instead. For a few cases we
    * could be more sophisticated.
    @@ -371,6 +395,8 @@ static int me_pagecache_clean(struct pag
    int ret = FAILED;
    struct address_space *mapping;

    + delete_from_lru_cache(p);
    +
    /*
    * For anonymous pages we're done the only reference left
    * should be the one m_f() holds.
    @@ -500,14 +526,20 @@ static int me_swapcache_dirty(struct pag
    /* Trigger EIO in shmem: */
    ClearPageUptodate(p);

    - return DELAYED;
    + if (!delete_from_lru_cache(p))
    + return DELAYED;
    + else
    + return FAILED;
    }

    static int me_swapcache_clean(struct page *p, unsigned long pfn)
    {
    delete_from_swap_cache(p);

    - return RECOVERED;
    + if (!delete_from_lru_cache(p))
    + return RECOVERED;
    + else
    + return FAILED;
    }

    /*
    @@ -726,7 +758,6 @@ static int hwpoison_user_mappings(struct

    int __memory_failure(unsigned long pfn, int trapno, int ref)
    {
    - unsigned long lru_flag;
    struct page_state *ps;
    struct page *p;
    int res;
    @@ -775,13 +806,11 @@ int __memory_failure(unsigned long pfn,
    */
    if (!PageLRU(p))
    lru_add_drain_all();
    - lru_flag = p->flags & lru;
    - if (isolate_lru_page(p)) {
    + if (!PageLRU(p)) {
    action_result(pfn, "non LRU", IGNORED);
    put_page(p);
    return -EBUSY;
    }
    - page_cache_release(p);

    /*
    * Lock the page and wait for writeback to finish.
    @@ -803,7 +832,7 @@ int __memory_failure(unsigned long pfn,
    /*
    * Torn down by someone else?
    */
    - if ((lru_flag & lru) && !PageSwapCache(p) && p->mapping == NULL) {
    + if (PageLRU(p) && !PageSwapCache(p) && p->mapping == NULL) {
    action_result(pfn, "already truncated LRU", IGNORED);
    res = 0;
    goto out;
    @@ -811,7 +840,7 @@ int __memory_failure(unsigned long pfn,

    res = -EBUSY;
    for (ps = error_states;; ps++) {
    - if (((p->flags | lru_flag)& ps->mask) == ps->res) {
    + if ((p->flags & ps->mask) == ps->res) {
    res = page_action(ps, p, pfn);
    break;
    }



    \
     
     \ /
      Last update: 2009-12-02 05:43    [W:0.027 / U:0.660 seconds]
    ©2003-2016 Jasper Spaans. hosted at Digital OceanAdvertise on this site