Re: [PATCH] fs/hostfs: Replace kmap() with kmap_local_page()
From: Ira Weiny
Date: Fri Dec 30 2022 - 18:50:29 EST
On Thu, Oct 13, 2022 at 06:17:00PM +0200, Fabio M. De Francesco wrote:
> The use of kmap() is being deprecated in favor of kmap_local_page().
>
> There are two main problems with kmap(): (1) It comes with an overhead as
> the mapping space is restricted and protected by a global lock for
> synchronization and (2) it also requires global TLB invalidation when the
> kmap’s pool wraps and it might block when the mapping space is fully
> utilized until a slot becomes available.
>
> With kmap_local_page() the mappings are per thread, CPU local, can take
> page faults, and can be called from any context (including interrupts).
> It is faster than kmap() in kernels with HIGHMEM enabled. Furthermore,
> the tasks can be preempted and, when they are scheduled to run again, the
> kernel virtual addresses are restored and still valid.
>
> Therefore, replace kmap() with kmap_local_page() in hostfs_kern.c, it
> being the only file with kmap() call sites currently left in fs/hostfs.
>
> Cc: "Venkataramanan, Anirudh" <anirudh.venkataramanan@xxxxxxxxx>
> Suggested-by: Ira Weiny <ira.weiny@xxxxxxxxx>
What can we do to move this patch along?
I'm not an expert but it looks ok to me.
Reviewed-by: Ira Weiny <ira.weiny@xxxxxxxxx>
> Signed-off-by: Fabio M. De Francesco <fmdefrancesco@xxxxxxxxx>
> ---
>
> These changes are not tested in a 32 bits VM as I use to do with other more
> problematic conversions. Mere code inspection makes me reasonably think
> that the rules of local mappings are not violated by this conversion.
>
> Furthermore, I have no idea how to test this code. If maintainers think
> that tests are absolutely necessary, any hints about how to perform them
> would be greatly appreciated.
>
> fs/hostfs/hostfs_kern.c | 15 ++++++++-------
> 1 file changed, 8 insertions(+), 7 deletions(-)
>
> diff --git a/fs/hostfs/hostfs_kern.c b/fs/hostfs/hostfs_kern.c
> index 07881b76d42f..0c9f89352601 100644
> --- a/fs/hostfs/hostfs_kern.c
> +++ b/fs/hostfs/hostfs_kern.c
> @@ -412,7 +412,7 @@ static int hostfs_writepage(struct page *page, struct writeback_control *wbc)
> if (page->index >= end_index)
> count = inode->i_size & (PAGE_SIZE-1);
>
> - buffer = kmap(page);
> + buffer = kmap_local_page(page);
>
> err = write_file(HOSTFS_I(inode)->fd, &base, buffer, count);
> if (err != count) {
> @@ -428,9 +428,9 @@ static int hostfs_writepage(struct page *page, struct writeback_control *wbc)
> err = 0;
>
> out:
> - kunmap(page);
> -
> + kunmap_local(buffer);
> unlock_page(page);
> +
> return err;
> }
>
> @@ -441,7 +441,7 @@ static int hostfs_read_folio(struct file *file, struct folio *folio)
> loff_t start = page_offset(page);
> int bytes_read, ret = 0;
>
> - buffer = kmap(page);
> + buffer = kmap_local_page(page);
> bytes_read = read_file(FILE_HOSTFS_I(file)->fd, &start, buffer,
> PAGE_SIZE);
> if (bytes_read < 0) {
> @@ -458,8 +458,9 @@ static int hostfs_read_folio(struct file *file, struct folio *folio)
>
> out:
> flush_dcache_page(page);
> - kunmap(page);
> + kunmap_local(buffer);
> unlock_page(page);
> +
> return ret;
> }
>
> @@ -484,9 +485,9 @@ static int hostfs_write_end(struct file *file, struct address_space *mapping,
> unsigned from = pos & (PAGE_SIZE - 1);
> int err;
>
> - buffer = kmap(page);
> + buffer = kmap_local_page(page);
> err = write_file(FILE_HOSTFS_I(file)->fd, &pos, buffer + from, copied);
> - kunmap(page);
> + kunmap_local(buffer);
>
> if (!PageUptodate(page) && err == PAGE_SIZE)
> SetPageUptodate(page);
> --
> 2.37.3
>