13 Jan, 2021

1 commit

  • commit c2407cf7d22d0c0d94cf20342b3b8f06f1d904e7 upstream.

    Ever since commit 2a9127fcf229 ("mm: rewrite wait_on_page_bit_common()
    logic") we've had some very occasional reports of BUG_ON(PageWriteback)
    in write_cache_pages(), which we thought we already fixed in commit
    073861ed77b6 ("mm: fix VM_BUG_ON(PageTail) and BUG_ON(PageWriteback)").

    But syzbot just reported another one, even with that commit in place.

    And it turns out that there's a simpler way to trigger the BUG_ON() than
    the one Hugh found with page re-use. It all boils down to the fact that
    the page writeback is ostensibly serialized by the page lock, but that
    isn't actually really true.

    Yes, the people _setting_ writeback all do so under the page lock, but
    the actual clearing of the bit - and waking up any waiters - happens
    without any page lock.

    This gives us this fairly simple race condition:

    CPU1 = end previous writeback
    CPU2 = start new writeback under page lock
    CPU3 = write_cache_pages()

    CPU1 CPU2 CPU3
    ---- ---- ----

    end_page_writeback()
    test_clear_page_writeback(page)
    ... delayed...

    lock_page();
    set_page_writeback()
    unlock_page()

    lock_page()
    wait_on_page_writeback();

    wake_up_page(page, PG_writeback);
    .. wakes up CPU3 ..

    BUG_ON(PageWriteback(page));

    where the BUG_ON() happens because we woke up the PG_writeback bit
    becasue of the _previous_ writeback, but a new one had already been
    started because the clearing of the bit wasn't actually atomic wrt the
    actual wakeup or serialized by the page lock.

    The reason this didn't use to happen was that the old logic in waiting
    on a page bit would just loop if it ever saw the bit set again.

    The nice proper fix would probably be to get rid of the whole "wait for
    writeback to clear, and then set it" logic in the writeback path, and
    replace it with an atomic "wait-to-set" (ie the same as we have for page
    locking: we set the page lock bit with a single "lock_page()", not with
    "wait for lock bit to clear and then set it").

    However, out current model for writeback is that the waiting for the
    writeback bit is done by the generic VFS code (ie write_cache_pages()),
    but the actual setting of the writeback bit is done much later by the
    filesystem ".writepages()" function.

    IOW, to make the writeback bit have that same kind of "wait-to-set"
    behavior as we have for page locking, we'd have to change our roughly
    ~50 different writeback functions. Painful.

    Instead, just make "wait_on_page_writeback()" loop on the very unlikely
    situation that the PG_writeback bit is still set, basically re-instating
    the old behavior. This is very non-optimal in case of contention, but
    since we only ever set the bit under the page lock, that situation is
    controlled.

    Reported-by: syzbot+2fc0712f8f8b8b8fa0ef@syzkaller.appspotmail.com
    Fixes: 2a9127fcf229 ("mm: rewrite wait_on_page_bit_common() logic")
    Acked-by: Hugh Dickins
    Cc: Andrew Morton
    Cc: Matthew Wilcox
    Cc: stable@kernel.org
    Signed-off-by: Linus Torvalds
    Signed-off-by: Greg Kroah-Hartman

    Linus Torvalds
     

25 Nov, 2020

1 commit

  • Twice now, when exercising ext4 looped on shmem huge pages, I have crashed
    on the PF_ONLY_HEAD check inside PageWaiters(): ext4_finish_bio() calling
    end_page_writeback() calling wake_up_page() on tail of a shmem huge page,
    no longer an ext4 page at all.

    The problem is that PageWriteback is not accompanied by a page reference
    (as the NOTE at the end of test_clear_page_writeback() acknowledges): as
    soon as TestClearPageWriteback has been done, that page could be removed
    from page cache, freed, and reused for something else by the time that
    wake_up_page() is reached.

    https://lore.kernel.org/linux-mm/20200827122019.GC14765@casper.infradead.org/
    Matthew Wilcox suggested avoiding or weakening the PageWaiters() tail
    check; but I'm paranoid about even looking at an unreferenced struct page,
    lest its memory might itself have already been reused or hotremoved (and
    wake_up_page_bit() may modify that memory with its ClearPageWaiters()).

    Then on crashing a second time, realized there's a stronger reason against
    that approach. If my testing just occasionally crashes on that check,
    when the page is reused for part of a compound page, wouldn't it be much
    more common for the page to get reused as an order-0 page before reaching
    wake_up_page()? And on rare occasions, might that reused page already be
    marked PageWriteback by its new user, and already be waited upon? What
    would that look like?

    It would look like BUG_ON(PageWriteback) after wait_on_page_writeback()
    in write_cache_pages() (though I have never seen that crash myself).

    Matthew Wilcox explaining this to himself:
    "page is allocated, added to page cache, dirtied, writeback starts,

    --- thread A ---
    filesystem calls end_page_writeback()
    test_clear_page_writeback()
    --- context switch to thread B ---
    truncate_inode_pages_range() finds the page, it doesn't have writeback set,
    we delete it from the page cache. Page gets reallocated, dirtied, writeback
    starts again. Then we call write_cache_pages(), see
    PageWriteback() set, call wait_on_page_writeback()
    --- context switch back to thread A ---
    wake_up_page(page, PG_writeback);
    ... thread B is woken, but because the wakeup was for the old use of
    the page, PageWriteback is still set.

    Devious"

    And prior to 2a9127fcf229 ("mm: rewrite wait_on_page_bit_common() logic")
    this would have been much less likely: before that, wake_page_function()'s
    non-exclusive case would stop walking and not wake if it found Writeback
    already set again; whereas now the non-exclusive case proceeds to wake.

    I have not thought of a fix that does not add a little overhead: the
    simplest fix is for end_page_writeback() to get_page() before calling
    test_clear_page_writeback(), then put_page() after wake_up_page().

    Was there a chance of missed wakeups before, since a page freed before
    reaching wake_up_page() would have PageWaiters cleared? I think not,
    because each waiter does hold a reference on the page. This bug comes
    when the old use of the page, the one we do TestClearPageWriteback on,
    had *no* waiters, so no additional page reference beyond the page cache
    (and whoever racily freed it). The reuse of the page has a waiter
    holding a reference, and its own PageWriteback set; but the belated
    wake_up_page() has woken the reuse to hit that BUG_ON(PageWriteback).

    Reported-by: syzbot+3622cea378100f45d59f@syzkaller.appspotmail.com
    Reported-by: Qian Cai
    Fixes: 2a9127fcf229 ("mm: rewrite wait_on_page_bit_common() logic")
    Signed-off-by: Hugh Dickins
    Cc: stable@vger.kernel.org # v5.8+
    Signed-off-by: Linus Torvalds

    Hugh Dickins
     

17 Oct, 2020

1 commit


25 Sep, 2020

3 commits

  • Replace the two negative flags that are always used together with a
    single positive flag that indicates the writeback capability instead
    of two related non-capabilities. Also remove the pointless wrappers
    to just check the flag.

    Signed-off-by: Christoph Hellwig
    Reviewed-by: Jan Kara
    Reviewed-by: Johannes Thumshirn
    Signed-off-by: Jens Axboe

    Christoph Hellwig
     
  • Replace BDI_CAP_NO_ACCT_WB with a positive BDI_CAP_WRITEBACK_ACCT to
    make the checks more obvious. Also remove the pointless
    bdi_cap_account_writeback wrapper that just obsfucates the check.

    Signed-off-by: Christoph Hellwig
    Reviewed-by: Jan Kara
    Reviewed-by: Johannes Thumshirn
    Signed-off-by: Jens Axboe

    Christoph Hellwig
     
  • The BDI_CAP_STABLE_WRITES is one of the few bits of information in the
    backing_dev_info shared between the block drivers and the writeback code.
    To help untangling the dependency replace it with a queue flag and a
    superblock flag derived from it. This also helps with the case of e.g.
    a file system requiring stable writes due to its own checksumming, but
    not forcing it on other users of the block device like the swap code.

    One downside is that we an't support the stable_pages_required bdi
    attribute in sysfs anymore. It is replaced with a queue attribute which
    also is writable for easier testing.

    Signed-off-by: Christoph Hellwig
    Reviewed-by: Jan Kara
    Reviewed-by: Johannes Thumshirn
    Signed-off-by: Jens Axboe

    Christoph Hellwig
     

08 Aug, 2020

1 commit

  • The global variable "vm_total_pages" is a relic from older days. There is
    only a single user that reads the variable - build_all_zonelists() - and
    the first thing it does is update it.

    Use a local variable in build_all_zonelists() instead and remove the
    global variable.

    Signed-off-by: David Hildenbrand
    Signed-off-by: Andrew Morton
    Reviewed-by: Wei Yang
    Reviewed-by: Pankaj Gupta
    Reviewed-by: Mike Rapoport
    Acked-by: Michal Hocko
    Cc: Johannes Weiner
    Cc: Huang Ying
    Cc: Minchan Kim
    Link: http://lkml.kernel.org/r/20200619132410.23859-2-david@redhat.com
    Signed-off-by: Linus Torvalds

    David Hildenbrand
     

05 Jun, 2020

1 commit


04 Jun, 2020

1 commit

  • Pull networking updates from David Miller:

    1) Allow setting bluetooth L2CAP modes via socket option, from Luiz
    Augusto von Dentz.

    2) Add GSO partial support to igc, from Sasha Neftin.

    3) Several cleanups and improvements to r8169 from Heiner Kallweit.

    4) Add IF_OPER_TESTING link state and use it when ethtool triggers a
    device self-test. From Andrew Lunn.

    5) Start moving away from custom driver versions, use the globally
    defined kernel version instead, from Leon Romanovsky.

    6) Support GRO vis gro_cells in DSA layer, from Alexander Lobakin.

    7) Allow hard IRQ deferral during NAPI, from Eric Dumazet.

    8) Add sriov and vf support to hinic, from Luo bin.

    9) Support Media Redundancy Protocol (MRP) in the bridging code, from
    Horatiu Vultur.

    10) Support netmap in the nft_nat code, from Pablo Neira Ayuso.

    11) Allow UDPv6 encapsulation of ESP in the ipsec code, from Sabrina
    Dubroca. Also add ipv6 support for espintcp.

    12) Lots of ReST conversions of the networking documentation, from Mauro
    Carvalho Chehab.

    13) Support configuration of ethtool rxnfc flows in bcmgenet driver,
    from Doug Berger.

    14) Allow to dump cgroup id and filter by it in inet_diag code, from
    Dmitry Yakunin.

    15) Add infrastructure to export netlink attribute policies to
    userspace, from Johannes Berg.

    16) Several optimizations to sch_fq scheduler, from Eric Dumazet.

    17) Fallback to the default qdisc if qdisc init fails because otherwise
    a packet scheduler init failure will make a device inoperative. From
    Jesper Dangaard Brouer.

    18) Several RISCV bpf jit optimizations, from Luke Nelson.

    19) Correct the return type of the ->ndo_start_xmit() method in several
    drivers, it's netdev_tx_t but many drivers were using
    'int'. From Yunjian Wang.

    20) Add an ethtool interface for PHY master/slave config, from Oleksij
    Rempel.

    21) Add BPF iterators, from Yonghang Song.

    22) Add cable test infrastructure, including ethool interfaces, from
    Andrew Lunn. Marvell PHY driver is the first to support this
    facility.

    23) Remove zero-length arrays all over, from Gustavo A. R. Silva.

    24) Calculate and maintain an explicit frame size in XDP, from Jesper
    Dangaard Brouer.

    25) Add CAP_BPF, from Alexei Starovoitov.

    26) Support terse dumps in the packet scheduler, from Vlad Buslov.

    27) Support XDP_TX bulking in dpaa2 driver, from Ioana Ciornei.

    28) Add devm_register_netdev(), from Bartosz Golaszewski.

    29) Minimize qdisc resets, from Cong Wang.

    30) Get rid of kernel_getsockopt and kernel_setsockopt in order to
    eliminate set_fs/get_fs calls. From Christoph Hellwig.

    * git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net-next: (2517 commits)
    selftests: net: ip_defrag: ignore EPERM
    net_failover: fixed rollback in net_failover_open()
    Revert "tipc: Fix potential tipc_aead refcnt leak in tipc_crypto_rcv"
    Revert "tipc: Fix potential tipc_node refcnt leak in tipc_rcv"
    vmxnet3: allow rx flow hash ops only when rss is enabled
    hinic: add set_channels ethtool_ops support
    selftests/bpf: Add a default $(CXX) value
    tools/bpf: Don't use $(COMPILE.c)
    bpf, selftests: Use bpf_probe_read_kernel
    s390/bpf: Use bcr 0,%0 as tail call nop filler
    s390/bpf: Maintain 8-byte stack alignment
    selftests/bpf: Fix verifier test
    selftests/bpf: Fix sample_cnt shared between two threads
    bpf, selftests: Adapt cls_redirect to call csum_level helper
    bpf: Add csum_level helper for fixing up csum levels
    bpf: Fix up bpf_skb_adjust_room helper's skb csum setting
    sfc: add missing annotation for efx_ef10_try_update_nic_stats_vf()
    crypto/chtls: IPv6 support for inline TLS
    Crypto/chcr: Fixes a coccinile check error
    Crypto/chcr: Fixes compilations warnings
    ...

    Linus Torvalds
     

03 Jun, 2020

3 commits

  • After an NFS page has been written it is considered "unstable" until a
    COMMIT request succeeds. If the COMMIT fails, the page will be
    re-written.

    These "unstable" pages are currently accounted as "reclaimable", either
    in WB_RECLAIMABLE, or in NR_UNSTABLE_NFS which is included in a
    'reclaimable' count. This might have made sense when sending the COMMIT
    required a separate action by the VFS/MM (e.g. releasepage() used to
    send a COMMIT). However now that all writes generated by ->writepages()
    will automatically be followed by a COMMIT (since commit 919e3bd9a875
    ("NFS: Ensure we commit after writeback is complete")) it makes more
    sense to treat them as writeback pages.

    So this patch removes NR_UNSTABLE_NFS and accounts unstable pages in
    NR_WRITEBACK and WB_WRITEBACK.

    A particular effect of this change is that when
    wb_check_background_flush() calls wb_over_bg_threshold(), the latter
    will report 'true' a lot less often as the 'unstable' pages are no
    longer considered 'dirty' (as there is nothing that writeback can do
    about them anyway).

    Currently wb_check_background_flush() will trigger writeback to NFS even
    when there are relatively few dirty pages (if there are lots of unstable
    pages), this can result in small writes going to the server (10s of
    Kilobytes rather than a Megabyte) which hurts throughput. With this
    patch, there are fewer writes which are each larger on average.

    Where the NR_UNSTABLE_NFS count was included in statistics
    virtual-files, the entry is retained, but the value is hard-coded as
    zero. static trace points and warning printks which mentioned this
    counter no longer report it.

    [akpm@linux-foundation.org: re-layout comment]
    [akpm@linux-foundation.org: fix printk warning]
    Signed-off-by: NeilBrown
    Signed-off-by: Andrew Morton
    Reviewed-by: Jan Kara
    Reviewed-by: Christoph Hellwig
    Acked-by: Trond Myklebust
    Acked-by: Michal Hocko [mm]
    Cc: Christoph Hellwig
    Cc: Chuck Lever
    Link: http://lkml.kernel.org/r/87d06j7gqa.fsf@notabene.neil.brown.name
    Signed-off-by: Linus Torvalds

    NeilBrown
     
  • PF_LESS_THROTTLE exists for loop-back nfsd (and a similar need in the
    loop block driver and callers of prctl(PR_SET_IO_FLUSHER)), where a
    daemon needs to write to one bdi (the final bdi) in order to free up
    writes queued to another bdi (the client bdi).

    The daemon sets PF_LESS_THROTTLE and gets a larger allowance of dirty
    pages, so that it can still dirty pages after other processses have been
    throttled. The purpose of this is to avoid deadlock that happen when
    the PF_LESS_THROTTLE process must write for any dirty pages to be freed,
    but it is being thottled and cannot write.

    This approach was designed when all threads were blocked equally,
    independently on which device they were writing to, or how fast it was.
    Since that time the writeback algorithm has changed substantially with
    different threads getting different allowances based on non-trivial
    heuristics. This means the simple "add 25%" heuristic is no longer
    reliable.

    The important issue is not that the daemon needs a *larger* dirty page
    allowance, but that it needs a *private* dirty page allowance, so that
    dirty pages for the "client" bdi that it is helping to clear (the bdi
    for an NFS filesystem or loop block device etc) do not affect the
    throttling of the daemon writing to the "final" bdi.

    This patch changes the heuristic so that the task is not throttled when
    the bdi it is writing to has a dirty page count below below (or equal
    to) the free-run threshold for that bdi. This ensures it will always be
    able to have some pages in flight, and so will not deadlock.

    In a steady-state, it is expected that PF_LOCAL_THROTTLE tasks might
    still be throttled by global threshold, but that is acceptable as it is
    only the deadlock state that is interesting for this flag.

    This approach of "only throttle when target bdi is busy" is consistent
    with the other use of PF_LESS_THROTTLE in current_may_throttle(), were
    it causes attention to be focussed only on the target bdi.

    So this patch
    - renames PF_LESS_THROTTLE to PF_LOCAL_THROTTLE,
    - removes the 25% bonus that that flag gives, and
    - If PF_LOCAL_THROTTLE is set, don't delay at all unless the
    global and the local free-run thresholds are exceeded.

    Note that previously realtime threads were treated the same as
    PF_LESS_THROTTLE threads. This patch does *not* change the behvaiour
    for real-time threads, so it is now different from the behaviour of nfsd
    and loop tasks. I don't know what is wanted for realtime.

    [akpm@linux-foundation.org: coding style fixes]
    Signed-off-by: NeilBrown
    Signed-off-by: Andrew Morton
    Reviewed-by: Jan Kara
    Acked-by: Chuck Lever [nfsd]
    Cc: Christoph Hellwig
    Cc: Michal Hocko
    Cc: Trond Myklebust
    Link: http://lkml.kernel.org/r/87ftbf7gs3.fsf@notabene.neil.brown.name
    Signed-off-by: Linus Torvalds

    NeilBrown
     
  • Commit 64081362e8ff ("mm/page-writeback.c: fix range_cyclic writeback
    vs writepages deadlock") left unused variable, remove it.

    Signed-off-by: Chao Yu
    Signed-off-by: Andrew Morton
    Reviewed-by: David Hildenbrand
    Link: http://lkml.kernel.org/r/20200528033740.17269-1-yuchao0@huawei.com
    Signed-off-by: Linus Torvalds

    Chao Yu
     

27 Apr, 2020

1 commit

  • Instead of having all the sysctl handlers deal with user pointers, which
    is rather hairy in terms of the BPF interaction, copy the input to and
    from userspace in common code. This also means that the strings are
    always NUL-terminated by the common code, making the API a little bit
    safer.

    As most handler just pass through the data to one of the common handlers
    a lot of the changes are mechnical.

    Signed-off-by: Christoph Hellwig
    Acked-by: Andrey Ignatov
    Signed-off-by: Al Viro

    Christoph Hellwig
     

03 Apr, 2020

3 commits

  • With the introduction of protected KVM guests on s390 there is now a
    concept of inaccessible pages. These pages need to be made accessible
    before the host can access them.

    While cpu accesses will trigger a fault that can be resolved, I/O accesses
    will just fail. We need to add a callback into architecture code for
    places that will do I/O, namely when writeback is started or when a page
    reference is taken.

    This is not only to enable paging, file backing etc, it is also necessary
    to protect the host against a malicious user space. For example a bad
    QEMU could simply start direct I/O on such protected memory. We do not
    want userspace to be able to trigger I/O errors and thus the logic is
    "whenever somebody accesses that page (gup) or does I/O, make sure that
    this page can be accessed". When the guest tries to access that page we
    will wait in the page fault handler for writeback to have finished and for
    the page_ref to be the expected value.

    On s390x the function is not supposed to fail, so it is ok to use a
    WARN_ON on failure. If we ever need some more finegrained handling we can
    tackle this when we know the details.

    Signed-off-by: Claudio Imbrenda
    Signed-off-by: Andrew Morton
    Reviewed-by: David Hildenbrand
    Reviewed-by: Christian Borntraeger
    Reviewed-by: John Hubbard
    Acked-by: Will Deacon
    Cc: Jan Kara
    Cc: Matthew Wilcox
    Cc: Ira Weiny
    Cc: Jérôme Glisse
    Cc: Al Viro
    Cc: Christoph Hellwig
    Cc: Dan Williams
    Cc: Dave Chinner
    Cc: Jason Gunthorpe
    Cc: Jonathan Corbet
    Cc: Michal Hocko
    Cc: Mike Kravetz
    Cc: Shuah Khan
    Cc: Vlastimil Babka
    Link: http://lkml.kernel.org/r/20200306132537.783769-3-imbrenda@linux.ibm.com
    Signed-off-by: Linus Torvalds

    Claudio Imbrenda
     
  • Dumping the page information in this circumstance helps for debugging.

    Signed-off-by: Matthew Wilcox (Oracle)
    Signed-off-by: Andrew Morton
    Reviewed-by: Christoph Hellwig
    Acked-by: Kirill A. Shutemov
    Cc: Aneesh Kumar K.V
    Cc: Pankaj Gupta
    Link: http://lkml.kernel.org/r/20200318140253.6141-7-willy@infradead.org
    Signed-off-by: Linus Torvalds

    Matthew Wilcox (Oracle)
     
  • There used to be a 'retry' label in between the two (identical) checks
    when first introduced in commit f446daaea9d4 ("mm: implement writeback
    livelock avoidance using page tagging"), and later modified/updated in
    commit 6e6938b6d313 ("writeback: introduce .tagged_writepages for the
    WB_SYNC_NONE sync stage").

    The label has been removed in commit 64081362e8ff ("mm/page-writeback.c:
    fix range_cyclic writeback vs writepages deadlock"), and the (identical)
    checks are now present / performed immediately one after another.

    So, remove/deduplicate the latter check, moving tag_pages_for_writeback()
    into the former check before the 'tag' variable assignment, so it's clear
    that it's not used in this (similarly-named) function call but only later
    in pagevec_lookup_range_tag().

    Signed-off-by: Mauricio Faria de Oliveira
    Signed-off-by: Andrew Morton
    Reviewed-by: Ira Weiny
    Reviewed-by: Andrew Morton
    Cc: Jan Kara
    Link: http://lkml.kernel.org/r/20200218221716.1648-1-mfo@canonical.com
    Signed-off-by: Linus Torvalds

    Mauricio Faria de Oliveira
     

14 Jan, 2020

3 commits

  • Use div64_ul() instead of do_div() if the divisor is unsigned long, to
    avoid truncation to 32-bit on 64-bit platforms.

    Link: http://lkml.kernel.org/r/20200102081442.8273-4-wenyang@linux.alibaba.com
    Signed-off-by: Wen Yang
    Reviewed-by: Andrew Morton
    Cc: Qian Cai
    Cc: Tejun Heo
    Cc: Jens Axboe
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Wen Yang
     
  • The two variables 'numerator' and 'denominator', though they are
    declared as long, they should actually be unsigned long (according to
    the implementation of the fprop_fraction_percpu() function)

    And do_div() does a 64-by-32 division, while the divisor 'denominator'
    is unsigned long, thus 64-bit on 64-bit platforms. Hence the proper
    function to call is div64_ul().

    Link: http://lkml.kernel.org/r/20200102081442.8273-3-wenyang@linux.alibaba.com
    Signed-off-by: Wen Yang
    Reviewed-by: Andrew Morton
    Cc: Qian Cai
    Cc: Tejun Heo
    Cc: Jens Axboe
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Wen Yang
     
  • Patch series "use div64_ul() instead of div_u64() if the divisor is
    unsigned long".

    We were first inspired by commit b0ab99e7736a ("sched: Fix possible divide
    by zero in avg_atom () calculation"), then refer to the recently analyzed
    mm code, we found this suspicious place.

    201 if (min) {
    202 min *= this_bw;
    203 do_div(min, tot_bw);
    204 }

    And we also disassembled and confirmed it:

    /usr/src/debug/kernel-4.9.168-016.ali3000/linux-4.9.168-016.ali3000.alios7.x86_64/mm/page-writeback.c: 201
    0xffffffff811c37da : xor %r10d,%r10d
    0xffffffff811c37dd : test %rax,%rax
    0xffffffff811c37e0 : je 0xffffffff811c3800
    /usr/src/debug/kernel-4.9.168-016.ali3000/linux-4.9.168-016.ali3000.alios7.x86_64/mm/page-writeback.c: 202
    0xffffffff811c37e2 : imul %r8,%rax
    /usr/src/debug/kernel-4.9.168-016.ali3000/linux-4.9.168-016.ali3000.alios7.x86_64/mm/page-writeback.c: 203
    0xffffffff811c37e6 : mov %r9d,%r10d ---> truncates it to 32 bits here
    0xffffffff811c37e9 : xor %edx,%edx
    0xffffffff811c37eb : div %r10
    0xffffffff811c37ee : imul %rbx,%rax
    0xffffffff811c37f2 : shr $0x2,%rax
    0xffffffff811c37f6 : mul %rcx
    0xffffffff811c37f9 : shr $0x2,%rdx
    0xffffffff811c37fd : mov %rdx,%r10

    This series uses div64_ul() instead of div_u64() if the divisor is
    unsigned long, to avoid truncation to 32-bit on 64-bit platforms.

    This patch (of 3):

    The variables 'min' and 'max' are unsigned long and do_div truncates
    them to 32 bits, which means it can test non-zero and be truncated to
    zero for division. Fix this issue by using div64_ul() instead.

    Link: http://lkml.kernel.org/r/20200102081442.8273-2-wenyang@linux.alibaba.com
    Fixes: 693108a8a667 ("writeback: make bdi->min/max_ratio handling cgroup writeback aware")
    Signed-off-by: Wen Yang
    Reviewed-by: Andrew Morton
    Cc: Qian Cai
    Cc: Tejun Heo
    Cc: Jens Axboe
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Wen Yang
     

27 Aug, 2019

1 commit

  • There's an inherent mismatch between memcg and writeback. The former
    trackes ownership per-page while the latter per-inode. This was a
    deliberate design decision because honoring per-page ownership in the
    writeback path is complicated, may lead to higher CPU and IO overheads
    and deemed unnecessary given that write-sharing an inode across
    different cgroups isn't a common use-case.

    Combined with inode majority-writer ownership switching, this works
    well enough in most cases but there are some pathological cases. For
    example, let's say there are two cgroups A and B which keep writing to
    different but confined parts of the same inode. B owns the inode and
    A's memory is limited far below B's. A's dirty ratio can rise enough
    to trigger balance_dirty_pages() sleeps but B's can be low enough to
    avoid triggering background writeback. A will be slowed down without
    a way to make writeback of the dirty pages happen.

    This patch implements foreign dirty recording and foreign mechanism so
    that when a memcg encounters a condition as above it can trigger
    flushes on bdi_writebacks which can clean its pages. Please see the
    comment on top of mem_cgroup_track_foreign_dirty_slowpath() for
    details.

    A reproducer follows.

    write-range.c::

    #include
    #include
    #include
    #include
    #include

    static const char *usage = "write-range FILE START SIZE\n";

    int main(int argc, char **argv)
    {
    int fd;
    unsigned long start, size, end, pos;
    char *endp;
    char buf[4096];

    if (argc < 4) {
    fprintf(stderr, usage);
    return 1;
    }

    fd = open(argv[1], O_WRONLY);
    if (fd < 0) {
    perror("open");
    return 1;
    }

    start = strtoul(argv[2], &endp, 0);
    if (*endp != '\0') {
    fprintf(stderr, usage);
    return 1;
    }

    size = strtoul(argv[3], &endp, 0);
    if (*endp != '\0') {
    fprintf(stderr, usage);
    return 1;
    }

    end = start + size;

    while (1) {
    for (pos = start; pos < end; ) {
    long bread, bwritten = 0;

    if (lseek(fd, pos, SEEK_SET) < 0) {
    perror("lseek");
    return 1;
    }

    bread = read(0, buf, sizeof(buf) < end - pos ?
    sizeof(buf) : end - pos);
    if (bread < 0) {
    perror("read");
    return 1;
    }
    if (bread == 0)
    return 0;

    while (bwritten < bread) {
    long this;

    this = write(fd, buf + bwritten,
    bread - bwritten);
    if (this < 0) {
    perror("write");
    return 1;
    }

    bwritten += this;
    pos += bwritten;
    }
    }
    }
    }

    repro.sh::

    #!/bin/bash

    set -e
    set -x

    sysctl -w vm.dirty_expire_centisecs=300000
    sysctl -w vm.dirty_writeback_centisecs=300000
    sysctl -w vm.dirtytime_expire_seconds=300000
    echo 3 > /proc/sys/vm/drop_caches

    TEST=/sys/fs/cgroup/test
    A=$TEST/A
    B=$TEST/B

    mkdir -p $A $B
    echo "+memory +io" > $TEST/cgroup.subtree_control
    echo $((1< $A/memory.high
    echo $((32< $B/memory.high

    rm -f testfile
    touch testfile
    fallocate -l 4G testfile

    echo "Starting B"

    (echo $BASHPID > $B/cgroup.procs
    pv -q --rate-limit 70M < /dev/urandom | ./write-range testfile $((2<< $A/cgroup.procs
    pv < /dev/urandom | ./write-range testfile 0 $((2<
    Signed-off-by: Tejun Heo
    Signed-off-by: Jens Axboe

    Tejun Heo
     

13 Jul, 2019

1 commit

  • account_page_dirtied() is only used by our set_page_dirty() helpers and
    should not be used anywhere else.

    Link: http://lkml.kernel.org/r/20190605183702.30572-1-hch@lst.de
    Signed-off-by: Christoph Hellwig
    Reviewed-by: Andrew Morton
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Christoph Hellwig
     

21 May, 2019

1 commit

  • Add SPDX license identifiers to all files which:

    - Have no license information of any form

    - Have EXPORT_.*_SYMBOL_GPL inside which was used in the
    initial scan/conversion to ignore the file

    These files fall under the project license, GPL v2 only. The resulting SPDX
    license identifier is:

    GPL-2.0-only

    Signed-off-by: Thomas Gleixner
    Signed-off-by: Greg Kroah-Hartman

    Thomas Gleixner
     

15 May, 2019

1 commit

  • Recently there have been some hung tasks on our server due to
    wait_on_page_writeback(), and we want to know the details of this
    PG_writeback, i.e. this page is writing back to which device. But it is
    not so convenient to get the details.

    I think it would be better to introduce a tracepoint for diagnosing the
    writeback details.

    Link: http://lkml.kernel.org/r/1556274402-19018-1-git-send-email-laoar.shao@gmail.com
    Signed-off-by: Yafang Shao
    Reviewed-by: Andrew Morton
    Cc: Jan Kara
    Cc: Michal Hocko
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Yafang Shao
     

06 Mar, 2019

1 commit

  • Many kernel-doc comments in mm/ have the return value descriptions
    either misformatted or omitted at all which makes kernel-doc script
    unhappy:

    $ make V=1 htmldocs
    ...
    ./mm/util.c:36: info: Scanning doc for kstrdup
    ./mm/util.c:41: warning: No description found for return value of 'kstrdup'
    ./mm/util.c:57: info: Scanning doc for kstrdup_const
    ./mm/util.c:66: warning: No description found for return value of 'kstrdup_const'
    ./mm/util.c:75: info: Scanning doc for kstrndup
    ./mm/util.c:83: warning: No description found for return value of 'kstrndup'
    ...

    Fixing the formatting and adding the missing return value descriptions
    eliminates ~100 such warnings.

    Link: http://lkml.kernel.org/r/1549549644-4903-4-git-send-email-rppt@linux.ibm.com
    Signed-off-by: Mike Rapoport
    Reviewed-by: Andrew Morton
    Cc: Jonathan Corbet
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Mike Rapoport
     

29 Dec, 2018

1 commit

  • write_cache_pages() is used in both background and integrity writeback
    scenarios by various filesystems. Background writeback is mostly
    concerned with cleaning a certain number of dirty pages based on various
    mm heuristics. It may not write the full set of dirty pages or wait for
    I/O to complete. Integrity writeback is responsible for persisting a set
    of dirty pages before the writeback job completes. For example, an
    fsync() call must perform integrity writeback to ensure data is on disk
    before the call returns.

    write_cache_pages() unconditionally breaks out of its processing loop in
    the event of a ->writepage() error. This is fine for background
    writeback, which had no strict requirements and will eventually come
    around again. This can cause problems for integrity writeback on
    filesystems that might need to clean up state associated with failed page
    writeouts. For example, XFS performs internal delayed allocation
    accounting before returning a ->writepage() error, where applicable. If
    the current writeback happens to be associated with an unmount and
    write_cache_pages() completes the writeback prematurely due to error, the
    filesystem is unmounted in an inconsistent state if dirty+delalloc pages
    still exist.

    To handle this problem, update write_cache_pages() to always process the
    full set of pages for integrity writeback regardless of ->writepage()
    errors. Save the first encountered error and return it to the caller once
    complete. This facilitates XFS (or any other fs that expects integrity
    writeback to process the entire set of dirty pages) to clean up its
    internal state completely in the event of persistent mapping errors.
    Background writeback continues to exit on the first error encountered.

    [akpm@linux-foundation.org: fix typo in comment]
    Link: http://lkml.kernel.org/r/20181116134304.32440-1-bfoster@redhat.com
    Signed-off-by: Brian Foster
    Reviewed-by: Jan Kara
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Brian Foster
     

29 Oct, 2018

1 commit

  • Pull XArray conversion from Matthew Wilcox:
    "The XArray provides an improved interface to the radix tree data
    structure, providing locking as part of the API, specifying GFP flags
    at allocation time, eliminating preloading, less re-walking the tree,
    more efficient iterations and not exposing RCU-protected pointers to
    its users.

    This patch set

    1. Introduces the XArray implementation

    2. Converts the pagecache to use it

    3. Converts memremap to use it

    The page cache is the most complex and important user of the radix
    tree, so converting it was most important. Converting the memremap
    code removes the only other user of the multiorder code, which allows
    us to remove the radix tree code that supported it.

    I have 40+ followup patches to convert many other users of the radix
    tree over to the XArray, but I'd like to get this part in first. The
    other conversions haven't been in linux-next and aren't suitable for
    applying yet, but you can see them in the xarray-conv branch if you're
    interested"

    * 'xarray' of git://git.infradead.org/users/willy/linux-dax: (90 commits)
    radix tree: Remove multiorder support
    radix tree test: Convert multiorder tests to XArray
    radix tree tests: Convert item_delete_rcu to XArray
    radix tree tests: Convert item_kill_tree to XArray
    radix tree tests: Move item_insert_order
    radix tree test suite: Remove multiorder benchmarking
    radix tree test suite: Remove __item_insert
    memremap: Convert to XArray
    xarray: Add range store functionality
    xarray: Move multiorder_check to in-kernel tests
    xarray: Move multiorder_shrink to kernel tests
    xarray: Move multiorder account test in-kernel
    radix tree test suite: Convert iteration test to XArray
    radix tree test suite: Convert tag_tagged_items to XArray
    radix tree: Remove radix_tree_clear_tags
    radix tree: Remove radix_tree_maybe_preload_order
    radix tree: Remove split/join code
    radix tree: Remove radix_tree_update_node_t
    page cache: Finish XArray conversion
    dax: Convert page fault handlers to XArray
    ...

    Linus Torvalds
     

27 Oct, 2018

1 commit

  • We've recently seen a workload on XFS filesystems with a repeatable
    deadlock between background writeback and a multi-process application
    doing concurrent writes and fsyncs to a small range of a file.

    range_cyclic
    writeback Process 1 Process 2

    xfs_vm_writepages
    write_cache_pages
    writeback_index = 2
    cycled = 0
    ....
    find page 2 dirty
    lock Page 2
    ->writepage
    page 2 writeback
    page 2 clean
    page 2 added to bio
    no more pages
    write()
    locks page 1
    dirties page 1
    locks page 2
    dirties page 1
    fsync()
    ....
    xfs_vm_writepages
    write_cache_pages
    start index 0
    find page 1 towrite
    lock Page 1
    ->writepage
    page 1 writeback
    page 1 clean
    page 1 added to bio
    find page 2 towrite
    lock Page 2
    page 2 is writeback

    write()
    locks page 1
    dirties page 1
    fsync()
    ....
    xfs_vm_writepages
    write_cache_pages
    start index 0

    !done && !cycled
    sets index to 0, restarts lookup
    find page 1 dirty
    find page 1 towrite
    lock Page 1
    page 1 is writeback

    lock Page 1

    DEADLOCK because:

    - process 1 needs page 2 writeback to complete to make
    enough progress to issue IO pending for page 1
    - writeback needs page 1 writeback to complete so process 2
    can progress and unlock the page it is blocked on, then it
    can issue the IO pending for page 2
    - process 2 can't make progress until process 1 issues IO
    for page 1

    The underlying cause of the problem here is that range_cyclic writeback is
    processing pages in descending index order as we hold higher index pages
    in a structure controlled from above write_cache_pages(). The
    write_cache_pages() caller needs to be able to submit these pages for IO
    before write_cache_pages restarts writeback at mapping index 0 to avoid
    wcp inverting the page lock/writeback wait order.

    generic_writepages() is not susceptible to this bug as it has no private
    context held across write_cache_pages() - filesystems using this
    infrastructure always submit pages in ->writepage immediately and so there
    is no problem with range_cyclic going back to mapping index 0.

    However:
    mpage_writepages() has a private bio context,
    exofs_writepages() has page_collect
    fuse_writepages() has fuse_fill_wb_data
    nfs_writepages() has nfs_pageio_descriptor
    xfs_vm_writepages() has xfs_writepage_ctx

    All of these ->writepages implementations can hold pages under writeback
    in their private structures until write_cache_pages() returns, and hence
    they are all susceptible to this deadlock.

    Also worth noting is that ext4 has it's own bastardised version of
    write_cache_pages() and so it /may/ have an equivalent deadlock. I looked
    at the code long enough to understand that it has a similar retry loop for
    range_cyclic writeback reaching the end of the file and then promptly ran
    away before my eyes bled too much. I'll leave it for the ext4 developers
    to determine if their code is actually has this deadlock and how to fix it
    if it has.

    There's a few ways I can see avoid this deadlock. There's probably more,
    but these are the first I've though of:

    1. get rid of range_cyclic altogether

    2. range_cyclic always stops at EOF, and we start again from
    writeback index 0 on the next call into write_cache_pages()

    2a. wcp also returns EAGAIN to ->writepages implementations to
    indicate range cyclic has hit EOF. writepages implementations can
    then flush the current context and call wpc again to continue. i.e.
    lift the retry into the ->writepages implementation

    3. range_cyclic uses trylock_page() rather than lock_page(), and it
    skips pages it can't lock without blocking. It will already do this
    for pages under writeback, so this seems like a no-brainer

    3a. all non-WB_SYNC_ALL writeback uses trylock_page() to avoid
    blocking as per pages under writeback.

    I don't think #1 is an option - range_cyclic prevents frequently
    dirtied lower file offset from starving background writeback of
    rarely touched higher file offsets.

    #2 is simple, and I don't think it will have any impact on
    performance as going back to the start of the file implies an
    immediate seek. We'll have exactly the same number of seeks if we
    switch writeback to another inode, and then come back to this one
    later and restart from index 0.

    #2a is pretty much "status quo without the deadlock". Moving the
    retry loop up into the wcp caller means we can issue IO on the
    pending pages before calling wcp again, and so avoid locking or
    waiting on pages in the wrong order. I'm not convinced we need to do
    this given that we get the same thing from #2 on the next writeback
    call from the writeback infrastructure.

    #3 is really just a band-aid - it doesn't fix the access/wait
    inversion problem, just prevents it from becoming a deadlock
    situation. I'd prefer we fix the inversion, not sweep it under the
    carpet like this.

    #3a is really an optimisation that just so happens to include the
    band-aid fix of #3.

    So it seems that the simplest way to fix this issue is to implement
    solution #2

    Link: http://lkml.kernel.org/r/20181005054526.21507-1-david@fromorbit.com
    Signed-off-by: Dave Chinner
    Reviewed-by: Jan Kara
    Cc: Nicholas Piggin
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Dave Chinner
     

21 Oct, 2018

1 commit


30 Aug, 2018

1 commit


18 Aug, 2018

1 commit

  • Commit 93f78d882865 ("writeback: move backing_dev_info->bdi_stat[] into
    bdi_writeback") replaced BDI_DIRTIED with WB_DIRTIED in
    account_page_redirty(). Update comment to track that change.

    BDI_DIRTIED => WB_DIRTIED
    BDI_WRITTEN => WB_WRITTEN

    Link: http://lkml.kernel.org/r/20180625171526.173483-1-gthelen@google.com
    Signed-off-by: Greg Thelen
    Reviewed-by: Jan Kara
    Acked-by: Tejun Heo
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Greg Thelen
     

21 Apr, 2018

1 commit

  • lock_page_memcg()/unlock_page_memcg() use spin_lock_irqsave/restore() if
    the page's memcg is undergoing move accounting, which occurs when a
    process leaves its memcg for a new one that has
    memory.move_charge_at_immigrate set.

    unlocked_inode_to_wb_begin,end() use spin_lock_irq/spin_unlock_irq() if
    the given inode is switching writeback domains. Switches occur when
    enough writes are issued from a new domain.

    This existing pattern is thus suspicious:
    lock_page_memcg(page);
    unlocked_inode_to_wb_begin(inode, &locked);
    ...
    unlocked_inode_to_wb_end(inode, locked);
    unlock_page_memcg(page);

    If both inode switch and process memcg migration are both in-flight then
    unlocked_inode_to_wb_end() will unconditionally enable interrupts while
    still holding the lock_page_memcg() irq spinlock. This suggests the
    possibility of deadlock if an interrupt occurs before unlock_page_memcg().

    truncate
    __cancel_dirty_page
    lock_page_memcg
    unlocked_inode_to_wb_begin
    unlocked_inode_to_wb_end


    end_page_writeback
    test_clear_page_writeback
    lock_page_memcg

    unlock_page_memcg

    Due to configuration limitations this deadlock is not currently possible
    because we don't mix cgroup writeback (a cgroupv2 feature) and
    memory.move_charge_at_immigrate (a cgroupv1 feature).

    If the kernel is hacked to always claim inode switching and memcg
    moving_account, then this script triggers lockup in less than a minute:

    cd /mnt/cgroup/memory
    mkdir a b
    echo 1 > a/memory.move_charge_at_immigrate
    echo 1 > b/memory.move_charge_at_immigrate
    (
    echo $BASHPID > a/cgroup.procs
    while true; do
    dd if=/dev/zero of=/mnt/big bs=1M count=256
    done
    ) &
    while true; do
    sync
    done &
    sleep 1h &
    SLEEP=$!
    while true; do
    echo $SLEEP > a/cgroup.procs
    echo $SLEEP > b/cgroup.procs
    done

    The deadlock does not seem possible, so it's debatable if there's any
    reason to modify the kernel. I suggest we should to prevent future
    surprises. And Wang Long said "this deadlock occurs three times in our
    environment", so there's more reason to apply this, even to stable.
    Stable 4.4 has minor conflicts applying this patch. For a clean 4.4 patch
    see "[PATCH for-4.4] writeback: safer lock nesting"
    https://lkml.org/lkml/2018/4/11/146

    Wang Long said "this deadlock occurs three times in our environment"

    [gthelen@google.com: v4]
    Link: http://lkml.kernel.org/r/20180411084653.254724-1-gthelen@google.com
    [akpm@linux-foundation.org: comment tweaks, struct initialization simplification]
    Change-Id: Ibb773e8045852978f6207074491d262f1b3fb613
    Link: http://lkml.kernel.org/r/20180410005908.167976-1-gthelen@google.com
    Fixes: 682aa8e1a6a1 ("writeback: implement unlocked_inode_to_wb transaction and use it for stat updates")
    Signed-off-by: Greg Thelen
    Reported-by: Wang Long
    Acked-by: Wang Long
    Acked-by: Michal Hocko
    Reviewed-by: Andrew Morton
    Cc: Johannes Weiner
    Cc: Tejun Heo
    Cc: Nicholas Piggin
    Cc: [v4.2+]
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Greg Thelen
     

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
     

30 Nov, 2017

1 commit

  • This reverts commit 0f6d24f87856 ("mm/page-writeback.c: print a warning
    if the vm dirtiness settings are illogical") because it causes false
    positive warnings during OOM situations as noticed by Tetsuo Handa:

    Node 0 active_anon:3525940kB inactive_anon:8372kB active_file:216kB inactive_file:1872kB unevictable:0kB isolated(anon):0kB isolated(file):0kB mapped:2504kB dirty:52kB writeback:0kB shmem:8660kB shmem_thp: 0kB shmem_pmdmapped: 0kB anon_thp: 636928kB writeback_tmp:0kB unstable:0kB all_unreclaimable? yes
    Node 0 DMA free:14848kB min:284kB low:352kB high:420kB active_anon:992kB inactive_anon:0kB active_file:0kB inactive_file:0kB unevictable:0kB writepending:0kB present:15988kB managed:15904kB mlocked:0kB kernel_stack:0kB pagetables:24kB bounce:0kB free_pcp:0kB local_pcp:0kB free_cma:0kB
    lowmem_reserve[]: 0 2687 3645 3645
    Node 0 DMA32 free:53004kB min:49608kB low:62008kB high:74408kB active_anon:2712648kB inactive_anon:0kB active_file:0kB inactive_file:0kB unevictable:0kB writepending:0kB present:3129216kB managed:2773132kB mlocked:0kB kernel_stack:96kB pagetables:5096kB bounce:0kB free_pcp:0kB local_pcp:0kB free_cma:0kB
    lowmem_reserve[]: 0 0 958 958
    Node 0 Normal free:17140kB min:17684kB low:22104kB high:26524kB active_anon:812300kB inactive_anon:8372kB active_file:1228kB inactive_file:1868kB unevictable:0kB writepending:52kB present:1048576kB managed:981224kB mlocked:0kB kernel_stack:3520kB pagetables:8552kB bounce:0kB free_pcp:120kB local_pcp:120kB free_cma:0kB
    lowmem_reserve[]: 0 0 0 0
    [...]
    Out of memory: Kill process 8459 (a.out) score 999 or sacrifice child
    Killed process 8459 (a.out) total-vm:4180kB, anon-rss:88kB, file-rss:0kB, shmem-rss:0kB
    oom_reaper: reaped process 8459 (a.out), now anon-rss:0kB, file-rss:0kB, shmem-rss:0kB
    vm direct limit must be set greater than background limit.

    The problem is that both thresh and bg_thresh will be 0 if
    available_memory is less than 4 pages when evaluating
    global_dirtyable_memory.

    While this might be worked around the whole point of the warning is
    dubious at best. We do rely on admins to do sensible things when
    changing tunable knobs. Dirty memory writeback knobs are not any
    special in that regards so revert the warning rather than adding more
    hacks to work this around.

    Debugged by Yafang Shao.

    Link: http://lkml.kernel.org/r/20171127091939.tahb77nznytcxw55@dhcp22.suse.cz
    Fixes: 0f6d24f87856 ("mm/page-writeback.c: print a warning if the vm dirtiness settings are illogical")
    Signed-off-by: Michal Hocko
    Reported-by: Tetsuo Handa
    Cc: Yafang Shao
    Cc: Jan Kara
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Michal Hocko
     

22 Nov, 2017

1 commit

  • In preparation for unconditionally passing the struct timer_list pointer to
    all timer callbacks, switch to using the new timer_setup() and from_timer()
    to pass the timer pointer explicitly.

    Cc: Jens Axboe
    Cc: Michal Hocko
    Cc: Andrew Morton
    Cc: Jan Kara
    Cc: Johannes Weiner
    Cc: Nicholas Piggin
    Cc: Vladimir Davydov
    Cc: Matthew Wilcox
    Cc: Jeff Layton
    Cc: linux-block@vger.kernel.org
    Cc: linux-mm@kvack.org
    Signed-off-by: Kees Cook

    Kees Cook
     

16 Nov, 2017

6 commits

  • The parameter `struct bdi_writeback *wb` is not been used in the
    function body. Remove it.

    Link: http://lkml.kernel.org/r/1509685485-15278-1-git-send-email-wanglong19@meituan.com
    Signed-off-by: Wang Long
    Reviewed-by: Jan Kara
    Acked-by: Tejun Heo
    Cc: Jens Axboe
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Wang Long
     
  • Every pagevec_init user claims the pages being released are hot even in
    cases where it is unlikely the pages are hot. As no one cares about the
    hotness of pages being released to the allocator, just ditch the
    parameter.

    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.

    Link: http://lkml.kernel.org/r/20171018075952.10627-6-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
     
  • Patch series "Speed up page cache truncation", v1.

    When rebasing our enterprise distro to a newer kernel (from 4.4 to 4.12)
    we have noticed a regression in bonnie++ benchmark when deleting files.
    Eventually we have tracked this down to a fact that page cache
    truncation got slower by about 10%. There were both gains and losses in
    the above interval of kernels but we have been able to identify that
    commit 83929372f629 ("filemap: prepare find and delete operations for
    huge pages") caused about 10% regression on its own.

    After some investigation it didn't seem easily possible to fix the
    regression while maintaining the THP in page cache functionality so
    we've decided to optimize the page cache truncation path instead to make
    up for the change. This series is a result of that effort.

    Patch 1 is an easy speedup of cancel_dirty_page(). Patches 2-6 refactor
    page cache truncation code so that it is easier to batch radix tree
    operations. Patch 7 implements batching of deletes from the radix tree
    which more than makes up for the original regression.

    This patch (of 7):

    cancel_dirty_page() does quite some work even for clean pages (fetching
    of mapping, locking of memcg, atomic bit op on page flags) so it
    accounts for ~2.5% of cost of truncation of a clean page. That is not
    much but still dumb for something we don't need at all. Check whether a
    page is actually dirty and avoid any work if not.

    Link: http://lkml.kernel.org/r/20171010151937.26984-2-jack@suse.cz
    Signed-off-by: Jan Kara
    Acked-by: Mel Gorman
    Reviewed-by: Andi Kleen
    Cc: Dave Hansen
    Cc: Dave Chinner
    Cc: "Kirill A. Shutemov"
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Jan Kara
     
  • In preparation for unconditionally passing the struct timer_list pointer
    to all timer callbacks, switch to using the new timer_setup() and
    from_timer() to pass the timer pointer explicitly.

    Link: http://lkml.kernel.org/r/20171016225913.GA99214@beast
    Signed-off-by: Kees Cook
    Reviewed-by: Jan Kara
    Cc: Johannes Weiner
    Cc: Vladimir Davydov
    Cc: Matthew Wilcox
    Cc: Jeff Layton
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Kees Cook
     
  • All users of pagevec_lookup() and pagevec_lookup_range() now pass
    PAGEVEC_SIZE as a desired number of pages. Just drop the argument.

    Link: http://lkml.kernel.org/r/20171009151359.31984-15-jack@suse.cz
    Signed-off-by: Jan Kara
    Reviewed-by: Daniel Jordan
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Jan Kara
     
  • Use pagevec_lookup_range_tag() in write_cache_pages() as it is
    interested only in pages from given range. Remove unnecessary code
    resulting from this.

    Link: http://lkml.kernel.org/r/20171009151359.31984-12-jack@suse.cz
    Signed-off-by: Jan Kara
    Reviewed-by: Daniel Jordan
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Jan Kara