[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20231108150606.2ec3cafb290f757f0e4c92d8@linux-foundation.org>
Date: Wed, 8 Nov 2023 15:06:06 -0800
From: Andrew Morton <akpm@...ux-foundation.org>
To: "Matthew Wilcox (Oracle)" <willy@...radead.org>
Cc: linux-ext4@...r.kernel.org, gfs2@...ts.linux.dev,
linux-fsdevel@...r.kernel.org, linux-xfs@...r.kernel.org,
"Darrick J . Wong" <djwong@...nel.org>,
linux-erofs@...ts.ozlabs.org, "Theodore Ts'o" <tytso@....edu>,
Andreas Dilger <adilger.kernel@...ger.ca>,
Andreas Gruenbacher <agruenba@...hat.com>
Subject: Re: [PATCH 1/3] mm: Add folio_zero_tail() and use it in ext4
On Tue, 7 Nov 2023 21:26:40 +0000 "Matthew Wilcox (Oracle)" <willy@...radead.org> wrote:
> Instead of unmapping the folio after copying the data to it, then mapping
> it again to zero the tail, provide folio_zero_tail() to zero the tail
> of an already-mapped folio.
>
> ...
>
> --- a/include/linux/highmem.h
> +++ b/include/linux/highmem.h
> @@ -483,6 +483,44 @@ static inline void memcpy_to_folio(struct folio *folio, size_t offset,
> flush_dcache_folio(folio);
> }
>
> +/**
> + * folio_zero_tail - Zero the tail of a folio.
> + * @folio: The folio to zero.
> + * @kaddr: The address the folio is currently mapped to.
> + * @offset: The byte offset in the folio to start zeroing at.
That's the argument ordering I would expect.
> + * If you have already used kmap_local_folio() to map a folio, written
> + * some data to it and now need to zero the end of the folio (and flush
> + * the dcache), you can use this function. If you do not have the
> + * folio kmapped (eg the folio has been partially populated by DMA),
> + * use folio_zero_range() or folio_zero_segment() instead.
> + *
> + * Return: An address which can be passed to kunmap_local().
> + */
> +static inline __must_check void *folio_zero_tail(struct folio *folio,
> + size_t offset, void *kaddr)
While that is not. addr,len is far more common that len,addr?
> +{
> + size_t len = folio_size(folio) - offset;
Calling it `remaining' would be more clear.
> +
> + if (folio_test_highmem(folio)) {
> + size_t max = PAGE_SIZE - offset_in_page(offset);
> +
> + while (len > max) {
Shouldn't this be `while (len)'? AFAICT this code can fail to clear
the final page.
> + memset(kaddr, 0, max);
> + kunmap_local(kaddr);
> + len -= max;
> + offset += max;
> + max = PAGE_SIZE;
> + kaddr = kmap_local_folio(folio, offset);
> + }
> + }
> +
> + memset(kaddr, 0, len);
> + flush_dcache_folio(folio);
> +
> + return kaddr;
> +}
> +
Powered by blists - more mailing lists