diff mbox series

[bpf-next,v3,2/7] mm/percpu.c: introduce pcpu_alloc_size()

Message ID 20231020133202.4043247-3-houtao@huaweicloud.com (mailing list archive)
State New
Headers show
Series bpf: Fixes for per-cpu kptr | expand

Commit Message

Hou Tao Oct. 20, 2023, 1:31 p.m. UTC
From: Hou Tao <houtao1@huawei.com>

Introduce pcpu_alloc_size() to get the size of the dynamic per-cpu
area. It will be used by bpf memory allocator in the following patches.
BPF memory allocator maintains per-cpu area caches for multiple area
sizes and its free API only has the to-be-freed per-cpu pointer, so it
needs the size of dynamic per-cpu area to select the corresponding cache
when bpf program frees the dynamic per-cpu pointer.

Acked-by: Dennis Zhou <dennis@kernel.org>
Signed-off-by: Hou Tao <houtao1@huawei.com>
---
 include/linux/percpu.h |  1 +
 mm/percpu.c            | 31 +++++++++++++++++++++++++++++++
 2 files changed, 32 insertions(+)

Comments

Dennis Zhou Oct. 20, 2023, 5:48 p.m. UTC | #1
On Fri, Oct 20, 2023 at 09:31:57PM +0800, Hou Tao wrote:
> From: Hou Tao <houtao1@huawei.com>
> 
> Introduce pcpu_alloc_size() to get the size of the dynamic per-cpu
> area. It will be used by bpf memory allocator in the following patches.
> BPF memory allocator maintains per-cpu area caches for multiple area
> sizes and its free API only has the to-be-freed per-cpu pointer, so it
> needs the size of dynamic per-cpu area to select the corresponding cache
> when bpf program frees the dynamic per-cpu pointer.
> 
> Acked-by: Dennis Zhou <dennis@kernel.org>
> Signed-off-by: Hou Tao <houtao1@huawei.com>
> ---
>  include/linux/percpu.h |  1 +
>  mm/percpu.c            | 31 +++++++++++++++++++++++++++++++
>  2 files changed, 32 insertions(+)
> 
> diff --git a/include/linux/percpu.h b/include/linux/percpu.h
> index 68fac2e7cbe67..8c677f185901b 100644
> --- a/include/linux/percpu.h
> +++ b/include/linux/percpu.h
> @@ -132,6 +132,7 @@ extern void __init setup_per_cpu_areas(void);
>  extern void __percpu *__alloc_percpu_gfp(size_t size, size_t align, gfp_t gfp) __alloc_size(1);
>  extern void __percpu *__alloc_percpu(size_t size, size_t align) __alloc_size(1);
>  extern void free_percpu(void __percpu *__pdata);
> +extern size_t pcpu_alloc_size(void __percpu *__pdata);
>  
>  DEFINE_FREE(free_percpu, void __percpu *, free_percpu(_T))
>  
> diff --git a/mm/percpu.c b/mm/percpu.c
> index 76b9c5e63c562..1759b91c8944a 100644
> --- a/mm/percpu.c
> +++ b/mm/percpu.c
> @@ -2244,6 +2244,37 @@ static void pcpu_balance_workfn(struct work_struct *work)
>  	mutex_unlock(&pcpu_alloc_mutex);
>  }
>  
> +/**
> + * pcpu_alloc_size - the size of the dynamic percpu area
> + * @ptr: pointer to the dynamic percpu area
> + *
> + * Returns the size of the @ptr allocation. This is undefined for statically
                                              ^ 

Nit: Alexei, when you pull this, can you make it a double space here?
Just keeps percpu's file consistent.

> + * defined percpu variables as there is no corresponding chunk->bound_map.
> + *
> + * RETURNS:
> + * The size of the dynamic percpu area.
> + *
> + * CONTEXT:
> + * Can be called from atomic context.
> + */
> +size_t pcpu_alloc_size(void __percpu *ptr)
> +{
> +	struct pcpu_chunk *chunk;
> +	unsigned long bit_off, end;
> +	void *addr;
> +
> +	if (!ptr)
> +		return 0;
> +
> +	addr = __pcpu_ptr_to_addr(ptr);
> +	/* No pcpu_lock here: ptr has not been freed, so chunk is still alive */
> +	chunk = pcpu_chunk_addr_search(addr);
> +	bit_off = (addr - chunk->base_addr) / PCPU_MIN_ALLOC_SIZE;
> +	end = find_next_bit(chunk->bound_map, pcpu_chunk_map_bits(chunk),
> +			    bit_off + 1);
> +	return (end - bit_off) * PCPU_MIN_ALLOC_SIZE;
> +}
> +
>  /**
>   * free_percpu - free percpu area
>   * @ptr: pointer to area to free
> -- 
> 2.29.2
> 

Thanks,
Dennis
Alexei Starovoitov Oct. 20, 2023, 5:58 p.m. UTC | #2
On Fri, Oct 20, 2023 at 10:48 AM Dennis Zhou <dennis@kernel.org> wrote:
>
> On Fri, Oct 20, 2023 at 09:31:57PM +0800, Hou Tao wrote:
> > From: Hou Tao <houtao1@huawei.com>
> >
> > Introduce pcpu_alloc_size() to get the size of the dynamic per-cpu
> > area. It will be used by bpf memory allocator in the following patches.
> > BPF memory allocator maintains per-cpu area caches for multiple area
> > sizes and its free API only has the to-be-freed per-cpu pointer, so it
> > needs the size of dynamic per-cpu area to select the corresponding cache
> > when bpf program frees the dynamic per-cpu pointer.
> >
> > Acked-by: Dennis Zhou <dennis@kernel.org>
> > Signed-off-by: Hou Tao <houtao1@huawei.com>
> > ---
> >  include/linux/percpu.h |  1 +
> >  mm/percpu.c            | 31 +++++++++++++++++++++++++++++++
> >  2 files changed, 32 insertions(+)
> >
> > diff --git a/include/linux/percpu.h b/include/linux/percpu.h
> > index 68fac2e7cbe67..8c677f185901b 100644
> > --- a/include/linux/percpu.h
> > +++ b/include/linux/percpu.h
> > @@ -132,6 +132,7 @@ extern void __init setup_per_cpu_areas(void);
> >  extern void __percpu *__alloc_percpu_gfp(size_t size, size_t align, gfp_t gfp) __alloc_size(1);
> >  extern void __percpu *__alloc_percpu(size_t size, size_t align) __alloc_size(1);
> >  extern void free_percpu(void __percpu *__pdata);
> > +extern size_t pcpu_alloc_size(void __percpu *__pdata);
> >
> >  DEFINE_FREE(free_percpu, void __percpu *, free_percpu(_T))
> >
> > diff --git a/mm/percpu.c b/mm/percpu.c
> > index 76b9c5e63c562..1759b91c8944a 100644
> > --- a/mm/percpu.c
> > +++ b/mm/percpu.c
> > @@ -2244,6 +2244,37 @@ static void pcpu_balance_workfn(struct work_struct *work)
> >       mutex_unlock(&pcpu_alloc_mutex);
> >  }
> >
> > +/**
> > + * pcpu_alloc_size - the size of the dynamic percpu area
> > + * @ptr: pointer to the dynamic percpu area
> > + *
> > + * Returns the size of the @ptr allocation. This is undefined for statically
>                                               ^
>
> Nit: Alexei, when you pull this, can you make it a double space here?
> Just keeps percpu's file consistent.

Argh. Already applied.
That's a very weird style you have in a few places.
$ grep '\.  [A-z]' mm/*.c|wc -l
1118
$ grep '\. [A-z]' mm/*.c|wc -l
2451

Single space is used more often in mm/* and in the rest of the kernel.

$ grep '\. [A-z]' mm/percpu.c|wc -l
10

percpu.c isn't consistent either.

I can force push if you really insist.
Dennis Zhou Oct. 20, 2023, 6:03 p.m. UTC | #3
On Fri, Oct 20, 2023 at 10:58:37AM -0700, Alexei Starovoitov wrote:
> On Fri, Oct 20, 2023 at 10:48 AM Dennis Zhou <dennis@kernel.org> wrote:
> >
> > On Fri, Oct 20, 2023 at 09:31:57PM +0800, Hou Tao wrote:
> > > From: Hou Tao <houtao1@huawei.com>
> > >
> > > Introduce pcpu_alloc_size() to get the size of the dynamic per-cpu
> > > area. It will be used by bpf memory allocator in the following patches.
> > > BPF memory allocator maintains per-cpu area caches for multiple area
> > > sizes and its free API only has the to-be-freed per-cpu pointer, so it
> > > needs the size of dynamic per-cpu area to select the corresponding cache
> > > when bpf program frees the dynamic per-cpu pointer.
> > >
> > > Acked-by: Dennis Zhou <dennis@kernel.org>
> > > Signed-off-by: Hou Tao <houtao1@huawei.com>
> > > ---
> > >  include/linux/percpu.h |  1 +
> > >  mm/percpu.c            | 31 +++++++++++++++++++++++++++++++
> > >  2 files changed, 32 insertions(+)
> > >
> > > diff --git a/include/linux/percpu.h b/include/linux/percpu.h
> > > index 68fac2e7cbe67..8c677f185901b 100644
> > > --- a/include/linux/percpu.h
> > > +++ b/include/linux/percpu.h
> > > @@ -132,6 +132,7 @@ extern void __init setup_per_cpu_areas(void);
> > >  extern void __percpu *__alloc_percpu_gfp(size_t size, size_t align, gfp_t gfp) __alloc_size(1);
> > >  extern void __percpu *__alloc_percpu(size_t size, size_t align) __alloc_size(1);
> > >  extern void free_percpu(void __percpu *__pdata);
> > > +extern size_t pcpu_alloc_size(void __percpu *__pdata);
> > >
> > >  DEFINE_FREE(free_percpu, void __percpu *, free_percpu(_T))
> > >
> > > diff --git a/mm/percpu.c b/mm/percpu.c
> > > index 76b9c5e63c562..1759b91c8944a 100644
> > > --- a/mm/percpu.c
> > > +++ b/mm/percpu.c
> > > @@ -2244,6 +2244,37 @@ static void pcpu_balance_workfn(struct work_struct *work)
> > >       mutex_unlock(&pcpu_alloc_mutex);
> > >  }
> > >
> > > +/**
> > > + * pcpu_alloc_size - the size of the dynamic percpu area
> > > + * @ptr: pointer to the dynamic percpu area
> > > + *
> > > + * Returns the size of the @ptr allocation. This is undefined for statically
> >                                               ^
> >
> > Nit: Alexei, when you pull this, can you make it a double space here?
> > Just keeps percpu's file consistent.
> 
> Argh. Already applied.
> That's a very weird style you have in a few places.
> $ grep '\.  [A-z]' mm/*.c|wc -l
> 1118
> $ grep '\. [A-z]' mm/*.c|wc -l
> 2451
> 
> Single space is used more often in mm/* and in the rest of the kernel.
> 
> $ grep '\. [A-z]' mm/percpu.c|wc -l
> 10
> 
> percpu.c isn't consistent either.
> 
> I can force push if you really insist.

Eh, if it's trouble I can fix it in the future. I know single space is
more common, but percpu was written with double so I'm trying my best to
keep the file consistent.

Thanks,
Dennis
Alexei Starovoitov Oct. 20, 2023, 9:17 p.m. UTC | #4
On Fri, Oct 20, 2023 at 11:03 AM Dennis Zhou <dennis@kernel.org> wrote:
>
> On Fri, Oct 20, 2023 at 10:58:37AM -0700, Alexei Starovoitov wrote:
> > On Fri, Oct 20, 2023 at 10:48 AM Dennis Zhou <dennis@kernel.org> wrote:
> > >
> > > On Fri, Oct 20, 2023 at 09:31:57PM +0800, Hou Tao wrote:
> > > > From: Hou Tao <houtao1@huawei.com>
> > > >
> > > > Introduce pcpu_alloc_size() to get the size of the dynamic per-cpu
> > > > area. It will be used by bpf memory allocator in the following patches.
> > > > BPF memory allocator maintains per-cpu area caches for multiple area
> > > > sizes and its free API only has the to-be-freed per-cpu pointer, so it
> > > > needs the size of dynamic per-cpu area to select the corresponding cache
> > > > when bpf program frees the dynamic per-cpu pointer.
> > > >
> > > > Acked-by: Dennis Zhou <dennis@kernel.org>
> > > > Signed-off-by: Hou Tao <houtao1@huawei.com>
> > > > ---
> > > >  include/linux/percpu.h |  1 +
> > > >  mm/percpu.c            | 31 +++++++++++++++++++++++++++++++
> > > >  2 files changed, 32 insertions(+)
> > > >
> > > > diff --git a/include/linux/percpu.h b/include/linux/percpu.h
> > > > index 68fac2e7cbe67..8c677f185901b 100644
> > > > --- a/include/linux/percpu.h
> > > > +++ b/include/linux/percpu.h
> > > > @@ -132,6 +132,7 @@ extern void __init setup_per_cpu_areas(void);
> > > >  extern void __percpu *__alloc_percpu_gfp(size_t size, size_t align, gfp_t gfp) __alloc_size(1);
> > > >  extern void __percpu *__alloc_percpu(size_t size, size_t align) __alloc_size(1);
> > > >  extern void free_percpu(void __percpu *__pdata);
> > > > +extern size_t pcpu_alloc_size(void __percpu *__pdata);
> > > >
> > > >  DEFINE_FREE(free_percpu, void __percpu *, free_percpu(_T))
> > > >
> > > > diff --git a/mm/percpu.c b/mm/percpu.c
> > > > index 76b9c5e63c562..1759b91c8944a 100644
> > > > --- a/mm/percpu.c
> > > > +++ b/mm/percpu.c
> > > > @@ -2244,6 +2244,37 @@ static void pcpu_balance_workfn(struct work_struct *work)
> > > >       mutex_unlock(&pcpu_alloc_mutex);
> > > >  }
> > > >
> > > > +/**
> > > > + * pcpu_alloc_size - the size of the dynamic percpu area
> > > > + * @ptr: pointer to the dynamic percpu area
> > > > + *
> > > > + * Returns the size of the @ptr allocation. This is undefined for statically
> > >                                               ^
> > >
> > > Nit: Alexei, when you pull this, can you make it a double space here?
> > > Just keeps percpu's file consistent.
> >
> > Argh. Already applied.
> > That's a very weird style you have in a few places.
> > $ grep '\.  [A-z]' mm/*.c|wc -l
> > 1118
> > $ grep '\. [A-z]' mm/*.c|wc -l
> > 2451
> >
> > Single space is used more often in mm/* and in the rest of the kernel.
> >
> > $ grep '\. [A-z]' mm/percpu.c|wc -l
> > 10
> >
> > percpu.c isn't consistent either.
> >
> > I can force push if you really insist.
>
> Eh, if it's trouble I can fix it in the future. I know single space is
> more common, but percpu was written with double so I'm trying my best to
> keep the file consistent.

Ok. Fair enough.
Force pushed with double space.
Hou Tao Oct. 21, 2023, 1:20 a.m. UTC | #5
Hi,

On 10/21/2023 5:17 AM, Alexei Starovoitov wrote:
> On Fri, Oct 20, 2023 at 11:03 AM Dennis Zhou <dennis@kernel.org> wrote:
>> On Fri, Oct 20, 2023 at 10:58:37AM -0700, Alexei Starovoitov wrote:
>>> On Fri, Oct 20, 2023 at 10:48 AM Dennis Zhou <dennis@kernel.org> wrote:
>>>> On Fri, Oct 20, 2023 at 09:31:57PM +0800, Hou Tao wrote:
>>>>> From: Hou Tao <houtao1@huawei.com>
>>>>>

SNIP
>>>>> + *
>>>>> + * Returns the size of the @ptr allocation. This is undefined for statically
>>>>                                               ^
>>>>
>>>> Nit: Alexei, when you pull this, can you make it a double space here?
>>>> Just keeps percpu's file consistent.
>>> Argh. Already applied.
>>> That's a very weird style you have in a few places.
>>> $ grep '\.  [A-z]' mm/*.c|wc -l
>>> 1118
>>> $ grep '\. [A-z]' mm/*.c|wc -l
>>> 2451
>>>
>>> Single space is used more often in mm/* and in the rest of the kernel.
>>>
>>> $ grep '\. [A-z]' mm/percpu.c|wc -l
>>> 10
>>>
>>> percpu.c isn't consistent either.
>>>
>>> I can force push if you really insist.
>> Eh, if it's trouble I can fix it in the future. I know single space is
>> more common, but percpu was written with double so I'm trying my best to
>> keep the file consistent.
> Ok. Fair enough.
> Force pushed with double space.

Thanks for the fixes. When I copied the sentence from the email, there
was indeed double spaces in it, but I simply ignored and "fixed" it, and
I also didn't double check the used style in mm/percpu.c. Will be more
carefully next time.
Tejun Heo Oct. 21, 2023, 2:03 a.m. UTC | #6
On Sat, Oct 21, 2023 at 09:20:29AM +0800, Hou Tao wrote:
> >> Eh, if it's trouble I can fix it in the future. I know single space is
> >> more common, but percpu was written with double so I'm trying my best to
> >> keep the file consistent.
> > Ok. Fair enough.
> > Force pushed with double space.
> 
> Thanks for the fixes. When I copied the sentence from the email, there
> was indeed double spaces in it, but I simply ignored and "fixed" it, and
> I also didn't double check the used style in mm/percpu.c. Will be more
> carefully next time.

FWIW, they are double spaced because emacs used to default to double spacing
and would never break single space when flowing paragraphs. e.g. If you
write "asdf fdsa. blah", it would never break the line between fdsa and
blah, sometimes leading to weird flowing. I just accepted that as a fact of
life and got used to double spacing. I did change the config quite a while
ago and now am using single space like a normal person.

So, it's upto Dennis but at least I don't mind gradually losing the double
spaces. No need to go through the files and convert them all at once, but if
the comment is gonna change anyway...

Thanks.
diff mbox series

Patch

diff --git a/include/linux/percpu.h b/include/linux/percpu.h
index 68fac2e7cbe67..8c677f185901b 100644
--- a/include/linux/percpu.h
+++ b/include/linux/percpu.h
@@ -132,6 +132,7 @@  extern void __init setup_per_cpu_areas(void);
 extern void __percpu *__alloc_percpu_gfp(size_t size, size_t align, gfp_t gfp) __alloc_size(1);
 extern void __percpu *__alloc_percpu(size_t size, size_t align) __alloc_size(1);
 extern void free_percpu(void __percpu *__pdata);
+extern size_t pcpu_alloc_size(void __percpu *__pdata);
 
 DEFINE_FREE(free_percpu, void __percpu *, free_percpu(_T))
 
diff --git a/mm/percpu.c b/mm/percpu.c
index 76b9c5e63c562..1759b91c8944a 100644
--- a/mm/percpu.c
+++ b/mm/percpu.c
@@ -2244,6 +2244,37 @@  static void pcpu_balance_workfn(struct work_struct *work)
 	mutex_unlock(&pcpu_alloc_mutex);
 }
 
+/**
+ * pcpu_alloc_size - the size of the dynamic percpu area
+ * @ptr: pointer to the dynamic percpu area
+ *
+ * Returns the size of the @ptr allocation. This is undefined for statically
+ * defined percpu variables as there is no corresponding chunk->bound_map.
+ *
+ * RETURNS:
+ * The size of the dynamic percpu area.
+ *
+ * CONTEXT:
+ * Can be called from atomic context.
+ */
+size_t pcpu_alloc_size(void __percpu *ptr)
+{
+	struct pcpu_chunk *chunk;
+	unsigned long bit_off, end;
+	void *addr;
+
+	if (!ptr)
+		return 0;
+
+	addr = __pcpu_ptr_to_addr(ptr);
+	/* No pcpu_lock here: ptr has not been freed, so chunk is still alive */
+	chunk = pcpu_chunk_addr_search(addr);
+	bit_off = (addr - chunk->base_addr) / PCPU_MIN_ALLOC_SIZE;
+	end = find_next_bit(chunk->bound_map, pcpu_chunk_map_bits(chunk),
+			    bit_off + 1);
+	return (end - bit_off) * PCPU_MIN_ALLOC_SIZE;
+}
+
 /**
  * free_percpu - free percpu area
  * @ptr: pointer to area to free