06 Dec, 2018

1 commit

  • commit 906f9cdfc2a0800f13683f9e4ebdfd08c12ee81b upstream.

    The term "freeze" is used in several ways in the kernel, and in mm it
    has the particular meaning of forcing page refcount temporarily to 0.
    freeze_page() is just too confusing a name for a function that unmaps a
    page: rename it unmap_page(), and rename unfreeze_page() remap_page().

    Went to change the mention of freeze_page() added later in mm/rmap.c,
    but found it to be incorrect: ordinary page reclaim reaches there too;
    but the substance of the comment still seems correct, so edit it down.

    Link: http://lkml.kernel.org/r/alpine.LSU.2.11.1811261514080.2275@eggly.anvils
    Fixes: e9b61f19858a5 ("thp: reintroduce split_huge_page()")
    Signed-off-by: Hugh Dickins
    Acked-by: Kirill A. Shutemov
    Cc: Jerome Glisse
    Cc: Konstantin Khlebnikov
    Cc: Matthew Wilcox
    Cc: [4.8+]
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds
    Signed-off-by: Sasha Levin

    Hugh Dickins
     

06 Oct, 2018

1 commit

  • The page migration code employs try_to_unmap() to try and unmap the source
    page. This is accomplished by using rmap_walk to find all vmas where the
    page is mapped. This search stops when page mapcount is zero. For shared
    PMD huge pages, the page map count is always 1 no matter the number of
    mappings. Shared mappings are tracked via the reference count of the PMD
    page. Therefore, try_to_unmap stops prematurely and does not completely
    unmap all mappings of the source page.

    This problem can result is data corruption as writes to the original
    source page can happen after contents of the page are copied to the target
    page. Hence, data is lost.

    This problem was originally seen as DB corruption of shared global areas
    after a huge page was soft offlined due to ECC memory errors. DB
    developers noticed they could reproduce the issue by (hotplug) offlining
    memory used to back huge pages. A simple testcase can reproduce the
    problem by creating a shared PMD mapping (note that this must be at least
    PUD_SIZE in size and PUD_SIZE aligned (1GB on x86)), and using
    migrate_pages() to migrate process pages between nodes while continually
    writing to the huge pages being migrated.

    To fix, have the try_to_unmap_one routine check for huge PMD sharing by
    calling huge_pmd_unshare for hugetlbfs huge pages. If it is a shared
    mapping it will be 'unshared' which removes the page table entry and drops
    the reference on the PMD page. After this, flush caches and TLB.

    mmu notifiers are called before locking page tables, but we can not be
    sure of PMD sharing until page tables are locked. Therefore, check for
    the possibility of PMD sharing before locking so that notifiers can
    prepare for the worst possible case.

    Link: http://lkml.kernel.org/r/20180823205917.16297-2-mike.kravetz@oracle.com
    [mike.kravetz@oracle.com: make _range_in_vma() a static inline]
    Link: http://lkml.kernel.org/r/6063f215-a5c8-2f0c-465a-2c515ddc952d@oracle.com
    Fixes: 39dde65c9940 ("shared page table for hugetlb page")
    Signed-off-by: Mike Kravetz
    Acked-by: Kirill A. Shutemov
    Reviewed-by: Naoya Horiguchi
    Acked-by: Michal Hocko
    Cc: Vlastimil Babka
    Cc: Davidlohr Bueso
    Cc: Jerome Glisse
    Cc: Mike Kravetz
    Cc:
    Signed-off-by: Andrew Morton
    Signed-off-by: Greg Kroah-Hartman

    Mike Kravetz
     

15 Jul, 2018

1 commit

  • KVM guests on s390 can notify the host of unused pages. This can result
    in pte_unused callbacks to be true for KVM guest memory.

    If a page is unused (checked with pte_unused) we might drop this page
    instead of paging it. This can have side-effects on userfaultd, when
    the page in question was already migrated:

    The next access of that page will trigger a fault and a user fault
    instead of faulting in a new and empty zero page. As QEMU does not
    expect a userfault on an already migrated page this migration will fail.

    The most straightforward solution is to ignore the pte_unused hint if a
    userfault context is active for this VMA.

    Link: http://lkml.kernel.org/r/20180703171854.63981-1-borntraeger@de.ibm.com
    Signed-off-by: Christian Borntraeger
    Cc: Martin Schwidefsky
    Cc: Andrea Arcangeli
    Cc: Mike Rapoport
    Cc: Janosch Frank
    Cc: David Hildenbrand
    Cc: Cornelia Huck
    Cc:
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Christian Borntraeger
     

28 Apr, 2018

1 commit


21 Apr, 2018

1 commit

  • My testing for the latest kernel supporting thp migration showed an
    infinite loop in offlining the memory block that is filled with shmem
    thps. We can get out of the loop with a signal, but kernel should return
    with failure in this case.

    What happens in the loop is that scan_movable_pages() repeats returning
    the same pfn without any progress. That's because page migration always
    fails for shmem thps.

    In memory offline code, memory blocks containing unmovable pages should be
    prevented from being offline targets by has_unmovable_pages() inside
    start_isolate_page_range(). So it's possible to change migratability for
    non-anonymous thps to avoid the issue, but it introduces more complex and
    thp-specific handling in migration code, so it might not good.

    So this patch is suggesting to fix the issue by enabling thp migration for
    shmem thp. Both of anon/shmem thp are migratable so we don't need
    precheck about the type of thps.

    Link: http://lkml.kernel.org/r/20180406030706.GA2434@hori1.linux.bs1.fc.nec.co.jp
    Fixes: commit 72b39cfc4d75 ("mm, memory_hotplug: do not fail offlining too early")
    Signed-off-by: Naoya Horiguchi
    Acked-by: Kirill A. Shutemov
    Cc: Zi Yan
    Cc: Vlastimil Babka
    Cc: Michal Hocko
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Naoya Horiguchi
     

17 Apr, 2018

2 commits

  • Mike Rapoport says:

    These patches convert files in Documentation/vm to ReST format, add an
    initial index and link it to the top level documentation.

    There are no contents changes in the documentation, except few spelling
    fixes. The relatively large diffstat stems from the indentation and
    paragraph wrapping changes.

    I've tried to keep the formatting as consistent as possible, but I could
    miss some places that needed markup and add some markup where it was not
    necessary.

    [jc: significant conflicts in vm/hmm.rst]

    Jonathan Corbet
     
  • Signed-off-by: Mike Rapoport
    Signed-off-by: Jonathan Corbet

    Mike Rapoport
     

12 Apr, 2018

1 commit

  • Remove the address_space ->tree_lock and use the xa_lock newly added to
    the radix_tree_root. Rename the address_space ->page_tree to ->i_pages,
    since we don't really care that it's a tree.

    [willy@infradead.org: fix nds32, fs/dax.c]
    Link: http://lkml.kernel.org/r/20180406145415.GB20605@bombadil.infradead.orgLink: http://lkml.kernel.org/r/20180313132639.17387-9-willy@infradead.org
    Signed-off-by: Matthew Wilcox
    Acked-by: Jeff Layton
    Cc: Darrick J. Wong
    Cc: Dave Chinner
    Cc: Ryusuke Konishi
    Cc: Will Deacon
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Matthew Wilcox
     

06 Apr, 2018

1 commit


18 Mar, 2018

1 commit

  • If a processor supports special metadata for a page, for example ADI
    version tags on SPARC M7, this metadata must be saved when the page is
    swapped out. The same metadata must be restored when the page is swapped
    back in. This patch adds two new architecture specific functions -
    arch_do_swap_page() to be called when a page is swapped in, and
    arch_unmap_one() to be called when a page is being unmapped for swap
    out. These architecture hooks allow page metadata to be saved if the
    architecture supports it.

    Signed-off-by: Khalid Aziz
    Cc: Khalid Aziz
    Acked-by: Jerome Marchand
    Reviewed-by: Anthony Yznaga
    Acked-by: Andrew Morton
    Signed-off-by: David S. Miller

    Khalid Aziz
     

16 Nov, 2017

3 commits

  • Most callers users of free_hot_cold_page claim the pages being released
    are cache hot. The exception is the page reclaim paths where it is
    likely that enough pages will be freed in the near future that the
    per-cpu lists are going to be recycled and the cache hotness information
    is lost. As no one really cares about the hotness of pages being
    released to the allocator, just ditch the parameter.

    The APIs are renamed to indicate that it's no longer about hot/cold
    pages. It should also be less confusing as there are subtle differences
    between them. __free_pages drops a reference and frees a page when the
    refcount reaches zero. free_hot_cold_page handled pages whose refcount
    was already zero which is non-obvious from the name. free_unref_page
    should be more obvious.

    No performance impact is expected as the overhead is marginal. The
    parameter is removed simply because it is a bit stupid to have a useless
    parameter copied everywhere.

    [mgorman@techsingularity.net: add pages to head, not tail]
    Link: http://lkml.kernel.org/r/20171019154321.qtpzaeftoyyw4iey@techsingularity.net
    Link: http://lkml.kernel.org/r/20171018075952.10627-8-mgorman@techsingularity.net
    Signed-off-by: Mel Gorman
    Acked-by: Vlastimil Babka
    Cc: Andi Kleen
    Cc: Dave Chinner
    Cc: Dave Hansen
    Cc: Jan Kara
    Cc: Johannes Weiner
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Mel Gorman
     
  • Variable cend is set but never read, hence it is redundant and can be
    removed.

    Cleans up clang build warning: Value stored to 'cend' is never read

    Link: http://lkml.kernel.org/r/20171011174942.1372-1-colin.king@canonical.com
    Fixes: 369ea8242c0f ("mm/rmap: update to new mmu_notifier semantic v2")
    Signed-off-by: Colin Ian King
    Acked-by: Kirill A. Shutemov
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Colin Ian King
     
  • This patch only affects users of mmu_notifier->invalidate_range callback
    which are device drivers related to ATS/PASID, CAPI, IOMMUv2, SVM ...
    and it is an optimization for those users. Everyone else is unaffected
    by it.

    When clearing a pte/pmd we are given a choice to notify the event under
    the page table lock (notify version of *_clear_flush helpers do call the
    mmu_notifier_invalidate_range). But that notification is not necessary
    in all cases.

    This patch removes almost all cases where it is useless to have a call
    to mmu_notifier_invalidate_range before
    mmu_notifier_invalidate_range_end. It also adds documentation in all
    those cases explaining why.

    Below is a more in depth analysis of why this is fine to do this:

    For secondary TLB (non CPU TLB) like IOMMU TLB or device TLB (when
    device use thing like ATS/PASID to get the IOMMU to walk the CPU page
    table to access a process virtual address space). There is only 2 cases
    when you need to notify those secondary TLB while holding page table
    lock when clearing a pte/pmd:

    A) page backing address is free before mmu_notifier_invalidate_range_end
    B) a page table entry is updated to point to a new page (COW, write fault
    on zero page, __replace_page(), ...)

    Case A is obvious you do not want to take the risk for the device to write
    to a page that might now be used by something completely different.

    Case B is more subtle. For correctness it requires the following sequence
    to happen:
    - take page table lock
    - clear page table entry and notify (pmd/pte_huge_clear_flush_notify())
    - set page table entry to point to new page

    If clearing the page table entry is not followed by a notify before setting
    the new pte/pmd value then you can break memory model like C11 or C++11 for
    the device.

    Consider the following scenario (device use a feature similar to ATS/
    PASID):

    Two address addrA and addrB such that |addrA - addrB| >= PAGE_SIZE we
    assume they are write protected for COW (other case of B apply too).

    [Time N] -----------------------------------------------------------------
    CPU-thread-0 {try to write to addrA}
    CPU-thread-1 {try to write to addrB}
    CPU-thread-2 {}
    CPU-thread-3 {}
    DEV-thread-0 {read addrA and populate device TLB}
    DEV-thread-2 {read addrB and populate device TLB}
    [Time N+1] ---------------------------------------------------------------
    CPU-thread-0 {COW_step0: {mmu_notifier_invalidate_range_start(addrA)}}
    CPU-thread-1 {COW_step0: {mmu_notifier_invalidate_range_start(addrB)}}
    CPU-thread-2 {}
    CPU-thread-3 {}
    DEV-thread-0 {}
    DEV-thread-2 {}
    [Time N+2] ---------------------------------------------------------------
    CPU-thread-0 {COW_step1: {update page table point to new page for addrA}}
    CPU-thread-1 {COW_step1: {update page table point to new page for addrB}}
    CPU-thread-2 {}
    CPU-thread-3 {}
    DEV-thread-0 {}
    DEV-thread-2 {}
    [Time N+3] ---------------------------------------------------------------
    CPU-thread-0 {preempted}
    CPU-thread-1 {preempted}
    CPU-thread-2 {write to addrA which is a write to new page}
    CPU-thread-3 {}
    DEV-thread-0 {}
    DEV-thread-2 {}
    [Time N+3] ---------------------------------------------------------------
    CPU-thread-0 {preempted}
    CPU-thread-1 {preempted}
    CPU-thread-2 {}
    CPU-thread-3 {write to addrB which is a write to new page}
    DEV-thread-0 {}
    DEV-thread-2 {}
    [Time N+4] ---------------------------------------------------------------
    CPU-thread-0 {preempted}
    CPU-thread-1 {COW_step3: {mmu_notifier_invalidate_range_end(addrB)}}
    CPU-thread-2 {}
    CPU-thread-3 {}
    DEV-thread-0 {}
    DEV-thread-2 {}
    [Time N+5] ---------------------------------------------------------------
    CPU-thread-0 {preempted}
    CPU-thread-1 {}
    CPU-thread-2 {}
    CPU-thread-3 {}
    DEV-thread-0 {read addrA from old page}
    DEV-thread-2 {read addrB from new page}

    So here because at time N+2 the clear page table entry was not pair with a
    notification to invalidate the secondary TLB, the device see the new value
    for addrB before seing the new value for addrA. This break total memory
    ordering for the device.

    When changing a pte to write protect or to point to a new write protected
    page with same content (KSM) it is ok to delay invalidate_range callback
    to mmu_notifier_invalidate_range_end() outside the page table lock. This
    is true even if the thread doing page table update is preempted right
    after releasing page table lock before calling
    mmu_notifier_invalidate_range_end

    Thanks to Andrea for thinking of a problematic scenario for COW.

    [jglisse@redhat.com: v2]
    Link: http://lkml.kernel.org/r/20171017031003.7481-2-jglisse@redhat.com
    Link: http://lkml.kernel.org/r/20170901173011.10745-1-jglisse@redhat.com
    Signed-off-by: Jérôme Glisse
    Cc: Andrea Arcangeli
    Cc: Nadav Amit
    Cc: Joerg Roedel
    Cc: Suravee Suthikulpanit
    Cc: David Woodhouse
    Cc: Alistair Popple
    Cc: Michael Ellerman
    Cc: Benjamin Herrenschmidt
    Cc: Stephen Rothwell
    Cc: Andrew Donnellan
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Jérôme Glisse
     

09 Sep, 2017

4 commits

  • Allow interval trees to quickly check for overlaps to avoid unnecesary
    tree lookups in interval_tree_iter_first().

    As of this patch, all interval tree flavors will require using a
    'rb_root_cached' such that we can have the leftmost node easily
    available. While most users will make use of this feature, those with
    special functions (in addition to the generic insert, delete, search
    calls) will avoid using the cached option as they can do funky things
    with insertions -- for example, vma_interval_tree_insert_after().

    [jglisse@redhat.com: fix deadlock from typo vm_lock_anon_vma()]
    Link: http://lkml.kernel.org/r/20170808225719.20723-1-jglisse@redhat.com
    Link: http://lkml.kernel.org/r/20170719014603.19029-12-dave@stgolabs.net
    Signed-off-by: Davidlohr Bueso
    Signed-off-by: Jérôme Glisse
    Acked-by: Christian König
    Acked-by: Peter Zijlstra (Intel)
    Acked-by: Doug Ledford
    Acked-by: Michael S. Tsirkin
    Cc: David Airlie
    Cc: Jason Wang
    Cc: Christian Benvenuti
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Davidlohr Bueso
     
  • Allow to unmap and restore special swap entry of un-addressable
    ZONE_DEVICE memory.

    Link: http://lkml.kernel.org/r/20170817000548.32038-17-jglisse@redhat.com
    Signed-off-by: Jérôme Glisse
    Cc: Kirill A. Shutemov
    Cc: Aneesh Kumar
    Cc: Balbir Singh
    Cc: Benjamin Herrenschmidt
    Cc: Dan Williams
    Cc: David Nellans
    Cc: Evgeny Baskakov
    Cc: Johannes Weiner
    Cc: John Hubbard
    Cc: Mark Hairgrove
    Cc: Michal Hocko
    Cc: Paul E. McKenney
    Cc: Ross Zwisler
    Cc: Sherry Cheung
    Cc: Subhash Gutti
    Cc: Vladimir Davydov
    Cc: Bob Liu
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Jérôme Glisse
     
  • Add thp migration's core code, including conversions between a PMD entry
    and a swap entry, setting PMD migration entry, removing PMD migration
    entry, and waiting on PMD migration entries.

    This patch makes it possible to support thp migration. If you fail to
    allocate a destination page as a thp, you just split the source thp as
    we do now, and then enter the normal page migration. If you succeed to
    allocate destination thp, you enter thp migration. Subsequent patches
    actually enable thp migration for each caller of page migration by
    allowing its get_new_page() callback to allocate thps.

    [zi.yan@cs.rutgers.edu: fix gcc-4.9.0 -Wmissing-braces warning]
    Link: http://lkml.kernel.org/r/A0ABA698-7486-46C3-B209-E95A9048B22C@cs.rutgers.edu
    [akpm@linux-foundation.org: fix x86_64 allnoconfig warning]
    Signed-off-by: Zi Yan
    Acked-by: Kirill A. Shutemov
    Cc: "H. Peter Anvin"
    Cc: Anshuman Khandual
    Cc: Dave Hansen
    Cc: David Nellans
    Cc: Ingo Molnar
    Cc: Mel Gorman
    Cc: Minchan Kim
    Cc: Naoya Horiguchi
    Cc: Thomas Gleixner
    Cc: Vlastimil Babka
    Cc: Andrea Arcangeli
    Cc: Michal Hocko
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Zi Yan
     
  • TTU_MIGRATION is used to convert pte into migration entry until thp
    split completes. This behavior conflicts with thp migration added later
    patches, so let's introduce a new TTU flag specifically for freezing.

    try_to_unmap() is used both for thp split (via freeze_page()) and page
    migration (via __unmap_and_move()). In freeze_page(), ttu_flag given
    for head page is like below (assuming anonymous thp):

    (TTU_IGNORE_MLOCK | TTU_IGNORE_ACCESS | TTU_RMAP_LOCKED | \
    TTU_MIGRATION | TTU_SPLIT_HUGE_PMD)

    and ttu_flag given for tail pages is:

    (TTU_IGNORE_MLOCK | TTU_IGNORE_ACCESS | TTU_RMAP_LOCKED | \
    TTU_MIGRATION)

    __unmap_and_move() calls try_to_unmap() with ttu_flag:

    (TTU_MIGRATION | TTU_IGNORE_MLOCK | TTU_IGNORE_ACCESS)

    Now I'm trying to insert a branch for thp migration at the top of
    try_to_unmap_one() like below

    static int try_to_unmap_one(struct page *page, struct vm_area_struct *vma,
    unsigned long address, void *arg)
    {
    ...
    /* PMD-mapped THP migration entry */
    if (!pvmw.pte && (flags & TTU_MIGRATION)) {
    if (!PageAnon(page))
    continue;

    set_pmd_migration_entry(&pvmw, page);
    continue;
    }
    ...
    }

    so try_to_unmap() for tail pages called by thp split can go into thp
    migration code path (which converts *pmd* into migration entry), while
    the expectation is to freeze thp (which converts *pte* into migration
    entry.)

    I detected this failure as a "bad page state" error in a testcase where
    split_huge_page() is called from queue_pages_pte_range().

    Link: http://lkml.kernel.org/r/20170717193955.20207-4-zi.yan@sent.com
    Signed-off-by: Naoya Horiguchi
    Signed-off-by: Zi Yan
    Acked-by: Kirill A. Shutemov
    Cc: "H. Peter Anvin"
    Cc: Anshuman Khandual
    Cc: Dave Hansen
    Cc: David Nellans
    Cc: Ingo Molnar
    Cc: Mel Gorman
    Cc: Minchan Kim
    Cc: Thomas Gleixner
    Cc: Vlastimil Babka
    Cc: Andrea Arcangeli
    Cc: Michal Hocko
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Naoya Horiguchi
     

01 Sep, 2017

1 commit

  • Replace all mmu_notifier_invalidate_page() calls by *_invalidate_range()
    and make sure it is bracketed by calls to *_invalidate_range_start()/end().

    Note that because we can not presume the pmd value or pte value we have
    to assume the worst and unconditionaly report an invalidation as
    happening.

    Changed since v2:
    - try_to_unmap_one() only one call to mmu_notifier_invalidate_range()
    - compute end with PAGE_SIZE << compound_order(page)
    - fix PageHuge() case in try_to_unmap_one()

    Signed-off-by: Jérôme Glisse
    Reviewed-by: Andrea Arcangeli
    Cc: Dan Williams
    Cc: Ross Zwisler
    Cc: Bernhard Held
    Cc: Adam Borowski
    Cc: Radim Krčmář
    Cc: Wanpeng Li
    Cc: Paolo Bonzini
    Cc: Takashi Iwai
    Cc: Nadav Amit
    Cc: Mike Galbraith
    Cc: Kirill A. Shutemov
    Cc: axie
    Cc: Andrew Morton
    Signed-off-by: Linus Torvalds

    Jérôme Glisse
     

30 Aug, 2017

1 commit

  • This reverts commit aac2fea94f7a3df8ad1eeb477eb2643f81fd5393.

    It turns out that that patch was complete and utter garbage, and broke
    KVM, resulting in odd oopses.

    Quoting Andrea Arcangeli:
    "The aforementioned commit has 3 bugs.

    1) mmu_notifier_invalidate_range cannot be used in replacement of
    mmu_notifier_invalidate_range_start/end.

    For KVM mmu_notifier_invalidate_range is a noop and rightfully so.

    A MMU notifier implementation has to implement either
    ->invalidate_range method or the invalidate_range_start/end
    methods, not both. And if you implement invalidate_range_start/end
    like KVM is forced to do, calling mmu_notifier_invalidate_range in
    common code is a noop for KVM.

    For those MMU notifiers that can get away only implementing
    ->invalidate_range, the ->invalidate_range is implicitly called by
    mmu_notifier_invalidate_range_end(). And only those secondary MMUs
    that share the same pagetable with the primary MMU (like AMD
    iommuv2) can get away only implementing ->invalidate_range.

    So all cases (THP on/off) are broken right now.

    To fix this is enough to replace mmu_notifier_invalidate_range with
    mmu_notifier_invalidate_range_start;mmu_notifier_invalidate_range_end.
    Either that or call multiple mmu_notifier_invalidate_page like
    before.

    2) address + (1UL << compound_order(page) is buggy, it should be
    PAGE_SIZE << compound_order(page), it's bytes not pages, 2M not
    512.

    3) The whole invalidate_range thing was an attempt to call a single
    invalidate while walking multiple 4k ptes that maps the same THP
    (after a pmd virtual split without physical compound page THP
    split).

    It's unclear if the rmap_walk will always provide an address that
    is 2M aligned as parameter to try_to_unmap_one, in presence of THP.
    I think it needs also an address &= (PAGE_SIZE <<
    compound_order(page)) - 1 to be safe"

    In general, we should stop making excuses for horrible MMU notifier
    users. It's much more important that the core VM is sane and safe, than
    letting MMU notifiers sleep.

    So if some MMU notifier is sleeping under a spinlock, we need to fix the
    notifier, not try to make excuses for that garbage in the core VM.

    Reported-and-tested-by: Bernhard Held
    Reported-and-tested-by: Adam Borowski
    Cc: Andrea Arcangeli
    Cc: Radim Krčmář
    Cc: Wanpeng Li
    Cc: Paolo Bonzini
    Cc: Takashi Iwai
    Cc: Nadav Amit
    Cc: Mike Galbraith
    Cc: Kirill A. Shutemov
    Cc: Jérôme Glisse
    Cc: axie
    Cc: Andrew Morton
    Signed-off-by: Linus Torvalds

    Linus Torvalds
     

11 Aug, 2017

1 commit

  • MMU notifiers can sleep, but in page_mkclean_one() we call
    mmu_notifier_invalidate_page() under page table lock.

    Let's instead use mmu_notifier_invalidate_range() outside
    page_vma_mapped_walk() loop.

    [jglisse@redhat.com: try_to_unmap_one() do not call mmu_notifier under ptl]
    Link: http://lkml.kernel.org/r/20170809204333.27485-1-jglisse@redhat.com
    Link: http://lkml.kernel.org/r/20170804134928.l4klfcnqatni7vsc@black.fi.intel.com
    Fixes: c7ab0d2fdc84 ("mm: convert try_to_unmap_one() to use page_vma_mapped_walk()")
    Signed-off-by: Kirill A. Shutemov
    Signed-off-by: Jérôme Glisse
    Reported-by: axie
    Cc: Alex Deucher
    Cc: "Writer, Tim"
    Cc:
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Kirill A. Shutemov
     

03 Aug, 2017

1 commit

  • Nadav Amit identified a theoritical race between page reclaim and
    mprotect due to TLB flushes being batched outside of the PTL being held.

    He described the race as follows:

    CPU0 CPU1
    ---- ----
    user accesses memory using RW PTE
    [PTE now cached in TLB]
    try_to_unmap_one()
    ==> ptep_get_and_clear()
    ==> set_tlb_ubc_flush_pending()
    mprotect(addr, PROT_READ)
    ==> change_pte_range()
    ==> [ PTE non-present - no flush ]

    user writes using cached RW PTE
    ...

    try_to_unmap_flush()

    The same type of race exists for reads when protecting for PROT_NONE and
    also exists for operations that can leave an old TLB entry behind such
    as munmap, mremap and madvise.

    For some operations like mprotect, it's not necessarily a data integrity
    issue but it is a correctness issue as there is a window where an
    mprotect that limits access still allows access. For munmap, it's
    potentially a data integrity issue although the race is massive as an
    munmap, mmap and return to userspace must all complete between the
    window when reclaim drops the PTL and flushes the TLB. However, it's
    theoritically possible so handle this issue by flushing the mm if
    reclaim is potentially currently batching TLB flushes.

    Other instances where a flush is required for a present pte should be ok
    as either the page lock is held preventing parallel reclaim or a page
    reference count is elevated preventing a parallel free leading to
    corruption. In the case of page_mkclean there isn't an obvious path
    that userspace could take advantage of without using the operations that
    are guarded by this patch. Other users such as gup as a race with
    reclaim looks just at PTEs. huge page variants should be ok as they
    don't race with reclaim. mincore only looks at PTEs. userfault also
    should be ok as if a parallel reclaim takes place, it will either fault
    the page back in or read some of the data before the flush occurs
    triggering a fault.

    Note that a variant of this patch was acked by Andy Lutomirski but this
    was for the x86 parts on top of his PCID work which didn't make the 4.13
    merge window as expected. His ack is dropped from this version and
    there will be a follow-on patch on top of PCID that will include his
    ack.

    [akpm@linux-foundation.org: tweak comments]
    [akpm@linux-foundation.org: fix spello]
    Link: http://lkml.kernel.org/r/20170717155523.emckq2esjro6hf3z@suse.de
    Reported-by: Nadav Amit
    Signed-off-by: Mel Gorman
    Cc: Andy Lutomirski
    Cc: [v4.4+]
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Mel Gorman
     

07 Jul, 2017

2 commits

  • lruvecs are at the intersection of the NUMA node and memcg, which is the
    scope for most paging activity.

    Introduce a convenient accounting infrastructure that maintains
    statistics per node, per memcg, and the lruvec itself.

    Then convert over accounting sites for statistics that are already
    tracked in both nodes and memcgs and can be easily switched.

    [hannes@cmpxchg.org: fix crash in the new cgroup stat keeping code]
    Link: http://lkml.kernel.org/r/20170531171450.GA10481@cmpxchg.org
    [hannes@cmpxchg.org: don't track uncharged pages at all
    Link: http://lkml.kernel.org/r/20170605175254.GA8547@cmpxchg.org
    [hannes@cmpxchg.org: add missing free_percpu()]
    Link: http://lkml.kernel.org/r/20170605175354.GB8547@cmpxchg.org
    [linux@roeck-us.net: hexagon: fix build error caused by include file order]
    Link: http://lkml.kernel.org/r/20170617153721.GA4382@roeck-us.net
    Link: http://lkml.kernel.org/r/20170530181724.27197-6-hannes@cmpxchg.org
    Signed-off-by: Johannes Weiner
    Signed-off-by: Guenter Roeck
    Acked-by: Vladimir Davydov
    Cc: Josef Bacik
    Cc: Michal Hocko
    Cc: Rik van Riel
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Johannes Weiner
     
  • Using set_pte_at() does not do the right thing when putting down
    HWPOISON swap entries for hugepages on architectures that support
    contiguous ptes.

    Fix this problem by using set_huge_swap_pte_at() which was introduced to
    fix exactly this problem.

    Link: http://lkml.kernel.org/r/20170522133604.11392-7-punit.agrawal@arm.com
    Signed-off-by: Punit Agrawal
    Acked-by: Steve Capper
    Cc: "Kirill A. Shutemov"
    Cc: Catalin Marinas
    Cc: Will Deacon
    Cc: Naoya Horiguchi
    Cc: Mike Kravetz
    Cc: Mark Rutland
    Cc: Hillf Danton
    Cc: Aneesh Kumar K.V
    Cc: Michal Hocko
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Punit Agrawal
     

24 May, 2017

1 commit

  • try_to_unmap_flush() used to open-code a rather x86-centric flush
    sequence: local_flush_tlb() + flush_tlb_others(). Rearrange the
    code so that the arch (only x86 for now) provides
    arch_tlbbatch_add_mm() and arch_tlbbatch_flush() and the core code
    calls those functions instead.

    I'll want this for x86 because, to enable address space ids, I can't
    support the flush_tlb_others() mode used by exising
    try_to_unmap_flush() implementation with good performance. I can
    support the new API fairly easily, though.

    I imagine that other architectures may be in a similar position.
    Architectures with strong remote flush primitives (arm64?) may have
    even worse performance problems with flush_tlb_others() the way that
    try_to_unmap_flush() uses it.

    Signed-off-by: Andy Lutomirski
    Acked-by: Kees Cook
    Cc: Andrew Morton
    Cc: Borislav Petkov
    Cc: Dave Hansen
    Cc: Linus Torvalds
    Cc: Mel Gorman
    Cc: Michal Hocko
    Cc: Nadav Amit
    Cc: Nadav Amit
    Cc: Peter Zijlstra
    Cc: Rik van Riel
    Cc: Sasha Levin
    Cc: Thomas Gleixner
    Cc: linux-mm@kvack.org
    Link: http://lkml.kernel.org/r/19f25a8581f9fb77876b7ff3b001f89835e34ea3.1495492063.git.luto@kernel.org
    Signed-off-by: Ingo Molnar

    Andy Lutomirski
     

11 May, 2017

1 commit

  • Pull RCU updates from Ingo Molnar:
    "The main changes are:

    - Debloat RCU headers

    - Parallelize SRCU callback handling (plus overlapping patches)

    - Improve the performance of Tree SRCU on a CPU-hotplug stress test

    - Documentation updates

    - Miscellaneous fixes"

    * 'core-rcu-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: (74 commits)
    rcu: Open-code the rcu_cblist_n_lazy_cbs() function
    rcu: Open-code the rcu_cblist_n_cbs() function
    rcu: Open-code the rcu_cblist_empty() function
    rcu: Separately compile large rcu_segcblist functions
    srcu: Debloat the header
    srcu: Adjust default auto-expediting holdoff
    srcu: Specify auto-expedite holdoff time
    srcu: Expedite first synchronize_srcu() when idle
    srcu: Expedited grace periods with reduced memory contention
    srcu: Make rcutorture writer stalls print SRCU GP state
    srcu: Exact tracking of srcu_data structures containing callbacks
    srcu: Make SRCU be built by default
    srcu: Fix Kconfig botch when SRCU not selected
    rcu: Make non-preemptive schedule be Tasks RCU quiescent state
    srcu: Expedite srcu_schedule_cbs_snp() callback invocation
    srcu: Parallelize callback handling
    kvm: Move srcu_struct fields to end of struct kvm
    rcu: Fix typo in PER_RCU_NODE_PERIOD header comment
    rcu: Use true/false in assignment to bool
    rcu: Use bool value directly
    ...

    Linus Torvalds
     

04 May, 2017

15 commits

  • The memory controllers stat function names are awkwardly long and
    arbitrarily different from the zone and node stat functions.

    The current interface is named:

    mem_cgroup_read_stat()
    mem_cgroup_update_stat()
    mem_cgroup_inc_stat()
    mem_cgroup_dec_stat()
    mem_cgroup_update_page_stat()
    mem_cgroup_inc_page_stat()
    mem_cgroup_dec_page_stat()

    This patch renames it to match the corresponding node stat functions:

    memcg_page_state() [node_page_state()]
    mod_memcg_state() [mod_node_state()]
    inc_memcg_state() [inc_node_state()]
    dec_memcg_state() [dec_node_state()]
    mod_memcg_page_state() [mod_node_page_state()]
    inc_memcg_page_state() [inc_node_page_state()]
    dec_memcg_page_state() [dec_node_page_state()]

    Link: http://lkml.kernel.org/r/20170404220148.28338-4-hannes@cmpxchg.org
    Signed-off-by: Johannes Weiner
    Acked-by: Vladimir Davydov
    Acked-by: Michal Hocko
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Johannes Weiner
     
  • The current duplication is a high-maintenance mess, and it's painful to
    add new items or query memcg state from the rest of the VM.

    This increases the size of the stat array marginally, but we should aim
    to track all these stats on a per-cgroup level anyway.

    Link: http://lkml.kernel.org/r/20170404220148.28338-3-hannes@cmpxchg.org
    Signed-off-by: Johannes Weiner
    Acked-by: Vladimir Davydov
    Cc: Michal Hocko
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Johannes Weiner
     
  • There is no user for it. Remove it.

    [minchan@kernel.org: use false instead of SWAP_FAIL]
    Link: http://lkml.kernel.org/r/20170316053313.GA19241@bbox
    Link: http://lkml.kernel.org/r/1489555493-14659-11-git-send-email-minchan@kernel.org
    Signed-off-by: Minchan Kim
    Cc: Anshuman Khandual
    Cc: Hillf Danton
    Cc: Johannes Weiner
    Cc: Kirill A. Shutemov
    Cc: Michal Hocko
    Cc: Naoya Horiguchi
    Cc: Vlastimil Babka
    Cc: Sergey Senozhatsky
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Minchan Kim
     
  • rmap_one's return value controls whether rmap_work should contine to
    scan other ptes or not so it's target for changing to boolean. Return
    true if the scan should be continued. Otherwise, return false to stop
    the scanning.

    This patch makes rmap_one's return value to boolean.

    Link: http://lkml.kernel.org/r/1489555493-14659-10-git-send-email-minchan@kernel.org
    Signed-off-by: Minchan Kim
    Cc: Anshuman Khandual
    Cc: Hillf Danton
    Cc: Johannes Weiner
    Cc: Kirill A. Shutemov
    Cc: Michal Hocko
    Cc: Naoya Horiguchi
    Cc: Vlastimil Babka
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Minchan Kim
     
  • There is no user of the return value from rmap_walk() and friends so
    this patch makes them void-returning functions.

    Link: http://lkml.kernel.org/r/1489555493-14659-9-git-send-email-minchan@kernel.org
    Signed-off-by: Minchan Kim
    Cc: Anshuman Khandual
    Cc: Hillf Danton
    Cc: Johannes Weiner
    Cc: Kirill A. Shutemov
    Cc: Michal Hocko
    Cc: Naoya Horiguchi
    Cc: Vlastimil Babka
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Minchan Kim
     
  • try_to_unmap() returns SWAP_SUCCESS or SWAP_FAIL so it's suitable for
    boolean return. This patch changes it.

    Link: http://lkml.kernel.org/r/1489555493-14659-8-git-send-email-minchan@kernel.org
    Signed-off-by: Minchan Kim
    Cc: Naoya Horiguchi
    Cc: Anshuman Khandual
    Cc: Hillf Danton
    Cc: Johannes Weiner
    Cc: Kirill A. Shutemov
    Cc: Michal Hocko
    Cc: Vlastimil Babka
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Minchan Kim
     
  • In 2002, [1] introduced SWAP_AGAIN. At that time, try_to_unmap_one used
    spin_trylock(&mm->page_table_lock) so it's really easy to contend and
    fail to hold a lock so SWAP_AGAIN to keep LRU status makes sense.

    However, now we changed it to mutex-based lock and be able to block
    without skip pte so there is few of small window to return SWAP_AGAIN so
    remove SWAP_AGAIN and just return SWAP_FAIL.

    [1] c48c43e, minimal rmap

    Link: http://lkml.kernel.org/r/1489555493-14659-7-git-send-email-minchan@kernel.org
    Signed-off-by: Minchan Kim
    Cc: Anshuman Khandual
    Cc: Hillf Danton
    Cc: Johannes Weiner
    Cc: Kirill A. Shutemov
    Cc: Michal Hocko
    Cc: Naoya Horiguchi
    Cc: Vlastimil Babka
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Minchan Kim
     
  • ttu doesn't need to return SWAP_MLOCK. Instead, just return SWAP_FAIL
    because it means the page is not-swappable so it should move to another
    LRU list(active or unevictable). putback friends will move it to right
    list depending on the page's LRU flag.

    Link: http://lkml.kernel.org/r/1489555493-14659-6-git-send-email-minchan@kernel.org
    Signed-off-by: Minchan Kim
    Cc: Anshuman Khandual
    Cc: Hillf Danton
    Cc: Johannes Weiner
    Cc: Kirill A. Shutemov
    Cc: Michal Hocko
    Cc: Naoya Horiguchi
    Cc: Vlastimil Babka
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Minchan Kim
     
  • try_to_munlock returns SWAP_MLOCK if the one of VMAs mapped the page has
    VM_LOCKED flag. In that time, VM set PG_mlocked to the page if the page
    is not pte-mapped THP which cannot be mlocked, either.

    With that, __munlock_isolated_page can use PageMlocked to check whether
    try_to_munlock is successful or not without relying on try_to_munlock's
    retval. It helps to make try_to_unmap/try_to_unmap_one simple with
    upcoming patches.

    [minchan@kernel.org: remove PG_Mlocked VM_BUG_ON check]
    Link: http://lkml.kernel.org/r/20170411025615.GA6545@bbox
    Link: http://lkml.kernel.org/r/1489555493-14659-5-git-send-email-minchan@kernel.org
    Signed-off-by: Minchan Kim
    Acked-by: Kirill A. Shutemov
    Acked-by: Vlastimil Babka
    Cc: Anshuman Khandual
    Cc: Hillf Danton
    Cc: Johannes Weiner
    Cc: Michal Hocko
    Cc: Naoya Horiguchi
    Cc: Sasha Levin
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Minchan Kim
     
  • If the page is mapped and rescue in try_to_unmap_one, the
    page_mapcount() of a page cannot be zero, so the page_mapcount check in
    try_to_unmap is enough to return SWAP_SUCCESS. IOW, SWAP_MLOCK check is
    redundant so remove it.

    Link: http://lkml.kernel.org/r/1489555493-14659-4-git-send-email-minchan@kernel.org
    Signed-off-by: Minchan Kim
    Cc: Anshuman Khandual
    Cc: Hillf Danton
    Cc: Johannes Weiner
    Cc: Kirill A. Shutemov
    Cc: Michal Hocko
    Cc: Naoya Horiguchi
    Cc: Vlastimil Babka
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Minchan Kim
     
  • If we found lazyfree page is dirty, try_to_unmap_one can just
    SetPageSwapBakced in there like PG_mlocked page and just return with
    SWAP_FAIL which is very natural because the page is not swappable right
    now so that vmscan can activate it. There is no point to introduce new
    return value SWAP_DIRTY in try_to_unmap at the moment.

    Link: http://lkml.kernel.org/r/1489555493-14659-3-git-send-email-minchan@kernel.org
    Signed-off-by: Minchan Kim
    Acked-by: Hillf Danton
    Acked-by: Kirill A. Shutemov
    Cc: Anshuman Khandual
    Cc: Johannes Weiner
    Cc: Michal Hocko
    Cc: Naoya Horiguchi
    Cc: Vlastimil Babka
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Minchan Kim
     
  • Nobody uses ret variable. Remove it.

    Link: http://lkml.kernel.org/r/1489555493-14659-2-git-send-email-minchan@kernel.org
    Signed-off-by: Minchan Kim
    Acked-by: Hillf Danton
    Acked-by: Kirill A. Shutemov
    Cc: Johannes Weiner
    Cc: Michal Hocko
    Cc: Kirill A. Shutemov
    Cc: Anshuman Khandual
    Cc: Vlastimil Babka
    Cc: Naoya Horiguchi

    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Minchan Kim
     
  • If a page is swapbacked, it means it should be in swapcache in
    try_to_unmap_one's path.

    If a page is !swapbacked, it mean it shouldn't be in swapcache in
    try_to_unmap_one's path.

    Check both two cases all at once and if it fails, warn and return
    SWAP_FAIL. Such bug never mean we should shut down the kernel.

    [minchan@kernel.org: do not use VM_WARN_ON_ONCE as if condition[
    Link: http://lkml.kernel.org/r/20170309060226.GB854@bbox
    Link: http://lkml.kernel.org/r/20170307055551.GC29458@bbox
    Signed-off-by: Minchan Kim
    Suggested-by: Johannes Weiner
    Acked-by: Michal Hocko
    Acked-by: Johannes Weiner
    Cc: Shaohua Li
    Cc: Hillf Danton
    Cc: Hugh Dickins
    Cc: Rik van Riel
    Cc: Mel Gorman
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Minchan Kim
     
  • When memory pressure is high, we free MADV_FREE pages. If the pages are
    not dirty in pte, the pages could be freed immediately. Otherwise we
    can't reclaim them. We put the pages back to anonumous LRU list (by
    setting SwapBacked flag) and the pages will be reclaimed in normal
    swapout way.

    We use normal page reclaim policy. Since MADV_FREE pages are put into
    inactive file list, such pages and inactive file pages are reclaimed
    according to their age. This is expected, because we don't want to
    reclaim too many MADV_FREE pages before used once pages.

    Based on Minchan's original patch

    [minchan@kernel.org: clean up lazyfree page handling]
    Link: http://lkml.kernel.org/r/20170303025237.GB3503@bbox
    Link: http://lkml.kernel.org/r/14b8eb1d3f6bf6cc492833f183ac8c304e560484.1487965799.git.shli@fb.com
    Signed-off-by: Shaohua Li
    Signed-off-by: Minchan Kim
    Acked-by: Minchan Kim
    Acked-by: Michal Hocko
    Acked-by: Johannes Weiner
    Acked-by: Hillf Danton
    Cc: Hugh Dickins
    Cc: Rik van Riel
    Cc: Mel Gorman
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Shaohua Li
     
  • There are a few places the code assumes anonymous pages should have
    SwapBacked flag set. MADV_FREE pages are anonymous pages but we are
    going to add them to LRU_INACTIVE_FILE list and clear SwapBacked flag
    for them. The assumption doesn't hold any more, so fix them.

    Link: http://lkml.kernel.org/r/3945232c0df3dd6c4ef001976f35a95f18dcb407.1487965799.git.shli@fb.com
    Signed-off-by: Shaohua Li
    Acked-by: Johannes Weiner
    Acked-by: Hillf Danton
    Cc: Michal Hocko
    Cc: Minchan Kim
    Cc: Hugh Dickins
    Cc: Rik van Riel
    Cc: Mel Gorman
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Shaohua Li