linux-mm.kvack.org archive mirror
 help / color / mirror / Atom feed
From: Uladzislau Rezki <urezki@gmail.com>
To: Julia Lawall <julia.lawall@inria.fr>
Cc: Uladzislau Rezki <urezki@gmail.com>,
	"Paul E. McKenney" <paulmck@kernel.org>,
	Vlastimil Babka <vbabka@suse.cz>,
	"linux-mm@kvack.org" <linux-mm@kvack.org>,
	RCU <rcu@vger.kernel.org>,
	cocci@inria.fr
Subject: Re: [cocci] patch idea: convert trivial call_rcu users to kfree_rcu
Date: Tue, 28 May 2024 15:21:02 +0200	[thread overview]
Message-ID: <ZlXaPuA4lC2ANTdN@pc636> (raw)
In-Reply-To: <2dd5bafb-ceb1-238d-2f51-83ebf135b73@inria.fr>

On Tue, May 28, 2024 at 02:08:20PM +0200, Julia Lawall wrote:
> 
> 
> On Tue, 28 May 2024, Uladzislau Rezki wrote:
> 
> > Hello.
> >
> > >
> > >
> > > On Mon, 27 May 2024, Paul E. McKenney wrote:
> > >
> > > > On Mon, May 27, 2024 at 10:13:40AM +0200, Julia Lawall wrote:
> > > > >
> > > > >
> > > > > On Mon, 27 May 2024, Vlastimil Babka wrote:
> > > > >
> > > > > > Hi,
> > > > > >
> > > > > > one bit from LSF/MM discussions is that there might be call_rcu users with a
> > > > > > callback that only does a kmem_cache_free() to a specific cache. Since SLOB
> > > > > > was removed, it's always ok to use kfree() and thus also kfree_rcu() on
> > > > > > allocations from kmem_cache_alloc() in addition to kmalloc(). Thus, such
> > > > > > call_rcu() users might be simplified to kfree_rcu(). I found some cases
> > > > > > semi-manually, but I'd expect coccinelle could help here so if anyone wants
> > > > > > to take this task, feel free to.
> > > > >
> > > > > Thanks for the suggestion!  I will try to look into it.
> > > >
> > > > Thank you both!
> > >
> > > I found the following functions.  Do you want some other information, such
> > > as where they are called from?
> > >
> > > Ignore the -s at the beginning of some lines.  Those are for emphasis. not
> > > to suggest to remove the code.
> > >
> > > I checked that the functions are only used in calls to call_rcu.
> > >
> > > Without more effort, Coccinelle only looks for functions defined in the
> > > same file.  Here are the functions that are passed to call_rcu where the
> > > function is not defined in the same file:
> > >
> > > need definition for audit_free_rule_rcu
> > > need definition for __i915_gem_free_object_rcu
> > > need definition for io_eventfd_ops
> > > need definition for ip_vs_dest_dst_rcu_free
> > > need definition for __put_task_struct_rcu_cb
> > > need definition for radix_tree_node_rcu_free
> > >
> > > They all do something more, although radix_tree_node_rcu_free doesn't do
> > > much more (some memsets).
> > >
> > > julia
> > >
> > > diff -u -p /home/jll/linux/drivers/net/wireguard/allowedips.c /tmp/nothing/drivers/net/wireguard/allowedips.c
> > > --- /home/jll/linux/drivers/net/wireguard/allowedips.c
> > > +++ /tmp/nothing/drivers/net/wireguard/allowedips.c
> > > @@ -50,7 +50,6 @@ static void push_rcu(struct allowedips_n
> > >
> > >  static void node_free_rcu(struct rcu_head *rcu)
> > >  {
> > > -	kmem_cache_free(node_cache, container_of(rcu, struct allowedips_node, rcu));
> > >  }
> > >
> > >  static void root_free_rcu(struct rcu_head *rcu)
> > > diff -u -p /home/jll/linux/fs/ecryptfs/dentry.c /tmp/nothing/fs/ecryptfs/dentry.c
> > > --- /home/jll/linux/fs/ecryptfs/dentry.c
> > > +++ /tmp/nothing/fs/ecryptfs/dentry.c
> > > @@ -53,8 +53,6 @@ struct kmem_cache *ecryptfs_dentry_info_
> > >
> > >  static void ecryptfs_dentry_free_rcu(struct rcu_head *head)
> > >  {
> > > -	kmem_cache_free(ecryptfs_dentry_info_cache,
> > > -		container_of(head, struct ecryptfs_dentry_info, rcu));
> > >  }
> > >
> > >  /**
> > > diff -u -p /home/jll/linux/kernel/fork.c /tmp/nothing/kernel/fork.c
> > > --- /home/jll/linux/kernel/fork.c
> > > +++ /tmp/nothing/kernel/fork.c
> > > @@ -378,7 +378,6 @@ static struct kmem_cache *thread_stack_c
> > >
> > >  static void thread_stack_free_rcu(struct rcu_head *rh)
> > >  {
> > > -	kmem_cache_free(thread_stack_cache, rh);
> > >  }
> > >
> > >  static void thread_stack_delayed_free(struct task_struct *tsk)
> > > diff -u -p /home/jll/linux/kernel/workqueue.c /tmp/nothing/kernel/workqueue.c
> > > --- /home/jll/linux/kernel/workqueue.c
> > > +++ /tmp/nothing/kernel/workqueue.c
> > > @@ -5024,8 +5024,6 @@ fail:
> > >
> > >  static void rcu_free_pwq(struct rcu_head *rcu)
> > >  {
> > > -	kmem_cache_free(pwq_cache,
> > > -			container_of(rcu, struct pool_workqueue, rcu));
> > >  }
> > >
> > >  /*
> > > diff -u -p /home/jll/linux/net/ipv4/inetpeer.c /tmp/nothing/net/ipv4/inetpeer.c
> > > --- /home/jll/linux/net/ipv4/inetpeer.c
> > > +++ /tmp/nothing/net/ipv4/inetpeer.c
> > > @@ -130,7 +130,6 @@ static struct inet_peer *lookup(const st
> > >
> > >  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 */
> > > diff -u -p /home/jll/linux/net/ipv6/xfrm6_tunnel.c /tmp/nothing/net/ipv6/xfrm6_tunnel.c
> > > --- /home/jll/linux/net/ipv6/xfrm6_tunnel.c
> > > +++ /tmp/nothing/net/ipv6/xfrm6_tunnel.c
> > > @@ -180,8 +180,6 @@ EXPORT_SYMBOL(xfrm6_tunnel_alloc_spi);
> > >
> > >  static void x6spi_destroy_rcu(struct rcu_head *head)
> > >  {
> > > -	kmem_cache_free(xfrm6_tunnel_spi_kmem,
> > > -			container_of(head, struct xfrm6_tunnel_spi, rcu_head));
> > >  }
> > >
> > >  static void xfrm6_tunnel_free_spi(struct net *net, xfrm_address_t *saddr)
> > > diff -u -p /home/jll/linux/security/security.c /tmp/nothing/security/security.c
> > > --- /home/jll/linux/security/security.c
> > > +++ /tmp/nothing/security/security.c
> > > @@ -1599,7 +1599,6 @@ static void inode_free_by_rcu(struct rcu
> > >  	/*
> > >  	 * The rcu head is at the start of the inode blob
> > >  	 */
> > > -	kmem_cache_free(lsm_inode_cache, head);
> > >  }
> > >
> > >  /**
> > >
> > See below some extra functions which can be eliminated. How i found them:
> >
> > find ./ -name "*.c" -o -name "*.h" | xargs grep -rn call_rcu -B 10 | grep kmem_cache_free
> >
> > <snip>
> >  static void nfsd4_free_file_rcu(struct rcu_head *rcu);
> 
> Thanks.  I tried to find this kind of issue, but it turned up nothing.
> There must be some mistake, and I will try again.
> 
You are welcome. Also there are several places like below:

<snip>
static void blk_free_queue_rcu(struct rcu_head *rcu_head)
{
        struct request_queue *q = container_of(rcu_head,
                        struct request_queue, rcu_head);

        percpu_ref_exit(&q->q_usage_counter);
        kmem_cache_free(blk_requestq_cachep, q);
}

static void blk_free_queue(struct request_queue *q)
{
        blk_free_queue_stats(q->stats);
        if (queue_is_mq(q))
                blk_mq_release(q);

        ida_free(&blk_queue_ida, q->id);
        call_rcu(&q->rcu_head, blk_free_queue_rcu);
}
<snip>

and potentially it can be also replaced:

<snip>
diff --git a/block/blk-core.c b/block/blk-core.c
index 82c3ae22d76d..898d6990600d 100644
--- a/block/blk-core.c
+++ b/block/blk-core.c
@@ -257,15 +257,6 @@ void blk_clear_pm_only(struct request_queue *q)
 }
 EXPORT_SYMBOL_GPL(blk_clear_pm_only);

-static void blk_free_queue_rcu(struct rcu_head *rcu_head)
-{
-       struct request_queue *q = container_of(rcu_head,
-                       struct request_queue, rcu_head);
-
-       percpu_ref_exit(&q->q_usage_counter);
-       kmem_cache_free(blk_requestq_cachep, q);
-}
-
 static void blk_free_queue(struct request_queue *q)
 {
        blk_free_queue_stats(q->stats);
@@ -273,7 +264,8 @@ static void blk_free_queue(struct request_queue *q)
                blk_mq_release(q);

        ida_free(&blk_queue_ida, q->id);
-       call_rcu(&q->rcu_head, blk_free_queue_rcu);
+       percpu_ref_exit(&q->q_usage_counter);
+       kfree_rcu(q, rcu_head);
 }

 /**
<snip>

but a maintainer of "blk-core.c" should check it if a usage counter can
be updated before a completion of GP.

Probably we can skip as of now such cases, so i do not have a strong
opinion here.

--
Uladzislau Rezki


  reply	other threads:[~2024-05-28 13:21 UTC|newest]

Thread overview: 24+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-05-27  7:46 Vlastimil Babka
2024-05-27  8:13 ` [cocci] " Julia Lawall
2024-05-27 19:27   ` Paul E. McKenney
2024-05-27 19:46     ` Uladzislau Rezki
2024-05-27 19:51       ` Julia Lawall
2024-05-27 20:36         ` Uladzislau Rezki
2024-05-27 20:43     ` Julia Lawall
2024-05-27 21:48       ` Paul E. McKenney
2024-05-28  5:09         ` Julia Lawall
2024-05-28 12:03       ` Uladzislau Rezki
2024-05-28 12:08         ` Julia Lawall
2024-05-28 13:21           ` Uladzislau Rezki [this message]
2024-05-28 14:29             ` Paul E. McKenney
2024-05-31 16:02               ` Julia Lawall
2024-06-03 17:25                 ` Paul E. McKenney
2024-06-03 19:29                 ` Vlastimil Babka
2024-06-03 19:51                   ` Julia Lawall
2024-06-04 11:26                 ` Uladzislau Rezki
2024-06-09  8:32                   ` Julia Lawall
2024-06-09 10:00                   ` Julia Lawall
2024-06-09 17:03                     ` Paul E. McKenney
2024-06-11 16:40                       ` Uladzislau Rezki
2024-06-11 17:25                         ` Paul E. McKenney
2024-06-11 17:27                           ` Uladzislau Rezki

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=ZlXaPuA4lC2ANTdN@pc636 \
    --to=urezki@gmail.com \
    --cc=cocci@inria.fr \
    --cc=julia.lawall@inria.fr \
    --cc=linux-mm@kvack.org \
    --cc=paulmck@kernel.org \
    --cc=rcu@vger.kernel.org \
    --cc=vbabka@suse.cz \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox