lkml.org 
[lkml]   [2021]   [Jul]   [30]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Date
    From
    Subject[PATCH 01/16] huge tmpfs: fix fallocate(vanilla) advance over huge pages
    shmem_fallocate() goes to a lot of trouble to leave its newly allocated
    pages !Uptodate, partly to identify and undo them on failure, partly to
    leave the overhead of clearing them until later. But the huge page case
    did not skip to the end of the extent, walked through the tail pages one
    by one, and appeared to work just fine: but in doing so, cleared and
    Uptodated the huge page, so there was no way to undo it on failure.

    Now advance immediately to the end of the huge extent, with a comment on
    why this is more than just an optimization. But although this speeds up
    huge tmpfs fallocation, it does leave the clearing until first use, and
    some users may have come to appreciate slow fallocate but fast first use:
    if they complain, then we can consider adding a pass to clear at the end.

    Fixes: 800d8c63b2e9 ("shmem: add huge pages support")
    Signed-off-by: Hugh Dickins <hughd@google.com>
    ---
    mm/shmem.c | 19 ++++++++++++++++---
    1 file changed, 16 insertions(+), 3 deletions(-)

    diff --git a/mm/shmem.c b/mm/shmem.c
    index 70d9ce294bb4..0cd5c9156457 100644
    --- a/mm/shmem.c
    +++ b/mm/shmem.c
    @@ -2736,7 +2736,7 @@ static long shmem_fallocate(struct file *file, int mode, loff_t offset,
    inode->i_private = &shmem_falloc;
    spin_unlock(&inode->i_lock);

    - for (index = start; index < end; index++) {
    + for (index = start; index < end; ) {
    struct page *page;

    /*
    @@ -2759,13 +2759,26 @@ static long shmem_fallocate(struct file *file, int mode, loff_t offset,
    goto undone;
    }

    + index++;
    + /*
    + * Here is a more important optimization than it appears:
    + * a second SGP_FALLOC on the same huge page will clear it,
    + * making it PageUptodate and un-undoable if we fail later.
    + */
    + if (PageTransCompound(page)) {
    + index = round_up(index, HPAGE_PMD_NR);
    + /* Beware 32-bit wraparound */
    + if (!index)
    + index--;
    + }
    +
    /*
    * Inform shmem_writepage() how far we have reached.
    * No need for lock or barrier: we have the page lock.
    */
    - shmem_falloc.next++;
    if (!PageUptodate(page))
    - shmem_falloc.nr_falloced++;
    + shmem_falloc.nr_falloced += index - shmem_falloc.next;
    + shmem_falloc.next = index;

    /*
    * If !PageUptodate, leave it that way so that freeable pages
    --
    2.26.2
    \
     
     \ /
      Last update: 2021-07-30 09:26    [W:4.570 / U:0.104 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site