diff mbox series

ipv6: mcast: Add __must_hold() annotations.

Message ID 20240808190256.149602-1-bpappas@pappasbrent.com (mailing list archive)
State Changes Requested
Delegated to: Netdev Maintainers
Headers show
Series ipv6: mcast: Add __must_hold() annotations. | expand

Checks

Context Check Description
netdev/series_format warning Single patches do not need cover letters; Target tree name not specified in the subject
netdev/tree_selection success Guessed tree name to be net-next
netdev/ynl success Generated files up to date; no warnings/errors; no diff in generated;
netdev/fixes_present success Fixes tag not required for -next series
netdev/header_inline success No static functions without inline keyword in header files
netdev/build_32bit success Errors and warnings before: 29 this patch: 29
netdev/build_tools success No tools touched, skip
netdev/cc_maintainers success CCed 5 of 5 maintainers
netdev/build_clang success Errors and warnings before: 29 this patch: 29
netdev/verify_signedoff success Signed-off-by tag matches author and committer
netdev/deprecated_api success None detected
netdev/check_selftest success No net selftest shell script
netdev/verify_fixes success No Fixes tag
netdev/build_allmodconfig_warn success Errors and warnings before: 30 this patch: 30
netdev/checkpatch success total: 0 errors, 0 warnings, 0 checks, 31 lines checked
netdev/build_clang_rust success No Rust files in patch. Skipping build
netdev/kdoc success Errors and warnings before: 0 this patch: 0
netdev/source_inline success Was 0 now: 0
netdev/contest success net-next-2024-08-09--09-00 (tests: 705)

Commit Message

Brent Pappas Aug. 8, 2024, 7:02 p.m. UTC
Add __must_hold(RCU) annotations to igmp6_mc_get_first(),
igmp6_mc_get_next(), and igmp6_mc_get_idx() to signify that they are
meant to be called in RCU critical sections.

Signed-off-by: Brent Pappas <bpappas@pappasbrent.com>
---
 net/ipv6/mcast.c | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

Comments

Kuniyuki Iwashima Aug. 8, 2024, 8:23 p.m. UTC | #1
From: Brent Pappas <bpappas@pappasbrent.com>
Date: Thu,  8 Aug 2024 15:02:55 -0400
> Add __must_hold(RCU) annotations to igmp6_mc_get_first(),
> igmp6_mc_get_next(), and igmp6_mc_get_idx() to signify that they are
> meant to be called in RCU critical sections.
> 
> Signed-off-by: Brent Pappas <bpappas@pappasbrent.com>
> ---
>  net/ipv6/mcast.c | 7 ++++++-
>  1 file changed, 6 insertions(+), 1 deletion(-)
> 
> diff --git a/net/ipv6/mcast.c b/net/ipv6/mcast.c
> index 7ba01d8cfbae..843d0d065242 100644
> --- a/net/ipv6/mcast.c
> +++ b/net/ipv6/mcast.c
> @@ -22,6 +22,7 @@
>   *		- MLDv2 support
>   */
>  
> +#include "linux/compiler_types.h"

Why "" ?

Btw, I think for_each_netdev_rcu() / rcu_dereference() in touched
functions are enough to cleary annotate RCU is needed there.

Even without it, I prefer rcu_read_lock_held(), I'm not sure to
what extent sparse can analyse functions statically though.


>  #include <linux/module.h>
>  #include <linux/errno.h>
>  #include <linux/types.h>
> @@ -2861,6 +2862,7 @@ struct igmp6_mc_iter_state {
>  #define igmp6_mc_seq_private(seq)	((struct igmp6_mc_iter_state *)(seq)->private)
>  
>  static inline struct ifmcaddr6 *igmp6_mc_get_first(struct seq_file *seq)
> +	__must_hold(RCU)
>  {
>  	struct ifmcaddr6 *im = NULL;
>  	struct igmp6_mc_iter_state *state = igmp6_mc_seq_private(seq);
> @@ -2882,7 +2884,9 @@ static inline struct ifmcaddr6 *igmp6_mc_get_first(struct seq_file *seq)
>  	return im;
>  }
>  
> -static struct ifmcaddr6 *igmp6_mc_get_next(struct seq_file *seq, struct ifmcaddr6 *im)
> +static struct ifmcaddr6 *igmp6_mc_get_next(struct seq_file *seq,
> +					   struct ifmcaddr6 *im)
> +	__must_hold(RCU)
>  {
>  	struct igmp6_mc_iter_state *state = igmp6_mc_seq_private(seq);
>  
> @@ -2902,6 +2906,7 @@ static struct ifmcaddr6 *igmp6_mc_get_next(struct seq_file *seq, struct ifmcaddr
>  }
>  
>  static struct ifmcaddr6 *igmp6_mc_get_idx(struct seq_file *seq, loff_t pos)
> +	__must_hold(RCU)
>  {
>  	struct ifmcaddr6 *im = igmp6_mc_get_first(seq);
>  	if (im)
> -- 
> 2.46.0
Brent Pappas Aug. 8, 2024, 11:14 p.m. UTC | #2
The 08/08/2024 13:23, Kuniyuki Iwashima wrote:
> From: Brent Pappas <bpappas@pappasbrent.com>
> Date: Thu,  8 Aug 2024 15:02:55 -0400
> > Add __must_hold(RCU) annotations to igmp6_mc_get_first(),
> > igmp6_mc_get_next(), and igmp6_mc_get_idx() to signify that they are
> > meant to be called in RCU critical sections.
> > 
> > Signed-off-by: Brent Pappas <bpappas@pappasbrent.com>
> > ---
> >  net/ipv6/mcast.c | 7 ++++++-
> >  1 file changed, 6 insertions(+), 1 deletion(-)
> > 
> > diff --git a/net/ipv6/mcast.c b/net/ipv6/mcast.c
> > index 7ba01d8cfbae..843d0d065242 100644
> > --- a/net/ipv6/mcast.c
> > +++ b/net/ipv6/mcast.c
> > @@ -22,6 +22,7 @@
> >   *		- MLDv2 support
> >   */
> >  
> > +#include "linux/compiler_types.h"
> Why "" ?

That was an accident; my language server (clangd) inserted the include
for me while I was typing and included the header with quotes instead of
angle brackets. I will submit a corrected patch if that will make this
change acceptable.

> Btw, I think for_each_netdev_rcu() / rcu_dereference() in touched
> functions are enough to cleary annotate RCU is needed there.

I see your point. I noticed that igmp6_mc_seq_start() calls
rcu_read_lock() and is annotated with __acquires(), and
igmp6_mc_seq_stop() calls rcu_read_unlock() and is annotated with
__releases(), so it seemed to me that the extra __must_hold()
annotations would be preferable. Unless there's a reason to prefer
__acquires() and __releases() over __must_hold()?

> Even without it, I prefer rcu_read_lock_held(), I'm not sure to
> what extent sparse can analyse functions statically though.

AFAIK, Sparse only uses these annotations to check for context
imbalances, and does not check, e.g., whether macros that access shared
values such as rcu_dereference() are only invoked in critical sections.
Full disclosure, I am working on a static analysis tool called Macroni
to provide more static checks for RCU (this is how I found these
unannotated functions).

> >  #include <linux/module.h>
> >  #include <linux/errno.h>
> >  #include <linux/types.h>
> > @@ -2861,6 +2862,7 @@ struct igmp6_mc_iter_state {
> >  #define igmp6_mc_seq_private(seq)	((struct igmp6_mc_iter_state *)(seq)->private)
> >  
> >  static inline struct ifmcaddr6 *igmp6_mc_get_first(struct seq_file *seq)
> > +	__must_hold(RCU)
> >  {
> >  	struct ifmcaddr6 *im = NULL;
> >  	struct igmp6_mc_iter_state *state = igmp6_mc_seq_private(seq);
> > @@ -2882,7 +2884,9 @@ static inline struct ifmcaddr6 *igmp6_mc_get_first(struct seq_file *seq)
> >  	return im;
> >  }
> >  
> > -static struct ifmcaddr6 *igmp6_mc_get_next(struct seq_file *seq, struct ifmcaddr6 *im)
> > +static struct ifmcaddr6 *igmp6_mc_get_next(struct seq_file *seq,
> > +					   struct ifmcaddr6 *im)
> > +	__must_hold(RCU)
> >  {
> >  	struct igmp6_mc_iter_state *state = igmp6_mc_seq_private(seq);
> >  
> > @@ -2902,6 +2906,7 @@ static struct ifmcaddr6 *igmp6_mc_get_next(struct seq_file *seq, struct ifmcaddr
> >  }
> >  
> >  static struct ifmcaddr6 *igmp6_mc_get_idx(struct seq_file *seq, loff_t pos)
> > +	__must_hold(RCU)
> >  {
> >  	struct ifmcaddr6 *im = igmp6_mc_get_first(seq);
> >  	if (im)
> > -- 
> > 2.46.0
diff mbox series

Patch

diff --git a/net/ipv6/mcast.c b/net/ipv6/mcast.c
index 7ba01d8cfbae..843d0d065242 100644
--- a/net/ipv6/mcast.c
+++ b/net/ipv6/mcast.c
@@ -22,6 +22,7 @@ 
  *		- MLDv2 support
  */
 
+#include "linux/compiler_types.h"
 #include <linux/module.h>
 #include <linux/errno.h>
 #include <linux/types.h>
@@ -2861,6 +2862,7 @@  struct igmp6_mc_iter_state {
 #define igmp6_mc_seq_private(seq)	((struct igmp6_mc_iter_state *)(seq)->private)
 
 static inline struct ifmcaddr6 *igmp6_mc_get_first(struct seq_file *seq)
+	__must_hold(RCU)
 {
 	struct ifmcaddr6 *im = NULL;
 	struct igmp6_mc_iter_state *state = igmp6_mc_seq_private(seq);
@@ -2882,7 +2884,9 @@  static inline struct ifmcaddr6 *igmp6_mc_get_first(struct seq_file *seq)
 	return im;
 }
 
-static struct ifmcaddr6 *igmp6_mc_get_next(struct seq_file *seq, struct ifmcaddr6 *im)
+static struct ifmcaddr6 *igmp6_mc_get_next(struct seq_file *seq,
+					   struct ifmcaddr6 *im)
+	__must_hold(RCU)
 {
 	struct igmp6_mc_iter_state *state = igmp6_mc_seq_private(seq);
 
@@ -2902,6 +2906,7 @@  static struct ifmcaddr6 *igmp6_mc_get_next(struct seq_file *seq, struct ifmcaddr
 }
 
 static struct ifmcaddr6 *igmp6_mc_get_idx(struct seq_file *seq, loff_t pos)
+	__must_hold(RCU)
 {
 	struct ifmcaddr6 *im = igmp6_mc_get_first(seq);
 	if (im)