Skip to contentSkip to conversation

rcu/kvfree: Add kvfree_rcu_barrier() API

PATCH Superseded Suren Baghdasaryan 2 participants 7 messages Oct 21, 2024 – Nov 6, 2024 Stable branch

v1 of 2 Superseded Latest is v2 →

lore
Share & tools
lore
#0 lore raw

PATCH 1/2 rcu/kvfree: Add kvfree_rcu_barrier() API

From: "Uladzislau Rezki (Sony)" <[email protected]>

From: Uladzislau Rezki <[email protected]>

commit 3c5d61ae919cc377c71118ccc76fa6e8518023f8 upstream.

Add a kvfree_rcu_barrier() function. It waits until all in-flight pointers are freed over RCU machinery. It does not wait any GP completion and it is within its right to return immediately if there are no outstanding pointers.

This function is useful when there is a need to guarantee that a memory is fully freed before destroying memory caches. For example, during unloading a kernel module.

---
 include/linux/rcutiny.h |   5 ++
 include/linux/rcutree.h |   1 +
 kernel/rcu/tree.c       | 109 +++++++++++++++++++++++++++++++++++++---
 3 files changed, 107 insertions(+), 8 deletions(-)
include/linux/rcutiny.h +5 -0
index d9ac7b136aea..522123050ff8 100644
@@ -111,6 +111,11 @@ static inline void __kvfree_call_rcu(struct rcu_head *head, void *ptr)
 	kvfree(ptr);
 }
 
+static inline void kvfree_rcu_barrier(void)
+{
+	rcu_barrier();
+}
+
 #ifdef CONFIG_KASAN_GENERIC
 void kvfree_call_rcu(struct rcu_head *head, void *ptr);
 #else
include/linux/rcutree.h +1 -0
index 254244202ea9..58e7db80f3a8 100644
@@ -35,6 +35,7 @@ static inline void rcu_virt_note_context_switch(void)
 
 void synchronize_rcu_expedited(void);
 void kvfree_call_rcu(struct rcu_head *head, void *ptr);
+void kvfree_rcu_barrier(void);
 
 void rcu_barrier(void);
 void rcu_momentary_dyntick_idle(void);
kernel/rcu/tree.c +101 -8

136 lines not on this page · raw message

base-commit: 17365d66f1c6aa6bf4f4cb9842f5edeac027bcfb

Signature · 1 line
2.47.0.105.g07ac214952-goog
#1 lore raw

PATCH 2/2 lib: alloc_tag_module_unload must wait for pending kfree_rcu calls

From: Florian Westphal <[email protected]>

From: Florian Westphal <[email protected]>

commit dc783ba4b9df3fb3e76e968b2cbeb9960069263c upstream.

Ben Greear reports following splat:

 ------------[ cut here ]------------
 net/netfilter/nf_nat_core.c:1114 module nf_nat func:nf_nat_register_fn has 256 allocated at module unload
 WARNING: CPU: 1 PID: 10421 at lib/alloc_tag.c:168 alloc_tag_module_unload+0x22b/0x3f0
 Modules linked in: nf_nat(-) btrfs ufs qnx4 hfsplus hfs minix vfat msdos fat
...
 Hardware name: Default string Default string/SKYBAY, BIOS 5.12 08/04/2020
 RIP: 0010:alloc_tag_module_unload+0x22b/0x3f0
  codetag_unload_module+0x19b/0x2a0
  ? codetag_load_module+0x80/0x80

nf_nat module exit calls kfree_rcu on those addresses, but the free operation is likely still pending by the time alloc_tag checks for leaks.

Wait for outstanding kfree_rcu operations to complete before checking resolves this warning.

Reproducer:
unshare -n iptables-nft -t nat -A PREROUTING -p tcp grep nf_nat /proc/allocinfo # will list 4 allocations rmmod nft_chain_nat
rmmod nf_nat # will WARN.

---
 lib/codetag.c | 3 +++
 1 file changed, 3 insertions(+)
lib/codetag.c +3 -0
index afa8a2d4f317..d1fbbb7c2ec3 100644
@@ -228,6 +228,9 @@ bool codetag_unload_module(struct module *mod)
 	if (!mod)
 		return true;
 
+	/* await any module's kfree_rcu() operations to complete */
+	kvfree_rcu_barrier();
+
 	mutex_lock(&codetag_lock);
 	list_for_each_entry(cttype, &codetag_types, link) {
 		struct codetag_module *found = NULL;
Signature · 1 line
2.47.0.105.g07ac214952-goog
maintainer
#2 lore raw

Re: [PATCH 6.11.y 2/2] lib: alloc_tag_module_unload must wait for pending kfree_rcu calls

Quoted 3 lines · Suren Baghdasaryan

From: Florian Westphal <[email protected]>

From: Florian Westphal <[email protected]>

Any reason for the duplicated "From:" lines?

thanks,

greg k-h

#3 lore raw

Re: [PATCH 6.11.y 2/2] lib: alloc_tag_module_unload must wait for pending kfree_rcu calls

Quoted 7 lines · Greg KH
Quoted 3 lines · Suren Baghdasaryan

From: Florian Westphal <[email protected]>

From: Florian Westphal <[email protected]>

Any reason for the duplicated "From:" lines?

No, just me incorrectly formatting the patches. Please feel free to remove the duplicates. Thanks!

Quoted 4 lines

thanks,

greg k-h

maintainer
#4 lore raw
In reply to Suren Baghdasaryan
Quoted 15 lines · Suren Baghdasaryan

From: "Uladzislau Rezki (Sony)" <[email protected]>

From: Uladzislau Rezki <[email protected]>

commit 3c5d61ae919cc377c71118ccc76fa6e8518023f8 upstream.

Add a kvfree_rcu_barrier() function. It waits until all in-flight pointers are freed over RCU machinery. It does not wait any GP completion and it is within its right to return immediately if there are no outstanding pointers.

This function is useful when there is a need to guarantee that a memory is fully freed before destroying memory caches. For example, during unloading a kernel module.

Quoted 7 lines
---
 include/linux/rcutiny.h |   5 ++
 include/linux/rcutree.h |   1 +
 kernel/rcu/tree.c       | 109 +++++++++++++++++++++++++++++++++++++---
 3 files changed, 107 insertions(+), 8 deletions(-)

We need a signed-off-by line from you, as you did the backport here, please fix that up and resend this series.

thanks,

greg k-h

#5 lore raw
Quoted 25 lines · Greg KH
Quoted 15 lines · Suren Baghdasaryan

From: "Uladzislau Rezki (Sony)" <[email protected]>

From: Uladzislau Rezki <[email protected]>

commit 3c5d61ae919cc377c71118ccc76fa6e8518023f8 upstream.

Add a kvfree_rcu_barrier() function. It waits until all in-flight pointers are freed over RCU machinery. It does not wait any GP completion and it is within its right to return immediately if there are no outstanding pointers.

This function is useful when there is a need to guarantee that a memory is fully freed before destroying memory caches. For example, during unloading a kernel module.

Quoted 7 lines
---
 include/linux/rcutiny.h |   5 ++
 include/linux/rcutree.h |   1 +
 kernel/rcu/tree.c       | 109 +++++++++++++++++++++++++++++++++++++---
 3 files changed, 107 insertions(+), 8 deletions(-)
Quoted 2 lines

We need a signed-off-by line from you, as you did the backport here, please fix that up and resend this series.

Doh! Ok, I'll resend it tomorrow morning. Thanks!

Quoted 4 lines

thanks,

greg k-h

#6 lore raw
Quoted 27 lines · Suren Baghdasaryan
Quoted 25 lines · Greg KH
Quoted 22 lines · Suren Baghdasaryan

From: "Uladzislau Rezki (Sony)" <[email protected]>

From: Uladzislau Rezki <[email protected]>

commit 3c5d61ae919cc377c71118ccc76fa6e8518023f8 upstream.

Add a kvfree_rcu_barrier() function. It waits until all in-flight pointers are freed over RCU machinery. It does not wait any GP completion and it is within its right to return immediately if there are no outstanding pointers.

This function is useful when there is a need to guarantee that a memory is fully freed before destroying memory caches. For example, during unloading a kernel module.

---
 include/linux/rcutiny.h |   5 ++
 include/linux/rcutree.h |   1 +
 kernel/rcu/tree.c       | 109 +++++++++++++++++++++++++++++++++++++---
 3 files changed, 107 insertions(+), 8 deletions(-)
Quoted 4 lines
Quoted 2 lines

We need a signed-off-by line from you, as you did the backport here, please fix that up and resend this series.

Doh! Ok, I'll resend it tomorrow morning. Thanks!

Added SOB in the new series posted at:
https://lore.kernel.org/all/[email protected]/

Quoted 5 lines
Quoted 5 lines

thanks,

greg k-h