16 Dec, 2009

23 commits

  • Better to have complete sentences.

    Signed-off-by: Andi Kleen

    Andi Kleen
     
  • Signed-off-by: Andi Kleen

    Andi Kleen
     
  • This is a simpler, gentler variant of memory_failure() for soft page
    offlining controlled from user space. It doesn't kill anything, just
    tries to invalidate and if that doesn't work migrate the
    page away.

    This is useful for predictive failure analysis, where a page has
    a high rate of corrected errors, but hasn't gone bad yet. Instead
    it can be offlined early and avoided.

    The offlining is controlled from sysfs, including a new generic
    entry point for hard page offlining for symmetry too.

    We use the page isolate facility to prevent re-allocation
    race. Normally this is only used by memory hotplug. To avoid
    races with memory allocation I am using lock_system_sleep().
    This avoids the situation where memory hotplug is about
    to isolate a page range and then hwpoison undoes that work.
    This is a big hammer currently, but the simplest solution
    currently.

    When the page is not free or LRU we try to free pages
    from slab and other caches. The slab freeing is currently
    quite dumb and does not try to focus on the specific slab
    cache which might own the page. This could be potentially
    improved later.

    Thanks to Fengguang Wu and Haicheng Li for some fixes.

    [Added fix from Andrew Morton to adapt to new migrate_pages prototype]
    Signed-off-by: Andi Kleen

    Andi Kleen
     
  • Signed-off-by: Andi Kleen

    Andi Kleen
     
  • shake_page handles more types of page caches than
    the much simpler lru_add_drain_all:

    - slab (quite inefficiently for now)
    - any other caches with a shrinker callback
    - per cpu page allocator pages
    - per CPU LRU

    Use this call to try to turn pages into free or LRU pages.
    Then handle the case of the page becoming free after drain everything.

    Signed-off-by: Andi Kleen

    Andi Kleen
     
  • In some use cases, user doesn't need extra filtering. E.g. user program
    can inject errors through madvise syscall to its own pages, however it
    might not know what the page state exactly is or which inode the page
    belongs to.

    So introduce an one-off interface "corrupt-filter-enable".

    Echo 0 to switch off page filters, and echo 1 to switch on the filters.
    [AK: changed default to 0]

    Signed-off-by: Haicheng Li
    Signed-off-by: Wu Fengguang
    Signed-off-by: Andi Kleen

    Haicheng Li
     
  • The hwpoison test suite need to inject hwpoison to a collection of
    selected task pages, and must not touch pages not owned by them and
    thus kill important system processes such as init. (But it's OK to
    mis-hwpoison free/unowned pages as well as shared clean pages.
    Mis-hwpoison of shared dirty pages will kill all tasks, so the test
    suite will target all or non of such tasks in the first place.)

    The memory cgroup serves this purpose well. We can put the target
    processes under the control of a memory cgroup, and tell the hwpoison
    injection code to only kill pages associated with some active memory
    cgroup.

    The prerequisite for doing hwpoison stress tests with mem_cgroup is,
    the mem_cgroup code tracks task pages _accurately_ (unless page is
    locked). Which we believe is/should be true.

    The benefits are simplification of hwpoison injector code. Also the
    mem_cgroup code will automatically be tested by hwpoison test cases.

    The alternative interfaces pin-pfn/unpin-pfn can also delegate the
    (process and page flags) filtering functions reliably to user space.
    However prototype implementation shows that this scheme adds more
    complexity than we wanted.

    Example test case:

    mkdir /cgroup/hwpoison

    usemem -m 100 -s 1000 &
    echo `jobs -p` > /cgroup/hwpoison/tasks

    memcg_ino=$(ls -id /cgroup/hwpoison | cut -f1 -d' ')
    echo $memcg_ino > /debug/hwpoison/corrupt-filter-memcg

    page-types -p `pidof init` --hwpoison # shall do nothing
    page-types -p `pidof usemem` --hwpoison # poison its pages

    [AK: Fix documentation]
    [Add fix for problem noticed by Li Zefan ;
    dentry in the css could be NULL]

    CC: KOSAKI Motohiro
    CC: Hugh Dickins
    CC: Daisuke Nishimura
    CC: Balbir Singh
    CC: KAMEZAWA Hiroyuki
    CC: Li Zefan
    CC: Paul Menage
    CC: Nick Piggin
    CC: Andi Kleen
    Signed-off-by: Wu Fengguang
    Signed-off-by: Andi Kleen

    Andi Kleen
     
  • When specified, only poison pages if ((page_flags & mask) == value).

    - corrupt-filter-flags-mask
    - corrupt-filter-flags-value

    This allows stress testing of many kinds of pages.

    Strictly speaking, the buddy pages requires taking zone lock, to avoid
    setting PG_hwpoison on a "was buddy but now allocated to someone" page.
    However we can just do nothing because we set PG_locked in the beginning,
    this prevents the page allocator from allocating it to someone. (It will
    BUG() on the unexpected PG_locked, which is fine for hwpoison testing.)

    [AK: Add select PROC_PAGE_MONITOR to satisfy dependency]

    CC: Nick Piggin
    Signed-off-by: Wu Fengguang
    Signed-off-by: Andi Kleen

    Wu Fengguang
     
  • Filesystem data/metadata present the most tricky-to-isolate pages.
    It requires careful code review and stress testing to get them right.

    The fs/device filter helps to target the stress tests to some specific
    filesystem pages. The filter condition is block device's major/minor
    numbers:
    - corrupt-filter-dev-major
    - corrupt-filter-dev-minor
    When specified (non -1), only page cache pages that belong to that
    device will be poisoned.

    The filters are checked reliably on the locked and refcounted page.

    Haicheng: clear PG_hwpoison and drop bad page count if filter not OK
    AK: Add documentation

    CC: Haicheng Li
    CC: Nick Piggin
    Signed-off-by: Wu Fengguang
    Signed-off-by: Andi Kleen

    Wu Fengguang
     
  • Return 0 to indicate success, when
    - action result is RECOVERED or DELAYED
    - no extra page reference

    Note that dirty swapcache pages are kept in swapcache, so can have one
    more reference count.

    Signed-off-by: Wu Fengguang
    Signed-off-by: Andi Kleen

    Wu Fengguang
     
  • Change semantics for
    - IGNORED: not handled; it may well be _unsafe_
    - DELAYED: to be handled later; it is _safe_

    With this change,
    - IGNORED/FAILED mean (maybe) Error
    - DELAYED/RECOVERED mean Success

    Signed-off-by: Wu Fengguang
    Signed-off-by: Andi Kleen

    Wu Fengguang
     
  • The unpoisoning interface is useful for stress testing tools to
    reclaim poisoned pages (to prevent OOM)

    There is no hardware level unpoisioning, so this
    cannot be used for real memory errors, only for software injected errors.

    Note that it may leak pages silently - those who have been removed from
    LRU cache, but not isolated from page cache/swap cache at hwpoison time.
    Especially the stress test of dirty swap cache pages shall reboot system
    before exhausting memory.

    AK: Fix comments, add documentation, add printks, rename symbol

    Signed-off-by: Wu Fengguang
    Signed-off-by: Andi Kleen

    Wu Fengguang
     
  • Most free pages in the buddy system have no PG_buddy set.
    Introduce is_free_buddy_page() for detecting them reliably.

    CC: Nick Piggin
    CC: Mel Gorman
    Signed-off-by: Wu Fengguang
    Signed-off-by: Andi Kleen

    Wu Fengguang
     
  • The buddy page has already be handled in the very beginning.
    So remove redundant code.

    Signed-off-by: Wu Fengguang
    Signed-off-by: Andi Kleen

    Wu Fengguang
     
  • 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

    Signed-off-by: Wu Fengguang
    Signed-off-by: Andi Kleen

    Wu Fengguang
     
  • Signed-off-by: Wu Fengguang
    Signed-off-by: Andi Kleen

    Wu Fengguang
     
  • Don't try to isolate a still mapped page. Otherwise we will hit the
    BUG_ON(page_mapped(page)) in __remove_from_page_cache().

    Signed-off-by: Wu Fengguang
    Signed-off-by: Andi Kleen

    Wu Fengguang
     
  • Now that "ref" is just a boolean turn it into
    a flags argument. First step is only a single flag
    that makes the code's intention more clear, but more
    may follow.

    Signed-off-by: Andi Kleen

    Andi Kleen
     
  • If page is double referenced in madvise_hwpoison() and __memory_failure(),
    remove_mapping() will fail because it expects page_count=2. Fix it by
    not grabbing extra page count in __memory_failure().

    Signed-off-by: Wu Fengguang
    Signed-off-by: Andi Kleen

    Wu Fengguang
     
  • Use a different errno than the usual EIO for invalid page numbers.
    This is mainly for better reporting for the injector.

    This also avoids calling action_result() with invalid pfn.

    Signed-off-by: Wu Fengguang
    Signed-off-by: Andi Kleen

    Wu Fengguang
     
  • (PG_swapbacked && !PG_lru) pages should not happen.
    Better to treat them as unknown pages.

    Signed-off-by: Wu Fengguang
    Signed-off-by: Andi Kleen

    Wu Fengguang
     
  • shake_page handles more types of page caches than lru_drain_all()

    - per cpu page allocator pages
    - per CPU LRU

    Stops early when the page became free.

    Used in followon patches.

    Signed-off-by: Andi Kleen

    Andi Kleen
     
  • Remove three degrees of obfuscation, left over from when we had
    CONFIG_UNEVICTABLE_LRU. MLOCK_PAGES is CONFIG_HAVE_MLOCKED_PAGE_BIT is
    CONFIG_HAVE_MLOCK is CONFIG_MMU. rmap.o (and memory-failure.o) are only
    built when CONFIG_MMU, so don't need such conditions at all.

    Somehow, I feel no compulsion to remove the CONFIG_HAVE_MLOCK* lines from
    169 defconfigs: leave those to evolve in due course.

    Signed-off-by: Hugh Dickins
    Cc: Izik Eidus
    Cc: Andrea Arcangeli
    Cc: Nick Piggin
    Reviewed-by: KOSAKI Motohiro
    Cc: Rik van Riel
    Cc: Lee Schermerhorn
    Cc: Andi Kleen
    Cc: KAMEZAWA Hiroyuki
    Cc: Wu Fengguang
    Cc: Minchan Kim
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Hugh Dickins
     

04 Dec, 2009

1 commit

  • That is "success", "unknown", "through", "performance", "[re|un]mapping"
    , "access", "default", "reasonable", "[con]currently", "temperature"
    , "channel", "[un]used", "application", "example","hierarchy", "therefore"
    , "[over|under]flow", "contiguous", "threshold", "enough" and others.

    Signed-off-by: André Goddard Rosa
    Signed-off-by: Jiri Kosina

    André Goddard Rosa
     

19 Oct, 2009

3 commits

  • The madvise injector already holds a reference when passing in a page
    to the memory-failure code. The code corrects for this additional reference
    for its checks, but the final printk output didn't. Fix that.

    Signed-off-by: Wu Fengguang
    Signed-off-by: Andi Kleen

    Wu Fengguang
     
  • Memory failure on a KSM page currently oopses on its NULL anon_vma in
    page_lock_anon_vma(): that may not be much worse than the consequence
    of ignoring it, but it is better to be consistent with how ZERO_PAGE
    and hugetlb pages and other awkward cases are treated. Just skip it.

    Signed-off-by: Hugh Dickins
    Signed-off-by: Andi Kleen

    Hugh Dickins
     
  • Right now we have some trouble with non atomic access
    to page flags when locking the page. To plug this hole
    for now, limit error recovery to LRU pages for now.

    This could be better fixed by defining a suitable protocol,
    but let's go this simple way for now

    This avoids unnecessary races with __set_page_locked() and
    __SetPageSlab*() and maybe more non-atomic page flag operations.

    This loses isolated pages which are currently in page reclaim, but these
    are relatively limited compared to the total memory.

    Signed-off-by: Wu Fengguang
    Signed-off-by: Andi Kleen
    [AK: new description, bug fixes, cleanups]

    Wu Fengguang
     

16 Sep, 2009

1 commit

  • Add the high level memory handler that poisons pages
    that got corrupted by hardware (typically by a two bit flip in a DIMM
    or a cache) on the Linux level. The goal is to prevent everyone
    from accessing these pages in the future.

    This done at the VM level by marking a page hwpoisoned
    and doing the appropriate action based on the type of page
    it is.

    The code that does this is portable and lives in mm/memory-failure.c

    To quote the overview comment:

    High level machine check handler. Handles pages reported by the
    hardware as being corrupted usually due to a 2bit ECC memory or cache
    failure.

    This focuses on pages detected as corrupted in the background.
    When the current CPU tries to consume corruption the currently
    running process can just be killed directly instead. This implies
    that if the error cannot be handled for some reason it's safe to
    just ignore it because no corruption has been consumed yet. Instead
    when that happens another machine check will happen.

    Handles page cache pages in various states. The tricky part
    here is that we can access any page asynchronous to other VM
    users, because memory failures could happen anytime and anywhere,
    possibly violating some of their assumptions. This is why this code
    has to be extremely careful. Generally it tries to use normal locking
    rules, as in get the standard locks, even if that means the
    error handling takes potentially a long time.

    Some of the operations here are somewhat inefficient and have non
    linear algorithmic complexity, because the data structures have not
    been optimized for this case. This is in particular the case
    for the mapping from a vma to a process. Since this case is expected
    to be rare we hope we can get away with this.

    There are in principle two strategies to kill processes on poison:
    - just unmap the data and wait for an actual reference before
    killing
    - kill as soon as corruption is detected.
    Both have advantages and disadvantages and should be used
    in different situations. Right now both are implemented and can
    be switched with a new sysctl vm.memory_failure_early_kill
    The default is early kill.

    The patch does some rmap data structure walking on its own to collect
    processes to kill. This is unusual because normally all rmap data structure
    knowledge is in rmap.c only. I put it here for now to keep
    everything together and rmap knowledge has been seeping out anyways

    Includes contributions from Johannes Weiner, Chris Mason, Fengguang Wu,
    Nick Piggin (who did a lot of great work) and others.

    Cc: npiggin@suse.de
    Cc: riel@redhat.com
    Signed-off-by: Andi Kleen
    Acked-by: Rik van Riel
    Reviewed-by: Hidehiro Kawai

    Andi Kleen