Netdev List
 help / color / mirror / Atom feed
* [PATCH] sctp: Set socket source address when additing first transport
From: Vlad Yasevich @ 2009-11-11 21:54 UTC (permalink / raw)
  To: davem; +Cc: netdev, linux-sctp, Vlad Yasevich
In-Reply-To: <1257879454-31661-1-git-send-email-vladislav.yasevich@hp.com>

Recent commits
	sctp: Get rid of an extra routing lookup when adding a transport
and
	sctp: Set source addresses on the association before adding transports

changed when routes are added to the sctp transports.  As such,
we didn't set the socket source address correctly when adding the first
transport.  The first transport is always the primary/active one, so
when adding it, set the socket source address.  This was causing
regression failures in SCTP tests.

Signed-off-by: Vlad Yasevich <vladislav.yasevich@hp.com>
---
 net/sctp/transport.c |    3 ++-
 1 files changed, 2 insertions(+), 1 deletions(-)

diff --git a/net/sctp/transport.c b/net/sctp/transport.c
index c256e48..3b141bb 100644
--- a/net/sctp/transport.c
+++ b/net/sctp/transport.c
@@ -308,7 +308,8 @@ void sctp_transport_route(struct sctp_transport *transport,
 		/* Initialize sk->sk_rcv_saddr, if the transport is the
 		 * association's active path for getsockname().
 		 */
-		if (asoc && (transport == asoc->peer.active_path))
+		if (asoc && (!asoc->peer.primary_path ||
+				(transport == asoc->peer.active_path)))
 			opt->pf->af->to_sk_saddr(&transport->saddr,
 						 asoc->base.sk);
 	} else
-- 
1.6.0.4


^ permalink raw reply related

* Re: large packet loss take2 2.6.31.x
From: Frans Pop @ 2009-11-11 22:05 UTC (permalink / raw)
  To: Andi Kleen; +Cc: Caleb Cushing, linux-kernel, netdev
In-Reply-To: <878wecka3g.fsf@basil.nowhere.org>

On Wednesday 11 November 2009, Andi Kleen wrote:
> Caleb Cushing <xenoterracide@gmail.com> writes:
> >> I'm attaching the bisection log and a 'good' dmesg output.
> >>
> >> c9fb3ded7a8a6769f3bcb3ef3d9aed61d3e376a9 is the first bad commit
>
> Just gives fatal: bad object c9fb3ded7a8a6769f3bcb3ef3d9aed61d3e376a9
> here on a standard Linus linux-2.6 tree.

Looks to be a commit from a stable update:

commit c9fb3ded7a8a6769f3bcb3ef3d9aed61d3e376a9
Author: Alan Stern <stern@rowland.harvard.edu>
Date:   Tue Sep 1 11:38:34 2009 -0400

    usb-serial: change referencing of port and serial structures

    commit 41bd34ddd7aa46dbc03b5bb33896e0fa8100fe7b upstream.

Cheers,
FJP

^ permalink raw reply

* [PATCH] netfilter: Should xt_osf_remove_callback() return negative on errors?
From: Roel Kluin @ 2009-11-11 22:33 UTC (permalink / raw)
  To: Andrew Morton, LKML, Patrick McHardy, David S. Miller,
	netfilter-devel

Return a negative error value

Signed-off-by: Roel Kluin <roel.kluin@gmail.com>
---
 net/netfilter/xt_osf.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

It seems strange that an error return can be positive or
negative, is this maybe required?

diff --git a/net/netfilter/xt_osf.c b/net/netfilter/xt_osf.c
index 63e1905..4d1a41b 100644
--- a/net/netfilter/xt_osf.c
+++ b/net/netfilter/xt_osf.c
@@ -118,7 +118,7 @@ static int xt_osf_remove_callback(struct sock *ctnl, struct sk_buff *skb,
 {
 	struct xt_osf_user_finger *f;
 	struct xt_osf_finger *sf;
-	int err = ENOENT;
+	int err = -ENOENT;
 
 	if (!osf_attrs[OSF_ATTR_FINGER])
 		return -EINVAL;

^ permalink raw reply related

* Re: [PATCH] [next-next-2.6] net: configurable device name hash
From: Stephen Hemminger @ 2009-11-11 22:24 UTC (permalink / raw)
  To: Octavian Purdila; +Cc: David Miller, netdev
In-Reply-To: <200911112347.41425.opurdila@ixiacom.com>

On Wed, 11 Nov 2009 23:47:41 +0200
Octavian Purdila <opurdila@ixiacom.com> wrote:

> On Wednesday 11 November 2009 23:33:42 you wrote:
> > On Wed, 11 Nov 2009 12:42:35 -0800 (PST)
> > 
> > David Miller <davem@davemloft.net> wrote:
> > > From: Octavian Purdila <opurdila@ixiacom.com>
> > > Date: Wed, 11 Nov 2009 21:38:44 +0200
> > >
> > > > I don't think we can dynamically size it at boot time since it
> > > > depends on the usage pattern which is impossible to determine at
> > > > boot time, right?
> > >
> > > We have no idea how many sockets will be used by the system yet we
> > > dynamically size the socket hash tables.
> > >
> > > Please do some research and see how we handle this elsewhere in the
> > > networking.
> > 
> > dcache also sizes hash bits at boot time on available memory.
> > See alloc_large_system_hash().
> > 
> 
> Thanks Stephen.
> 
> I was actually taking a look at that but I see that the device hash is 
> allocated per net namespace which means we can't use 
> alloc_large_system_hash().
> 
> We could use a similar function that will work in the per namespace 
> initialization context, but this might upset net namespace folks since we will 
> get a large hash for every namespace.
> 
> Not sure what can be done to address that problem now except using a boot 
> parameter to override the defaults. A better solution would be to be able to 
> use "namespace create" parameters but it appears we don't have this 
> possibility, yet.
> 

Remember though that really hash sizes really don't buy that much more speed.
Going from 256 to 1024 gives a 4x benefit but with 10,000 devices that
just means scanning 10 vs. 40 names. It is not like the file system cache
where name lookup is a major component of overhead.

You can still use alloc_large_system_hash, but just constrain it to a maximum
of order 10 or something.

-- 

^ permalink raw reply

* Re: r8169: fix driver drop incoming packets >= 1515 if MTU is set between 1515 and 1536
From: Raimonds Cicans @ 2009-11-11 22:36 UTC (permalink / raw)
  To: Ben Hutchings; +Cc: romieu, netdev
In-Reply-To: <1257970536.2839.73.camel@achroite.uk.solarflarecom.com>

Ben Hutchings:
> On Wed, 2009-11-11 at 22:05 +0200, Raimonds Cicans wrote:
>> Ben Hutchings:
>>> On Wed, 2009-11-11 at 20:20 +0200, Raimonds Cicans wrote:
>>>> Driver drop incoming packets >= 1515(1) if MTU is set between 1515(1) and 1536.
>>>>
>>>> 1) exact number depends on some factors:
>>>> - VLAN tagged or not
>>>> - patch "r8169: Fix card drop incoming VLAN tagged MTU byte large jumbo frames"
>>>>   applied or not
>>> [...]
>>>
>>> MTU is a limit on transmission; it is not required to limit received
>>> frames.
>> ???
>>
>> In r8169 driver MTU is used to calculate receive buffer size.
>> Receive buffer size is used to configure hardware incoming packet filter.
>>
>> For jumbo frames:
>> Receive buffer size = Max frame size = MTU + 14 (ethernet header) + 4
>> (vlan header) + 4 (ethernet checksum) = MTU + 22
>>
>> Bug:
>> driver for all MTU up to 1536 use receive buffer size 1536
> [...]
> 
> OK, now I understand.  The subject line you used is not grammatical and
> I originally thought you considered it a bug that the driver might
> accept packets with payload greater than MTU.

Sorry for my poor English.

> To make it clear, perhaps you could change the subject to:
> 'r8169: Fix receive buffer length when MTU is between 1515 and 1536'
> and then explain the current behaviour below that.

Ok. I will try to make new version tomorrow.

Raimonds Cicans


^ permalink raw reply

* Re: large packet loss take2 2.6.31.x
From: Caleb Cushing @ 2009-11-11 22:48 UTC (permalink / raw)
  To: Frans Pop; +Cc: Andi Kleen, linux-kernel, netdev
In-Reply-To: <200911112305.54824.elendil@planet.nl>

On Wed, Nov 11, 2009 at 5:05 PM, Frans Pop <elendil@planet.nl> wrote:
> On Wednesday 11 November 2009, Andi Kleen wrote:
>> Caleb Cushing <xenoterracide@gmail.com> writes:
>> >> I'm attaching the bisection log and a 'good' dmesg output.
>> >>
>> >> c9fb3ded7a8a6769f3bcb3ef3d9aed61d3e376a9 is the first bad commit
>>
>> Just gives fatal: bad object c9fb3ded7a8a6769f3bcb3ef3d9aed61d3e376a9
>> here on a standard Linus linux-2.6 tree.
>
> Looks to be a commit from a stable update:
>
> commit c9fb3ded7a8a6769f3bcb3ef3d9aed61d3e376a9
> Author: Alan Stern <stern@rowland.harvard.edu>
> Date:   Tue Sep 1 11:38:34 2009 -0400
>
>    usb-serial: change referencing of port and serial structures
>
>    commit 41bd34ddd7aa46dbc03b5bb33896e0fa8100fe7b upstream.
>
> Cheers,
> FJP
>

yeah it is. it's from greg kroah-hartman's tree.
-- 
Caleb Cushing

http://xenoterracide.blogspot.com

^ permalink raw reply

* [net-next PATCH 0/4] qlge: Fixes and clean up for qlge.
From: Ron Mercer @ 2009-11-11 22:54 UTC (permalink / raw)
  To: davem; +Cc: netdev, ron.mercer


Two small fixes, one cleanup and a driver version change for qlge.

1) Remove frame route change in qlge_suspend().  This operation is now
done by the firmware.

2) Add asic reset to force known state at open().

3) Change module parameter to match qlge_xxx convention.

4) Change driver version.



^ permalink raw reply

* [net-next PATCH 2/4] qlge: Add asic reset to open call.
From: Ron Mercer @ 2009-11-11 22:54 UTC (permalink / raw)
  To: davem; +Cc: netdev, ron.mercer
In-Reply-To: <1257980046-2420-1-git-send-email-ron.mercer@qlogic.com>

Force asic to known state at open().

Signed-off-by: Ron Mercer <ron.mercer@qlogic.com>
---
 drivers/net/qlge/qlge_main.c |    4 ++++
 1 files changed, 4 insertions(+), 0 deletions(-)

diff --git a/drivers/net/qlge/qlge_main.c b/drivers/net/qlge/qlge_main.c
index 2bfa783..d2a4bbe 100644
--- a/drivers/net/qlge/qlge_main.c
+++ b/drivers/net/qlge/qlge_main.c
@@ -3714,6 +3714,10 @@ static int qlge_open(struct net_device *ndev)
 	int err = 0;
 	struct ql_adapter *qdev = netdev_priv(ndev);
 
+	err = ql_adapter_reset(qdev);
+	if (err)
+		return err;
+
 	err = ql_configure_rings(qdev);
 	if (err)
 		return err;
-- 
1.6.0.2


^ permalink raw reply related

* [net-next PATCH 1/4] qlge: Do not change frame routing during suspend.
From: Ron Mercer @ 2009-11-11 22:54 UTC (permalink / raw)
  To: davem; +Cc: netdev, ron.mercer
In-Reply-To: <1257980046-2420-1-git-send-email-ron.mercer@qlogic.com>

We do not need to change the frame routing to direct all frames to the
management fifo during suspend.  This is now done by the firmware.

Signed-off-by: Ron Mercer <ron.mercer@qlogic.com>
---
 drivers/net/qlge/qlge_main.c |    3 ---
 1 files changed, 0 insertions(+), 3 deletions(-)

diff --git a/drivers/net/qlge/qlge_main.c b/drivers/net/qlge/qlge_main.c
index bd8e164..2bfa783 100644
--- a/drivers/net/qlge/qlge_main.c
+++ b/drivers/net/qlge/qlge_main.c
@@ -3514,9 +3514,6 @@ int ql_wol(struct ql_adapter *qdev)
 	}
 
 	if (qdev->wol) {
-		/* Reroute all packets to Management Interface */
-		ql_write32(qdev, MGMT_RCV_CFG, (MGMT_RCV_CFG_RM |
-			(MGMT_RCV_CFG_RM << 16)));
 		wol |= MB_WOL_MODE_ON;
 		status = ql_mb_wol_mode(qdev, wol);
 		QPRINTK(qdev, DRV, ERR, "WOL %s (wol code 0x%x) on %s\n",
-- 
1.6.0.2


^ permalink raw reply related

* [net-next PATCH 4/4] qlge: Change version to v1.00.00.23.00.00-01.
From: Ron Mercer @ 2009-11-11 22:54 UTC (permalink / raw)
  To: davem; +Cc: netdev, ron.mercer
In-Reply-To: <1257980046-2420-1-git-send-email-ron.mercer@qlogic.com>

Signed-off-by: Ron Mercer <ron.mercer@qlogic.com>
---
 drivers/net/qlge/qlge.h |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/drivers/net/qlge/qlge.h b/drivers/net/qlge/qlge.h
index 1f59f05..862c1aa 100644
--- a/drivers/net/qlge/qlge.h
+++ b/drivers/net/qlge/qlge.h
@@ -16,7 +16,7 @@
  */
 #define DRV_NAME  	"qlge"
 #define DRV_STRING 	"QLogic 10 Gigabit PCI-E Ethernet Driver "
-#define DRV_VERSION	"v1.00.00-b3"
+#define DRV_VERSION	"v1.00.00.23.00.00-01"
 
 #define PFX "qlge: "
 #define QPRINTK(qdev, nlevel, klevel, fmt, args...)     \
-- 
1.6.0.2


^ permalink raw reply related

* [net-next PATCH 3/4] qlge: Clean up module parameter name.
From: Ron Mercer @ 2009-11-11 22:54 UTC (permalink / raw)
  To: davem; +Cc: netdev, ron.mercer
In-Reply-To: <1257980046-2420-1-git-send-email-ron.mercer@qlogic.com>

Change it to match qlge_xxx convention.

Signed-off-by: Ron Mercer <ron.mercer@qlogic.com>
---
 drivers/net/qlge/qlge_main.c |   16 ++++++++--------
 1 files changed, 8 insertions(+), 8 deletions(-)

diff --git a/drivers/net/qlge/qlge_main.c b/drivers/net/qlge/qlge_main.c
index d2a4bbe..e2ee47d 100644
--- a/drivers/net/qlge/qlge_main.c
+++ b/drivers/net/qlge/qlge_main.c
@@ -69,9 +69,9 @@ MODULE_PARM_DESC(debug, "Debug level (0=none,...,16=all)");
 #define MSIX_IRQ 0
 #define MSI_IRQ 1
 #define LEG_IRQ 2
-static int irq_type = MSIX_IRQ;
-module_param(irq_type, int, MSIX_IRQ);
-MODULE_PARM_DESC(irq_type, "0 = MSI-X, 1 = MSI, 2 = Legacy.");
+static int qlge_irq_type = MSIX_IRQ;
+module_param(qlge_irq_type, int, MSIX_IRQ);
+MODULE_PARM_DESC(qlge_irq_type, "0 = MSI-X, 1 = MSI, 2 = Legacy.");
 
 static struct pci_device_id qlge_pci_tbl[] __devinitdata = {
 	{PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, QLGE_DEVICE_ID_8012)},
@@ -2870,7 +2870,7 @@ static void ql_enable_msix(struct ql_adapter *qdev)
 	int i, err;
 
 	/* Get the MSIX vectors. */
-	if (irq_type == MSIX_IRQ) {
+	if (qlge_irq_type == MSIX_IRQ) {
 		/* Try to alloc space for the msix struct,
 		 * if it fails then go to MSI/legacy.
 		 */
@@ -2878,7 +2878,7 @@ static void ql_enable_msix(struct ql_adapter *qdev)
 					    sizeof(struct msix_entry),
 					    GFP_KERNEL);
 		if (!qdev->msi_x_entry) {
-			irq_type = MSI_IRQ;
+			qlge_irq_type = MSI_IRQ;
 			goto msi;
 		}
 
@@ -2901,7 +2901,7 @@ static void ql_enable_msix(struct ql_adapter *qdev)
 			QPRINTK(qdev, IFUP, WARNING,
 				"MSI-X Enable failed, trying MSI.\n");
 			qdev->intr_count = 1;
-			irq_type = MSI_IRQ;
+			qlge_irq_type = MSI_IRQ;
 		} else if (err == 0) {
 			set_bit(QL_MSIX_ENABLED, &qdev->flags);
 			QPRINTK(qdev, IFUP, INFO,
@@ -2912,7 +2912,7 @@ static void ql_enable_msix(struct ql_adapter *qdev)
 	}
 msi:
 	qdev->intr_count = 1;
-	if (irq_type == MSI_IRQ) {
+	if (qlge_irq_type == MSI_IRQ) {
 		if (!pci_enable_msi(qdev->pdev)) {
 			set_bit(QL_MSI_ENABLED, &qdev->flags);
 			QPRINTK(qdev, IFUP, INFO,
@@ -2920,7 +2920,7 @@ msi:
 			return;
 		}
 	}
-	irq_type = LEG_IRQ;
+	qlge_irq_type = LEG_IRQ;
 	QPRINTK(qdev, IFUP, DEBUG, "Running with legacy interrupts.\n");
 }
 
-- 
1.6.0.2


^ permalink raw reply related

* Re: [PATCH 2/2] rps: changes to bnx2x to get device hash
From: Matt Carlson @ 2009-11-11 23:21 UTC (permalink / raw)
  To: Tom Herbert; +Cc: David Miller, netdev@vger.kernel.org
In-Reply-To: <65634d660911102253lbfc0927i4e4c0eba6d7d765d@mail.gmail.com>

On Tue, Nov 10, 2009 at 10:53:36PM -0800, Tom Herbert wrote:
> @@ -6223,9 +6257,10 @@ static int bnx2x_init_common(struct bnx2x *bp)
>  	bnx2x_init_block(bp, PBF_BLOCK, COMMON_STAGE);
> 
>  	REG_WR(bp, SRC_REG_SOFT_RST, 1);
> -	for (i = SRC_REG_KEYRSS0_0; i <= SRC_REG_KEYRSS1_9; i += 4) {
> -		REG_WR(bp, i, 0xc0cac01a);
> -		/* TODO: replace with something meaningful */
> +	{
> +		int i;
> +		for (i = SRC_REG_KEYRSS0_0; i <= SRC_REG_KEYRSS1_9; i += 4)
> +			REG_WR(bp, i, random32());
>  	}
>  	bnx2x_init_block(bp, SRCH_BLOCK, COMMON_STAGE);
>  #ifdef BCM_CNIC

Is a random hash key really better than arbitrary static values?  
Setting the hash key to random values means, from chip reset to chip
reset, you could get different performance results.  Unless we
we understood how the key affects performance, I would think that
reproducable performance numbers would be more desirable, no?


^ permalink raw reply

* [PATCH] X25: Enable setting of cause and diagnostic fields
From: andrew hendry @ 2009-11-12  0:13 UTC (permalink / raw)
  To: netdev, linux-x25; +Cc: linux-kernel

Adds SIOCX25SCAUSEDIAG, allowing X.25 programs to set the cause and
diagnostic fields.
Normally used to indicate status upon closing connections.

Signed-off-by: Andrew Hendry <andrew.hendry@gmail.com>


diff -uprN -X a/Documentation/dontdiff a/include/linux/x25.h
b/include/linux/x25.h
--- a/include/linux/x25.h	2009-11-11 14:03:26.659663301 +1100
+++ b/include/linux/x25.h	2009-11-11 16:05:06.625958557 +1100
@@ -25,6 +25,7 @@
 #define SIOCX25SENDCALLACCPT    (SIOCPROTOPRIVATE + 9)
 #define SIOCX25GDTEFACILITIES (SIOCPROTOPRIVATE + 10)
 #define SIOCX25SDTEFACILITIES (SIOCPROTOPRIVATE + 11)
+#define SIOCX25SCAUSEDIAG     (SIOCPROTOPRIVATE + 12)

 /*
  *	Values for {get,set}sockopt.
diff -uprN -X a/Documentation/dontdiff a/net/x25/af_x25.c b/net/x25/af_x25.c
--- a/net/x25/af_x25.c	2009-11-11 14:02:44.027061001 +1100
+++ b/net/x25/af_x25.c	2009-11-11 16:22:51.374077963 +1100
@@ -1430,6 +1430,17 @@ static int x25_ioctl(struct socket *sock
 			break;
 		}

+		case SIOCX25SCAUSEDIAG: {
+			struct x25_causediag causediag;
+			rc = -EFAULT;
+			if (copy_from_user(&causediag, argp, sizeof(causediag)))
+				break;
+			x25->causediag = causediag;
+			rc = 0;
+			break;
+
+		}
+
 		case SIOCX25SCUDMATCHLEN: {
 			struct x25_subaddr sub_addr;
 			rc = -EINVAL;
diff -uprN -X a/Documentation/dontdiff a/net/x25/x25_subr.c b/net/x25/x25_subr.c
--- a/net/x25/x25_subr.c	2009-11-11 14:02:44.026061128 +1100
+++ b/net/x25/x25_subr.c	2009-11-11 16:28:30.316150252 +1100
@@ -225,6 +225,12 @@ void x25_write_internal(struct sock *sk,
 			break;

 		case X25_CLEAR_REQUEST:
+			dptr    = skb_put(skb, 3);
+			*dptr++ = frametype;
+			*dptr++ = x25->causediag.cause;
+			*dptr++ = x25->causediag.diagnostic;
+			break;
+
 		case X25_RESET_REQUEST:
 			dptr    = skb_put(skb, 3);
 			*dptr++ = frametype;

^ permalink raw reply

* [PATCH net-2.6] Revert "net: Support inclusion of <linux/socket.h> before <sys/socket.h>"
From: Ben Hutchings @ 2009-11-12  2:00 UTC (permalink / raw)
  To: David Miller; +Cc: netdev, 538372

This reverts commit 9c501935a3cdcf6b1d35aaee3aa11c7a7051a305.  That
commit caused <linux/rtnetlink.h> to require that <sys/socket.h> is
included first, breaking autoconf tests for <linux/rtnetlink.h> and
presumably some real programs too.

Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
---
Please apply this to net-2.6.

I'm not sure what the proper solution is; maybe make <linux/socket.h>
include <sys/socket.h> if __KERNEL__ is not defined?

Ben.

 include/linux/socket.h |   21 ++++++++++++++++++---
 1 files changed, 18 insertions(+), 3 deletions(-)

diff --git a/include/linux/socket.h b/include/linux/socket.h
index 3273a0c..3b461df 100644
--- a/include/linux/socket.h
+++ b/include/linux/socket.h
@@ -16,7 +16,7 @@ struct __kernel_sockaddr_storage {
 				/* _SS_MAXSIZE value minus size of ss_family */
 } __attribute__ ((aligned(_K_SS_ALIGNSIZE)));	/* force desired alignment */
 
-#ifdef __KERNEL__
+#if defined(__KERNEL__) || !defined(__GLIBC__) || (__GLIBC__ < 2)
 
 #include <asm/socket.h>			/* arch-dependent defines	*/
 #include <linux/sockios.h>		/* the SIOCxxx I/O controls	*/
@@ -101,6 +101,21 @@ struct cmsghdr {
 			      ((char *)(cmsg) - (char *)(mhdr)->msg_control)))
 
 /*
+ *	This mess will go away with glibc
+ */
+ 
+#ifdef __KERNEL__
+#define __KINLINE static inline
+#elif  defined(__GNUC__) 
+#define __KINLINE static __inline__
+#elif defined(__cplusplus)
+#define __KINLINE static inline
+#else
+#define __KINLINE static
+#endif
+
+
+/*
  *	Get the next cmsg header
  *
  *	PLEASE, do not touch this function. If you think, that it is
@@ -113,7 +128,7 @@ struct cmsghdr {
  *	ancillary object DATA.				--ANK (980731)
  */
  
-static inline struct cmsghdr * __cmsg_nxthdr(void *__ctl, __kernel_size_t __size,
+__KINLINE struct cmsghdr * __cmsg_nxthdr(void *__ctl, __kernel_size_t __size,
 					       struct cmsghdr *__cmsg)
 {
 	struct cmsghdr * __ptr;
@@ -125,7 +140,7 @@ static inline struct cmsghdr * __cmsg_nxthdr(void *__ctl, __kernel_size_t __size
 	return __ptr;
 }
 
-static inline struct cmsghdr * cmsg_nxthdr (struct msghdr *__msg, struct cmsghdr *__cmsg)
+__KINLINE struct cmsghdr * cmsg_nxthdr (struct msghdr *__msg, struct cmsghdr *__cmsg)
 {
 	return __cmsg_nxthdr(__msg->msg_control, __msg->msg_controllen, __cmsg);
 }
-- 
1.6.5.2



^ permalink raw reply related

* Re: [PATCHv9 3/3] vhost_net: a kernel-level virtio server
From: Rusty Russell @ 2009-11-12  2:18 UTC (permalink / raw)
  To: Michael S. Tsirkin
  Cc: netdev, virtualization, kvm, linux-kernel, mingo, linux-mm, akpm,
	hpa, gregory.haskins, s.hetze, Daniel Walker, Eric Dumazet
In-Reply-To: <20091110113637.GB6989@redhat.com>

On Tue, 10 Nov 2009 10:06:37 pm Michael S. Tsirkin wrote:
> If tun is a module, vhost must be a module, too.
> If tun is built-in or disabled, vhost can be built-in.

I really like the brainbending :)  Keeps readers on their toes...

Applied,
Rusty.

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

^ permalink raw reply

* Re: [PATCH 1/2] rps: core implementation
From: David Miller @ 2009-11-12  2:32 UTC (permalink / raw)
  To: andi; +Cc: eric.dumazet, therbert, netdev
In-Reply-To: <87d43oka86.fsf@basil.nowhere.org>

From: Andi Kleen <andi@firstfloor.org>
Date: Wed, 11 Nov 2009 22:44:25 +0100

> Eric Dumazet <eric.dumazet@gmail.com> writes:
>>
>> Problem of possible cpus is the number can be very large on some arches,
>> but yet few cpus online....
> 
> Actually that should be rare. Especially not very large compared to online.

The ratio can be as high as 256/1 on Niagara boxes.

^ permalink raw reply

* Re: [PATCH] [next-next-2.6] net: configurable device name hash
From: David Miller @ 2009-11-12  2:36 UTC (permalink / raw)
  To: opurdila; +Cc: shemminger, netdev
In-Reply-To: <200911112347.41425.opurdila@ixiacom.com>

From: Octavian Purdila <opurdila@ixiacom.com>
Date: Wed, 11 Nov 2009 23:47:41 +0200

> We could use a similar function that will work in the per namespace
> initialization context, but this might upset net namespace folks
> since we will get a large hash for every namespace.

Use kzalloc(), that's sufficient for a 64K or so hash table which is
way more than you ever will need.

Use the GFP_* flags that will silently (ie. without a log message)
fail, and divide by two until you successfully allocate the table if
you're worried about memory fragmentation at allocation time.

This is so straightforward, I can't believe we're talking so much
about how to implement this, it's a 15 minute hack :-)

^ permalink raw reply

* Re: [PATCH 2/2] rps: changes to bnx2x to get device hash
From: David Miller @ 2009-11-12  2:42 UTC (permalink / raw)
  To: mcarlson; +Cc: therbert, netdev
In-Reply-To: <20091111232103.GA1217@xw6200.broadcom.net>

From: "Matt Carlson" <mcarlson@broadcom.com>
Date: Wed, 11 Nov 2009 15:21:03 -0800

> Is a random hash key really better than arbitrary static values?  
> Setting the hash key to random values means, from chip reset to chip
> reset, you could get different performance results.  Unless we
> we understood how the key affects performance, I would think that
> reproducable performance numbers would be more desirable, no?

Security.

If someone knows the key and the hash function, they can purposely
pick address and port combinations that always hash to the same queue,
decresing your horsepower to handle traffic by orders of magnitude.

^ permalink raw reply

* Re: [PATCH net-2.6] Revert "net: Support inclusion of <linux/socket.h> before <sys/socket.h>"
From: David Miller @ 2009-11-12  2:51 UTC (permalink / raw)
  To: ben; +Cc: netdev, 538372
In-Reply-To: <1257991205.2237.73.camel@localhost>

From: Ben Hutchings <ben@decadent.org.uk>
Date: Thu, 12 Nov 2009 02:00:05 +0000

> This reverts commit 9c501935a3cdcf6b1d35aaee3aa11c7a7051a305.  That
> commit caused <linux/rtnetlink.h> to require that <sys/socket.h> is
> included first, breaking autoconf tests for <linux/rtnetlink.h> and
> presumably some real programs too.
> 
> Signed-off-by: Ben Hutchings <ben@decadent.org.uk>

I'm not reverting this Ben.  The dependency those programs and
autoconf tests have is _dubious_ at best.

It means they were depending upon the libc5 checks passing, that's
rediculious and not something we should cater to.

If you really want it to work that linux/rtnetlink.h is included first
before sys/socket.h in userland, fix that specifically instead.  But
I believe such a dependency is reasonable and the userspace bits need
fixing.


^ permalink raw reply

* Re: [patch] missing dev_put() on error path in vif_add()
From: Wang Chen @ 2009-11-12  2:50 UTC (permalink / raw)
  To: Dan Carpenter; +Cc: netdev, davem
In-Reply-To: <alpine.DEB.2.00.0911111339100.9485@bicker>

Dan Carpenter said the following on 2009-11-11 20:03:
> The other error paths in front of this one have a dev_put() but this one 
> got missed.
> 
> Found by smatch static checker.
> 
> regards,
> dan carpenter
> 
> Signed-off-by: Dan Carpenter <error27@gmail.com>
> 
> --- orig/net/ipv4/ipmr.c	2009-11-11 13:34:20.000000000 +0200
> +++ devel/net/ipv4/ipmr.c	2009-11-11 13:34:59.000000000 +0200
> @@ -483,8 +483,10 @@
>  		return -EINVAL;
>  	}
>  
> -	if ((in_dev = __in_dev_get_rtnl(dev)) == NULL)
> +	if ((in_dev = __in_dev_get_rtnl(dev)) == NULL) {
> +		dev_put(dev);
>  		return -EADDRNOTAVAIL;
> +	}
>  	IPV4_DEVCONF(in_dev->cnf, MC_FORWARDING)++;
>  	ip_rt_multicast_event(in_dev);
>  

It's my fault. Introduced in 7dc00c82cbb0119cf4663f65bbaa2cc55f961db2.

Acked-by: Wang Chen <ellre923@gmail.com>

^ permalink raw reply

* Re: [PATCH 0/6] gianfar: Some fixes
From: David Miller @ 2009-11-12  3:04 UTC (permalink / raw)
  To: galak; +Cc: jdl, B05799, netdev, linuxppc-dev, afleming, shemminger, buytenh
In-Reply-To: <BEE5C957-99C1-4399-AB5D-BCF5BC05A73C@kernel.crashing.org>

From: Kumar Gala <galak@kernel.crashing.org>
Date: Wed, 11 Nov 2009 09:16:41 -0600

> 
> On Nov 10, 2009, at 6:10 PM, Anton Vorontsov wrote:
> 
>> Hi all,
>>
>> Here are some fixes for the gianfar driver, patches on the way.
>>
>> Thanks,
> 
> Acked-by: Kumar Gala <galak@kernel.crashing.org>

All applied to net-next-2.6, thanks.

^ permalink raw reply

* Re: [PATCH net-2.6] Revert "net: Support inclusion of <linux/socket.h> before <sys/socket.h>"
From: Ben Hutchings @ 2009-11-12  3:05 UTC (permalink / raw)
  To: David Miller; +Cc: netdev, 538372
In-Reply-To: <20091111.185124.22668587.davem@davemloft.net>

[-- Attachment #1: Type: text/plain, Size: 1118 bytes --]

On Wed, 2009-11-11 at 18:51 -0800, David Miller wrote:
> From: Ben Hutchings <ben@decadent.org.uk>
> Date: Thu, 12 Nov 2009 02:00:05 +0000
> 
> > This reverts commit 9c501935a3cdcf6b1d35aaee3aa11c7a7051a305.  That
> > commit caused <linux/rtnetlink.h> to require that <sys/socket.h> is
> > included first, breaking autoconf tests for <linux/rtnetlink.h> and
> > presumably some real programs too.
> > 
> > Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
> 
> I'm not reverting this Ben.  The dependency those programs and
> autoconf tests have is _dubious_ at best.
> 
> It means they were depending upon the libc5 checks passing, that's
> rediculious and not something we should cater to.
[...]

Sorry, I'm getting my headers mixed up.  The problem is with
<linux/netlink.h> not <linux/rtnetlink.h>.

<linux/netlink.h> will not compile for userland, because
<linux/socket.h> is no longer defining sa_family_t.  For userland, this
should be defined by <sys/socket.h>.

Ben.

-- 
Ben Hutchings
Lowery's Law:
             If it jams, force it. If it breaks, it needed replacing anyway.

[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 828 bytes --]

^ permalink raw reply

* Re: [PATCH net-2.6] Revert "net: Support inclusion of <linux/socket.h> before <sys/socket.h>"
From: David Miller @ 2009-11-12  3:09 UTC (permalink / raw)
  To: ben; +Cc: netdev, 538372
In-Reply-To: <1257995115.2237.90.camel@localhost>

From: Ben Hutchings <ben@decadent.org.uk>
Date: Thu, 12 Nov 2009 03:05:15 +0000

> <linux/netlink.h> will not compile for userland, because
> <linux/socket.h> is no longer defining sa_family_t.  For userland, this
> should be defined by <sys/socket.h>.

Still, you still essentially have two choices:

1) Tell userland, sorry you need to include sys/socket.h before
   other "socket stuff" and that means linux/netlink.h in
   particular

2) Put a !__KERNEL__ sys/socket.h include in there, but that's
   asking for trouble.

Ok?

^ permalink raw reply

* Re: [PATCH] ifb: add multi-queue support
From: Changli Gao @ 2009-11-12  3:12 UTC (permalink / raw)
  To: Patrick McHardy
  Cc: David S. Miller, Stephen Hemminger, Eric Dumazet, Tom Herbert,
	netdev
In-Reply-To: <4AFADF64.8070601@trash.net>

On Wed, Nov 11, 2009 at 11:59 PM, Patrick McHardy <kaber@trash.net> wrote:
> Changli Gao wrote:
>> diff --git a/drivers/net/ifb.c b/drivers/net/ifb.c
>> index 69c2566..ac04e85 100644
>> --- a/drivers/net/ifb.c
>> +++ b/drivers/net/ifb.c
>> ...
>> +/* Number of ifb devices to be set up by this module. */
>>  static int numifbs = 2;
>> +module_param(numifbs, int, 0444);
>> +MODULE_PARM_DESC(numifbs, "Number of ifb devices");
>>
>> -static void ri_tasklet(unsigned long dev);
>> -static netdev_tx_t ifb_xmit(struct sk_buff *skb, struct net_device *dev);
>> -static int ifb_open(struct net_device *dev);
>> -static int ifb_close(struct net_device *dev);
>> +/* Number of TX queues per ifb */
>> +static int numtxqs = 1;
>> +module_param(numtxqs, int, 0444);
>> +MODULE_PARM_DESC(numtxqs, "Number of TX queues per ifb");
>
> unsigned?

Yea, unsigned is better, and I need to check whether its value is
smaller than 1 somewhere. The same will be done with IFLA_NTXQ.

>
>> +             while ((skb = skb_dequeue(&pq->tq)) != NULL) {
>> +                     u32 from = G_TC_FROM(skb->tc_verd);
>> +
>> +                     skb->tc_verd = 0;
>> +                     skb->tc_verd = SET_TC_NCLS(skb->tc_verd);
>> +                     txq->tx_packets++;
>> +                     txq->tx_bytes +=skb->len;
>> +
>> +                     rcu_read_lock();
>> +                     skb->dev = dev_get_by_index_rcu(&init_net, skb->iif);
>> +                     if (!skb->dev) {
>> +                             rcu_read_unlock();
>> +                             dev_kfree_skb(skb);
>> +                             txq->tx_dropped++;
>> +                             break;
>> +                     }
>> +                     rcu_read_unlock();
>> +                     skb->iif = dev->ifindex;
>
> What protects the device from disappearing here and below during
> dev_queue_xmit() and netif_rx_ni()?

For dev_queue_xmit(), dev is holded by skb->_dst, so there is no
problem. But for netif_rx_ni(), I don't know how to prevent the device
disappearing, and it seems that all the NIC drivers have this problem.
Maybe there was the assumption about the execution context of
netif_rx() before. Now softirq can't be executed by softirqd, so the
packet receiving path maybe interleaved. I don't know how to prevent
it happening.


>> +
>> +static u16 ifb_select_queue(struct net_device *dev, struct sk_buff *skb)
>> +{
>> +     u32 addr1, addr2;
>> +     u32 hash, ihl;
>> +     union {
>> +             u16 in16[2];
>> +             u32 in32;
>> +     } ports;
>> +     u8 ip_proto;
>> +
>> +     if ((hash = skb_rx_queue_recorded(skb))) {
>> +             while (hash >= dev->real_num_tx_queues)
>> +                     hash -= dev->real_num_tx_queues;
>> +             return hash;
>> +     }
>> +
>> +     switch (skb->protocol) {
>> +     case __constant_htons(ETH_P_IP):
>> +             if (!(ip_hdr(skb)->frag_off & htons(IP_MF | IP_OFFSET)))
>> +                     ip_proto = ip_hdr(skb)->protocol;
>> +             else
>> +                     ip_proto = 0;
>
> So fragments will get reordered?

Yea. It is OK, as the number of fragments isn't large. If we decide to
avoid this, we have to reasm them as netfilter does. and it isn't
efficiency.

>
>> +             addr1 = ip_hdr(skb)->saddr;
>> +             addr2 = ip_hdr(skb)->daddr;
>> +             ihl = ip_hdr(skb)->ihl << 2;
>
> ip_hdrlen()?

Yea, I'll use ip_hdrlen() instead.

>
>> +             break;
>> +     case __constant_htons(ETH_P_IPV6):
>> +             ip_proto = ipv6_hdr(skb)->nexthdr;
>> +             addr1 = ipv6_hdr(skb)->saddr.s6_addr32[3];
>> +             addr2 = ipv6_hdr(skb)->daddr.s6_addr32[3];
>> +             ihl = 10;
>
> Where does 10 come from?

It should be 40, after reviewing IPV6, I found that I need to loop
until finding the right protocol value.

>
>> +             break;
>> +     default:
>> +             return 0;
>
> Perhaps hash on skb->protocol here.

use return skb->protocol % dev->real_num_tx_queues; instead.

>
>> +     }
>> +     if (addr1 > addr2)
>> +             swap(addr1, addr2);
>> +
>> +     switch (ip_proto) {
>> +     case IPPROTO_TCP:
>> +     case IPPROTO_UDP:
>> +     case IPPROTO_DCCP:
>> +     case IPPROTO_ESP:
>> +     case IPPROTO_AH:
>> +     case IPPROTO_SCTP:
>> +     case IPPROTO_UDPLITE:
>> +             ports.in32 = *((u32 *) (skb_network_header(skb) + ihl));
>> +             if (ports.in16[0] > ports.in16[1])
>> +                     swap(ports.in16[0], ports.in16[1]);
>> +             break;
>> +
>> +     default:
>> +             ports.in32 = 0;
>> +             break;
>> +     }
>> +
>> +     hash = jhash_3words(addr1, addr2, ports.in32,
>> +                         simple_tx_hashrnd ^ ip_proto);
>> +
>> +     return (u16) (((u64) hash * dev->real_num_tx_queues) >> 32);
>> +}
>> +
>> +static int ifb_init(struct net_device *dev)
>> +{
>> +     struct ifb_private *dp = netdev_priv(dev);
>> +     struct ifb_private_q *pq = dp->pq;
>> +     int i;
>> +
>> +     pq = kmalloc(sizeof(*pq) * dev->real_num_tx_queues, GFP_KERNEL);
>
> kcalloc()?

OK.

>> +     if (pq == NULL)
>> +             return -ENOMEM;
>> +     dp->pq = pq;
>> +
>> +     for (i = 0; i < dev->real_num_tx_queues; i++) {
>> +             pq[i].dev = dev;
>> +             skb_queue_head_init(&pq[i].rq);
>> +             skb_queue_head_init(&pq[i].tq);
>> +             init_waitqueue_head(&pq[i].wq);
>> +             pq[i].rx_packets = 0;
>> +             pq[i].rx_bytes = 0;
>> +             pq[i].rx_dropped = 0;
>> +     }
>> +
>> +     return 0;
>> +}
>
>> +static int ifb_get_tx_queues(struct net *net, struct nlattr *tb[],
>> +                          unsigned int *num_tx_queues,
>> +                          unsigned int *real_num_tx_queues)
>> +{
>> +     if (tb[IFLA_NTXQ]) {
>> +             *num_tx_queues = nla_get_u16(tb[IFLA_NTXQ]);
>
> We currently use unsigned ints for the queue number, so please
> use an u32 for the attribute as well.
>
>> +             *real_num_tx_queues = *num_tx_queues;
>> +     } else {
>> +             *num_tx_queues = numtxqs;
>> +             *real_num_tx_queues = numtxqs;
>> +     }
>> +
>> +     return 0;
>> +}
>> +
>
        u16                     (*ndo_select_queue)(struct net_device *dev,
                                                    struct sk_buff *skb);
use u16 as the return value so ..., and I think u16 is big enough. If
you insist on this, I'll use u32 instead.


-- 
Regards,
Changli Gao(xiaosuo@gmail.com)

^ permalink raw reply

* [PATCH net-next-2.6] ipv6: use RCU to walk list of network devices
From: Eric Dumazet @ 2009-11-12  3:34 UTC (permalink / raw)
  To: David Miller; +Cc: Stephen Hemminger, netdev
In-Reply-To: <20091110175647.683253741@vyatta.com>

Stephen Hemminger a écrit :
> No longer need read_lock(&dev_base_lock), use RCU instead.
> This also needs to be optimized for large number of devices.
> 
> Signed-off-by: Stephen Hemminger <shemminger@vyatta.com>

I gave a look at your patch Stephen and found we need a new
next_net_device_rcu(struct net_device *dev) as well,
as next_net_device() is not RCU safe.

(followup patch is probably needed to use it in net/ipv4/igmp.c,
after commit 61fbab77a843d2e77232 : IPV4: use rcu to walk list of devices in IGMP)

We also can avoid taking references on inet6_dev structs.

[PATCH net-next-2.6] ipv6: use RCU to walk list of network devices

No longer need read_lock(&dev_base_lock), use RCU instead.
We also can avoid taking references on inet6_dev structs.

Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>
---
 include/linux/netdevice.h |   10 +++++++
 net/ipv6/anycast.c        |   29 +++++++++-----------
 net/ipv6/mcast.c          |   51 ++++++++++++++++--------------------
 3 files changed, 47 insertions(+), 43 deletions(-)

diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index 083b598..2734a67 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -1093,6 +1093,16 @@ static inline struct net_device *next_net_device(struct net_device *dev)
 	return lh == &net->dev_base_head ? NULL : net_device_entry(lh);
 }
 
+static inline struct net_device *next_net_device_rcu(struct net_device *dev)
+{
+	struct list_head *lh;
+	struct net *net;
+
+	net = dev_net(dev);
+	lh = rcu_dereference(dev->dev_list.next);
+	return lh == &net->dev_base_head ? NULL : net_device_entry(lh);
+}
+
 static inline struct net_device *first_net_device(struct net *net)
 {
 	return list_empty(&net->dev_base_head) ? NULL :
diff --git a/net/ipv6/anycast.c b/net/ipv6/anycast.c
index 2f00ca8..f1c74c8 100644
--- a/net/ipv6/anycast.c
+++ b/net/ipv6/anycast.c
@@ -431,9 +431,9 @@ static inline struct ifacaddr6 *ac6_get_first(struct seq_file *seq)
 	struct net *net = seq_file_net(seq);
 
 	state->idev = NULL;
-	for_each_netdev(net, state->dev) {
+	for_each_netdev_rcu(net, state->dev) {
 		struct inet6_dev *idev;
-		idev = in6_dev_get(state->dev);
+		idev = __in6_dev_get(state->dev);
 		if (!idev)
 			continue;
 		read_lock_bh(&idev->lock);
@@ -443,7 +443,6 @@ static inline struct ifacaddr6 *ac6_get_first(struct seq_file *seq)
 			break;
 		}
 		read_unlock_bh(&idev->lock);
-		in6_dev_put(idev);
 	}
 	return im;
 }
@@ -454,16 +453,15 @@ static struct ifacaddr6 *ac6_get_next(struct seq_file *seq, struct ifacaddr6 *im
 
 	im = im->aca_next;
 	while (!im) {
-		if (likely(state->idev != NULL)) {
+		if (likely(state->idev != NULL))
 			read_unlock_bh(&state->idev->lock);
-			in6_dev_put(state->idev);
-		}
-		state->dev = next_net_device(state->dev);
+
+		state->dev = next_net_device_rcu(state->dev);
 		if (!state->dev) {
 			state->idev = NULL;
 			break;
 		}
-		state->idev = in6_dev_get(state->dev);
+		state->idev = __in6_dev_get(state->dev);
 		if (!state->idev)
 			continue;
 		read_lock_bh(&state->idev->lock);
@@ -482,29 +480,30 @@ static struct ifacaddr6 *ac6_get_idx(struct seq_file *seq, loff_t pos)
 }
 
 static void *ac6_seq_start(struct seq_file *seq, loff_t *pos)
-	__acquires(dev_base_lock)
+	__acquires(RCU)
 {
-	read_lock(&dev_base_lock);
+	rcu_read_lock();
 	return ac6_get_idx(seq, *pos);
 }
 
 static void *ac6_seq_next(struct seq_file *seq, void *v, loff_t *pos)
 {
-	struct ifacaddr6 *im;
-	im = ac6_get_next(seq, v);
+	struct ifacaddr6 *im = ac6_get_next(seq, v);
+
 	++*pos;
 	return im;
 }
 
 static void ac6_seq_stop(struct seq_file *seq, void *v)
-	__releases(dev_base_lock)
+	__releases(RCU)
 {
 	struct ac6_iter_state *state = ac6_seq_private(seq);
+
 	if (likely(state->idev != NULL)) {
 		read_unlock_bh(&state->idev->lock);
-		in6_dev_put(state->idev);
+		state->idev = NULL;
 	}
-	read_unlock(&dev_base_lock);
+	rcu_read_unlock();
 }
 
 static int ac6_seq_show(struct seq_file *seq, void *v)
diff --git a/net/ipv6/mcast.c b/net/ipv6/mcast.c
index f9fcf69..1f9c444 100644
--- a/net/ipv6/mcast.c
+++ b/net/ipv6/mcast.c
@@ -2375,9 +2375,9 @@ static inline struct ifmcaddr6 *igmp6_mc_get_first(struct seq_file *seq)
 	struct net *net = seq_file_net(seq);
 
 	state->idev = NULL;
-	for_each_netdev(net, state->dev) {
+	for_each_netdev_rcu(net, state->dev) {
 		struct inet6_dev *idev;
-		idev = in6_dev_get(state->dev);
+		idev = __in6_dev_get(state->dev);
 		if (!idev)
 			continue;
 		read_lock_bh(&idev->lock);
@@ -2387,7 +2387,6 @@ static inline struct ifmcaddr6 *igmp6_mc_get_first(struct seq_file *seq)
 			break;
 		}
 		read_unlock_bh(&idev->lock);
-		in6_dev_put(idev);
 	}
 	return im;
 }
@@ -2398,16 +2397,15 @@ static struct ifmcaddr6 *igmp6_mc_get_next(struct seq_file *seq, struct ifmcaddr
 
 	im = im->next;
 	while (!im) {
-		if (likely(state->idev != NULL)) {
+		if (likely(state->idev != NULL))
 			read_unlock_bh(&state->idev->lock);
-			in6_dev_put(state->idev);
-		}
-		state->dev = next_net_device(state->dev);
+
+		state->dev = next_net_device_rcu(state->dev);
 		if (!state->dev) {
 			state->idev = NULL;
 			break;
 		}
-		state->idev = in6_dev_get(state->dev);
+		state->idev = __in6_dev_get(state->dev);
 		if (!state->idev)
 			continue;
 		read_lock_bh(&state->idev->lock);
@@ -2426,31 +2424,31 @@ static struct ifmcaddr6 *igmp6_mc_get_idx(struct seq_file *seq, loff_t pos)
 }
 
 static void *igmp6_mc_seq_start(struct seq_file *seq, loff_t *pos)
-	__acquires(dev_base_lock)
+	__acquires(RCU)
 {
-	read_lock(&dev_base_lock);
+	rcu_read_lock();
 	return igmp6_mc_get_idx(seq, *pos);
 }
 
 static void *igmp6_mc_seq_next(struct seq_file *seq, void *v, loff_t *pos)
 {
-	struct ifmcaddr6 *im;
-	im = igmp6_mc_get_next(seq, v);
+	struct ifmcaddr6 *im = igmp6_mc_get_next(seq, v);
+
 	++*pos;
 	return im;
 }
 
 static void igmp6_mc_seq_stop(struct seq_file *seq, void *v)
-	__releases(dev_base_lock)
+	__releases(RCU)
 {
 	struct igmp6_mc_iter_state *state = igmp6_mc_seq_private(seq);
+
 	if (likely(state->idev != NULL)) {
 		read_unlock_bh(&state->idev->lock);
-		in6_dev_put(state->idev);
 		state->idev = NULL;
 	}
 	state->dev = NULL;
-	read_unlock(&dev_base_lock);
+	rcu_read_unlock();
 }
 
 static int igmp6_mc_seq_show(struct seq_file *seq, void *v)
@@ -2507,9 +2505,9 @@ static inline struct ip6_sf_list *igmp6_mcf_get_first(struct seq_file *seq)
 
 	state->idev = NULL;
 	state->im = NULL;
-	for_each_netdev(net, state->dev) {
+	for_each_netdev_rcu(net, state->dev) {
 		struct inet6_dev *idev;
-		idev = in6_dev_get(state->dev);
+		idev = __in6_dev_get(state->dev);
 		if (unlikely(idev == NULL))
 			continue;
 		read_lock_bh(&idev->lock);
@@ -2525,7 +2523,6 @@ static inline struct ip6_sf_list *igmp6_mcf_get_first(struct seq_file *seq)
 			spin_unlock_bh(&im->mca_lock);
 		}
 		read_unlock_bh(&idev->lock);
-		in6_dev_put(idev);
 	}
 	return psf;
 }
@@ -2539,16 +2536,15 @@ static struct ip6_sf_list *igmp6_mcf_get_next(struct seq_file *seq, struct ip6_s
 		spin_unlock_bh(&state->im->mca_lock);
 		state->im = state->im->next;
 		while (!state->im) {
-			if (likely(state->idev != NULL)) {
+			if (likely(state->idev != NULL))
 				read_unlock_bh(&state->idev->lock);
-				in6_dev_put(state->idev);
-			}
-			state->dev = next_net_device(state->dev);
+
+			state->dev = next_net_device_rcu(state->dev);
 			if (!state->dev) {
 				state->idev = NULL;
 				goto out;
 			}
-			state->idev = in6_dev_get(state->dev);
+			state->idev = __in6_dev_get(state->dev);
 			if (!state->idev)
 				continue;
 			read_lock_bh(&state->idev->lock);
@@ -2573,9 +2569,9 @@ static struct ip6_sf_list *igmp6_mcf_get_idx(struct seq_file *seq, loff_t pos)
 }
 
 static void *igmp6_mcf_seq_start(struct seq_file *seq, loff_t *pos)
-	__acquires(dev_base_lock)
+	__acquires(RCU)
 {
-	read_lock(&dev_base_lock);
+	rcu_read_lock();
 	return *pos ? igmp6_mcf_get_idx(seq, *pos - 1) : SEQ_START_TOKEN;
 }
 
@@ -2591,7 +2587,7 @@ static void *igmp6_mcf_seq_next(struct seq_file *seq, void *v, loff_t *pos)
 }
 
 static void igmp6_mcf_seq_stop(struct seq_file *seq, void *v)
-	__releases(dev_base_lock)
+	__releases(RCU)
 {
 	struct igmp6_mcf_iter_state *state = igmp6_mcf_seq_private(seq);
 	if (likely(state->im != NULL)) {
@@ -2600,11 +2596,10 @@ static void igmp6_mcf_seq_stop(struct seq_file *seq, void *v)
 	}
 	if (likely(state->idev != NULL)) {
 		read_unlock_bh(&state->idev->lock);
-		in6_dev_put(state->idev);
 		state->idev = NULL;
 	}
 	state->dev = NULL;
-	read_unlock(&dev_base_lock);
+	rcu_read_unlock();
 }
 
 static int igmp6_mcf_seq_show(struct seq_file *seq, void *v)

^ permalink raw reply related


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox