From: Tejaswi Tanikella <tejaswit@codeaurora.org>
To: netdev@vger.kernel.org, f.fainelli@gmail.com
Cc: andrew@lunn.ch, davem@davemloft.net
Subject: [PATCH net 1/2] ipv4: igmp: use alarmtimer to prevent delayed reports
Date: Mon, 11 Jun 2018 17:21:05 +0530 [thread overview]
Message-ID: <20180611115058.GA12452@tejaswit-linux.qualcomm.com> (raw)
On receiving a IGMPv2/v3 query, based on max_delay set in the header a
timer is started to send out a response after a random time within
max_delay. If the system then moves into suspend state, Report is
delayed until system wakes up.
Use a alarmtimer instead of using a timer. Alarmtimer will wake the
system up from suspend to send out the IGMP report.
Signed-off-by: Tejaswi Tanikella <tejaswit@codeaurora.org>
---
v2: use alarmtimer instead of wakelock.
---
If these changes are fine, I'll share similar patches for MLD and ARP.
---
include/linux/igmp.h | 7 ++++++-
net/ipv4/igmp.c | 27 ++++++++++++++++-----------
2 files changed, 22 insertions(+), 12 deletions(-)
diff --git a/include/linux/igmp.h b/include/linux/igmp.h
index f823185..45852eb 100644
--- a/include/linux/igmp.h
+++ b/include/linux/igmp.h
@@ -20,6 +20,9 @@
#include <linux/in.h>
#include <linux/refcount.h>
#include <uapi/linux/igmp.h>
+#ifdef CONFIG_IP_MULTICAST
+#include <linux/alarmtimer.h>
+#endif
static inline struct igmphdr *igmp_hdr(const struct sk_buff *skb)
{
@@ -83,7 +86,9 @@ struct ip_mc_list {
struct ip_mc_list __rcu *next_rcu;
};
struct ip_mc_list __rcu *next_hash;
- struct timer_list timer;
+#ifdef CONFIG_IP_MULTICAST
+ struct alarm alarm;
+#endif
int users;
refcount_t refcnt;
spinlock_t lock;
diff --git a/net/ipv4/igmp.c b/net/ipv4/igmp.c
index 85b617b..c30b5c4 100644
--- a/net/ipv4/igmp.c
+++ b/net/ipv4/igmp.c
@@ -199,7 +199,7 @@ static void ip_ma_put(struct ip_mc_list *im)
static void igmp_stop_timer(struct ip_mc_list *im)
{
spin_lock_bh(&im->lock);
- if (del_timer(&im->timer))
+ if (alarm_cancel(&im->alarm))
refcount_dec(&im->refcnt);
im->tm_running = 0;
im->reporter = 0;
@@ -210,11 +210,11 @@ static void igmp_stop_timer(struct ip_mc_list *im)
/* It must be called with locked im->lock */
static void igmp_start_timer(struct ip_mc_list *im, int max_delay)
{
- int tv = prandom_u32() % max_delay;
+ ktime_t expiry = jiffies_to_ktime(prandom_u32() % max_delay + 2);
im->tm_running = 1;
- if (!mod_timer(&im->timer, jiffies+tv+2))
- refcount_inc(&im->refcnt);
+ alarm_start_relative(&im->alarm, expiry);
+ refcount_inc(&im->refcnt);
}
static void igmp_gq_start_timer(struct in_device *in_dev)
@@ -241,11 +241,14 @@ static void igmp_ifc_start_timer(struct in_device *in_dev, int delay)
static void igmp_mod_timer(struct ip_mc_list *im, int max_delay)
{
+ ktime_t expiry;
+
spin_lock_bh(&im->lock);
im->unsolicit_count = 0;
- if (del_timer(&im->timer)) {
- if ((long)(im->timer.expires-jiffies) < max_delay) {
- add_timer(&im->timer);
+ expiry = alarm_expires_remaining(&im->alarm);
+ if (alarm_cancel(&im->alarm)) {
+ if (ktime_to_jiffies(expiry) < max_delay) {
+ alarm_start_relative(&im->alarm, expiry);
im->tm_running = 1;
spin_unlock_bh(&im->lock);
return;
@@ -812,9 +815,9 @@ static void igmp_ifc_event(struct in_device *in_dev)
}
-static void igmp_timer_expire(struct timer_list *t)
+enum alarmtimer_restart igmp_timer_expire(struct alarm *alarm, ktime_t now)
{
- struct ip_mc_list *im = from_timer(im, t, timer);
+ struct ip_mc_list *im = container_of(alarm, struct ip_mc_list, alarm);
struct in_device *in_dev = im->interface;
spin_lock(&im->lock);
@@ -835,6 +838,8 @@ static void igmp_timer_expire(struct timer_list *t)
igmp_send_report(in_dev, im, IGMPV3_HOST_MEMBERSHIP_REPORT);
ip_ma_put(im);
+
+ return ALARMTIMER_NORESTART;
}
/* mark EXCLUDE-mode sources */
@@ -1413,7 +1418,7 @@ void ip_mc_inc_group(struct in_device *in_dev, __be32 addr)
refcount_set(&im->refcnt, 1);
spin_lock_init(&im->lock);
#ifdef CONFIG_IP_MULTICAST
- timer_setup(&im->timer, igmp_timer_expire, 0);
+ alarm_init(&im->alarm, ALARM_BOOTTIME, igmp_timer_expire);
im->unsolicit_count = net->ipv4.sysctl_igmp_qrv;
#endif
@@ -2811,7 +2816,7 @@ static int igmp_mc_seq_show(struct seq_file *seq, void *v)
state->dev->ifindex, state->dev->name, state->in_dev->mc_count, querier);
}
- delta = im->timer.expires - jiffies;
+ delta = ktime_to_jiffies(alarm_expires_remaining(&im->alarm));
seq_printf(seq,
"\t\t\t\t%08X %5d %d:%08lX\t\t%d\n",
im->multiaddr, im->users,
--
1.9.1
next reply other threads:[~2018-06-11 11:51 UTC|newest]
Thread overview: 11+ messages / expand[flat|nested] mbox.gz Atom feed top
2018-06-11 11:51 Tejaswi Tanikella [this message]
2018-06-11 11:52 ` [PATCH 2/2] ktime: helpers to convert between ktime and jiffies Tejaswi Tanikella
2018-06-12 16:30 ` Andrew Lunn
2018-06-13 13:35 ` Tejaswi Tanikella
2018-06-13 16:51 ` Florian Fainelli
2018-06-11 13:25 ` [PATCH net 1/2] ipv4: igmp: use alarmtimer to prevent delayed reports kbuild test robot
2018-06-11 13:25 ` kbuild test robot
2018-06-12 16:28 ` Andrew Lunn
2018-06-13 13:32 ` Tejaswi Tanikella
2018-06-13 14:44 ` Andrew Lunn
2018-06-14 13:14 ` Tejaswi Tanikella
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=20180611115058.GA12452@tejaswit-linux.qualcomm.com \
--to=tejaswit@codeaurora.org \
--cc=andrew@lunn.ch \
--cc=davem@davemloft.net \
--cc=f.fainelli@gmail.com \
--cc=netdev@vger.kernel.org \
/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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.