* [patch net 0/2] net: ipv4: fix couple of addr lifetime related bugs
@ 2013-04-05 9:39 Jiri Pirko
2013-04-05 9:39 ` [patch net 1/2] net: ipv4: reset check_lifetime_work after changing lifetime Jiri Pirko
` (2 more replies)
0 siblings, 3 replies; 4+ messages in thread
From: Jiri Pirko @ 2013-04-05 9:39 UTC (permalink / raw)
To: netdev; +Cc: davem, kuznet, jmorris, yoshfuji, kaber
Jiri Pirko (2):
net: ipv4: reset check_lifetime_work after changing lifetime
net: ipv4: fix schelude while atomic bug in check_lifetime()
net/ipv4/devinet.c | 60 +++++++++++++++++++++++++++++++++++++++---------------
1 file changed, 44 insertions(+), 16 deletions(-)
--
1.8.1.2
^ permalink raw reply [flat|nested] 4+ messages in thread
* [patch net 1/2] net: ipv4: reset check_lifetime_work after changing lifetime
2013-04-05 9:39 [patch net 0/2] net: ipv4: fix couple of addr lifetime related bugs Jiri Pirko
@ 2013-04-05 9:39 ` Jiri Pirko
2013-04-05 9:39 ` [patch net 2/2] net: ipv4: fix schedule while atomic bug in check_lifetime() Jiri Pirko
2013-04-08 16:05 ` [patch net 0/2] net: ipv4: fix couple of addr lifetime related bugs David Miller
2 siblings, 0 replies; 4+ messages in thread
From: Jiri Pirko @ 2013-04-05 9:39 UTC (permalink / raw)
To: netdev; +Cc: davem, kuznet, jmorris, yoshfuji, kaber
This will result in calling check_lifetime in nearest opportunity and
that function will adjust next time to call check_lifetime correctly.
Without this, check_lifetime is called in time computed by previous run,
not affecting modified lifetime.
Introduced by: commit 5c766d642bcaf "ipv4: introduce address lifetime"
Signed-off-by: Jiri Pirko <jiri@resnulli.us>
---
net/ipv4/devinet.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/net/ipv4/devinet.c b/net/ipv4/devinet.c
index 96083b7..00386e0 100644
--- a/net/ipv4/devinet.c
+++ b/net/ipv4/devinet.c
@@ -804,6 +804,8 @@ static int inet_rtm_newaddr(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg
return -EEXIST;
ifa = ifa_existing;
set_ifa_lifetime(ifa, valid_lft, prefered_lft);
+ cancel_delayed_work(&check_lifetime_work);
+ schedule_delayed_work(&check_lifetime_work, 0);
rtmsg_ifa(RTM_NEWADDR, ifa, nlh, NETLINK_CB(skb).portid);
blocking_notifier_call_chain(&inetaddr_chain, NETDEV_UP, ifa);
}
--
1.8.1.2
^ permalink raw reply related [flat|nested] 4+ messages in thread
* [patch net 2/2] net: ipv4: fix schedule while atomic bug in check_lifetime()
2013-04-05 9:39 [patch net 0/2] net: ipv4: fix couple of addr lifetime related bugs Jiri Pirko
2013-04-05 9:39 ` [patch net 1/2] net: ipv4: reset check_lifetime_work after changing lifetime Jiri Pirko
@ 2013-04-05 9:39 ` Jiri Pirko
2013-04-08 16:05 ` [patch net 0/2] net: ipv4: fix couple of addr lifetime related bugs David Miller
2 siblings, 0 replies; 4+ messages in thread
From: Jiri Pirko @ 2013-04-05 9:39 UTC (permalink / raw)
To: netdev; +Cc: davem, kuznet, jmorris, yoshfuji, kaber
move might_sleep operations out of the rcu_read_lock() section.
Also fix iterating over ifa_dev->ifa_list
Introduced by: commit 5c766d642bcaf "ipv4: introduce address lifetime"
Signed-off-by: Jiri Pirko <jiri@resnulli.us>
---
net/ipv4/devinet.c | 58 +++++++++++++++++++++++++++++++++++++++---------------
1 file changed, 42 insertions(+), 16 deletions(-)
diff --git a/net/ipv4/devinet.c b/net/ipv4/devinet.c
index 00386e0..c6287cd 100644
--- a/net/ipv4/devinet.c
+++ b/net/ipv4/devinet.c
@@ -587,13 +587,16 @@ static void check_lifetime(struct work_struct *work)
{
unsigned long now, next, next_sec, next_sched;
struct in_ifaddr *ifa;
+ struct hlist_node *n;
int i;
now = jiffies;
next = round_jiffies_up(now + ADDR_CHECK_FREQUENCY);
- rcu_read_lock();
for (i = 0; i < IN4_ADDR_HSIZE; i++) {
+ bool change_needed = false;
+
+ rcu_read_lock();
hlist_for_each_entry_rcu(ifa, &inet_addr_lst[i], hash) {
unsigned long age;
@@ -606,16 +609,7 @@ static void check_lifetime(struct work_struct *work)
if (ifa->ifa_valid_lft != INFINITY_LIFE_TIME &&
age >= ifa->ifa_valid_lft) {
- struct in_ifaddr **ifap ;
-
- rtnl_lock();
- for (ifap = &ifa->ifa_dev->ifa_list;
- *ifap != NULL; ifap = &ifa->ifa_next) {
- if (*ifap == ifa)
- inet_del_ifa(ifa->ifa_dev,
- ifap, 1);
- }
- rtnl_unlock();
+ change_needed = true;
} else if (ifa->ifa_preferred_lft ==
INFINITY_LIFE_TIME) {
continue;
@@ -625,10 +619,8 @@ static void check_lifetime(struct work_struct *work)
next = ifa->ifa_tstamp +
ifa->ifa_valid_lft * HZ;
- if (!(ifa->ifa_flags & IFA_F_DEPRECATED)) {
- ifa->ifa_flags |= IFA_F_DEPRECATED;
- rtmsg_ifa(RTM_NEWADDR, ifa, NULL, 0);
- }
+ if (!(ifa->ifa_flags & IFA_F_DEPRECATED))
+ change_needed = true;
} else if (time_before(ifa->ifa_tstamp +
ifa->ifa_preferred_lft * HZ,
next)) {
@@ -636,8 +628,42 @@ static void check_lifetime(struct work_struct *work)
ifa->ifa_preferred_lft * HZ;
}
}
+ rcu_read_unlock();
+ if (!change_needed)
+ continue;
+ rtnl_lock();
+ hlist_for_each_entry_safe(ifa, n, &inet_addr_lst[i], hash) {
+ unsigned long age;
+
+ if (ifa->ifa_flags & IFA_F_PERMANENT)
+ continue;
+
+ /* We try to batch several events at once. */
+ age = (now - ifa->ifa_tstamp +
+ ADDRCONF_TIMER_FUZZ_MINUS) / HZ;
+
+ if (ifa->ifa_valid_lft != INFINITY_LIFE_TIME &&
+ age >= ifa->ifa_valid_lft) {
+ struct in_ifaddr **ifap;
+
+ for (ifap = &ifa->ifa_dev->ifa_list;
+ *ifap != NULL; ifap = &(*ifap)->ifa_next) {
+ if (*ifap == ifa) {
+ inet_del_ifa(ifa->ifa_dev,
+ ifap, 1);
+ break;
+ }
+ }
+ } else if (ifa->ifa_preferred_lft !=
+ INFINITY_LIFE_TIME &&
+ age >= ifa->ifa_preferred_lft &&
+ !(ifa->ifa_flags & IFA_F_DEPRECATED)) {
+ ifa->ifa_flags |= IFA_F_DEPRECATED;
+ rtmsg_ifa(RTM_NEWADDR, ifa, NULL, 0);
+ }
+ }
+ rtnl_unlock();
}
- rcu_read_unlock();
next_sec = round_jiffies_up(next);
next_sched = next;
--
1.8.1.2
^ permalink raw reply related [flat|nested] 4+ messages in thread
* Re: [patch net 0/2] net: ipv4: fix couple of addr lifetime related bugs
2013-04-05 9:39 [patch net 0/2] net: ipv4: fix couple of addr lifetime related bugs Jiri Pirko
2013-04-05 9:39 ` [patch net 1/2] net: ipv4: reset check_lifetime_work after changing lifetime Jiri Pirko
2013-04-05 9:39 ` [patch net 2/2] net: ipv4: fix schedule while atomic bug in check_lifetime() Jiri Pirko
@ 2013-04-08 16:05 ` David Miller
2 siblings, 0 replies; 4+ messages in thread
From: David Miller @ 2013-04-08 16:05 UTC (permalink / raw)
To: jiri; +Cc: netdev, kuznet, jmorris, yoshfuji, kaber
From: Jiri Pirko <jiri@resnulli.us>
Date: Fri, 5 Apr 2013 11:39:37 +0200
> Jiri Pirko (2):
> net: ipv4: reset check_lifetime_work after changing lifetime
> net: ipv4: fix schelude while atomic bug in check_lifetime()
Both applied, thanks Jiri.
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2013-04-08 16:05 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2013-04-05 9:39 [patch net 0/2] net: ipv4: fix couple of addr lifetime related bugs Jiri Pirko
2013-04-05 9:39 ` [patch net 1/2] net: ipv4: reset check_lifetime_work after changing lifetime Jiri Pirko
2013-04-05 9:39 ` [patch net 2/2] net: ipv4: fix schedule while atomic bug in check_lifetime() Jiri Pirko
2013-04-08 16:05 ` [patch net 0/2] net: ipv4: fix couple of addr lifetime related bugs David Miller
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).