* RE: [PATCH] rhashtable: Fix potential deadlock by moving schedule_work outside lock
[not found] ` <20250102-daffy-vanilla-boar-6e1a61@leitao>
@ 2025-01-09 3:16 ` Michael Kelley
2025-01-09 10:15 ` Breno Leitao
0 siblings, 1 reply; 15+ messages in thread
From: Michael Kelley @ 2025-01-09 3:16 UTC (permalink / raw)
To: Breno Leitao, Herbert Xu, saeedm@nvidia.com, tariqt@nvidia.com,
linux-hyperv@vger.kernel.org
Cc: Andrew Morton, Thomas Graf, Tejun Heo, Hao Luo, Josh Don,
Barret Rhoden, netdev@vger.kernel.org,
linux-kernel@vger.kernel.org
From: Breno Leitao <leitao@debian.org> Sent: Thursday, January 2, 2025 2:16 AM
>
> On Sat, Dec 21, 2024 at 05:06:55PM +0800, Herbert Xu wrote:
> > On Thu, Dec 12, 2024 at 08:33:31PM +0800, Herbert Xu wrote:
> > >
> > > The growth check should stay with the atomic_inc. Something like
> > > this should work:
> >
> > OK I've applied your patch with the atomic_inc move.
>
> Sorry, I was on vacation, and I am back now. Let me know if you need
> anything further.
>
> Thanks for fixing it,
> --breno
Breno and Herbert --
This patch seems to break things in linux-next. I'm testing with
linux-next20250108 in a VM in the Azure public cloud. The Mellanox mlx5
ethernet NIC in the VM is failing to get setup.
I bisected to commit e1d3422c95f0 ("rhashtable: Fix potential deadlock
by moving schedule_work outside lock"), then debugged why opening
the mlx5 NIC device is failing. The failure is in the XDP code in function
__xdp_reg_mem_model() where the call to rhashtable_insert_slow()
is returning -E2BIG. The problem does not occur when the commit
is reverted.
The function call stack is this:
dev_open()
__dev_open()
mlx5e_open()
mlx5e_open_locked()
mlx5e_open_channels()
mlx5e_open_channel()
mlx5e_open_queues()
mlx5e_open_rxq_rq()
mlx5e_open_rq()
mlx5e_alloc_rq()
xdp_rxq_info_reg_mem_model()
__xdp_reg_mem_model()
rhashtable_insert_slow()
I have not debugged further as I don't know anything about the
rhashtable code or the XDP code. The only repro I have is a VM
in Azure. I thought I'd ask you (Breno and Herbert) to review
the patch again and see if there's a path that could cause the
hash table to be incorrectly detected as full.
I've included the linux-hyperv mailing list and the mlx5 driver
maintainers on this email. Someone involved with Azure/Hyper-V
or the mlx5 driver may have seen the problem, and I want to try
to avoid duplicative debugging.
Let me know if there's something I can do to help debug further.
Thanks,
Michael Kelley
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH] rhashtable: Fix potential deadlock by moving schedule_work outside lock
2025-01-09 3:16 ` [PATCH] rhashtable: Fix potential deadlock by moving schedule_work outside lock Michael Kelley
@ 2025-01-09 10:15 ` Breno Leitao
2025-01-10 9:27 ` Herbert Xu
0 siblings, 1 reply; 15+ messages in thread
From: Breno Leitao @ 2025-01-09 10:15 UTC (permalink / raw)
To: Michael Kelley
Cc: Herbert Xu, saeedm@nvidia.com, tariqt@nvidia.com,
linux-hyperv@vger.kernel.org, Andrew Morton, Thomas Graf,
Tejun Heo, Hao Luo, Josh Don, Barret Rhoden,
netdev@vger.kernel.org, linux-kernel@vger.kernel.org
Hello Michael,
On Thu, Jan 09, 2025 at 03:16:03AM +0000, Michael Kelley wrote:
> From: Breno Leitao <leitao@debian.org> Sent: Thursday, January 2, 2025 2:16 AM
> >
> > On Sat, Dec 21, 2024 at 05:06:55PM +0800, Herbert Xu wrote:
> > > On Thu, Dec 12, 2024 at 08:33:31PM +0800, Herbert Xu wrote:
> > > >
> > > > The growth check should stay with the atomic_inc. Something like
> > > > this should work:
> > >
> > > OK I've applied your patch with the atomic_inc move.
> >
> > Sorry, I was on vacation, and I am back now. Let me know if you need
> > anything further.
> >
> > Thanks for fixing it,
> > --breno
>
> Breno and Herbert --
>
> This patch seems to break things in linux-next. I'm testing with
> linux-next20250108 in a VM in the Azure public cloud. The Mellanox mlx5
> ethernet NIC in the VM is failing to get setup.
Thanks for reporting the issue. I started rolling this patch to Meta's
fleet, and we started seeing a similar problem. Altough not fully
understood yet.
I would suggest we revert this patch until we investigate further. I'll
prepare and send a revert patch shortly.
Sorry for the noise,
--breno
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH] rhashtable: Fix potential deadlock by moving schedule_work outside lock
2025-01-09 10:15 ` Breno Leitao
@ 2025-01-10 9:27 ` Herbert Xu
2025-01-10 9:49 ` Breno Leitao
` (2 more replies)
0 siblings, 3 replies; 15+ messages in thread
From: Herbert Xu @ 2025-01-10 9:27 UTC (permalink / raw)
To: Breno Leitao
Cc: Michael Kelley, saeedm@nvidia.com, tariqt@nvidia.com,
linux-hyperv@vger.kernel.org, Andrew Morton, Thomas Graf,
Tejun Heo, Hao Luo, Josh Don, Barret Rhoden,
netdev@vger.kernel.org, linux-kernel@vger.kernel.org
On Thu, Jan 09, 2025 at 02:15:17AM -0800, Breno Leitao wrote:
>
> I would suggest we revert this patch until we investigate further. I'll
> prepare and send a revert patch shortly.
Sorry, I think it was my addition that broke things. The condition
for checking whether an entry is inserted is incorrect, thus resulting
in an underflow of the number of entries after entry removal.
Please test this patch:
---8<---
The function rhashtable_insert_one only returns NULL iff the
insertion was successful, so that alone should be tested before
increment nelems. Testing the variable data is redundant, and
buggy because we will have overwritten the original value of data
by this point.
Reported-by: Michael Kelley <mhklinux@outlook.com>
Fixes: e1d3422c95f0 ("rhashtable: Fix potential deadlock by moving schedule_work outside lock")
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
diff --git a/lib/rhashtable.c b/lib/rhashtable.c
index bf956b85455a..e196b6f0e35a 100644
--- a/lib/rhashtable.c
+++ b/lib/rhashtable.c
@@ -621,7 +621,7 @@ static void *rhashtable_try_insert(struct rhashtable *ht, const void *key,
rht_unlock(tbl, bkt, flags);
- if (PTR_ERR(data) == -ENOENT && !new_tbl) {
+ if (!new_tbl) {
atomic_inc(&ht->nelems);
if (rht_grow_above_75(ht, tbl))
schedule_work(&ht->run_work);
--
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 related [flat|nested] 15+ messages in thread
* Re: [PATCH] rhashtable: Fix potential deadlock by moving schedule_work outside lock
2025-01-10 9:27 ` Herbert Xu
@ 2025-01-10 9:49 ` Breno Leitao
2025-01-10 10:07 ` Herbert Xu
2025-01-10 14:46 ` Zaslonko Mikhail
2025-01-10 16:59 ` Michael Kelley
2 siblings, 1 reply; 15+ messages in thread
From: Breno Leitao @ 2025-01-10 9:49 UTC (permalink / raw)
To: Herbert Xu
Cc: Michael Kelley, saeedm@nvidia.com, tariqt@nvidia.com,
linux-hyperv@vger.kernel.org, Andrew Morton, Thomas Graf,
Tejun Heo, Hao Luo, Josh Don, Barret Rhoden,
netdev@vger.kernel.org, linux-kernel@vger.kernel.org
Hello Herbet,
On Fri, Jan 10, 2025 at 05:27:49PM +0800, Herbert Xu wrote:
> Sorry, I think it was my addition that broke things. The condition
> for checking whether an entry is inserted is incorrect, thus resulting
> in an underflow of the number of entries after entry removal.
That is what I though originally as well, but I was not convinced. While
reading the code, I understood that, if new_tbl is not NULL, then
PTR_ERR(data) will be -ENOENT.
In which case `net_tbl` will not be NULL, and PTR_ERR(data) != -ENOENT?
Thanks for solving it.
> Please test this patch:
I don't have an easy reproducer yet, but, I will get this patch in ~50
hosts and see if any of them misbehave during the weekend.
Misbehaving in my case is strongly associate with messages like the
following being printed:
kobject_uevent: unable to create netlink socket!
Thanks
--breno
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH] rhashtable: Fix potential deadlock by moving schedule_work outside lock
2025-01-10 9:49 ` Breno Leitao
@ 2025-01-10 10:07 ` Herbert Xu
0 siblings, 0 replies; 15+ messages in thread
From: Herbert Xu @ 2025-01-10 10:07 UTC (permalink / raw)
To: Breno Leitao
Cc: Michael Kelley, saeedm@nvidia.com, tariqt@nvidia.com,
linux-hyperv@vger.kernel.org, Andrew Morton, Thomas Graf,
Tejun Heo, Hao Luo, Josh Don, Barret Rhoden,
netdev@vger.kernel.org, linux-kernel@vger.kernel.org
On Fri, Jan 10, 2025 at 01:49:44AM -0800, Breno Leitao wrote:
>
> That is what I though originally as well, but I was not convinced. While
> reading the code, I understood that, if new_tbl is not NULL, then
> PTR_ERR(data) will be -ENOENT.
>
> In which case `net_tbl` will not be NULL, and PTR_ERR(data) != -ENOENT?
The bug arises when an insertion succeeds. So new_tbl is NULL.
The original value of data should have been -ENOENT, however,
it gets overwritten after rhashtable_insert_one (data is now
NULL).
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] 15+ messages in thread
* Re: [PATCH] rhashtable: Fix potential deadlock by moving schedule_work outside lock
2025-01-10 9:27 ` Herbert Xu
2025-01-10 9:49 ` Breno Leitao
@ 2025-01-10 14:46 ` Zaslonko Mikhail
2025-01-10 16:59 ` Michael Kelley
2 siblings, 0 replies; 15+ messages in thread
From: Zaslonko Mikhail @ 2025-01-10 14:46 UTC (permalink / raw)
To: Herbert Xu, Breno Leitao
Cc: Michael Kelley, saeedm@nvidia.com, tariqt@nvidia.com,
linux-hyperv@vger.kernel.org, Andrew Morton, Thomas Graf,
Tejun Heo, Hao Luo, Josh Don, Barret Rhoden,
netdev@vger.kernel.org, linux-kernel@vger.kernel.org,
Heiko Carstens, Alexander Gordeev
Herbert and Breno,
On 10.01.2025 10:27, Herbert Xu wrote:
> On Thu, Jan 09, 2025 at 02:15:17AM -0800, Breno Leitao wrote:
>
> Reported-by: Michael Kelley <mhklinux@outlook.com>
> Fixes: e1d3422c95f0 ("rhashtable: Fix potential deadlock by moving schedule_work outside lock")
> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
>
> diff --git a/lib/rhashtable.c b/lib/rhashtable.c
> index bf956b85455a..e196b6f0e35a 100644
> --- a/lib/rhashtable.c
> +++ b/lib/rhashtable.c
> @@ -621,7 +621,7 @@ static void *rhashtable_try_insert(struct rhashtable *ht, const void *key,
>
> rht_unlock(tbl, bkt, flags);
>
> - if (PTR_ERR(data) == -ENOENT && !new_tbl) {
> + if (!new_tbl) {
> atomic_inc(&ht->nelems);
> if (rht_grow_above_75(ht, tbl))
> schedule_work(&ht->run_work);
I'd like to let you know that I was getting OOM failure on s390 when booting
the kernel (linux-next20250109) with limited memory (mem=1G kernel parameter).
Problem took place in both zVM and LPAR environments. Bisecting also revealed
the commit e1d3422c95f0 ("rhashtable: Fix potential deadlock by moving
schedule_work outside lock").
Afterwards, I tried the fix from Herbert above and the error does not appear
any more. So it seems to resolve the issue.
Thanks,
Mikhail
^ permalink raw reply [flat|nested] 15+ messages in thread
* RE: [PATCH] rhashtable: Fix potential deadlock by moving schedule_work outside lock
2025-01-10 9:27 ` Herbert Xu
2025-01-10 9:49 ` Breno Leitao
2025-01-10 14:46 ` Zaslonko Mikhail
@ 2025-01-10 16:59 ` Michael Kelley
2025-01-10 17:24 ` [v2 PATCH] rhashtable: Fix rhashtable_try_insert test Herbert Xu
2 siblings, 1 reply; 15+ messages in thread
From: Michael Kelley @ 2025-01-10 16:59 UTC (permalink / raw)
To: Herbert Xu, Breno Leitao
Cc: saeedm@nvidia.com, tariqt@nvidia.com,
linux-hyperv@vger.kernel.org, Andrew Morton, Thomas Graf,
Tejun Heo, Hao Luo, Josh Don, Barret Rhoden,
netdev@vger.kernel.org, linux-kernel@vger.kernel.org
From: Herbert Xu <herbert@gondor.apana.org.au> Sent: Friday, January 10, 2025 1:28 AM
>
> On Thu, Jan 09, 2025 at 02:15:17AM -0800, Breno Leitao wrote:
> >
> > I would suggest we revert this patch until we investigate further. I'll
> > prepare and send a revert patch shortly.
>
> Sorry, I think it was my addition that broke things. The condition
> for checking whether an entry is inserted is incorrect, thus resulting
> in an underflow of the number of entries after entry removal.
>
> Please test this patch:
>
> ---8<---
> The function rhashtable_insert_one only returns NULL iff the
> insertion was successful, so that alone should be tested before
> increment nelems. Testing the variable data is redundant, and
> buggy because we will have overwritten the original value of data
> by this point.
>
> Reported-by: Michael Kelley <mhklinux@outlook.com>
> Fixes: e1d3422c95f0 ("rhashtable: Fix potential deadlock by moving schedule_work
> outside lock")
> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
>
> diff --git a/lib/rhashtable.c b/lib/rhashtable.c
> index bf956b85455a..e196b6f0e35a 100644
> --- a/lib/rhashtable.c
> +++ b/lib/rhashtable.c
> @@ -621,7 +621,7 @@ static void *rhashtable_try_insert(struct rhashtable *ht, const
> void *key,
>
> rht_unlock(tbl, bkt, flags);
>
> - if (PTR_ERR(data) == -ENOENT && !new_tbl) {
> + if (!new_tbl) {
> atomic_inc(&ht->nelems);
> if (rht_grow_above_75(ht, tbl))
> schedule_work(&ht->run_work);
> --
This patch fixes the problem I saw with VMs in the Azure cloud. Thanks!
Michael Kelley
^ permalink raw reply [flat|nested] 15+ messages in thread
* [v2 PATCH] rhashtable: Fix rhashtable_try_insert test
2025-01-10 16:59 ` Michael Kelley
@ 2025-01-10 17:24 ` Herbert Xu
2025-01-10 18:22 ` Michael Kelley
0 siblings, 1 reply; 15+ messages in thread
From: Herbert Xu @ 2025-01-10 17:24 UTC (permalink / raw)
To: Michael Kelley
Cc: Breno Leitao, saeedm@nvidia.com, tariqt@nvidia.com,
linux-hyperv@vger.kernel.org, Andrew Morton, Thomas Graf,
Tejun Heo, Hao Luo, Josh Don, Barret Rhoden,
netdev@vger.kernel.org, linux-kernel@vger.kernel.org
On Fri, Jan 10, 2025 at 04:59:28PM +0000, Michael Kelley wrote:
>
> This patch fixes the problem I saw with VMs in the Azure cloud. Thanks!
Sorry, but the test on data is needed after all (it was just
buggy). Otherwise we will break rhlist. So please test this
patch instead.
---8<---
The test on whether rhashtable_insert_one did an insertion relies
on the value returned by rhashtable_lookup_one. Unfortunately that
value is overwritten after rhashtable_insert_one returns. Fix this
by saving the old value.
Also simplify the test as only data == NULL matters.
Reported-by: Michael Kelley <mhklinux@outlook.com>
Fixes: e1d3422c95f0 ("rhashtable: Fix potential deadlock by moving schedule_work outside lock")
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
diff --git a/lib/rhashtable.c b/lib/rhashtable.c
index bf956b85455a..e36b36f3146d 100644
--- a/lib/rhashtable.c
+++ b/lib/rhashtable.c
@@ -611,17 +611,20 @@ static void *rhashtable_try_insert(struct rhashtable *ht, const void *key,
new_tbl = rht_dereference_rcu(tbl->future_tbl, ht);
data = ERR_PTR(-EAGAIN);
} else {
+ void *odata;
+
flags = rht_lock(tbl, bkt);
data = rhashtable_lookup_one(ht, bkt, tbl,
hash, key, obj);
new_tbl = rhashtable_insert_one(ht, bkt, tbl,
hash, obj, data);
+ odata = data;
if (PTR_ERR(new_tbl) != -EEXIST)
data = ERR_CAST(new_tbl);
rht_unlock(tbl, bkt, flags);
- if (PTR_ERR(data) == -ENOENT && !new_tbl) {
+ if (odata && !new_tbl) {
atomic_inc(&ht->nelems);
if (rht_grow_above_75(ht, tbl))
schedule_work(&ht->run_work);
--
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 related [flat|nested] 15+ messages in thread
* RE: [v2 PATCH] rhashtable: Fix rhashtable_try_insert test
2025-01-10 17:24 ` [v2 PATCH] rhashtable: Fix rhashtable_try_insert test Herbert Xu
@ 2025-01-10 18:22 ` Michael Kelley
2025-01-14 3:15 ` [v3 " Herbert Xu
0 siblings, 1 reply; 15+ messages in thread
From: Michael Kelley @ 2025-01-10 18:22 UTC (permalink / raw)
To: Herbert Xu
Cc: Breno Leitao, saeedm@nvidia.com, tariqt@nvidia.com,
linux-hyperv@vger.kernel.org, Andrew Morton, Thomas Graf,
Tejun Heo, Hao Luo, Josh Don, Barret Rhoden,
netdev@vger.kernel.org, linux-kernel@vger.kernel.org
From: Herbert Xu <herbert@gondor.apana.org.au> Sent: Friday, January 10, 2025 9:24 AM
>
> On Fri, Jan 10, 2025 at 04:59:28PM +0000, Michael Kelley wrote:
> >
> > This patch fixes the problem I saw with VMs in the Azure cloud. Thanks!
>
> Sorry, but the test on data is needed after all (it was just
> buggy). Otherwise we will break rhlist. So please test this
> patch instead.
>
> ---8<---
> The test on whether rhashtable_insert_one did an insertion relies
> on the value returned by rhashtable_lookup_one. Unfortunately that
> value is overwritten after rhashtable_insert_one returns. Fix this
> by saving the old value.
>
> Also simplify the test as only data == NULL matters.
>
> Reported-by: Michael Kelley <mhklinux@outlook.com>
> Fixes: e1d3422c95f0 ("rhashtable: Fix potential deadlock by moving schedule_work
> outside lock")
> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
>
> diff --git a/lib/rhashtable.c b/lib/rhashtable.c
> index bf956b85455a..e36b36f3146d 100644
> --- a/lib/rhashtable.c
> +++ b/lib/rhashtable.c
> @@ -611,17 +611,20 @@ static void *rhashtable_try_insert(struct rhashtable *ht,
> const void *key,
> new_tbl = rht_dereference_rcu(tbl->future_tbl, ht);
> data = ERR_PTR(-EAGAIN);
> } else {
> + void *odata;
> +
> flags = rht_lock(tbl, bkt);
> data = rhashtable_lookup_one(ht, bkt, tbl,
> hash, key, obj);
> new_tbl = rhashtable_insert_one(ht, bkt, tbl,
> hash, obj, data);
> + odata = data;
> if (PTR_ERR(new_tbl) != -EEXIST)
> data = ERR_CAST(new_tbl);
>
> rht_unlock(tbl, bkt, flags);
>
> - if (PTR_ERR(data) == -ENOENT && !new_tbl) {
> + if (odata && !new_tbl) {
> atomic_inc(&ht->nelems);
> if (rht_grow_above_75(ht, tbl))
> schedule_work(&ht->run_work);
This patch passes my tests. I'm doing a narrow test to verify that
the boot failure when opening the Mellanox NIC is no longer occurring.
I also unloaded/reloaded the mlx5 driver a couple of times. For good
measure, I then did a full Linux kernel build, and all is good. My testing
does not broadly verify correct operation of rhashtable except as it
gets exercised implicitly by these basic tests.
Michael
^ permalink raw reply [flat|nested] 15+ messages in thread
* [v3 PATCH] rhashtable: Fix rhashtable_try_insert test
2025-01-10 18:22 ` Michael Kelley
@ 2025-01-14 3:15 ` Herbert Xu
2025-01-14 11:58 ` Michael Kelley
` (3 more replies)
0 siblings, 4 replies; 15+ messages in thread
From: Herbert Xu @ 2025-01-14 3:15 UTC (permalink / raw)
To: Michael Kelley
Cc: Breno Leitao, saeedm@nvidia.com, tariqt@nvidia.com,
linux-hyperv@vger.kernel.org, Andrew Morton, Thomas Graf,
Tejun Heo, Hao Luo, Josh Don, Barret Rhoden,
netdev@vger.kernel.org, linux-kernel@vger.kernel.org,
Linux Crypto Mailing List
On Fri, Jan 10, 2025 at 06:22:40PM +0000, Michael Kelley wrote:
>
> This patch passes my tests. I'm doing a narrow test to verify that
> the boot failure when opening the Mellanox NIC is no longer occurring.
> I also unloaded/reloaded the mlx5 driver a couple of times. For good
> measure, I then did a full Linux kernel build, and all is good. My testing
> does not broadly verify correct operation of rhashtable except as it
> gets exercised implicitly by these basic tests.
Thanks for testing! The patch needs one more change though as
moving the atomic_inc outside of the lock was a bad idea on my
part. This could cause atomic_inc/atomic_dec to be reordered
thus resulting in an underflow.
Thanks,
---8<---
The test on whether rhashtable_insert_one did an insertion relies
on the value returned by rhashtable_lookup_one. Unfortunately that
value is overwritten after rhashtable_insert_one returns. Fix this
by moving the test before data gets overwritten.
Simplify the test as only data == NULL matters.
Finally move atomic_inc back within the lock as otherwise it may
be reordered with the atomic_dec on the removal side, potentially
leading to an underflow.
Reported-by: Michael Kelley <mhklinux@outlook.com>
Fixes: e1d3422c95f0 ("rhashtable: Fix potential deadlock by moving schedule_work outside lock")
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
diff --git a/lib/rhashtable.c b/lib/rhashtable.c
index bf956b85455a..0e9a1d4cf89b 100644
--- a/lib/rhashtable.c
+++ b/lib/rhashtable.c
@@ -611,21 +611,23 @@ static void *rhashtable_try_insert(struct rhashtable *ht, const void *key,
new_tbl = rht_dereference_rcu(tbl->future_tbl, ht);
data = ERR_PTR(-EAGAIN);
} else {
+ bool inserted;
+
flags = rht_lock(tbl, bkt);
data = rhashtable_lookup_one(ht, bkt, tbl,
hash, key, obj);
new_tbl = rhashtable_insert_one(ht, bkt, tbl,
hash, obj, data);
+ inserted = data && !new_tbl;
+ if (inserted)
+ atomic_inc(&ht->nelems);
if (PTR_ERR(new_tbl) != -EEXIST)
data = ERR_CAST(new_tbl);
rht_unlock(tbl, bkt, flags);
- if (PTR_ERR(data) == -ENOENT && !new_tbl) {
- atomic_inc(&ht->nelems);
- if (rht_grow_above_75(ht, tbl))
- schedule_work(&ht->run_work);
- }
+ if (inserted && rht_grow_above_75(ht, tbl))
+ schedule_work(&ht->run_work);
}
} while (!IS_ERR_OR_NULL(new_tbl));
--
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 related [flat|nested] 15+ messages in thread
* RE: [v3 PATCH] rhashtable: Fix rhashtable_try_insert test
2025-01-14 3:15 ` [v3 " Herbert Xu
@ 2025-01-14 11:58 ` Michael Kelley
2025-01-15 15:15 ` Breno Leitao
` (2 subsequent siblings)
3 siblings, 0 replies; 15+ messages in thread
From: Michael Kelley @ 2025-01-14 11:58 UTC (permalink / raw)
To: Herbert Xu
Cc: Breno Leitao, saeedm@nvidia.com, tariqt@nvidia.com,
linux-hyperv@vger.kernel.org, Andrew Morton, Thomas Graf,
Tejun Heo, Hao Luo, Josh Don, Barret Rhoden,
netdev@vger.kernel.org, linux-kernel@vger.kernel.org,
Linux Crypto Mailing List
From: Herbert Xu <herbert@gondor.apana.org.au> Sent: Monday, January 13, 2025 7:15 PM
>
> On Fri, Jan 10, 2025 at 06:22:40PM +0000, Michael Kelley wrote:
> >
> > This patch passes my tests. I'm doing a narrow test to verify that
> > the boot failure when opening the Mellanox NIC is no longer occurring.
> > I also unloaded/reloaded the mlx5 driver a couple of times. For good
> > measure, I then did a full Linux kernel build, and all is good. My testing
> > does not broadly verify correct operation of rhashtable except as it
> > gets exercised implicitly by these basic tests.
>
> Thanks for testing! The patch needs one more change though as
> moving the atomic_inc outside of the lock was a bad idea on my
> part. This could cause atomic_inc/atomic_dec to be reordered
> thus resulting in an underflow.
>
> Thanks,
I've tested this version of the fix in the same limited way as
before. All is good. I'm still testing against linux-next20250108
from a few days ago, but that should not make any difference.
I have *not* reviewed the code change itself.
Tested-by: Michael Kelley <mhklinux@outlook.com>
>
> ---8<---
> The test on whether rhashtable_insert_one did an insertion relies
> on the value returned by rhashtable_lookup_one. Unfortunately that
> value is overwritten after rhashtable_insert_one returns. Fix this
> by moving the test before data gets overwritten.
>
> Simplify the test as only data == NULL matters.
>
> Finally move atomic_inc back within the lock as otherwise it may
> be reordered with the atomic_dec on the removal side, potentially
> leading to an underflow.
>
> Reported-by: Michael Kelley <mhklinux@outlook.com>
> Fixes: e1d3422c95f0 ("rhashtable: Fix potential deadlock by moving schedule_work outside lock")
> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
>
> diff --git a/lib/rhashtable.c b/lib/rhashtable.c
> index bf956b85455a..0e9a1d4cf89b 100644
> --- a/lib/rhashtable.c
> +++ b/lib/rhashtable.c
> @@ -611,21 +611,23 @@ static void *rhashtable_try_insert(struct rhashtable *ht,
> const void *key,
> new_tbl = rht_dereference_rcu(tbl->future_tbl, ht);
> data = ERR_PTR(-EAGAIN);
> } else {
> + bool inserted;
> +
> flags = rht_lock(tbl, bkt);
> data = rhashtable_lookup_one(ht, bkt, tbl,
> hash, key, obj);
> new_tbl = rhashtable_insert_one(ht, bkt, tbl,
> hash, obj, data);
> + inserted = data && !new_tbl;
> + if (inserted)
> + atomic_inc(&ht->nelems);
> if (PTR_ERR(new_tbl) != -EEXIST)
> data = ERR_CAST(new_tbl);
>
> rht_unlock(tbl, bkt, flags);
>
> - if (PTR_ERR(data) == -ENOENT && !new_tbl) {
> - atomic_inc(&ht->nelems);
> - if (rht_grow_above_75(ht, tbl))
> - schedule_work(&ht->run_work);
> - }
> + if (inserted && rht_grow_above_75(ht, tbl))
> + schedule_work(&ht->run_work);
> }
> } while (!IS_ERR_OR_NULL(new_tbl));
>
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [v3 PATCH] rhashtable: Fix rhashtable_try_insert test
2025-01-14 3:15 ` [v3 " Herbert Xu
2025-01-14 11:58 ` Michael Kelley
@ 2025-01-15 15:15 ` Breno Leitao
2025-01-16 9:10 ` Herbert Xu
2025-01-16 11:48 ` Alexander Gordeev
2025-01-17 13:20 ` Zaslonko Mikhail
3 siblings, 1 reply; 15+ messages in thread
From: Breno Leitao @ 2025-01-15 15:15 UTC (permalink / raw)
To: Herbert Xu
Cc: Michael Kelley, saeedm@nvidia.com, tariqt@nvidia.com,
linux-hyperv@vger.kernel.org, Andrew Morton, Thomas Graf,
Tejun Heo, Hao Luo, Josh Don, Barret Rhoden,
netdev@vger.kernel.org, linux-kernel@vger.kernel.org,
Linux Crypto Mailing List
On Tue, Jan 14, 2025 at 11:15:19AM +0800, Herbert Xu wrote:
> On Fri, Jan 10, 2025 at 06:22:40PM +0000, Michael Kelley wrote:
> >
> > This patch passes my tests. I'm doing a narrow test to verify that
> > the boot failure when opening the Mellanox NIC is no longer occurring.
> > I also unloaded/reloaded the mlx5 driver a couple of times. For good
> > measure, I then did a full Linux kernel build, and all is good. My testing
> > does not broadly verify correct operation of rhashtable except as it
> > gets exercised implicitly by these basic tests.
>
> Thanks for testing! The patch needs one more change though as
> moving the atomic_inc outside of the lock was a bad idea on my
> part. This could cause atomic_inc/atomic_dec to be reordered
> thus resulting in an underflow.
>
> Thanks,
>
> ---8<---
> The test on whether rhashtable_insert_one did an insertion relies
> on the value returned by rhashtable_lookup_one. Unfortunately that
> value is overwritten after rhashtable_insert_one returns. Fix this
> by moving the test before data gets overwritten.
>
> Simplify the test as only data == NULL matters.
>
> Finally move atomic_inc back within the lock as otherwise it may
> be reordered with the atomic_dec on the removal side, potentially
> leading to an underflow.
>
> Reported-by: Michael Kelley <mhklinux@outlook.com>
> Fixes: e1d3422c95f0 ("rhashtable: Fix potential deadlock by moving schedule_work outside lock")
> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Reviewed-by: Breno Leitao <leitao@debian.org>
> diff --git a/lib/rhashtable.c b/lib/rhashtable.c
> index bf956b85455a..0e9a1d4cf89b 100644
> --- a/lib/rhashtable.c
> +++ b/lib/rhashtable.c
> @@ -611,21 +611,23 @@ static void *rhashtable_try_insert(struct rhashtable *ht, const void *key,
> new_tbl = rht_dereference_rcu(tbl->future_tbl, ht);
> data = ERR_PTR(-EAGAIN);
> } else {
> + bool inserted;
> +
> flags = rht_lock(tbl, bkt);
> data = rhashtable_lookup_one(ht, bkt, tbl,
> hash, key, obj);
> new_tbl = rhashtable_insert_one(ht, bkt, tbl,
> hash, obj, data);
> + inserted = data && !new_tbl;
> + if (inserted)
> + atomic_inc(&ht->nelems);
> if (PTR_ERR(new_tbl) != -EEXIST)
> data = ERR_CAST(new_tbl);
>
> rht_unlock(tbl, bkt, flags);
>
> - if (PTR_ERR(data) == -ENOENT && !new_tbl) {
> - atomic_inc(&ht->nelems);
> - if (rht_grow_above_75(ht, tbl))
> - schedule_work(&ht->run_work);
> - }
> + if (inserted && rht_grow_above_75(ht, tbl))
> + schedule_work(&ht->run_work);
That makes sense, since data could be ERR_PTR(-ENOENT) and ERR_PTR(-EAGAIN), and
the object being inserted, which means that nelems should be increased.
It was hard to review this patch, basically rhashtable_insert_one()
returns three type of values, and you are interested in only one case,
when the obj was inserted.
These are the type of values that is coming from
rhashtable_insert_one():
1) NULL: if object was inserted OR if data is NULL
2) Non error and !NULL: A new table to look at
3) ERR: Definitely not added
I am wondering if we decoupled the first case, and only return NULL iff
the object was added, it would simplify this logic.
Something like the following (not tested):
diff --git a/lib/rhashtable.c b/lib/rhashtable.c
index 3e555d012ed60..5a0ec71e990ee 100644
--- a/lib/rhashtable.c
+++ b/lib/rhashtable.c
@@ -554,7 +554,7 @@ static struct bucket_table *rhashtable_insert_one(
return ERR_PTR(-EEXIST);
if (PTR_ERR(data) != -EAGAIN && PTR_ERR(data) != -ENOENT)
- return ERR_CAST(data);
+ return ERR_PTR(-EINVAL);
new_tbl = rht_dereference_rcu(tbl->future_tbl, ht);
if (new_tbl)
Thanks for fixing it,
--breno
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [v3 PATCH] rhashtable: Fix rhashtable_try_insert test
2025-01-15 15:15 ` Breno Leitao
@ 2025-01-16 9:10 ` Herbert Xu
0 siblings, 0 replies; 15+ messages in thread
From: Herbert Xu @ 2025-01-16 9:10 UTC (permalink / raw)
To: Breno Leitao
Cc: Michael Kelley, saeedm@nvidia.com, tariqt@nvidia.com,
linux-hyperv@vger.kernel.org, Andrew Morton, Thomas Graf,
Tejun Heo, Hao Luo, Josh Don, Barret Rhoden,
netdev@vger.kernel.org, linux-kernel@vger.kernel.org,
Linux Crypto Mailing List
On Wed, Jan 15, 2025 at 07:15:46AM -0800, Breno Leitao wrote:
>
> Something like the following (not tested):
>
> diff --git a/lib/rhashtable.c b/lib/rhashtable.c
> index 3e555d012ed60..5a0ec71e990ee 100644
> --- a/lib/rhashtable.c
> +++ b/lib/rhashtable.c
> @@ -554,7 +554,7 @@ static struct bucket_table *rhashtable_insert_one(
> return ERR_PTR(-EEXIST);
>
> if (PTR_ERR(data) != -EAGAIN && PTR_ERR(data) != -ENOENT)
> - return ERR_CAST(data);
> + return ERR_PTR(-EINVAL);
But data == NULL is not an error, it is a successful return value
for rhltable. It's when a key already exists in the rhltable
and we're simply appending the new object to it. Thus the insertion
was successful but the hash table did not grow.
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] 15+ messages in thread
* Re: [v3 PATCH] rhashtable: Fix rhashtable_try_insert test
2025-01-14 3:15 ` [v3 " Herbert Xu
2025-01-14 11:58 ` Michael Kelley
2025-01-15 15:15 ` Breno Leitao
@ 2025-01-16 11:48 ` Alexander Gordeev
2025-01-17 13:20 ` Zaslonko Mikhail
3 siblings, 0 replies; 15+ messages in thread
From: Alexander Gordeev @ 2025-01-16 11:48 UTC (permalink / raw)
To: Herbert Xu
Cc: Michael Kelley, Breno Leitao, saeedm@nvidia.com,
tariqt@nvidia.com, linux-hyperv@vger.kernel.org, Andrew Morton,
Thomas Graf, Tejun Heo, Hao Luo, Josh Don, Barret Rhoden,
netdev@vger.kernel.org, linux-kernel@vger.kernel.org,
Linux Crypto Mailing List, Zaslonko Mikhail
On Tue, Jan 14, 2025 at 11:15:19AM +0800, Herbert Xu wrote:
Hi Herbert,
> Thanks for testing! The patch needs one more change though as
> moving the atomic_inc outside of the lock was a bad idea on my
> part. This could cause atomic_inc/atomic_dec to be reordered
> thus resulting in an underflow.
I want to confirm that this patch fixes massive strangenesses and
few crashes observed on s390 systems, in addition to OOMs reported
by Mikhail Zaslonko earlier.
> Thanks,
Thanks!
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [v3 PATCH] rhashtable: Fix rhashtable_try_insert test
2025-01-14 3:15 ` [v3 " Herbert Xu
` (2 preceding siblings ...)
2025-01-16 11:48 ` Alexander Gordeev
@ 2025-01-17 13:20 ` Zaslonko Mikhail
3 siblings, 0 replies; 15+ messages in thread
From: Zaslonko Mikhail @ 2025-01-17 13:20 UTC (permalink / raw)
To: Herbert Xu, Michael Kelley
Cc: Breno Leitao, saeedm@nvidia.com, tariqt@nvidia.com,
linux-hyperv@vger.kernel.org, Andrew Morton, Thomas Graf,
Tejun Heo, Hao Luo, Josh Don, Barret Rhoden,
netdev@vger.kernel.org, linux-kernel@vger.kernel.org,
Linux Crypto Mailing List
Hello,
On 14.01.2025 04:15, Herbert Xu wrote:
> On Fri, Jan 10, 2025 at 06:22:40PM +0000, Michael Kelley wrote:
>
> Thanks for testing! The patch needs one more change though as
> moving the atomic_inc outside of the lock was a bad idea on my
> part. This could cause atomic_inc/atomic_dec to be reordered
> thus resulting in an underflow.
>
> Thanks,
I've tested v3 patch on s390 for the boot OOM problem with 'mem=1G'
kernel parameter we experience on current linux-next kernel and confirm
that the issue is no longer present.
Tested-by: Mikhail Zaslonko <zaslonko@linux.ibm.com>
>
> ---8<---
> The test on whether rhashtable_insert_one did an insertion relies
> on the value returned by rhashtable_lookup_one. Unfortunately that
> value is overwritten after rhashtable_insert_one returns. Fix this
> by moving the test before data gets overwritten.
>
> Simplify the test as only data == NULL matters.
>
> Finally move atomic_inc back within the lock as otherwise it may
> be reordered with the atomic_dec on the removal side, potentially
> leading to an underflow.
>
> Reported-by: Michael Kelley <mhklinux@outlook.com>
> Fixes: e1d3422c95f0 ("rhashtable: Fix potential deadlock by moving schedule_work outside lock")
> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
>
> diff --git a/lib/rhashtable.c b/lib/rhashtable.c
> index bf956b85455a..0e9a1d4cf89b 100644
> --- a/lib/rhashtable.c
> +++ b/lib/rhashtable.c
> @@ -611,21 +611,23 @@ static void *rhashtable_try_insert(struct rhashtable *ht, const void *key,
> new_tbl = rht_dereference_rcu(tbl->future_tbl, ht);
> data = ERR_PTR(-EAGAIN);
> } else {
> + bool inserted;
> +
> flags = rht_lock(tbl, bkt);
> data = rhashtable_lookup_one(ht, bkt, tbl,
> hash, key, obj);
> new_tbl = rhashtable_insert_one(ht, bkt, tbl,
> hash, obj, data);
> + inserted = data && !new_tbl;
> + if (inserted)
> + atomic_inc(&ht->nelems);
> if (PTR_ERR(new_tbl) != -EEXIST)
> data = ERR_CAST(new_tbl);
>
> rht_unlock(tbl, bkt, flags);
>
> - if (PTR_ERR(data) == -ENOENT && !new_tbl) {
> - atomic_inc(&ht->nelems);
> - if (rht_grow_above_75(ht, tbl))
> - schedule_work(&ht->run_work);
> - }
> + if (inserted && rht_grow_above_75(ht, tbl))
> + schedule_work(&ht->run_work);
> }
> } while (!IS_ERR_OR_NULL(new_tbl));
>
Thanks!
^ permalink raw reply [flat|nested] 15+ messages in thread
end of thread, other threads:[~2025-01-17 13:21 UTC | newest]
Thread overview: 15+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
[not found] <20241128-scx_lockdep-v1-1-2315b813b36b@debian.org>
[not found] ` <Z1rYGzEpMub4Fp6i@gondor.apana.org.au>
[not found] ` <Z2aFL3dNLYOcmzH3@gondor.apana.org.au>
[not found] ` <20250102-daffy-vanilla-boar-6e1a61@leitao>
2025-01-09 3:16 ` [PATCH] rhashtable: Fix potential deadlock by moving schedule_work outside lock Michael Kelley
2025-01-09 10:15 ` Breno Leitao
2025-01-10 9:27 ` Herbert Xu
2025-01-10 9:49 ` Breno Leitao
2025-01-10 10:07 ` Herbert Xu
2025-01-10 14:46 ` Zaslonko Mikhail
2025-01-10 16:59 ` Michael Kelley
2025-01-10 17:24 ` [v2 PATCH] rhashtable: Fix rhashtable_try_insert test Herbert Xu
2025-01-10 18:22 ` Michael Kelley
2025-01-14 3:15 ` [v3 " Herbert Xu
2025-01-14 11:58 ` Michael Kelley
2025-01-15 15:15 ` Breno Leitao
2025-01-16 9:10 ` Herbert Xu
2025-01-16 11:48 ` Alexander Gordeev
2025-01-17 13:20 ` Zaslonko Mikhail
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox