Skip to content

Commit

Permalink
Merge branch 'replace-call_rcu-by-kfree_rcu-for-simple-kmem_cache_fre…
Browse files Browse the repository at this point in the history
…e-callback'

Julia Lawall says:

====================
replace call_rcu by kfree_rcu for simple kmem_cache_free callback

Since SLOB was removed and since
commit 6c6c47b ("mm, slab: call kvfree_rcu_barrier() from kmem_cache_destroy()"),
it is not necessary to use call_rcu when the callback only performs
kmem_cache_free. Use kfree_rcu() directly.

The changes were done using the following Coccinelle semantic patch.
This semantic patch is designed to ignore cases where the callback
function is used in another way.

// <smpl>

@r@
expression e;
local idexpression e2;
identifier cb,f,g;
position p;
@@

(
call_rcu(...,e2)
|
call_rcu(&e->f,cb@p)
|
call_rcu(&e->f.g,cb@p)
)

@r1@
type T,T1;
identifier x,r.cb;
@@

 cb(...) {
(
   kmem_cache_free(...);
|
   T x = ...;
   kmem_cache_free(...,(T1)x);
|
   T x;
   x = ...;
   kmem_cache_free(...,(T1)x);
)
 }

@s depends on r1@
position p != r.p;
identifier r.cb;
@@

 cb@p

@script:ocaml@
cb << r.cb;
p << s.p;
@@

Printf.eprintf "Other use of %s at %s:%d\n" cb (List.hd p).file (List.hd p).line

@depends on r1 && !s@
expression e;
identifier r.cb,f,g;
position r.p;
@@

(
- call_rcu(&e->f,cb@p)
+ kfree_rcu(e,f)
|
- call_rcu(&e->f.g,cb@p)
+ kfree_rcu(e,f.g)
)

@r1a depends on !s@
type T,T1;
identifier x,r.cb;
@@

- cb(...) {
(
-  kmem_cache_free(...);
|
-  T x = ...;
-  kmem_cache_free(...,(T1)x);
|
-  T x;
-  x = ...;
-  kmem_cache_free(...,(T1)x);
)
- }

@r2 depends on !r1@
identifier r.cb;
@@

cb(...) {
 ...
}

@script:ocaml depends on !r1 && !r2@
cb << r.cb;
@@

Printf.eprintf "need definition for %s\n" cb
// </smpl>
====================

Acked-by: Paul E. McKenney <paulmck@kernel.org>
Acked-by: Vlastimil Babka <vbabka@suse.cz>
Link: https://patch.msgid.link/20241013201704.49576-1-Julia.Lawall@inria.fr
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
  • Loading branch information
Jakub Kicinski committed Oct 15, 2024
2 parents 1d30417 + 7bb3ecb commit 0241720
Show file tree
Hide file tree
Showing 5 changed files with 6 additions and 39 deletions.
9 changes: 1 addition & 8 deletions net/bridge/br_fdb.c
Original file line number Diff line number Diff line change
Expand Up @@ -73,13 +73,6 @@ static inline int has_expired(const struct net_bridge *br,
time_before_eq(fdb->updated + hold_time(br), jiffies);
}

static void fdb_rcu_free(struct rcu_head *head)
{
struct net_bridge_fdb_entry *ent
= container_of(head, struct net_bridge_fdb_entry, rcu);
kmem_cache_free(br_fdb_cache, ent);
}

static int fdb_to_nud(const struct net_bridge *br,
const struct net_bridge_fdb_entry *fdb)
{
Expand Down Expand Up @@ -329,7 +322,7 @@ static void fdb_delete(struct net_bridge *br, struct net_bridge_fdb_entry *f,
if (test_and_clear_bit(BR_FDB_DYNAMIC_LEARNED, &f->flags))
atomic_dec(&br->fdb_n_learned);
fdb_notify(br, f, RTM_DELNEIGH, swdev_notify);
call_rcu(&f->rcu, fdb_rcu_free);
kfree_rcu(f, rcu);
}

/* Delete a local entry if no other port had the same address.
Expand Down
8 changes: 1 addition & 7 deletions net/ipv4/fib_trie.c
Original file line number Diff line number Diff line change
Expand Up @@ -292,15 +292,9 @@ static const int inflate_threshold = 50;
static const int halve_threshold_root = 15;
static const int inflate_threshold_root = 30;

static void __alias_free_mem(struct rcu_head *head)
{
struct fib_alias *fa = container_of(head, struct fib_alias, rcu);
kmem_cache_free(fn_alias_kmem, fa);
}

static inline void alias_free_mem_rcu(struct fib_alias *fa)
{
call_rcu(&fa->rcu, __alias_free_mem);
kfree_rcu(fa, rcu);
}

#define TNODE_VMALLOC_MAX \
Expand Down
9 changes: 2 additions & 7 deletions net/ipv4/inetpeer.c
Original file line number Diff line number Diff line change
Expand Up @@ -128,11 +128,6 @@ static struct inet_peer *lookup(const struct inetpeer_addr *daddr,
return NULL;
}

static void inetpeer_free_rcu(struct rcu_head *head)
{
kmem_cache_free(peer_cachep, container_of(head, struct inet_peer, rcu));
}

/* perform garbage collect on all items stacked during a lookup */
static void inet_peer_gc(struct inet_peer_base *base,
struct inet_peer *gc_stack[],
Expand Down Expand Up @@ -168,7 +163,7 @@ static void inet_peer_gc(struct inet_peer_base *base,
if (p) {
rb_erase(&p->rb_node, &base->rb_root);
base->total--;
call_rcu(&p->rcu, inetpeer_free_rcu);
kfree_rcu(p, rcu);
}
}
}
Expand Down Expand Up @@ -242,7 +237,7 @@ void inet_putpeer(struct inet_peer *p)
WRITE_ONCE(p->dtime, (__u32)jiffies);

if (refcount_dec_and_test(&p->refcnt))
call_rcu(&p->rcu, inetpeer_free_rcu);
kfree_rcu(p, rcu);
}
EXPORT_SYMBOL_GPL(inet_putpeer);

Expand Down
9 changes: 1 addition & 8 deletions net/ipv6/ip6_fib.c
Original file line number Diff line number Diff line change
Expand Up @@ -198,16 +198,9 @@ static void node_free_immediate(struct net *net, struct fib6_node *fn)
net->ipv6.rt6_stats->fib_nodes--;
}

static void node_free_rcu(struct rcu_head *head)
{
struct fib6_node *fn = container_of(head, struct fib6_node, rcu);

kmem_cache_free(fib6_node_kmem, fn);
}

static void node_free(struct net *net, struct fib6_node *fn)
{
call_rcu(&fn->rcu, node_free_rcu);
kfree_rcu(fn, rcu);
net->ipv6.rt6_stats->fib_nodes--;
}

Expand Down
10 changes: 1 addition & 9 deletions net/kcm/kcmsock.c
Original file line number Diff line number Diff line change
Expand Up @@ -1584,14 +1584,6 @@ static int kcm_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
return err;
}

static void free_mux(struct rcu_head *rcu)
{
struct kcm_mux *mux = container_of(rcu,
struct kcm_mux, rcu);

kmem_cache_free(kcm_muxp, mux);
}

static void release_mux(struct kcm_mux *mux)
{
struct kcm_net *knet = mux->knet;
Expand Down Expand Up @@ -1619,7 +1611,7 @@ static void release_mux(struct kcm_mux *mux)
knet->count--;
mutex_unlock(&knet->mutex);

call_rcu(&mux->rcu, free_mux);
kfree_rcu(mux, rcu);
}

static void kcm_done(struct kcm_sock *kcm)
Expand Down

0 comments on commit 0241720

Please sign in to comment.