/proc/net/igmp6 walks IPv6 multicast memberships under RCU and reads mca_work.timer.expires to print the remaining multicast timer. The delayed-work timer can be updated concurrently. Annotate the intentional lockless procfs snapshot with READ_ONCE(). Signed-off-by: Yuyang Huang --- net/ipv6/mcast.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/net/ipv6/mcast.c b/net/ipv6/mcast.c index bd3972730aa0..04b811b3be97 100644 --- a/net/ipv6/mcast.c +++ b/net/ipv6/mcast.c @@ -2984,6 +2984,7 @@ static int igmp6_mc_seq_show(struct seq_file *seq, void *v) struct ifmcaddr6 *im = (struct ifmcaddr6 *)v; struct igmp6_mc_iter_state *state = igmp6_mc_seq_private(seq); unsigned int mca_flags = READ_ONCE(im->mca_flags); + unsigned long expires = READ_ONCE(im->mca_work.timer.expires); seq_printf(seq, "%-4d %-15s %pi6 %5d %08X %ld\n", @@ -2991,7 +2992,7 @@ static int igmp6_mc_seq_show(struct seq_file *seq, void *v) &im->mca_addr, READ_ONCE(im->mca_users), mca_flags, (mca_flags & MAF_TIMER_RUNNING) ? - jiffies_to_clock_t(im->mca_work.timer.expires - jiffies) : 0); + jiffies_to_clock_t(expires - jiffies) : 0); return 0; } -- 2.43.0