netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] ipv6/addrconf: speedup /proc/net/if_inet6 filling
@ 2012-01-04  9:31 Mihai Maruseac
  2012-01-04 16:22 ` Stephen Hemminger
  2012-01-04 21:01 ` David Miller
  0 siblings, 2 replies; 5+ messages in thread
From: Mihai Maruseac @ 2012-01-04  9:31 UTC (permalink / raw)
  To: davem
  Cc: eric.dumazet, kuznet, jmorris, yoshfuji, kaber, netdev,
	mihai.maruseac, Mihai Maruseac, Daniel Baluta

This ensures a linear behaviour when filling /proc/net/if_inet6 thus making
ifconfig run really fast on IPv6 only addresses. In fact, with this patch and
the IPv4 one sent a while ago, ifconfig will run in linear time regardless of
address type.

IPv4 related patch: f04565ddf52e401880f8ba51de0dff8ba51c99fd
	 dev: use name hash for dev_seq_ops
	 ...

Some statistics (running ifconfig > /dev/null on a different setup):

iface count / IPv6 no-patch time / IPv6 patched time / IPv4 time
----------------------------------------------------------------
      6250  |       0.23 s       |      0.13 s       |  0.11 s
     12500  |       0.62 s       |      0.28 s       |  0.22 s
     25000  |       2.91 s       |      0.57 s       |  0.46 s
     50000  |      11.37 s       |      1.21 s       |  0.94 s
    128000  |      86.78 s       |      3.05 s       |  2.54 s

Signed-off-by: Mihai Maruseac <mmaruseac@ixiacom.com>
Cc: Daniel Baluta <dbaluta@ixiacom.com>
---
 net/ipv6/addrconf.c |   43 ++++++++++++++++++++++++++++---------------
 1 files changed, 28 insertions(+), 15 deletions(-)

diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
index 59a9d0e..adb972a 100644
--- a/net/ipv6/addrconf.c
+++ b/net/ipv6/addrconf.c
@@ -3078,20 +3078,39 @@ static void addrconf_dad_run(struct inet6_dev *idev)
 struct if6_iter_state {
 	struct seq_net_private p;
 	int bucket;
+	int offset;
 };
 
-static struct inet6_ifaddr *if6_get_first(struct seq_file *seq)
+static struct inet6_ifaddr *if6_get_first(struct seq_file *seq, loff_t pos)
 {
 	struct inet6_ifaddr *ifa = NULL;
 	struct if6_iter_state *state = seq->private;
 	struct net *net = seq_file_net(seq);
+	int p = 0;
 
-	for (state->bucket = 0; state->bucket < IN6_ADDR_HSIZE; ++state->bucket) {
+	/* initial bucket if pos is 0 */
+	if (pos == 0) {
+		state->bucket = 0;
+		state->offset = 0;
+	}
+
+	for (; state->bucket < IN6_ADDR_HSIZE; ++state->bucket) {
 		struct hlist_node *n;
 		hlist_for_each_entry_rcu_bh(ifa, n, &inet6_addr_lst[state->bucket],
-					 addr_lst)
+					 addr_lst) {
+			/* sync with offset */
+			if (p < state->offset) {
+				p++;
+				continue;
+			}
+			state->offset++;
 			if (net_eq(dev_net(ifa->idev->dev), net))
 				return ifa;
+		}
+
+		/* prepare for next bucket */
+		state->offset = 0;
+		p = 0;
 	}
 	return NULL;
 }
@@ -3103,13 +3122,17 @@ static struct inet6_ifaddr *if6_get_next(struct seq_file *seq,
 	struct net *net = seq_file_net(seq);
 	struct hlist_node *n = &ifa->addr_lst;
 
-	hlist_for_each_entry_continue_rcu_bh(ifa, n, addr_lst)
+	hlist_for_each_entry_continue_rcu_bh(ifa, n, addr_lst) {
+		state->offset++;
 		if (net_eq(dev_net(ifa->idev->dev), net))
 			return ifa;
+	}
 
 	while (++state->bucket < IN6_ADDR_HSIZE) {
+		state->offset = 0;
 		hlist_for_each_entry_rcu_bh(ifa, n,
 				     &inet6_addr_lst[state->bucket], addr_lst) {
+			state->offset++;
 			if (net_eq(dev_net(ifa->idev->dev), net))
 				return ifa;
 		}
@@ -3118,21 +3141,11 @@ static struct inet6_ifaddr *if6_get_next(struct seq_file *seq,
 	return NULL;
 }
 
-static struct inet6_ifaddr *if6_get_idx(struct seq_file *seq, loff_t pos)
-{
-	struct inet6_ifaddr *ifa = if6_get_first(seq);
-
-	if (ifa)
-		while (pos && (ifa = if6_get_next(seq, ifa)) != NULL)
-			--pos;
-	return pos ? NULL : ifa;
-}
-
 static void *if6_seq_start(struct seq_file *seq, loff_t *pos)
 	__acquires(rcu_bh)
 {
 	rcu_read_lock_bh();
-	return if6_get_idx(seq, *pos);
+	return if6_get_first(seq, *pos);
 }
 
 static void *if6_seq_next(struct seq_file *seq, void *v, loff_t *pos)
-- 
1.7.4.1

^ permalink raw reply related	[flat|nested] 5+ messages in thread

* Re: [PATCH] ipv6/addrconf: speedup /proc/net/if_inet6 filling
  2012-01-04  9:31 [PATCH] ipv6/addrconf: speedup /proc/net/if_inet6 filling Mihai Maruseac
@ 2012-01-04 16:22 ` Stephen Hemminger
  2012-01-04 17:03   ` Mihai Maruseac
  2012-01-04 21:01 ` David Miller
  1 sibling, 1 reply; 5+ messages in thread
From: Stephen Hemminger @ 2012-01-04 16:22 UTC (permalink / raw)
  To: Mihai Maruseac
  Cc: davem, eric.dumazet, kuznet, jmorris, yoshfuji, kaber, netdev,
	Mihai Maruseac, Daniel Baluta

On Wed,  4 Jan 2012 11:31:35 +0200
Mihai Maruseac <mihai.maruseac@gmail.com> wrote:

> This ensures a linear behaviour when filling /proc/net/if_inet6 thus making
> ifconfig run really fast on IPv6 only addresses. In fact, with this patch and
> the IPv4 one sent a while ago, ifconfig will run in linear time regardless of
> address type.
> 
> IPv4 related patch: f04565ddf52e401880f8ba51de0dff8ba51c99fd
> 	 dev: use name hash for dev_seq_ops
> 	 ...
> 
> Some statistics (running ifconfig > /dev/null on a different setup):
> 
> iface count / IPv6 no-patch time / IPv6 patched time / IPv4 time
> ----------------------------------------------------------------
>       6250  |       0.23 s       |      0.13 s       |  0.11 s
>      12500  |       0.62 s       |      0.28 s       |  0.22 s
>      25000  |       2.91 s       |      0.57 s       |  0.46 s
>      50000  |      11.37 s       |      1.21 s       |  0.94 s
>     128000  |      86.78 s       |      3.05 s       |  2.54 s
> 
> Signed-off-by: Mihai Maruseac <mmaruseac@ixiacom.com>
> Cc: Daniel Baluta <dbaluta@ixiacom.com>
> ---
>  net/ipv6/addrconf.c |   43 ++++++++++++++++++++++++++++---------------
>  1 files changed, 28 insertions(+), 15 deletions(-)
> 


What about netlink? Also ifconfig is really considered deprecated,
especially for ipv6 usage.

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH] ipv6/addrconf: speedup /proc/net/if_inet6 filling
  2012-01-04 16:22 ` Stephen Hemminger
@ 2012-01-04 17:03   ` Mihai Maruseac
  2012-01-05 14:07     ` Mihai Maruseac
  0 siblings, 1 reply; 5+ messages in thread
From: Mihai Maruseac @ 2012-01-04 17:03 UTC (permalink / raw)
  To: Stephen Hemminger
  Cc: davem, eric.dumazet, kuznet, jmorris, yoshfuji, kaber, netdev,
	Mihai Maruseac, Daniel Baluta

On Wed, Jan 4, 2012 at 6:22 PM, Stephen Hemminger <shemminger@vyatta.com> wrote:
> On Wed,  4 Jan 2012 11:31:35 +0200
> Mihai Maruseac <mihai.maruseac@gmail.com> wrote:
>
>> This ensures a linear behaviour when filling /proc/net/if_inet6 thus making
>> ifconfig run really fast on IPv6 only addresses. In fact, with this patch and
>> the IPv4 one sent a while ago, ifconfig will run in linear time regardless of
>> address type.
>>
>> IPv4 related patch: f04565ddf52e401880f8ba51de0dff8ba51c99fd
>>        dev: use name hash for dev_seq_ops
>>        ...
>>
>> Some statistics (running ifconfig > /dev/null on a different setup):
>>
>> iface count / IPv6 no-patch time / IPv6 patched time / IPv4 time
>> ----------------------------------------------------------------
>>       6250  |       0.23 s       |      0.13 s       |  0.11 s
>>      12500  |       0.62 s       |      0.28 s       |  0.22 s
>>      25000  |       2.91 s       |      0.57 s       |  0.46 s
>>      50000  |      11.37 s       |      1.21 s       |  0.94 s
>>     128000  |      86.78 s       |      3.05 s       |  2.54 s
>>
>> Signed-off-by: Mihai Maruseac <mmaruseac@ixiacom.com>
>> Cc: Daniel Baluta <dbaluta@ixiacom.com>
>> ---
>>  net/ipv6/addrconf.c |   43 ++++++++++++++++++++++++++++---------------
>>  1 files changed, 28 insertions(+), 15 deletions(-)
>>
>
>
> What about netlink? Also ifconfig is really considered deprecated,
> especially for ipv6 usage.

Yes, ifconfig is deprecated but the /proc/net/if_inet6 file can be
used in a lot of bash scripts and this was what we wanted to optimize.

We tried to look at the netlink sockets used in iproute2 but there
seems to be no way to improve the performance there. We used 3 pair of
eyes for this before giving up.

I'll come back with statistics from ip a s in at most 24 hours, I
cannot test right now.

Thanks,
Mihai

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH] ipv6/addrconf: speedup /proc/net/if_inet6 filling
  2012-01-04  9:31 [PATCH] ipv6/addrconf: speedup /proc/net/if_inet6 filling Mihai Maruseac
  2012-01-04 16:22 ` Stephen Hemminger
@ 2012-01-04 21:01 ` David Miller
  1 sibling, 0 replies; 5+ messages in thread
From: David Miller @ 2012-01-04 21:01 UTC (permalink / raw)
  To: mihai.maruseac
  Cc: eric.dumazet, kuznet, jmorris, yoshfuji, kaber, netdev,
	mmaruseac, dbaluta

From: Mihai Maruseac <mihai.maruseac@gmail.com>
Date: Wed,  4 Jan 2012 11:31:35 +0200

> This ensures a linear behaviour when filling /proc/net/if_inet6 thus making
> ifconfig run really fast on IPv6 only addresses. In fact, with this patch and
> the IPv4 one sent a while ago, ifconfig will run in linear time regardless of
> address type.
> 
> IPv4 related patch: f04565ddf52e401880f8ba51de0dff8ba51c99fd
> 	 dev: use name hash for dev_seq_ops
> 	 ...
> 
> Some statistics (running ifconfig > /dev/null on a different setup):
> 
> iface count / IPv6 no-patch time / IPv6 patched time / IPv4 time
> ----------------------------------------------------------------
>       6250  |       0.23 s       |      0.13 s       |  0.11 s
>      12500  |       0.62 s       |      0.28 s       |  0.22 s
>      25000  |       2.91 s       |      0.57 s       |  0.46 s
>      50000  |      11.37 s       |      1.21 s       |  0.94 s
>     128000  |      86.78 s       |      3.05 s       |  2.54 s
> 
> Signed-off-by: Mihai Maruseac <mmaruseac@ixiacom.com>
> Cc: Daniel Baluta <dbaluta@ixiacom.com>

Applied, thanks.

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH] ipv6/addrconf: speedup /proc/net/if_inet6 filling
  2012-01-04 17:03   ` Mihai Maruseac
@ 2012-01-05 14:07     ` Mihai Maruseac
  0 siblings, 0 replies; 5+ messages in thread
From: Mihai Maruseac @ 2012-01-05 14:07 UTC (permalink / raw)
  To: Stephen Hemminger
  Cc: davem, eric.dumazet, kuznet, jmorris, yoshfuji, kaber, netdev,
	Mihai Maruseac, Daniel Baluta

On Wed, Jan 4, 2012 at 7:03 PM, Mihai Maruseac <mihai.maruseac@gmail.com> wrote:
> On Wed, Jan 4, 2012 at 6:22 PM, Stephen Hemminger <shemminger@vyatta.com> wrote:
>> On Wed,  4 Jan 2012 11:31:35 +0200
>> Mihai Maruseac <mihai.maruseac@gmail.com> wrote:
>>
>>> This ensures a linear behaviour when filling /proc/net/if_inet6 thus making
>>> ifconfig run really fast on IPv6 only addresses. In fact, with this patch and
>>> the IPv4 one sent a while ago, ifconfig will run in linear time regardless of
>>> address type.
>>>
>>> IPv4 related patch: f04565ddf52e401880f8ba51de0dff8ba51c99fd
>>>        dev: use name hash for dev_seq_ops
>>>        ...
>>>
>>> Some statistics (running ifconfig > /dev/null on a different setup):
>>>
>>> iface count / IPv6 no-patch time / IPv6 patched time / IPv4 time
>>> ----------------------------------------------------------------
>>>       6250  |       0.23 s       |      0.13 s       |  0.11 s
>>>      12500  |       0.62 s       |      0.28 s       |  0.22 s
>>>      25000  |       2.91 s       |      0.57 s       |  0.46 s
>>>      50000  |      11.37 s       |      1.21 s       |  0.94 s
>>>     128000  |      86.78 s       |      3.05 s       |  2.54 s
>>>
>>> Signed-off-by: Mihai Maruseac <mmaruseac@ixiacom.com>
>>> Cc: Daniel Baluta <dbaluta@ixiacom.com>
>>> ---
>>>  net/ipv6/addrconf.c |   43 ++++++++++++++++++++++++++++---------------
>>>  1 files changed, 28 insertions(+), 15 deletions(-)
>>>
>>
>>
>> What about netlink? Also ifconfig is really considered deprecated,
>> especially for ipv6 usage.
>
> Yes, ifconfig is deprecated but the /proc/net/if_inet6 file can be
> used in a lot of bash scripts and this was what we wanted to optimize.
>
> We tried to look at the netlink sockets used in iproute2 but there
> seems to be no way to improve the performance there. We used 3 pair of
> eyes for this before giving up.
>
> I'll come back with statistics from ip a s in at most 24 hours, I
> cannot test right now.


Here are the statistics comparing ip a s with ifconfig, as promised:

* for IPv6:

iface count / ifconfig /   ip a s
----------------------------------------------
       6250  |  0.13 s  |     1.23 s
     12500  |  0.28 s  |     5.03 s
     25000  |  0.57 s  |   20.17 s
     50000  |  1.21 s  |   87.25 s
   128000  |  3.05 s  |  968.12 s

* for IPv4:

iface count / ifconfig /   ip a s
----------------------------------------------
       6250  |  0.11 s  |     0.61 s
     12500  |  0.22 s  |     2.49 s
     25000  |  0.46 s  |   10.12 s
     50000  |  0.94 s  |   40.36 s
   128000  |  2.54 s  |  293.14 s

It seems that an optimisation for the ip case is required. We have a
quadratic behaviour here too.

Thanks,
Mihai

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2012-01-05 14:07 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-01-04  9:31 [PATCH] ipv6/addrconf: speedup /proc/net/if_inet6 filling Mihai Maruseac
2012-01-04 16:22 ` Stephen Hemminger
2012-01-04 17:03   ` Mihai Maruseac
2012-01-05 14:07     ` Mihai Maruseac
2012-01-04 21:01 ` 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).