lkml.org 
[lkml]   [2022]   [Apr]   [14]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 5.4 049/475] mempolicy: mbind_range() set_policy() after vma_merge()
    Date
    From: Hugh Dickins <hughd@google.com>

    commit 4e0906008cdb56381638aa17d9c32734eae6d37a upstream.

    v2.6.34 commit 9d8cebd4bcd7 ("mm: fix mbind vma merge problem") introduced
    vma_merge() to mbind_range(); but unlike madvise, mlock and mprotect, it
    put a "continue" to next vma where its precedents go to update flags on
    current vma before advancing: that left vma with the wrong setting in the
    infamous vma_merge() case 8.

    v3.10 commit 1444f92c8498 ("mm: merging memory blocks resets mempolicy")
    tried to fix that in vma_adjust(), without fully understanding the issue.

    v3.11 commit 3964acd0dbec ("mm: mempolicy: fix mbind_range() &&
    vma_adjust() interaction") reverted that, and went about the fix in the
    right way, but chose to optimize out an unnecessary mpol_dup() with a
    prior mpol_equal() test. But on tmpfs, that also pessimized out the vital
    call to its ->set_policy(), leaving the new mbind unenforced.

    The user visible effect was that the pages got allocated on the local
    node (happened to be 0), after the mbind() caller had specifically
    asked for them to be allocated on node 1. There was not any page
    migration involved in the case reported: the pages simply got allocated
    on the wrong node.

    Just delete that optimization now (though it could be made conditional on
    vma not having a set_policy). Also remove the "next" variable: it turned
    out to be blameless, but also pointless.

    Link: https://lkml.kernel.org/r/319e4db9-64ae-4bca-92f0-ade85d342ff@google.com
    Fixes: 3964acd0dbec ("mm: mempolicy: fix mbind_range() && vma_adjust() interaction")
    Signed-off-by: Hugh Dickins <hughd@google.com>
    Acked-by: Oleg Nesterov <oleg@redhat.com>
    Reviewed-by: Liam R. Howlett <Liam.Howlett@oracle.com>
    Cc: Vlastimil Babka <vbabka@suse.cz>
    Cc: <stable@vger.kernel.org>
    Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
    Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
    Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
    ---
    mm/mempolicy.c | 8 +-------
    1 file changed, 1 insertion(+), 7 deletions(-)

    --- a/mm/mempolicy.c
    +++ b/mm/mempolicy.c
    @@ -731,7 +731,6 @@ static int vma_replace_policy(struct vm_
    static int mbind_range(struct mm_struct *mm, unsigned long start,
    unsigned long end, struct mempolicy *new_pol)
    {
    - struct vm_area_struct *next;
    struct vm_area_struct *prev;
    struct vm_area_struct *vma;
    int err = 0;
    @@ -747,8 +746,7 @@ static int mbind_range(struct mm_struct
    if (start > vma->vm_start)
    prev = vma;

    - for (; vma && vma->vm_start < end; prev = vma, vma = next) {
    - next = vma->vm_next;
    + for (; vma && vma->vm_start < end; prev = vma, vma = vma->vm_next) {
    vmstart = max(start, vma->vm_start);
    vmend = min(end, vma->vm_end);

    @@ -762,10 +760,6 @@ static int mbind_range(struct mm_struct
    new_pol, vma->vm_userfaultfd_ctx);
    if (prev) {
    vma = prev;
    - next = vma->vm_next;
    - if (mpol_equal(vma_policy(vma), new_pol))
    - continue;
    - /* vma_merge() joined vma && vma->next, case 8 */
    goto replace;
    }
    if (vma->vm_start != vmstart) {

    \
     
     \ /
      Last update: 2022-04-14 16:22    [W:2.065 / U:0.468 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site