* [PATCH] padata: Fix possible divide-by-0 panic in padata_mt_helper()
@ 2024-08-06 17:46 Waiman Long
2024-08-10 4:05 ` Herbert Xu
2024-08-10 17:44 ` Kamlesh Gurudasani
0 siblings, 2 replies; 20+ messages in thread
From: Waiman Long @ 2024-08-06 17:46 UTC (permalink / raw)
To: Steffen Klassert, Daniel Jordan, Andrew Morton
Cc: linux-crypto, linux-kernel, Waiman Long
We are hit with a not easily reproducible divide-by-0 panic in padata.c
at bootup time.
[ 10.017908] Oops: divide error: 0000 1 PREEMPT SMP NOPTI
[ 10.017908] CPU: 26 PID: 2627 Comm: kworker/u1666:1 Not tainted 6.10.0-15.el10.x86_64 #1
[ 10.017908] Hardware name: Lenovo ThinkSystem SR950 [7X12CTO1WW]/[7X12CTO1WW], BIOS [PSE140J-2.30] 07/20/2021
[ 10.017908] Workqueue: events_unbound padata_mt_helper
[ 10.017908] RIP: 0010:padata_mt_helper+0x39/0xb0
:
[ 10.017963] Call Trace:
[ 10.017968] <TASK>
[ 10.018004] ? padata_mt_helper+0x39/0xb0
[ 10.018084] process_one_work+0x174/0x330
[ 10.018093] worker_thread+0x266/0x3a0
[ 10.018111] kthread+0xcf/0x100
[ 10.018124] ret_from_fork+0x31/0x50
[ 10.018138] ret_from_fork_asm+0x1a/0x30
[ 10.018147] </TASK>
Looking at the padata_mt_helper() function, the only way a divide-by-0
panic can happen is when ps->chunk_size is 0. The way that chunk_size is
initialized in padata_do_multithreaded(), chunk_size can be 0 when the
min_chunk in the passed-in padata_mt_job structure is 0.
Fix this divide-by-0 panic by making sure that chunk_size will be at
least 1 no matter what the input parameters are.
Fixes: 004ed42638f4 ("padata: add basic support for multithreaded jobs")
Signed-off-by: Waiman Long <longman@redhat.com>
---
kernel/padata.c | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/kernel/padata.c b/kernel/padata.c
index 53f4bc912712..0fa6c2895460 100644
--- a/kernel/padata.c
+++ b/kernel/padata.c
@@ -517,6 +517,13 @@ void __init padata_do_multithreaded(struct padata_mt_job *job)
ps.chunk_size = max(ps.chunk_size, job->min_chunk);
ps.chunk_size = roundup(ps.chunk_size, job->align);
+ /*
+ * chunk_size can be 0 if the caller sets min_chunk to 0. So force it
+ * to at least 1 to prevent divide-by-0 panic in padata_mt_helper().`
+ */
+ if (!ps.chunk_size)
+ ps.chunk_size = 1U;
+
list_for_each_entry(pw, &works, pw_list)
if (job->numa_aware) {
int old_node = atomic_read(&last_used_nid);
--
2.43.5
^ permalink raw reply related [flat|nested] 20+ messages in thread
* Re: [PATCH] padata: Fix possible divide-by-0 panic in padata_mt_helper()
2024-08-06 17:46 [PATCH] padata: Fix possible divide-by-0 panic in padata_mt_helper() Waiman Long
@ 2024-08-10 4:05 ` Herbert Xu
2024-08-11 1:30 ` Waiman Long
2024-08-10 17:44 ` Kamlesh Gurudasani
1 sibling, 1 reply; 20+ messages in thread
From: Herbert Xu @ 2024-08-10 4:05 UTC (permalink / raw)
To: Waiman Long
Cc: steffen.klassert, daniel.m.jordan, akpm, linux-crypto,
linux-kernel, longman
Waiman Long <longman@redhat.com> wrote:
>
> diff --git a/kernel/padata.c b/kernel/padata.c
> index 53f4bc912712..0fa6c2895460 100644
> --- a/kernel/padata.c
> +++ b/kernel/padata.c
> @@ -517,6 +517,13 @@ void __init padata_do_multithreaded(struct padata_mt_job *job)
> ps.chunk_size = max(ps.chunk_size, job->min_chunk);
> ps.chunk_size = roundup(ps.chunk_size, job->align);
>
> + /*
> + * chunk_size can be 0 if the caller sets min_chunk to 0. So force it
> + * to at least 1 to prevent divide-by-0 panic in padata_mt_helper().`
> + */
> + if (!ps.chunk_size)
> + ps.chunk_size = 1U;
Perhaps change the first ps.chunk_size assignment to use DIV_ROUND_UP
instead?
Thanks,
--
Email: Herbert Xu <herbert@gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH] padata: Fix possible divide-by-0 panic in padata_mt_helper()
2024-08-06 17:46 [PATCH] padata: Fix possible divide-by-0 panic in padata_mt_helper() Waiman Long
2024-08-10 4:05 ` Herbert Xu
@ 2024-08-10 17:44 ` Kamlesh Gurudasani
2024-08-11 3:33 ` Waiman Long
1 sibling, 1 reply; 20+ messages in thread
From: Kamlesh Gurudasani @ 2024-08-10 17:44 UTC (permalink / raw)
To: Waiman Long, Steffen Klassert, Daniel Jordan, Andrew Morton
Cc: linux-crypto, linux-kernel, Waiman Long
Waiman Long <longman@redhat.com> writes:
> We are hit with a not easily reproducible divide-by-0 panic in padata.c
> at bootup time.
>
> [ 10.017908] Oops: divide error: 0000 1 PREEMPT SMP NOPTI
> [ 10.017908] CPU: 26 PID: 2627 Comm: kworker/u1666:1 Not tainted 6.10.0-15.el10.x86_64 #1
> [ 10.017908] Hardware name: Lenovo ThinkSystem SR950 [7X12CTO1WW]/[7X12CTO1WW], BIOS [PSE140J-2.30] 07/20/2021
> [ 10.017908] Workqueue: events_unbound padata_mt_helper
> [ 10.017908] RIP: 0010:padata_mt_helper+0x39/0xb0
> :
> [ 10.017963] Call Trace:
> [ 10.017968] <TASK>
> [ 10.018004] ? padata_mt_helper+0x39/0xb0
> [ 10.018084] process_one_work+0x174/0x330
> [ 10.018093] worker_thread+0x266/0x3a0
> [ 10.018111] kthread+0xcf/0x100
> [ 10.018124] ret_from_fork+0x31/0x50
> [ 10.018138] ret_from_fork_asm+0x1a/0x30
> [ 10.018147] </TASK>
>
> Looking at the padata_mt_helper() function, the only way a divide-by-0
> panic can happen is when ps->chunk_size is 0. The way that chunk_size is
> initialized in padata_do_multithreaded(), chunk_size can be 0 when the
> min_chunk in the passed-in padata_mt_job structure is 0.
>
> Fix this divide-by-0 panic by making sure that chunk_size will be at
> least 1 no matter what the input parameters are.
>
> Fixes: 004ed42638f4 ("padata: add basic support for multithreaded jobs")
> Signed-off-by: Waiman Long <longman@redhat.com>
> ---
> kernel/padata.c | 7 +++++++
> 1 file changed, 7 insertions(+)
>
> diff --git a/kernel/padata.c b/kernel/padata.c
> index 53f4bc912712..0fa6c2895460 100644
> --- a/kernel/padata.c
> +++ b/kernel/padata.c
> @@ -517,6 +517,13 @@ void __init padata_do_multithreaded(struct padata_mt_job *job)
> ps.chunk_size = max(ps.chunk_size, job->min_chunk);
> ps.chunk_size = roundup(ps.chunk_size, job->align);
>
> + /*
> + * chunk_size can be 0 if the caller sets min_chunk to 0. So force it
> + * to at least 1 to prevent divide-by-0 panic in padata_mt_helper().`
> + */
Thanks for the patch and detailed comment.
> + if (!ps.chunk_size)
> + ps.chunk_size = 1U;
> +
could it be
ps.chunk_size = max(ps.chunk_size, 1U);
or can be merged with earlier max()
ps.chunk_size = max(ps.chunk_size, max(job->min_chunk, 1U));
ps.chunk_size = roundup(ps.chunk_size, job->align);
sits well with how entire file is written and compiler is optimizing
them to same level.
Kamlesh
> list_for_each_entry(pw, &works, pw_list)
> if (job->numa_aware) {
> int old_node = atomic_read(&last_used_nid);
> --
> 2.43.5
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH] padata: Fix possible divide-by-0 panic in padata_mt_helper()
2024-08-10 4:05 ` Herbert Xu
@ 2024-08-11 1:30 ` Waiman Long
2024-08-11 1:45 ` Herbert Xu
0 siblings, 1 reply; 20+ messages in thread
From: Waiman Long @ 2024-08-11 1:30 UTC (permalink / raw)
To: Herbert Xu
Cc: steffen.klassert, daniel.m.jordan, akpm, linux-crypto,
linux-kernel
On 8/10/24 00:05, Herbert Xu wrote:
> Waiman Long <longman@redhat.com> wrote:
>> diff --git a/kernel/padata.c b/kernel/padata.c
>> index 53f4bc912712..0fa6c2895460 100644
>> --- a/kernel/padata.c
>> +++ b/kernel/padata.c
>> @@ -517,6 +517,13 @@ void __init padata_do_multithreaded(struct padata_mt_job *job)
>> ps.chunk_size = max(ps.chunk_size, job->min_chunk);
>> ps.chunk_size = roundup(ps.chunk_size, job->align);
>>
>> + /*
>> + * chunk_size can be 0 if the caller sets min_chunk to 0. So force it
>> + * to at least 1 to prevent divide-by-0 panic in padata_mt_helper().`
>> + */
>> + if (!ps.chunk_size)
>> + ps.chunk_size = 1U;
> Perhaps change the first ps.chunk_size assignment to use DIV_ROUND_UP
> instead?
I think DIV_ROUND_UP() will exactly the same problem that if chunk_size
is 0, you still got a 0 result. round_up() only if the 2nd argument is a
power of 2 while with DIV_ROUND_UP(), the second argument can be any
number except 0.
Cheers,
Longman
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH] padata: Fix possible divide-by-0 panic in padata_mt_helper()
2024-08-11 1:30 ` Waiman Long
@ 2024-08-11 1:45 ` Herbert Xu
2024-08-11 3:11 ` Waiman Long
0 siblings, 1 reply; 20+ messages in thread
From: Herbert Xu @ 2024-08-11 1:45 UTC (permalink / raw)
To: Waiman Long
Cc: steffen.klassert, daniel.m.jordan, akpm, linux-crypto,
linux-kernel
On Sat, Aug 10, 2024 at 09:30:25PM -0400, Waiman Long wrote:
>
> On 8/10/24 00:05, Herbert Xu wrote:
> > Waiman Long <longman@redhat.com> wrote:
> > > diff --git a/kernel/padata.c b/kernel/padata.c
> > > index 53f4bc912712..0fa6c2895460 100644
> > > --- a/kernel/padata.c
> > > +++ b/kernel/padata.c
> > > @@ -517,6 +517,13 @@ void __init padata_do_multithreaded(struct padata_mt_job *job)
> > > ps.chunk_size = max(ps.chunk_size, job->min_chunk);
> > > ps.chunk_size = roundup(ps.chunk_size, job->align);
> > >
> > > + /*
> > > + * chunk_size can be 0 if the caller sets min_chunk to 0. So force it
> > > + * to at least 1 to prevent divide-by-0 panic in padata_mt_helper().`
> > > + */
> > > + if (!ps.chunk_size)
> > > + ps.chunk_size = 1U;
> > Perhaps change the first ps.chunk_size assignment to use DIV_ROUND_UP
> > instead?
>
> I think DIV_ROUND_UP() will exactly the same problem that if chunk_size is
> 0, you still got a 0 result. round_up() only if the 2nd argument is a power
> of 2 while with DIV_ROUND_UP(), the second argument can be any number except
> 0.
Unless I'm missing something chunk_size cannot be zero before the
division because that's the first thing we check upon entry into
this function.
Cheers,
--
Email: Herbert Xu <herbert@gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH] padata: Fix possible divide-by-0 panic in padata_mt_helper()
2024-08-11 1:45 ` Herbert Xu
@ 2024-08-11 3:11 ` Waiman Long
2024-08-11 3:13 ` Herbert Xu
0 siblings, 1 reply; 20+ messages in thread
From: Waiman Long @ 2024-08-11 3:11 UTC (permalink / raw)
To: Herbert Xu
Cc: steffen.klassert, daniel.m.jordan, akpm, linux-crypto,
linux-kernel
On 8/10/24 21:45, Herbert Xu wrote:
> On Sat, Aug 10, 2024 at 09:30:25PM -0400, Waiman Long wrote:
>> On 8/10/24 00:05, Herbert Xu wrote:
>>> Waiman Long <longman@redhat.com> wrote:
>>>> diff --git a/kernel/padata.c b/kernel/padata.c
>>>> index 53f4bc912712..0fa6c2895460 100644
>>>> --- a/kernel/padata.c
>>>> +++ b/kernel/padata.c
>>>> @@ -517,6 +517,13 @@ void __init padata_do_multithreaded(struct padata_mt_job *job)
>>>> ps.chunk_size = max(ps.chunk_size, job->min_chunk);
>>>> ps.chunk_size = roundup(ps.chunk_size, job->align);
>>>>
>>>> + /*
>>>> + * chunk_size can be 0 if the caller sets min_chunk to 0. So force it
>>>> + * to at least 1 to prevent divide-by-0 panic in padata_mt_helper().`
>>>> + */
>>>> + if (!ps.chunk_size)
>>>> + ps.chunk_size = 1U;
>>> Perhaps change the first ps.chunk_size assignment to use DIV_ROUND_UP
>>> instead?
>> I think DIV_ROUND_UP() will exactly the same problem that if chunk_size is
>> 0, you still got a 0 result. round_up() only if the 2nd argument is a power
>> of 2 while with DIV_ROUND_UP(), the second argument can be any number except
>> 0.
> Unless I'm missing something chunk_size cannot be zero before the
> division because that's the first thing we check upon entry into
> this function.
chunk_size is initialized as
ps.chunk_size = job->size / (ps.nworks * load_balance_factor);
chunk_size will be 0 if job->size < (ps.nworks * load_balance_factor).
If min_chunk is 0, chunk_size will remain 0.
After looking at the dump file when the crash happen at
padata_mt_helper(). I had determined that ps->chunk_size was indeed 0
which caused the divide-by-0 panic. I actually got 2 different bug
reports of this div-by-0 panic, one with a debug and another one with a
non-debug kernel.
Cheers,
Longman
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH] padata: Fix possible divide-by-0 panic in padata_mt_helper()
2024-08-11 3:11 ` Waiman Long
@ 2024-08-11 3:13 ` Herbert Xu
2024-08-11 3:27 ` Waiman Long
0 siblings, 1 reply; 20+ messages in thread
From: Herbert Xu @ 2024-08-11 3:13 UTC (permalink / raw)
To: Waiman Long
Cc: steffen.klassert, daniel.m.jordan, akpm, linux-crypto,
linux-kernel
On Sat, Aug 10, 2024 at 11:11:07PM -0400, Waiman Long wrote:
>
> > Unless I'm missing something chunk_size cannot be zero before the
> > division because that's the first thing we check upon entry into
> > this function.
>
> chunk_size is initialized as
>
> ps.chunk_size = job->size / (ps.nworks * load_balance_factor);
>
> chunk_size will be 0 if job->size < (ps.nworks * load_balance_factor). If
> min_chunk is 0, chunk_size will remain 0.
That's why I was suggesting that you replace the division by
DIV_ROUND_UP. That should ensure that ps.chunk_size is not zero.
Cheers,
--
Email: Herbert Xu <herbert@gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH] padata: Fix possible divide-by-0 panic in padata_mt_helper()
2024-08-11 3:13 ` Herbert Xu
@ 2024-08-11 3:27 ` Waiman Long
2024-08-11 3:41 ` Herbert Xu
0 siblings, 1 reply; 20+ messages in thread
From: Waiman Long @ 2024-08-11 3:27 UTC (permalink / raw)
To: Herbert Xu
Cc: steffen.klassert, daniel.m.jordan, akpm, linux-crypto,
linux-kernel
On 8/10/24 23:13, Herbert Xu wrote:
> On Sat, Aug 10, 2024 at 11:11:07PM -0400, Waiman Long wrote:
>>> Unless I'm missing something chunk_size cannot be zero before the
>>> division because that's the first thing we check upon entry into
>>> this function.
>> chunk_size is initialized as
>>
>> ps.chunk_size = job->size / (ps.nworks * load_balance_factor);
>>
>> chunk_size will be 0 if job->size < (ps.nworks * load_balance_factor). If
>> min_chunk is 0, chunk_size will remain 0.
> That's why I was suggesting that you replace the division by
> DIV_ROUND_UP. That should ensure that ps.chunk_size is not zero.
Now I see what you mean. Yes, we can probably change that to a
DIV_ROUND_UP operation to make sure that chunk_size is at least one
unless job->size is 0. I still think the current patch is a bit more
fail-safe.
Cheers, Longman
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH] padata: Fix possible divide-by-0 panic in padata_mt_helper()
2024-08-10 17:44 ` Kamlesh Gurudasani
@ 2024-08-11 3:33 ` Waiman Long
2024-08-11 5:44 ` Kamlesh Gurudasani
0 siblings, 1 reply; 20+ messages in thread
From: Waiman Long @ 2024-08-11 3:33 UTC (permalink / raw)
To: Kamlesh Gurudasani, Steffen Klassert, Daniel Jordan,
Andrew Morton
Cc: linux-crypto, linux-kernel
On 8/10/24 13:44, Kamlesh Gurudasani wrote:
> Waiman Long <longman@redhat.com> writes:
>
>> We are hit with a not easily reproducible divide-by-0 panic in padata.c
>> at bootup time.
>>
>> [ 10.017908] Oops: divide error: 0000 1 PREEMPT SMP NOPTI
>> [ 10.017908] CPU: 26 PID: 2627 Comm: kworker/u1666:1 Not tainted 6.10.0-15.el10.x86_64 #1
>> [ 10.017908] Hardware name: Lenovo ThinkSystem SR950 [7X12CTO1WW]/[7X12CTO1WW], BIOS [PSE140J-2.30] 07/20/2021
>> [ 10.017908] Workqueue: events_unbound padata_mt_helper
>> [ 10.017908] RIP: 0010:padata_mt_helper+0x39/0xb0
>> :
>> [ 10.017963] Call Trace:
>> [ 10.017968] <TASK>
>> [ 10.018004] ? padata_mt_helper+0x39/0xb0
>> [ 10.018084] process_one_work+0x174/0x330
>> [ 10.018093] worker_thread+0x266/0x3a0
>> [ 10.018111] kthread+0xcf/0x100
>> [ 10.018124] ret_from_fork+0x31/0x50
>> [ 10.018138] ret_from_fork_asm+0x1a/0x30
>> [ 10.018147] </TASK>
>>
>> Looking at the padata_mt_helper() function, the only way a divide-by-0
>> panic can happen is when ps->chunk_size is 0. The way that chunk_size is
>> initialized in padata_do_multithreaded(), chunk_size can be 0 when the
>> min_chunk in the passed-in padata_mt_job structure is 0.
>>
>> Fix this divide-by-0 panic by making sure that chunk_size will be at
>> least 1 no matter what the input parameters are.
>>
>> Fixes: 004ed42638f4 ("padata: add basic support for multithreaded jobs")
>> Signed-off-by: Waiman Long <longman@redhat.com>
>> ---
>> kernel/padata.c | 7 +++++++
>> 1 file changed, 7 insertions(+)
>>
>> diff --git a/kernel/padata.c b/kernel/padata.c
>> index 53f4bc912712..0fa6c2895460 100644
>> --- a/kernel/padata.c
>> +++ b/kernel/padata.c
>> @@ -517,6 +517,13 @@ void __init padata_do_multithreaded(struct padata_mt_job *job)
>> ps.chunk_size = max(ps.chunk_size, job->min_chunk);
>> ps.chunk_size = roundup(ps.chunk_size, job->align);
>>
>> + /*
>> + * chunk_size can be 0 if the caller sets min_chunk to 0. So force it
>> + * to at least 1 to prevent divide-by-0 panic in padata_mt_helper().`
>> + */
> Thanks for the patch and detailed comment.
>> + if (!ps.chunk_size)
>> + ps.chunk_size = 1U;
>> +
> could it be
> ps.chunk_size = max(ps.chunk_size, 1U);
>
> or can be merged with earlier max()
> ps.chunk_size = max(ps.chunk_size, max(job->min_chunk, 1U));
> ps.chunk_size = roundup(ps.chunk_size, job->align);
>
> sits well with how entire file is written and compiler is optimizing
> them to same level.
I had actually thought about doing that as an alternative. I used the
current patch to avoid putting too many max() calls there. I can go this
route if you guys prefer this.
Cheers,
Longman
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH] padata: Fix possible divide-by-0 panic in padata_mt_helper()
2024-08-11 3:27 ` Waiman Long
@ 2024-08-11 3:41 ` Herbert Xu
[not found] ` <c5cc5ea9-1135-4ac6-a38f-652ed07dae17@redhat.com>
0 siblings, 1 reply; 20+ messages in thread
From: Herbert Xu @ 2024-08-11 3:41 UTC (permalink / raw)
To: Waiman Long
Cc: steffen.klassert, daniel.m.jordan, akpm, linux-crypto,
linux-kernel
On Sat, Aug 10, 2024 at 11:27:55PM -0400, Waiman Long wrote:
>
> Now I see what you mean. Yes, we can probably change that to a DIV_ROUND_UP
> operation to make sure that chunk_size is at least one unless job->size is
> 0. I still think the current patch is a bit more fail-safe.
The very first thing the function does is check that job->size is
not zero. So this should be all that is necessary.
Thanks,
--
Email: Herbert Xu <herbert@gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH] padata: Fix possible divide-by-0 panic in padata_mt_helper()
2024-08-11 3:33 ` Waiman Long
@ 2024-08-11 5:44 ` Kamlesh Gurudasani
2024-08-13 18:28 ` Waiman Long
0 siblings, 1 reply; 20+ messages in thread
From: Kamlesh Gurudasani @ 2024-08-11 5:44 UTC (permalink / raw)
To: Waiman Long, Steffen Klassert, Daniel Jordan, Andrew Morton
Cc: linux-crypto, linux-kernel
Waiman Long <longman@redhat.com> writes:
> On 8/10/24 13:44, Kamlesh Gurudasani wrote:
>> Waiman Long <longman@redhat.com> writes:
>>
...
>>> diff --git a/kernel/padata.c b/kernel/padata.c
>>> index 53f4bc912712..0fa6c2895460 100644
>>> --- a/kernel/padata.c
>>> +++ b/kernel/padata.c
>>> @@ -517,6 +517,13 @@ void __init padata_do_multithreaded(struct padata_mt_job *job)
>>> ps.chunk_size = max(ps.chunk_size, job->min_chunk);
>>> ps.chunk_size = roundup(ps.chunk_size, job->align);
>>>
>>> + /*
>>> + * chunk_size can be 0 if the caller sets min_chunk to 0. So force it
>>> + * to at least 1 to prevent divide-by-0 panic in padata_mt_helper().`
>>> + */
>> Thanks for the patch and detailed comment.
>>> + if (!ps.chunk_size)
>>> + ps.chunk_size = 1U;
>>> +
>> could it be
>> ps.chunk_size = max(ps.chunk_size, 1U);
>>
>> or can be merged with earlier max()
>> ps.chunk_size = max(ps.chunk_size, max(job->min_chunk, 1U));
>> ps.chunk_size = roundup(ps.chunk_size, job->align);
>>
>> sits well with how entire file is written and compiler is optimizing
>> them to same level.
>
> I had actually thought about doing that as an alternative. I used the
> current patch to avoid putting too many max() calls there. I can go this
> route if you guys prefer this.
Just curious, what is your reason for avoiding too many max() calls? Both
if (!ps.chunk_size)
ps.chunk_size = 1U;
and
ps.chunk_size = max(ps.chunk_size, 1U);
are having same number of instructions [1].
[1] https://godbolt.org/z/ajrK59c67
We can avoid nested max(), though following would make it easier to understand.
ps.chunk_size = max(ps.chunk_size, 1U);
Cheers,
Kamlesh
>
> Cheers,
> Longman
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH] padata: Fix possible divide-by-0 panic in padata_mt_helper()
2024-08-11 5:44 ` Kamlesh Gurudasani
@ 2024-08-13 18:28 ` Waiman Long
0 siblings, 0 replies; 20+ messages in thread
From: Waiman Long @ 2024-08-13 18:28 UTC (permalink / raw)
To: Kamlesh Gurudasani, Steffen Klassert, Daniel Jordan,
Andrew Morton
Cc: linux-crypto, linux-kernel
On 8/11/24 01:44, Kamlesh Gurudasani wrote:
> Waiman Long <longman@redhat.com> writes:
>
>> On 8/10/24 13:44, Kamlesh Gurudasani wrote:
>>> Waiman Long <longman@redhat.com> writes:
>>>
> ...
>>>> diff --git a/kernel/padata.c b/kernel/padata.c
>>>> index 53f4bc912712..0fa6c2895460 100644
>>>> --- a/kernel/padata.c
>>>> +++ b/kernel/padata.c
>>>> @@ -517,6 +517,13 @@ void __init padata_do_multithreaded(struct padata_mt_job *job)
>>>> ps.chunk_size = max(ps.chunk_size, job->min_chunk);
>>>> ps.chunk_size = roundup(ps.chunk_size, job->align);
>>>>
>>>> + /*
>>>> + * chunk_size can be 0 if the caller sets min_chunk to 0. So force it
>>>> + * to at least 1 to prevent divide-by-0 panic in padata_mt_helper().`
>>>> + */
>>> Thanks for the patch and detailed comment.
>>>> + if (!ps.chunk_size)
>>>> + ps.chunk_size = 1U;
>>>> +
>>> could it be
>>> ps.chunk_size = max(ps.chunk_size, 1U);
>>>
>>> or can be merged with earlier max()
>>> ps.chunk_size = max(ps.chunk_size, max(job->min_chunk, 1U));
>>> ps.chunk_size = roundup(ps.chunk_size, job->align);
>>>
>>> sits well with how entire file is written and compiler is optimizing
>>> them to same level.
>> I had actually thought about doing that as an alternative. I used the
>> current patch to avoid putting too many max() calls there. I can go this
>> route if you guys prefer this.
> Just curious, what is your reason for avoiding too many max() calls? Both
> if (!ps.chunk_size)
> ps.chunk_size = 1U;
> and
> ps.chunk_size = max(ps.chunk_size, 1U);
>
> are having same number of instructions [1].
>
> [1] https://godbolt.org/z/ajrK59c67
>
> We can avoid nested max(), though following would make it easier to understand.
>
> ps.chunk_size = max(ps.chunk_size, 1U);
That will certainly work. My current patch has been merged into the
Linus tree. You are welcome to post another patch to clean it up if you
want.
Cheers,
Longman
>
> Cheers,
> Kamlesh
>
>> Cheers,
>> Longman
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH] padata: Fix possible divide-by-0 panic in padata_mt_helper()
[not found] ` <c5cc5ea9-1135-4ac6-a38f-652ed07dae17@redhat.com>
@ 2024-08-17 7:12 ` Herbert Xu
2024-08-19 22:29 ` Daniel Jordan
0 siblings, 1 reply; 20+ messages in thread
From: Herbert Xu @ 2024-08-17 7:12 UTC (permalink / raw)
To: Waiman Long
Cc: steffen.klassert, daniel.m.jordan, akpm, linux-crypto,
linux-kernel
On Mon, Aug 12, 2024 at 10:04:07AM -0400, Waiman Long wrote:
>
> Anyway, using DIV_ROUND_UP() is a slight change in behavior as chunk_size
> will be increased by 1 in most cases. I am a bit hesitant to make this
> change without looking into more detail about the rationale behind the
> current code.
I don't think it matters much. Just look at the two lines after
the division, they're both rounding the value up. So clearly this
is expected to handle the case where work gets bunched up into the
first N CPUs, potentially leaving some CPUs unused.
But Daniel wrote the code so he can have the last say of whether
we should round up after the division or after the other two ops.
Daniel?
Cheers,
--
Email: Herbert Xu <herbert@gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH] padata: Fix possible divide-by-0 panic in padata_mt_helper()
2024-08-17 7:12 ` Herbert Xu
@ 2024-08-19 22:29 ` Daniel Jordan
2024-08-20 0:07 ` Waiman Long
2024-08-20 4:06 ` Herbert Xu
0 siblings, 2 replies; 20+ messages in thread
From: Daniel Jordan @ 2024-08-19 22:29 UTC (permalink / raw)
To: Herbert Xu
Cc: Waiman Long, steffen.klassert, akpm, linux-crypto, linux-kernel
On Sat, Aug 17, 2024 at 03:12:37PM GMT, Herbert Xu wrote:
> On Mon, Aug 12, 2024 at 10:04:07AM -0400, Waiman Long wrote:
> >
> > Anyway, using DIV_ROUND_UP() is a slight change in behavior as chunk_size
> > will be increased by 1 in most cases. I am a bit hesitant to make this
> > change without looking into more detail about the rationale behind the
> > current code.
>
> I don't think it matters much. Just look at the two lines after
> the division, they're both rounding the value up. So clearly this
> is expected to handle the case where work gets bunched up into the
> first N CPUs, potentially leaving some CPUs unused.
Yeah, the caller is supposed to use min_chunk as a hint for what a
reasonable amount of work is per thread and so avoid wasteful amounts of
threads.
> But Daniel wrote the code so he can have the last say of whether
> we should round up after the division or after the other two ops.
I think either way works fine with the three existing users and how they
choose job->min_chunk and job->size.
The DIV_ROUND_UP approach reads a bit nicer to me, but I can imagine
oddball cases where rounding up is undesirable (say, near-zero values
for size, min_chunk, and align; padata_work_alloc_mt returns many fewer
works than requested; and a single unit of work is very expensive) so
that rounding up makes a bigger difference. So, the way it now is seems
ok.
By the way, this bug must've happened coming from
hugetlb_pages_alloc_boot(), right, Waiman? Because the other padata
users have hardcoded min_chunk. I guess it was a case of
h->max_huge_pages < num_node_state(N_MEMORY) * 2
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH] padata: Fix possible divide-by-0 panic in padata_mt_helper()
2024-08-19 22:29 ` Daniel Jordan
@ 2024-08-20 0:07 ` Waiman Long
2024-08-20 4:06 ` Herbert Xu
1 sibling, 0 replies; 20+ messages in thread
From: Waiman Long @ 2024-08-20 0:07 UTC (permalink / raw)
To: Daniel Jordan, Herbert Xu
Cc: steffen.klassert, akpm, linux-crypto, linux-kernel
On 8/19/24 18:29, Daniel Jordan wrote:
> On Sat, Aug 17, 2024 at 03:12:37PM GMT, Herbert Xu wrote:
>> On Mon, Aug 12, 2024 at 10:04:07AM -0400, Waiman Long wrote:
>>> Anyway, using DIV_ROUND_UP() is a slight change in behavior as chunk_size
>>> will be increased by 1 in most cases. I am a bit hesitant to make this
>>> change without looking into more detail about the rationale behind the
>>> current code.
>> I don't think it matters much. Just look at the two lines after
>> the division, they're both rounding the value up. So clearly this
>> is expected to handle the case where work gets bunched up into the
>> first N CPUs, potentially leaving some CPUs unused.
> Yeah, the caller is supposed to use min_chunk as a hint for what a
> reasonable amount of work is per thread and so avoid wasteful amounts of
> threads.
>
>> But Daniel wrote the code so he can have the last say of whether
>> we should round up after the division or after the other two ops.
> I think either way works fine with the three existing users and how they
> choose job->min_chunk and job->size.
>
> The DIV_ROUND_UP approach reads a bit nicer to me, but I can imagine
> oddball cases where rounding up is undesirable (say, near-zero values
> for size, min_chunk, and align; padata_work_alloc_mt returns many fewer
> works than requested; and a single unit of work is very expensive) so
> that rounding up makes a bigger difference. So, the way it now is seems
> ok.
>
>
> By the way, this bug must've happened coming from
> hugetlb_pages_alloc_boot(), right, Waiman? Because the other padata
> users have hardcoded min_chunk. I guess it was a case of
>
> h->max_huge_pages < num_node_state(N_MEMORY) * 2
>
Yes, I guess the hugetlbfs caller is the cause of this div-by-0 problem.
This is likely a bug that needs to be fixed. The current patch does
guarantee that padata won't crash like that even with rogue caller.
Cheers,
Longman
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH] padata: Fix possible divide-by-0 panic in padata_mt_helper()
2024-08-19 22:29 ` Daniel Jordan
2024-08-20 0:07 ` Waiman Long
@ 2024-08-20 4:06 ` Herbert Xu
2024-08-20 21:24 ` Daniel Jordan
1 sibling, 1 reply; 20+ messages in thread
From: Herbert Xu @ 2024-08-20 4:06 UTC (permalink / raw)
To: Daniel Jordan
Cc: Waiman Long, steffen.klassert, akpm, linux-crypto, linux-kernel
On Mon, Aug 19, 2024 at 06:29:52PM -0400, Daniel Jordan wrote:
>
> The DIV_ROUND_UP approach reads a bit nicer to me, but I can imagine
> oddball cases where rounding up is undesirable (say, near-zero values
> for size, min_chunk, and align; padata_work_alloc_mt returns many fewer
> works than requested; and a single unit of work is very expensive) so
> that rounding up makes a bigger difference. So, the way it now is seems
> ok.
In that case let's do the max ahead of the align check:
ps.chunk_size = max(ps.chunk_size, 1ul);
ps.chunk_size = roundup(ps.chunk_size, job->align);
If we do it after then it may come out unaligned (e.g., job->align = 8
and ps.chunk_size = 1).
Cheers,
--
Email: Herbert Xu <herbert@gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH] padata: Fix possible divide-by-0 panic in padata_mt_helper()
2024-08-20 4:06 ` Herbert Xu
@ 2024-08-20 21:24 ` Daniel Jordan
2024-08-21 8:10 ` [EXTERNAL] " Kamlesh Gurudasani
0 siblings, 1 reply; 20+ messages in thread
From: Daniel Jordan @ 2024-08-20 21:24 UTC (permalink / raw)
To: Herbert Xu
Cc: Waiman Long, steffen.klassert, akpm, linux-crypto, linux-kernel,
Kamlesh Gurudasani
On Tue, Aug 20, 2024 at 12:06:47PM GMT, Herbert Xu wrote:
> On Mon, Aug 19, 2024 at 06:29:52PM -0400, Daniel Jordan wrote:
> >
> > The DIV_ROUND_UP approach reads a bit nicer to me, but I can imagine
> > oddball cases where rounding up is undesirable (say, near-zero values
> > for size, min_chunk, and align; padata_work_alloc_mt returns many fewer
> > works than requested; and a single unit of work is very expensive) so
> > that rounding up makes a bigger difference. So, the way it now is seems
> > ok.
>
> In that case let's do the max ahead of the align check:
>
> ps.chunk_size = max(ps.chunk_size, 1ul);
> ps.chunk_size = roundup(ps.chunk_size, job->align);
>
> If we do it after then it may come out unaligned (e.g., job->align = 8
> and ps.chunk_size = 1).
Sure, I think Kamlesh was the first to suggest max, so maybe Kamlesh
would like to make the change. I'll send a patch otherwise.
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [EXTERNAL] Re: [PATCH] padata: Fix possible divide-by-0 panic in padata_mt_helper()
2024-08-20 21:24 ` Daniel Jordan
@ 2024-08-21 8:10 ` Kamlesh Gurudasani
2024-08-21 21:10 ` Kamlesh Gurudasani
0 siblings, 1 reply; 20+ messages in thread
From: Kamlesh Gurudasani @ 2024-08-21 8:10 UTC (permalink / raw)
To: Daniel Jordan, Herbert Xu
Cc: Waiman Long, steffen.klassert, akpm, linux-crypto, linux-kernel
Daniel Jordan <daniel.m.jordan@oracle.com> writes:
> On Tue, Aug 20, 2024 at 12:06:47PM GMT, Herbert Xu wrote:
>> On Mon, Aug 19, 2024 at 06:29:52PM -0400, Daniel Jordan wrote:
>> >
>> > The DIV_ROUND_UP approach reads a bit nicer to me, but I can imagine
>> > oddball cases where rounding up is undesirable (say, near-zero values
>> > for size, min_chunk, and align; padata_work_alloc_mt returns many fewer
>> > works than requested; and a single unit of work is very expensive) so
>> > that rounding up makes a bigger difference. So, the way it now is seems
>> > ok.
>>
>> In that case let's do the max ahead of the align check:
>>
>> ps.chunk_size = max(ps.chunk_size, 1ul);
>> ps.chunk_size = roundup(ps.chunk_size, job->align);
>>
>> If we do it after then it may come out unaligned (e.g., job->align = 8
>> and ps.chunk_size = 1).
>
> Sure, I think Kamlesh was the first to suggest max, so maybe Kamlesh
> would like to make the change. I'll send a patch otherwise.
Thanks for consideration, Daniel. I'll send a patch.
cheers,
Kamlesh
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH] padata: Fix possible divide-by-0 panic in padata_mt_helper()
2024-08-21 8:10 ` [EXTERNAL] " Kamlesh Gurudasani
@ 2024-08-21 21:10 ` Kamlesh Gurudasani
2024-08-23 0:45 ` Daniel Jordan
0 siblings, 1 reply; 20+ messages in thread
From: Kamlesh Gurudasani @ 2024-08-21 21:10 UTC (permalink / raw)
To: Daniel Jordan, Herbert Xu
Cc: Waiman Long, steffen.klassert, akpm, linux-crypto, linux-kernel
Kamlesh Gurudasani <kamlesh@ti.com> writes:
> Daniel Jordan <daniel.m.jordan@oracle.com> writes:
>
>> On Tue, Aug 20, 2024 at 12:06:47PM GMT, Herbert Xu wrote:
>>> On Mon, Aug 19, 2024 at 06:29:52PM -0400, Daniel Jordan wrote:
>>> >
>>> > The DIV_ROUND_UP approach reads a bit nicer to me, but I can imagine
>>> > oddball cases where rounding up is undesirable (say, near-zero values
>>> > for size, min_chunk, and align; padata_work_alloc_mt returns many fewer
>>> > works than requested; and a single unit of work is very expensive) so
>>> > that rounding up makes a bigger difference. So, the way it now is seems
>>> > ok.
>>>
>>> In that case let's do the max ahead of the align check:
>>>
>>> ps.chunk_size = max(ps.chunk_size, 1ul);
>>> ps.chunk_size = roundup(ps.chunk_size, job->align);
>>>
>>> If we do it after then it may come out unaligned (e.g., job->align = 8
>>> and ps.chunk_size = 1).
>>
>> Sure, I think Kamlesh was the first to suggest max, so maybe Kamlesh
>> would like to make the change. I'll send a patch otherwise.
> Thanks for consideration, Daniel. I'll send a patch.
Sent.
Just curious about one thing on line 495,
nworks = max(job->size / max(job->min_chunk, job->align), 1ul);
what happens if both min_chunk and align are 0.
cheers,
Kamlesh
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH] padata: Fix possible divide-by-0 panic in padata_mt_helper()
2024-08-21 21:10 ` Kamlesh Gurudasani
@ 2024-08-23 0:45 ` Daniel Jordan
0 siblings, 0 replies; 20+ messages in thread
From: Daniel Jordan @ 2024-08-23 0:45 UTC (permalink / raw)
To: Kamlesh Gurudasani
Cc: Herbert Xu, Waiman Long, steffen.klassert, akpm, linux-crypto,
linux-kernel
On Thu, Aug 22, 2024 at 02:40:57AM GMT, Kamlesh Gurudasani wrote:
> Kamlesh Gurudasani <kamlesh@ti.com> writes:
>
> > Daniel Jordan <daniel.m.jordan@oracle.com> writes:
> >
> >> On Tue, Aug 20, 2024 at 12:06:47PM GMT, Herbert Xu wrote:
> >>> On Mon, Aug 19, 2024 at 06:29:52PM -0400, Daniel Jordan wrote:
> >>> >
> >>> > The DIV_ROUND_UP approach reads a bit nicer to me, but I can imagine
> >>> > oddball cases where rounding up is undesirable (say, near-zero values
> >>> > for size, min_chunk, and align; padata_work_alloc_mt returns many fewer
> >>> > works than requested; and a single unit of work is very expensive) so
> >>> > that rounding up makes a bigger difference. So, the way it now is seems
> >>> > ok.
> >>>
> >>> In that case let's do the max ahead of the align check:
> >>>
> >>> ps.chunk_size = max(ps.chunk_size, 1ul);
> >>> ps.chunk_size = roundup(ps.chunk_size, job->align);
> >>>
> >>> If we do it after then it may come out unaligned (e.g., job->align = 8
> >>> and ps.chunk_size = 1).
> >>
> >> Sure, I think Kamlesh was the first to suggest max, so maybe Kamlesh
> >> would like to make the change. I'll send a patch otherwise.
> > Thanks for consideration, Daniel. I'll send a patch.
> Sent.
>
> Just curious about one thing on line 495,
>
> nworks = max(job->size / max(job->min_chunk, job->align), 1ul);
>
> what happens if both min_chunk and align are 0.
That's a fair point. It's another of those things that's not supposed
to happen, but it's worth making padata robust to it.
^ permalink raw reply [flat|nested] 20+ messages in thread
end of thread, other threads:[~2024-08-23 0:45 UTC | newest]
Thread overview: 20+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-08-06 17:46 [PATCH] padata: Fix possible divide-by-0 panic in padata_mt_helper() Waiman Long
2024-08-10 4:05 ` Herbert Xu
2024-08-11 1:30 ` Waiman Long
2024-08-11 1:45 ` Herbert Xu
2024-08-11 3:11 ` Waiman Long
2024-08-11 3:13 ` Herbert Xu
2024-08-11 3:27 ` Waiman Long
2024-08-11 3:41 ` Herbert Xu
[not found] ` <c5cc5ea9-1135-4ac6-a38f-652ed07dae17@redhat.com>
2024-08-17 7:12 ` Herbert Xu
2024-08-19 22:29 ` Daniel Jordan
2024-08-20 0:07 ` Waiman Long
2024-08-20 4:06 ` Herbert Xu
2024-08-20 21:24 ` Daniel Jordan
2024-08-21 8:10 ` [EXTERNAL] " Kamlesh Gurudasani
2024-08-21 21:10 ` Kamlesh Gurudasani
2024-08-23 0:45 ` Daniel Jordan
2024-08-10 17:44 ` Kamlesh Gurudasani
2024-08-11 3:33 ` Waiman Long
2024-08-11 5:44 ` Kamlesh Gurudasani
2024-08-13 18:28 ` Waiman Long
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.