linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] hfsplus: Convert kmap() to kmap_local_page() in bitmap.c
@ 2022-07-24 20:50 Fabio M. De Francesco
  2022-07-25 17:17 ` Viacheslav Dubeyko
  0 siblings, 1 reply; 8+ messages in thread
From: Fabio M. De Francesco @ 2022-07-24 20:50 UTC (permalink / raw)
  To: linux-fsdevel, linux-kernel; +Cc: Fabio M. De Francesco, Ira Weiny

kmap() is being deprecated in favor of kmap_local_page().

There are two main problems with kmap(): (1) It comes with an overhead as
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 are still valid.

Since its use in bitmap.c is safe everywhere, it should be preferred.

Therefore, replace kmap() with kmap_local_page() in bnode.c.

Suggested-by: Ira Weiny <ira.weiny@intel.com>
Signed-off-by: Fabio M. De Francesco <fmdefrancesco@gmail.com>
---
 fs/hfsplus/bitmap.c | 18 +++++++++---------
 1 file changed, 9 insertions(+), 9 deletions(-)

diff --git a/fs/hfsplus/bitmap.c b/fs/hfsplus/bitmap.c
index cebce0cfe340..0848b053b365 100644
--- a/fs/hfsplus/bitmap.c
+++ b/fs/hfsplus/bitmap.c
@@ -39,7 +39,7 @@ int hfsplus_block_allocate(struct super_block *sb, u32 size,
 		start = size;
 		goto out;
 	}
-	pptr = kmap(page);
+	pptr = kmap_local_page(page);
 	curr = pptr + (offset & (PAGE_CACHE_BITS - 1)) / 32;
 	i = offset % 32;
 	offset &= ~(PAGE_CACHE_BITS - 1);
@@ -74,7 +74,7 @@ int hfsplus_block_allocate(struct super_block *sb, u32 size,
 			}
 			curr++;
 		}
-		kunmap(page);
+		kunmap_local(pptr);
 		offset += PAGE_CACHE_BITS;
 		if (offset >= size)
 			break;
@@ -127,7 +127,7 @@ int hfsplus_block_allocate(struct super_block *sb, u32 size,
 			len -= 32;
 		}
 		set_page_dirty(page);
-		kunmap(page);
+		kunmap_local(pptr);
 		offset += PAGE_CACHE_BITS;
 		page = read_mapping_page(mapping, offset / PAGE_CACHE_BITS,
 					 NULL);
@@ -135,7 +135,7 @@ int hfsplus_block_allocate(struct super_block *sb, u32 size,
 			start = size;
 			goto out;
 		}
-		pptr = kmap(page);
+		pptr = kmap_local_page(page);
 		curr = pptr;
 		end = pptr + PAGE_CACHE_BITS / 32;
 	}
@@ -151,7 +151,7 @@ int hfsplus_block_allocate(struct super_block *sb, u32 size,
 done:
 	*curr = cpu_to_be32(n);
 	set_page_dirty(page);
-	kunmap(page);
+	kunmap_local(pptr);
 	*max = offset + (curr - pptr) * 32 + i - start;
 	sbi->free_blocks -= *max;
 	hfsplus_mark_mdb_dirty(sb);
@@ -185,7 +185,7 @@ int hfsplus_block_free(struct super_block *sb, u32 offset, u32 count)
 	page = read_mapping_page(mapping, pnr, NULL);
 	if (IS_ERR(page))
 		goto kaboom;
-	pptr = kmap(page);
+	pptr = kmap_local_page(page);
 	curr = pptr + (offset & (PAGE_CACHE_BITS - 1)) / 32;
 	end = pptr + PAGE_CACHE_BITS / 32;
 	len = count;
@@ -215,11 +215,11 @@ int hfsplus_block_free(struct super_block *sb, u32 offset, u32 count)
 		if (!count)
 			break;
 		set_page_dirty(page);
-		kunmap(page);
+		kunmap_local(pptr);
 		page = read_mapping_page(mapping, ++pnr, NULL);
 		if (IS_ERR(page))
 			goto kaboom;
-		pptr = kmap(page);
+		pptr = kmap_local_page(page);
 		curr = pptr;
 		end = pptr + PAGE_CACHE_BITS / 32;
 	}
@@ -231,7 +231,7 @@ int hfsplus_block_free(struct super_block *sb, u32 offset, u32 count)
 	}
 out:
 	set_page_dirty(page);
-	kunmap(page);
+	kunmap_local(pptr);
 	sbi->free_blocks += len;
 	hfsplus_mark_mdb_dirty(sb);
 	mutex_unlock(&sbi->alloc_mutex);
-- 
2.37.1


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* Re: [PATCH] hfsplus: Convert kmap() to kmap_local_page() in bitmap.c
  2022-07-24 20:50 [PATCH] hfsplus: Convert kmap() to kmap_local_page() in bitmap.c Fabio M. De Francesco
@ 2022-07-25 17:17 ` Viacheslav Dubeyko
  2022-07-25 17:54   ` Matthew Wilcox
  2022-07-26 12:04   ` Fabio M. De Francesco
  0 siblings, 2 replies; 8+ messages in thread
From: Viacheslav Dubeyko @ 2022-07-25 17:17 UTC (permalink / raw)
  To: Fabio M. De Francesco; +Cc: linux-fsdevel, linux-kernel, Ira Weiny



> On Jul 24, 2022, at 1:50 PM, Fabio M. De Francesco <fmdefrancesco@gmail.com> wrote:
> 
> kmap() is being deprecated in favor of kmap_local_page().
> 
> There are two main problems with kmap(): (1) It comes with an overhead as
> 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 are still valid.
> 
> Since its use in bitmap.c is safe everywhere, it should be preferred.
> 
> Therefore, replace kmap() with kmap_local_page() in bnode.c.
> 

Looks good. Maybe, it makes sense to combine all kmap() related modifications in HFS+ into
one patchset?

Reviewed by: Viacheslav Dubeyko <slava@dubeyko.com> 

Thanks,
Slava.

> Suggested-by: Ira Weiny <ira.weiny@intel.com>
> Signed-off-by: Fabio M. De Francesco <fmdefrancesco@gmail.com>
> ---
> fs/hfsplus/bitmap.c | 18 +++++++++---------
> 1 file changed, 9 insertions(+), 9 deletions(-)
> 
> diff --git a/fs/hfsplus/bitmap.c b/fs/hfsplus/bitmap.c
> index cebce0cfe340..0848b053b365 100644
> --- a/fs/hfsplus/bitmap.c
> +++ b/fs/hfsplus/bitmap.c
> @@ -39,7 +39,7 @@ int hfsplus_block_allocate(struct super_block *sb, u32 size,
> 		start = size;
> 		goto out;
> 	}
> -	pptr = kmap(page);
> +	pptr = kmap_local_page(page);
> 	curr = pptr + (offset & (PAGE_CACHE_BITS - 1)) / 32;
> 	i = offset % 32;
> 	offset &= ~(PAGE_CACHE_BITS - 1);
> @@ -74,7 +74,7 @@ int hfsplus_block_allocate(struct super_block *sb, u32 size,
> 			}
> 			curr++;
> 		}
> -		kunmap(page);
> +		kunmap_local(pptr);
> 		offset += PAGE_CACHE_BITS;
> 		if (offset >= size)
> 			break;
> @@ -127,7 +127,7 @@ int hfsplus_block_allocate(struct super_block *sb, u32 size,
> 			len -= 32;
> 		}
> 		set_page_dirty(page);
> -		kunmap(page);
> +		kunmap_local(pptr);
> 		offset += PAGE_CACHE_BITS;
> 		page = read_mapping_page(mapping, offset / PAGE_CACHE_BITS,
> 					 NULL);
> @@ -135,7 +135,7 @@ int hfsplus_block_allocate(struct super_block *sb, u32 size,
> 			start = size;
> 			goto out;
> 		}
> -		pptr = kmap(page);
> +		pptr = kmap_local_page(page);
> 		curr = pptr;
> 		end = pptr + PAGE_CACHE_BITS / 32;
> 	}
> @@ -151,7 +151,7 @@ int hfsplus_block_allocate(struct super_block *sb, u32 size,
> done:
> 	*curr = cpu_to_be32(n);
> 	set_page_dirty(page);
> -	kunmap(page);
> +	kunmap_local(pptr);
> 	*max = offset + (curr - pptr) * 32 + i - start;
> 	sbi->free_blocks -= *max;
> 	hfsplus_mark_mdb_dirty(sb);
> @@ -185,7 +185,7 @@ int hfsplus_block_free(struct super_block *sb, u32 offset, u32 count)
> 	page = read_mapping_page(mapping, pnr, NULL);
> 	if (IS_ERR(page))
> 		goto kaboom;
> -	pptr = kmap(page);
> +	pptr = kmap_local_page(page);
> 	curr = pptr + (offset & (PAGE_CACHE_BITS - 1)) / 32;
> 	end = pptr + PAGE_CACHE_BITS / 32;
> 	len = count;
> @@ -215,11 +215,11 @@ int hfsplus_block_free(struct super_block *sb, u32 offset, u32 count)
> 		if (!count)
> 			break;
> 		set_page_dirty(page);
> -		kunmap(page);
> +		kunmap_local(pptr);
> 		page = read_mapping_page(mapping, ++pnr, NULL);
> 		if (IS_ERR(page))
> 			goto kaboom;
> -		pptr = kmap(page);
> +		pptr = kmap_local_page(page);
> 		curr = pptr;
> 		end = pptr + PAGE_CACHE_BITS / 32;
> 	}
> @@ -231,7 +231,7 @@ int hfsplus_block_free(struct super_block *sb, u32 offset, u32 count)
> 	}
> out:
> 	set_page_dirty(page);
> -	kunmap(page);
> +	kunmap_local(pptr);
> 	sbi->free_blocks += len;
> 	hfsplus_mark_mdb_dirty(sb);
> 	mutex_unlock(&sbi->alloc_mutex);
> -- 
> 2.37.1
> 


^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH] hfsplus: Convert kmap() to kmap_local_page() in bitmap.c
  2022-07-25 17:17 ` Viacheslav Dubeyko
@ 2022-07-25 17:54   ` Matthew Wilcox
  2022-07-26 18:40     ` Viacheslav Dubeyko
  2022-07-26 19:11     ` Ira Weiny
  2022-07-26 12:04   ` Fabio M. De Francesco
  1 sibling, 2 replies; 8+ messages in thread
From: Matthew Wilcox @ 2022-07-25 17:54 UTC (permalink / raw)
  To: Viacheslav Dubeyko
  Cc: Fabio M. De Francesco, linux-fsdevel, linux-kernel, Ira Weiny

On Mon, Jul 25, 2022 at 10:17:13AM -0700, Viacheslav Dubeyko wrote:
> Looks good. Maybe, it makes sense to combine all kmap() related modifications in HFS+ into
> one patchset?

For bisection, I'd think it best to leave them separate?

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH] hfsplus: Convert kmap() to kmap_local_page() in bitmap.c
  2022-07-25 17:17 ` Viacheslav Dubeyko
  2022-07-25 17:54   ` Matthew Wilcox
@ 2022-07-26 12:04   ` Fabio M. De Francesco
  1 sibling, 0 replies; 8+ messages in thread
From: Fabio M. De Francesco @ 2022-07-26 12:04 UTC (permalink / raw)
  To: Viacheslav Dubeyko; +Cc: linux-fsdevel, linux-kernel, Ira Weiny

On lunedì 25 luglio 2022 19:17:13 CEST Viacheslav Dubeyko wrote:
> 
> > On Jul 24, 2022, at 1:50 PM, Fabio M. De Francesco 
<fmdefrancesco@gmail.com> wrote:
> > 
> > kmap() is being deprecated in favor of kmap_local_page().
> > 
> > There are two main problems with kmap(): (1) It comes with an overhead 
as
> > 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 are still valid.
> > 
> > Since its use in bitmap.c is safe everywhere, it should be preferred.
> > 
> > Therefore, replace kmap() with kmap_local_page() in bnode.c.
> > 
> 
> Looks good. Maybe, it makes sense to combine all kmap() related 
modifications in HFS+ into
> one patchset?
> 
> Reviewed by: Viacheslav Dubeyko <slava@dubeyko.com> 

Thanks for your reviews of this and of the other patch to bnode.c.

Actually, I started with the first file I met (bnode.c) because I noticed 
that maintainers don't need to care about any special ordering for applying 
the patches, since each of them is self-contained.

This is why I haven't thought of making a series of them.

Currently only one file is still left with some kmap() call sites. I'll 
work on that within the next days.

Again thanks,

Fabio 

> Thanks,
> Slava.
> 
> > Suggested-by: Ira Weiny <ira.weiny@intel.com>
> > Signed-off-by: Fabio M. De Francesco <fmdefrancesco@gmail.com>
> > ---
> > fs/hfsplus/bitmap.c | 18 +++++++++---------
> > 1 file changed, 9 insertions(+), 9 deletions(-)

[snip]



^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH] hfsplus: Convert kmap() to kmap_local_page() in bitmap.c
  2022-07-25 17:54   ` Matthew Wilcox
@ 2022-07-26 18:40     ` Viacheslav Dubeyko
  2022-08-01 12:56       ` Fabio M. De Francesco
  2022-07-26 19:11     ` Ira Weiny
  1 sibling, 1 reply; 8+ messages in thread
From: Viacheslav Dubeyko @ 2022-07-26 18:40 UTC (permalink / raw)
  To: Matthew Wilcox
  Cc: Fabio M. De Francesco, linux-fsdevel, linux-kernel, Ira Weiny



> On Jul 25, 2022, at 10:54 AM, Matthew Wilcox <willy@infradead.org> wrote:
> 
> On Mon, Jul 25, 2022 at 10:17:13AM -0700, Viacheslav Dubeyko wrote:
>> Looks good. Maybe, it makes sense to combine all kmap() related modifications in HFS+ into
>> one patchset?
> 
> For bisection, I'd think it best to leave them separate?

I am OK with any way. My point that it will be good to have patchset to see all modified places together, from logical point of view. Even if we have some issue with kmap() change on kmap_local_page(), then, as far as I can see, the root of issue should be kmap_local_page() but not HFS+ code. Oppositely, if it’s some undiscovered HFS+ issue, then again kmap_local_page() changes nothing. But I am OK if it is separate patches too.

Thanks,
Slava.

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH] hfsplus: Convert kmap() to kmap_local_page() in bitmap.c
  2022-07-25 17:54   ` Matthew Wilcox
  2022-07-26 18:40     ` Viacheslav Dubeyko
@ 2022-07-26 19:11     ` Ira Weiny
  2022-07-26 20:38       ` Matthew Wilcox
  1 sibling, 1 reply; 8+ messages in thread
From: Ira Weiny @ 2022-07-26 19:11 UTC (permalink / raw)
  To: Matthew Wilcox
  Cc: Viacheslav Dubeyko, Fabio M. De Francesco, linux-fsdevel, linux-kernel

On Mon, Jul 25, 2022 at 06:54:50PM +0100, Matthew Wilcox wrote:
> On Mon, Jul 25, 2022 at 10:17:13AM -0700, Viacheslav Dubeyko wrote:
> > Looks good. Maybe, it makes sense to combine all kmap() related modifications in HFS+ into
> > one patchset?
> 
> For bisection, I'd think it best to leave them separate?

I'm not quite sure I understand why putting the individual patches into a
series makes bisection easier?  It does make sense to keep individual patches.

Ira

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH] hfsplus: Convert kmap() to kmap_local_page() in bitmap.c
  2022-07-26 19:11     ` Ira Weiny
@ 2022-07-26 20:38       ` Matthew Wilcox
  0 siblings, 0 replies; 8+ messages in thread
From: Matthew Wilcox @ 2022-07-26 20:38 UTC (permalink / raw)
  To: Ira Weiny
  Cc: Viacheslav Dubeyko, Fabio M. De Francesco, linux-fsdevel, linux-kernel

On Tue, Jul 26, 2022 at 12:11:50PM -0700, Ira Weiny wrote:
> On Mon, Jul 25, 2022 at 06:54:50PM +0100, Matthew Wilcox wrote:
> > On Mon, Jul 25, 2022 at 10:17:13AM -0700, Viacheslav Dubeyko wrote:
> > > Looks good. Maybe, it makes sense to combine all kmap() related modifications in HFS+ into
> > > one patchset?
> > 
> > For bisection, I'd think it best to leave them separate?
> 
> I'm not quite sure I understand why putting the individual patches into a
> series makes bisection easier?  It does make sense to keep individual patches.

If somebody reports a bug, bisection will tell you which of these
kmap-conversion patches is at fault, reducing the amount of brainpower
you have to invest in determining where the bug is.

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH] hfsplus: Convert kmap() to kmap_local_page() in bitmap.c
  2022-07-26 18:40     ` Viacheslav Dubeyko
@ 2022-08-01 12:56       ` Fabio M. De Francesco
  0 siblings, 0 replies; 8+ messages in thread
From: Fabio M. De Francesco @ 2022-08-01 12:56 UTC (permalink / raw)
  To: Matthew Wilcox, Viacheslav Dubeyko, Ira Weiny; +Cc: linux-fsdevel, linux-kernel

On martedì 26 luglio 2022 20:40:29 CEST Viacheslav Dubeyko wrote:
> 
> > On Jul 25, 2022, at 10:54 AM, Matthew Wilcox <willy@infradead.org> 
wrote:
> > 
> > On Mon, Jul 25, 2022 at 10:17:13AM -0700, Viacheslav Dubeyko wrote:
> >> Looks good. Maybe, it makes sense to combine all kmap() related 
modifications in HFS+ into
> >> one patchset?
> > 
> > For bisection, I'd think it best to leave them separate?
> 
> I am OK with any way. My point that it will be good to have patchset to 
see all modified places together, from logical point of view. Even if we 
have some issue with kmap() change on kmap_local_page(), then, as far as I 
can see, the root of issue should be kmap_local_page() but not HFS+ code. 
Oppositely, if it’s some undiscovered HFS+ issue, then again 
kmap_local_page() changes nothing. But I am OK if it is separate patches 
too.
> 
> Thanks,
> Slava.
> 
And I am OK with sending a patchset :-)

I'm sorry because, while working on the last conversions for HFS+ in 
btree.c, I just noticed that I had overlooked one other kmap() call site in 
bitmap.c.

Therefore, I'd like to ask to drop this patch and I'll also ask to drop the 
patch to bnode.c in the related thread. 

When done, I'll send a series of three patches, one per file (bnode.c, 
bitmap.c, btree.c).

Thanks,

Fabio




^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2022-08-01 12:57 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-07-24 20:50 [PATCH] hfsplus: Convert kmap() to kmap_local_page() in bitmap.c Fabio M. De Francesco
2022-07-25 17:17 ` Viacheslav Dubeyko
2022-07-25 17:54   ` Matthew Wilcox
2022-07-26 18:40     ` Viacheslav Dubeyko
2022-08-01 12:56       ` Fabio M. De Francesco
2022-07-26 19:11     ` Ira Weiny
2022-07-26 20:38       ` Matthew Wilcox
2022-07-26 12:04   ` Fabio M. De Francesco

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).