Netdev List
 help / color / mirror / Atom feed
* [PATCH net-next 7/9] r8169:update rtl8168dp ephy parameter
From: Chunhao Lin @ 2014-12-09 16:46 UTC (permalink / raw)
  To: netdev; +Cc: nic_swsd, linux-kernel, Chunhao Lin
In-Reply-To: <1418143563-7652-1-git-send-email-hau@realtek.com>

Update rtl8168dp ephy parameter to improve pcie compatibility.

Signed-off-by: Chunhao Lin <hau@realtek.com>
---
 drivers/net/ethernet/realtek/r8169.c | 39 ++++++++----------------------------
 1 file changed, 8 insertions(+), 31 deletions(-)

diff --git a/drivers/net/ethernet/realtek/r8169.c b/drivers/net/ethernet/realtek/r8169.c
index a979519..42eda35 100644
--- a/drivers/net/ethernet/realtek/r8169.c
+++ b/drivers/net/ethernet/realtek/r8169.c
@@ -5730,45 +5730,25 @@ static void rtl_hw_start_8168d(struct rtl8169_private *tp)
 	RTL_W16(CPlusCmd, RTL_R16(CPlusCmd) & ~R8168_CPCMD_QUIRK_MASK);
 }
 
-static void rtl_hw_start_8168dp(struct rtl8169_private *tp)
-{
-	void __iomem *ioaddr = tp->mmio_addr;
-	struct pci_dev *pdev = tp->pci_dev;
-
-	rtl_csi_access_enable_1(tp);
-
-	if (tp->dev->mtu <= ETH_DATA_LEN)
-		rtl_tx_performance_tweak(pdev, 0x5 << MAX_READ_REQUEST_SHIFT);
-
-	RTL_W8(MaxTxPacketSize, TxPacketMax);
-
-	rtl_disable_clock_request(pdev);
-}
-
 static void rtl_hw_start_8168d_4(struct rtl8169_private *tp)
 {
 	void __iomem *ioaddr = tp->mmio_addr;
 	struct pci_dev *pdev = tp->pci_dev;
 	static const struct ephy_info e_info_8168d_4[] = {
-		{ 0x0b, ~0,	0x48 },
-		{ 0x19, 0x20,	0x50 },
-		{ 0x0c, ~0,	0x20 }
+		{ 0x0b, 0x0000,	0x0048 },
+		{ 0x19, 0x0020,	0x0050 },
+		{ 0x0c, 0x0100,	0x0020 },
+		{ 0x10, 0x0004,	0x0000 }
 	};
-	int i;
 
 	rtl_csi_access_enable_1(tp);
 
-	rtl_tx_performance_tweak(pdev, 0x5 << MAX_READ_REQUEST_SHIFT);
+	if (tp->dev->mtu <= ETH_DATA_LEN)
+		rtl_tx_performance_tweak(pdev, 0x5 << MAX_READ_REQUEST_SHIFT);
 
 	RTL_W8(MaxTxPacketSize, TxPacketMax);
 
-	for (i = 0; i < ARRAY_SIZE(e_info_8168d_4); i++) {
-		const struct ephy_info *e = e_info_8168d_4 + i;
-		u16 w;
-
-		w = rtl_ephy_read(tp, e->offset);
-		rtl_ephy_write(tp, 0x03, (w & e->mask) | e->bits);
-	}
+	rtl_ephy_init(tp, e_info_8168d_4, ARRAY_SIZE(e_info_8168d_4));
 
 	rtl_enable_clock_request(pdev);
 }
@@ -6328,11 +6308,8 @@ static void rtl_hw_start_8168(struct net_device *dev)
 		break;
 
 	case RTL_GIGA_MAC_VER_28:
-		rtl_hw_start_8168d_4(tp);
-		break;
-
 	case RTL_GIGA_MAC_VER_31:
-		rtl_hw_start_8168dp(tp);
+		rtl_hw_start_8168d_4(tp);
 		break;
 
 	case RTL_GIGA_MAC_VER_32:
-- 
1.9.1

^ permalink raw reply related

* [PATCH net-next 6/9] r8169:update rtl8168e-vl ephy parameter
From: Chunhao Lin @ 2014-12-09 16:46 UTC (permalink / raw)
  To: netdev; +Cc: nic_swsd, linux-kernel, Chunhao Lin
In-Reply-To: <1418143563-7652-1-git-send-email-hau@realtek.com>

Update rtl8168e-vl ephy parameter to improve pcie compatibility.

Signed-off-by: Chunhao Lin <hau@realtek.com>
---
 drivers/net/ethernet/realtek/r8169.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/realtek/r8169.c b/drivers/net/ethernet/realtek/r8169.c
index 2ff8b73..a979519 100644
--- a/drivers/net/ethernet/realtek/r8169.c
+++ b/drivers/net/ethernet/realtek/r8169.c
@@ -5817,7 +5817,9 @@ static void rtl_hw_start_8168e_2(struct rtl8169_private *tp)
 	struct pci_dev *pdev = tp->pci_dev;
 	static const struct ephy_info e_info_8168e_2[] = {
 		{ 0x09, 0x0000,	0x0080 },
-		{ 0x19, 0x0000,	0x0224 }
+		{ 0x19, 0x0000,	0x0224 },
+		{ 0x00, 0x0000,	0x0008 },
+		{ 0x0c, 0x3df0,	0x0200 }
 	};
 
 	rtl_csi_access_enable_1(tp);
-- 
1.9.1

^ permalink raw reply related

* [PATCH net-next 5/9] r8169:update rtl8168fb ephy parameter
From: Chunhao Lin @ 2014-12-09 16:45 UTC (permalink / raw)
  To: netdev; +Cc: nic_swsd, linux-kernel, Chunhao Lin
In-Reply-To: <1418143563-7652-1-git-send-email-hau@realtek.com>

Update rtl8168fb ephy parameter to improve pcie compatibility.

Signed-off-by: Chunhao Lin <hau@realtek.com>
---
 drivers/net/ethernet/realtek/r8169.c | 28 ++++++++++++++++++++++++++--
 1 file changed, 26 insertions(+), 2 deletions(-)

diff --git a/drivers/net/ethernet/realtek/r8169.c b/drivers/net/ethernet/realtek/r8169.c
index bb5a3ba..2ff8b73 100644
--- a/drivers/net/ethernet/realtek/r8169.c
+++ b/drivers/net/ethernet/realtek/r8169.c
@@ -5889,7 +5889,9 @@ static void rtl_hw_start_8168f_1(struct rtl8169_private *tp)
 		{ 0x06, 0x00c0,	0x0020 },
 		{ 0x08, 0x0001,	0x0002 },
 		{ 0x09, 0x0000,	0x0080 },
-		{ 0x19, 0x0000,	0x0224 }
+		{ 0x19, 0x0000,	0x0224 },
+		{ 0x00, 0x0000,	0x0008 },
+		{ 0x0c, 0x3df0,	0x0200 }
 	};
 
 	rtl_hw_start_8168f(tp);
@@ -5902,6 +5904,26 @@ static void rtl_hw_start_8168f_1(struct rtl8169_private *tp)
 	RTL_W8(EEE_LED, RTL_R8(EEE_LED) & ~0x07);
 }
 
+static void rtl_hw_start_8168f_2(struct rtl8169_private *tp)
+{
+	void __iomem *ioaddr = tp->mmio_addr;
+	static const struct ephy_info e_info_8168f_2[] = {
+		{ 0x09, 0x0000,	0x0080 },
+		{ 0x19, 0x0000,	0x0224 },
+		{ 0x00, 0x0000,	0x0008 },
+		{ 0x0c, 0x3df0,	0x0200 }
+	};
+
+	rtl_hw_start_8168f(tp);
+
+	rtl_ephy_init(tp, e_info_8168f_2, ARRAY_SIZE(e_info_8168f_2));
+
+	rtl_w0w1_eri(tp, 0x0d4, ERIAR_MASK_0011, 0x0c00, 0xff00, ERIAR_EXGMAC);
+
+	/* Adjust EEE LED frequency */
+	RTL_W8(EEE_LED, RTL_R8(EEE_LED) & ~0x07);
+}
+
 static void rtl_hw_start_8411(struct rtl8169_private *tp)
 {
 	static const struct ephy_info e_info_8411[] = {
@@ -6320,9 +6342,11 @@ static void rtl_hw_start_8168(struct net_device *dev)
 		break;
 
 	case RTL_GIGA_MAC_VER_35:
-	case RTL_GIGA_MAC_VER_36:
 		rtl_hw_start_8168f_1(tp);
 		break;
+	case RTL_GIGA_MAC_VER_36:
+		rtl_hw_start_8168f_2(tp);
+		break;
 
 	case RTL_GIGA_MAC_VER_38:
 		rtl_hw_start_8411(tp);
-- 
1.9.1

^ permalink raw reply related

* [PATCH net-next 4/9] r8169:update rtl8411 ephy parameter
From: Chunhao Lin @ 2014-12-09 16:45 UTC (permalink / raw)
  To: netdev; +Cc: nic_swsd, linux-kernel, Chunhao Lin
In-Reply-To: <1418143563-7652-1-git-send-email-hau@realtek.com>

Update rtl8411 ephy parameter to improve pcie compatibility.

Signed-off-by: Chunhao Lin <hau@realtek.com>
---
 drivers/net/ethernet/realtek/r8169.c | 8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/drivers/net/ethernet/realtek/r8169.c b/drivers/net/ethernet/realtek/r8169.c
index 9c946df..bb5a3ba 100644
--- a/drivers/net/ethernet/realtek/r8169.c
+++ b/drivers/net/ethernet/realtek/r8169.c
@@ -5904,17 +5904,19 @@ static void rtl_hw_start_8168f_1(struct rtl8169_private *tp)
 
 static void rtl_hw_start_8411(struct rtl8169_private *tp)
 {
-	static const struct ephy_info e_info_8168f_1[] = {
+	static const struct ephy_info e_info_8411[] = {
 		{ 0x06, 0x00c0,	0x0020 },
 		{ 0x0f, 0xffff,	0x5200 },
 		{ 0x1e, 0x0000,	0x4000 },
-		{ 0x19, 0x0000,	0x0224 }
+		{ 0x19, 0x0000,	0x0224 },
+		{ 0x00, 0x0000,	0x0008 },
+		{ 0x0c, 0x3df0,	0x0200 }
 	};
 
 	rtl_hw_start_8168f(tp);
 	rtl_pcie_state_l2l3_enable(tp, false);
 
-	rtl_ephy_init(tp, e_info_8168f_1, ARRAY_SIZE(e_info_8168f_1));
+	rtl_ephy_init(tp, e_info_8411, ARRAY_SIZE(e_info_8411));
 
 	rtl_w0w1_eri(tp, 0x0d4, ERIAR_MASK_0011, 0x0c00, 0x0000, ERIAR_EXGMAC);
 }
-- 
1.9.1

^ permalink raw reply related

* [PATCH net-next 3/9] r8169:update rtl8411b ephy parameter
From: Chunhao Lin @ 2014-12-09 16:45 UTC (permalink / raw)
  To: netdev; +Cc: nic_swsd, linux-kernel, Chunhao Lin
In-Reply-To: <1418143563-7652-1-git-send-email-hau@realtek.com>

Update rtl8411b ephy parameter to improve pcie compatibility.

Signed-off-by: Chunhao Lin <hau@realtek.com>
---
 drivers/net/ethernet/realtek/r8169.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/drivers/net/ethernet/realtek/r8169.c b/drivers/net/ethernet/realtek/r8169.c
index 10aa0b1..9c946df 100644
--- a/drivers/net/ethernet/realtek/r8169.c
+++ b/drivers/net/ethernet/realtek/r8169.c
@@ -6000,10 +6000,11 @@ static void rtl_hw_start_8411_2(struct rtl8169_private *tp)
 	void __iomem *ioaddr = tp->mmio_addr;
 	static const struct ephy_info e_info_8411_2[] = {
 		{ 0x00, 0x0000,	0x0008 },
-		{ 0x0c, 0x3df0,	0x0200 },
+		{ 0x0c, 0x3bf0,	0x0400 },
 		{ 0x0f, 0xffff,	0x5200 },
 		{ 0x19, 0x0020,	0x0000 },
-		{ 0x1e, 0x0000,	0x2000 }
+		{ 0x1e, 0x0000,	0x2000 },
+		{ 0x06, 0x0000,	0x0010 }
 	};
 
 	rtl_hw_start_8168g(tp);
-- 
1.9.1

^ permalink raw reply related

* [PATCH net-next 2/9] r8169:update rtl8168gu ephy parameter
From: Chunhao Lin @ 2014-12-09 16:45 UTC (permalink / raw)
  To: netdev; +Cc: nic_swsd, linux-kernel, Chunhao Lin
In-Reply-To: <1418143563-7652-1-git-send-email-hau@realtek.com>

Update rtl8168gu ephy parameter to improve pcie compatibility.

Signed-off-by: Chunhao Lin <hau@realtek.com>
---
 drivers/net/ethernet/realtek/r8169.c | 13 +++++++++----
 1 file changed, 9 insertions(+), 4 deletions(-)

diff --git a/drivers/net/ethernet/realtek/r8169.c b/drivers/net/ethernet/realtek/r8169.c
index b77efcb..10aa0b1 100644
--- a/drivers/net/ethernet/realtek/r8169.c
+++ b/drivers/net/ethernet/realtek/r8169.c
@@ -5976,10 +5976,15 @@ static void rtl_hw_start_8168g_2(struct rtl8169_private *tp)
 {
 	void __iomem *ioaddr = tp->mmio_addr;
 	static const struct ephy_info e_info_8168g_2[] = {
-		{ 0x00, 0x0000,	0x0008 },
-		{ 0x0c, 0x3df0,	0x0200 },
-		{ 0x19, 0xffff,	0xfc00 },
-		{ 0x1e, 0xffff,	0x20eb }
+		{ 0x00, 0x0008,	0x0000 },
+		{ 0x0c, 0x37d0,	0x0820 },
+		{ 0x1e, 0x0000,	0x0001 },
+		{ 0x19, 0x8000,	0x0000 },
+		{ 0x19, 0xffff,	0x7c00 },
+		{ 0x1e, 0xffff,	0x20eb },
+		{ 0x0d, 0xffff,	0x1666 },
+		{ 0x00, 0x0000,	0x0080 },
+		{ 0x06, 0xffff,	0xf050 }
 	};
 
 	rtl_hw_start_8168g(tp);
-- 
1.9.1

^ permalink raw reply related

* [PATCH net-next 1/9] r8169:update rtl8168g ephy parameter
From: Chunhao Lin @ 2014-12-09 16:45 UTC (permalink / raw)
  To: netdev; +Cc: nic_swsd, linux-kernel, Chunhao Lin
In-Reply-To: <1418143563-7652-1-git-send-email-hau@realtek.com>

Update rtl8168g ephy parameter to improve pcie compatibility.

Signed-off-by: Chunhao Lin <hau@realtek.com>
---
 drivers/net/ethernet/realtek/r8169.c | 24 +++++++++++++++++++++---
 1 file changed, 21 insertions(+), 3 deletions(-)

diff --git a/drivers/net/ethernet/realtek/r8169.c b/drivers/net/ethernet/realtek/r8169.c
index b9c2f33..b77efcb 100644
--- a/drivers/net/ethernet/realtek/r8169.c
+++ b/drivers/net/ethernet/realtek/r8169.c
@@ -5919,7 +5919,7 @@ static void rtl_hw_start_8411(struct rtl8169_private *tp)
 	rtl_w0w1_eri(tp, 0x0d4, ERIAR_MASK_0011, 0x0c00, 0x0000, ERIAR_EXGMAC);
 }
 
-static void rtl_hw_start_8168g_1(struct rtl8169_private *tp)
+static void rtl_hw_start_8168g(struct rtl8169_private *tp)
 {
 	void __iomem *ioaddr = tp->mmio_addr;
 	struct pci_dev *pdev = tp->pci_dev;
@@ -5954,6 +5954,24 @@ static void rtl_hw_start_8168g_1(struct rtl8169_private *tp)
 	rtl_pcie_state_l2l3_enable(tp, false);
 }
 
+static void rtl_hw_start_8168g_1(struct rtl8169_private *tp)
+{
+	void __iomem *ioaddr = tp->mmio_addr;
+	static const struct ephy_info e_info_8168g_1[] = {
+		{ 0x00, 0x0000,	0x0008 },
+		{ 0x0c, 0x37d0,	0x0820 },
+		{ 0x1e, 0x0000,	0x0001 },
+		{ 0x19, 0x8000,	0x0000 }
+	};
+
+	rtl_hw_start_8168g(tp);
+
+	/* disable aspm and clock request before access ephy */
+	RTL_W8(Config2, RTL_R8(Config2) & ~ClkReqEn);
+	RTL_W8(Config5, RTL_R8(Config5) & ~ASPM_en);
+	rtl_ephy_init(tp, e_info_8168g_1, ARRAY_SIZE(e_info_8168g_1));
+}
+
 static void rtl_hw_start_8168g_2(struct rtl8169_private *tp)
 {
 	void __iomem *ioaddr = tp->mmio_addr;
@@ -5964,7 +5982,7 @@ static void rtl_hw_start_8168g_2(struct rtl8169_private *tp)
 		{ 0x1e, 0xffff,	0x20eb }
 	};
 
-	rtl_hw_start_8168g_1(tp);
+	rtl_hw_start_8168g(tp);
 
 	/* disable aspm and clock request before access ephy */
 	RTL_W8(Config2, RTL_R8(Config2) & ~ClkReqEn);
@@ -5983,7 +6001,7 @@ static void rtl_hw_start_8411_2(struct rtl8169_private *tp)
 		{ 0x1e, 0x0000,	0x2000 }
 	};
 
-	rtl_hw_start_8168g_1(tp);
+	rtl_hw_start_8168g(tp);
 
 	/* disable aspm and clock request before access ephy */
 	RTL_W8(Config2, RTL_R8(Config2) & ~ClkReqEn);
-- 
1.9.1

^ permalink raw reply related

* [PATCH net-next 0/9] r8169:update hardware ephy parameter
From: Chunhao Lin @ 2014-12-09 16:45 UTC (permalink / raw)
  To: netdev; +Cc: nic_swsd, linux-kernel, Chunhao Lin

Update hardware ephy parameter to improve pcie compatibility.

These series of patch include the ephy update of following adapters.
rtl8168g
rtl8168gu
rtl8411b
rtl8411
rtl8168fb
rtl8168e-vl
rtl8168dp
rtl8105
rtl8402

Chunhao Lin (9):
  r8169:update rtl8168g ephy parameter
  r8169:update rtl8168gu ephy parameter
  r8169:update rtl8411b ephy parameter
  r8169:update rtl8411 ephy parameter
  r8169:update rtl8168fb ephy parameter
  r8169:update rtl8168e-vl ephy parameter
  r8169:update rtl8168dp ephy parameter
  r8169:update rtl8105e ephy parameter
  r8169:update rtl8402 ephy parameter

 drivers/net/ethernet/realtek/r8169.c | 127 +++++++++++++++++++++--------------
 1 file changed, 78 insertions(+), 49 deletions(-)

-- 
1.9.1

^ permalink raw reply

* Re: [bisect] 3.18 oops in tcp_v4_send_reset()
From: Eric Dumazet @ 2014-12-09 16:28 UTC (permalink / raw)
  To: dann frazier; +Cc: netdev, Eric Dumazet, Alexander Duyck, David S. Miller
In-Reply-To: <1418141914.14835.21.camel@edumazet-glaptop2.roam.corp.google.com>

On Tue, 2014-12-09 at 08:18 -0800, Eric Dumazet wrote:
> On Tue, 2014-12-09 at 08:16 -0800, Eric Dumazet wrote:
> > On Tue, 2014-12-09 at 09:00 -0700, dann frazier wrote:
> > > I'm observing a very reproducible oops which I have bisected down to
> > > commit ca777ef:
> 
> > 
> > Following patch should have fixed this 
> > 
> > http://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=c3658e8d0f10147fc86018be7f11668246c156d3
> > 
> 
> Oh well, fix was not complete. I'll submit a followup patch.
> 

Could you try following fix before I send official patch ?

Thanks !

diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c
index 33f5ff068c7958515e0f63792883a58fb5d6a341..a3f72d7fc06c07c43e1c00b67970eaee074e4593 100644
--- a/net/ipv4/tcp_ipv4.c
+++ b/net/ipv4/tcp_ipv4.c
@@ -623,6 +623,7 @@ static void tcp_v4_send_reset(struct sock *sk, struct sk_buff *skb)
 	arg.iov[0].iov_base = (unsigned char *)&rep;
 	arg.iov[0].iov_len  = sizeof(rep.th);
 
+	net = sk ? sock_net(sk) : dev_net(skb_dst(skb)->dev);
 #ifdef CONFIG_TCP_MD5SIG
 	hash_location = tcp_parse_md5sig_option(th);
 	if (!sk && hash_location) {
@@ -633,7 +634,7 @@ static void tcp_v4_send_reset(struct sock *sk, struct sk_buff *skb)
 		 * Incoming packet is checked with md5 hash with finding key,
 		 * no RST generated if md5 hash doesn't match.
 		 */
-		sk1 = __inet_lookup_listener(dev_net(skb_dst(skb)->dev),
+		sk1 = __inet_lookup_listener(net,
 					     &tcp_hashinfo, ip_hdr(skb)->saddr,
 					     th->source, ip_hdr(skb)->daddr,
 					     ntohs(th->source), inet_iif(skb));
@@ -681,7 +682,6 @@ static void tcp_v4_send_reset(struct sock *sk, struct sk_buff *skb)
 	if (sk)
 		arg.bound_dev_if = sk->sk_bound_dev_if;
 
-	net = dev_net(skb_dst(skb)->dev);
 	arg.tos = ip_hdr(skb)->tos;
 	ip_send_unicast_reply(net, skb, &TCP_SKB_CB(skb)->header.h4.opt,
 			      ip_hdr(skb)->saddr, ip_hdr(skb)->daddr,

^ permalink raw reply related

* Re: [bisect] 3.18 oops in tcp_v4_send_reset()
From: Eric Dumazet @ 2014-12-09 16:18 UTC (permalink / raw)
  To: dann frazier; +Cc: netdev, Eric Dumazet, Alexander Duyck, David S. Miller
In-Reply-To: <1418141783.14835.20.camel@edumazet-glaptop2.roam.corp.google.com>

On Tue, 2014-12-09 at 08:16 -0800, Eric Dumazet wrote:
> On Tue, 2014-12-09 at 09:00 -0700, dann frazier wrote:
> > I'm observing a very reproducible oops which I have bisected down to
> > commit ca777ef:

> 
> Following patch should have fixed this 
> 
> http://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=c3658e8d0f10147fc86018be7f11668246c156d3
> 

Oh well, fix was not complete. I'll submit a followup patch.

^ permalink raw reply

* Re: [bisect] 3.18 oops in tcp_v4_send_reset()
From: Eric Dumazet @ 2014-12-09 16:16 UTC (permalink / raw)
  To: dann frazier; +Cc: netdev, Eric Dumazet, Alexander Duyck, David S. Miller
In-Reply-To: <20141209160023.GA31520@fluid.dannf>

On Tue, 2014-12-09 at 09:00 -0700, dann frazier wrote:
> I'm observing a very reproducible oops which I have bisected down to
> commit ca777ef:
> 
>     tcp: remove dst refcount false sharing for prequeue mode
> 
> I'm reproducing using the juju application, and this occurs when
> tearing down a local lxc container (juju bootstrap/juju
> destroy-environment local). Also worth noting that I'm on an
> arm64 system. I'll follow up w/ results once I've attempted to
> reproduce on x86, and if I'm able to create a simpler reproducer.
> 
> [  540.914174] Unable to handle kernel NULL pointer dereference at virtual address 00000018
> [  540.922254] pgd = ffffffc3ea9bb000
> [  540.925646] [00000018] *pgd=00000043e7bfb003, *pud=00000043e7bfb003, *pmd=0000000000000000
> [  540.933902] Internal error: Oops: 96000006 [#1] SMP
> [  540.938754] Modules linked in: veth xt_CHECKSUM xt_tcpudp iptable_mangle ipt_MASQUERADE nf_nat_masquerade_ipv4 iptable_nat nf
> _conntrack_ipv4 nf_defrag_ipv4 nf_nat_ipv4 nf_nat nf_conntrack bridge stp llc ip_tables x_tables ahci_xgene libahci_platform lib
> ahci xgene_enet
> [  540.962592] CPU: 4 PID: 2788 Comm: mongod Not tainted 3.18.0 #65
> [  540.968566] task: ffffffc0fe45d400 ti: ffffffc3e6510000 task.ti: ffffffc3e6510000
> [  540.976014] PC is at tcp_v4_send_reset+0x2ec/0x3e4
> [  540.980778] LR is at tcp_v4_send_reset+0x3c8/0x3e4
> [  540.985542] pc : [<ffffffc00069b5dc>] lr : [<ffffffc00069b6b8>] pstate: 80000145
> [  540.992897] sp : ffffffc3e6513a60
> [  540.996192] x29: ffffffc3e6513a60 x28: ffffffc3e7a8c600 
> [  541.001494] x27: 0000000000000000 x26: ffffffc3e6510000 
> [  541.006796] x25: 0000000000000000 x24: ffffffc3e6513ab8 
> [  541.012099] x23: 0000000000000000 x22: 0000000000000000 
> [  541.017401] x21: ffffffc3e7a8c600 x20: ffffffc000b65000 
> [  541.022703] x19: ffffffc3e655e6e0 x18: 000000000000000d 
> [  541.028005] x17: 0000007fb2735e10 x16: ffffffc00012052c 
> [  541.033306] x15: 0000007fb2728590 x14: 282039363638333a 
> [  541.038608] x13: 0000000062df7dbf x12: 206e6f697463656e 
> [  541.043910] x11: 0000000000000000 x10: 0000000000000000 
> [  541.049212] x9 : 00000000000012d1 x8 : 00000000000346db 
> [  541.054515] x7 : 0000000000000018 x6 : 0000000000000014 
> [  541.059817] x5 : ffffffc3e6513ae0 x4 : 0000000000000000 
> [  541.065118] x3 : ffffffc0fe6d70ac x2 : ffffffc3e655e71c 
> [  541.070420] x1 : ffffffc3e655e6e0 x0 : 00000000000000ac 
> [  541.075722] 
> [  541.077202] Process mongod (pid: 2788, stack limit = 0xffffffc3e6510058)
> [  541.083868] Stack: (0xffffffc3e6513a60 to 0xffffffc3e6514000)

> [  541.455640] Call trace:
> [  541.458074] [<ffffffc00069b5dc>] tcp_v4_send_reset+0x2ec/0x3e4
> [  541.463877] [<ffffffc00069bc04>] tcp_v4_do_rcv+0xfc/0x350
> [  541.469247] [<ffffffc000686ff0>] tcp_prequeue_process+0x98/0xdc
> [  541.475134] [<ffffffc0006880cc>] tcp_recvmsg+0x4c8/0xa0c
> [  541.480419] [<ffffffc0006b1f10>] inet_recvmsg+0x98/0xb4
> [  541.485618] [<ffffffc0006241a8>] sock_aio_read.part.12+0xf0/0x118
> [  541.491679] [<ffffffc000624218>] sock_aio_read+0x48/0x74
> [  541.496964] [<ffffffc0002006bc>] do_sync_read+0x8c/0xd0
> [  541.502161] [<ffffffc000201290>] vfs_read+0x128/0x1a8
> [  541.507185] [<ffffffc000201c34>] SyS_read+0x50/0xb0
> [  541.512037] Code: 927ff884 b9408ba6 910203a5 8b000063 (f9400c80) 
> [  541.518108] ---[ end trace 524a277a323ba5bd ]---
> --


Following patch should have fixed this 

http://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=c3658e8d0f10147fc86018be7f11668246c156d3

^ permalink raw reply

* [bisect] 3.18 oops in tcp_v4_send_reset()
From: dann frazier @ 2014-12-09 16:00 UTC (permalink / raw)
  To: netdev; +Cc: Eric Dumazet, Alexander Duyck, David S. Miller

I'm observing a very reproducible oops which I have bisected down to
commit ca777ef:

    tcp: remove dst refcount false sharing for prequeue mode

I'm reproducing using the juju application, and this occurs when
tearing down a local lxc container (juju bootstrap/juju
destroy-environment local). Also worth noting that I'm on an
arm64 system. I'll follow up w/ results once I've attempted to
reproduce on x86, and if I'm able to create a simpler reproducer.

[  540.914174] Unable to handle kernel NULL pointer dereference at virtual address 00000018
[  540.922254] pgd = ffffffc3ea9bb000
[  540.925646] [00000018] *pgd=00000043e7bfb003, *pud=00000043e7bfb003, *pmd=0000000000000000
[  540.933902] Internal error: Oops: 96000006 [#1] SMP
[  540.938754] Modules linked in: veth xt_CHECKSUM xt_tcpudp iptable_mangle ipt_MASQUERADE nf_nat_masquerade_ipv4 iptable_nat nf
_conntrack_ipv4 nf_defrag_ipv4 nf_nat_ipv4 nf_nat nf_conntrack bridge stp llc ip_tables x_tables ahci_xgene libahci_platform lib
ahci xgene_enet
[  540.962592] CPU: 4 PID: 2788 Comm: mongod Not tainted 3.18.0 #65
[  540.968566] task: ffffffc0fe45d400 ti: ffffffc3e6510000 task.ti: ffffffc3e6510000
[  540.976014] PC is at tcp_v4_send_reset+0x2ec/0x3e4
[  540.980778] LR is at tcp_v4_send_reset+0x3c8/0x3e4
[  540.985542] pc : [<ffffffc00069b5dc>] lr : [<ffffffc00069b6b8>] pstate: 80000145
[  540.992897] sp : ffffffc3e6513a60
[  540.996192] x29: ffffffc3e6513a60 x28: ffffffc3e7a8c600 
[  541.001494] x27: 0000000000000000 x26: ffffffc3e6510000 
[  541.006796] x25: 0000000000000000 x24: ffffffc3e6513ab8 
[  541.012099] x23: 0000000000000000 x22: 0000000000000000 
[  541.017401] x21: ffffffc3e7a8c600 x20: ffffffc000b65000 
[  541.022703] x19: ffffffc3e655e6e0 x18: 000000000000000d 
[  541.028005] x17: 0000007fb2735e10 x16: ffffffc00012052c 
[  541.033306] x15: 0000007fb2728590 x14: 282039363638333a 
[  541.038608] x13: 0000000062df7dbf x12: 206e6f697463656e 
[  541.043910] x11: 0000000000000000 x10: 0000000000000000 
[  541.049212] x9 : 00000000000012d1 x8 : 00000000000346db 
[  541.054515] x7 : 0000000000000018 x6 : 0000000000000014 
[  541.059817] x5 : ffffffc3e6513ae0 x4 : 0000000000000000 
[  541.065118] x3 : ffffffc0fe6d70ac x2 : ffffffc3e655e71c 
[  541.070420] x1 : ffffffc3e655e6e0 x0 : 00000000000000ac 
[  541.075722] 
[  541.077202] Process mongod (pid: 2788, stack limit = 0xffffffc3e6510058)
[  541.083868] Stack: (0xffffffc3e6513a60 to 0xffffffc3e6514000)
[  541.089585] 3a60: e6513b20 ffffffc3 0069bc08 ffffffc0 e655e6e0 ffffffc3 e7a8c600 ffffffc3
[  541.097720] 3a80: 00000000 00000000 00000001 00000000 009be3c0 ffffffc0 e7a8cacc ffffffc3
[  541.105855] 3aa0: e7a8c690 ffffffc3 e7a8c600 ffffffc3 00000000 00000000 bccb9990 bf7ddf62
[  541.113990] 3ac0: 00000000 00000450 00000000 00000000 00000000 00000000 00000000 00000000
[  541.122124] 3ae0: e6513ab8 ffffffc3 00000014 00000000 00000000 02001afe 00000008 00000000
[  541.130259] 3b00: 00000000 00000000 00628130 ffffffc0 e6513b40 ffffffc3 dc8cb000 cb88537f
[  541.138394] 3b20: e6513b80 ffffffc3 00686ff4 ffffffc0 e7a8c600 ffffffc3 e7a8cb08 ffffffc3
[  541.146528] 3b40: 00000000 00000000 00000001 00000000 009be3c0 ffffffc0 e7a8cacc ffffffc3
[  541.154662] 3b60: 00000000 00000000 00628130 ffffffc0 e7a8c600 ffffffc3 00000000 00000000
[  541.162797] 3b80: e6513ba0 ffffffc3 006880d0 ffffffc0 00000000 00000000 00000005 00000000
[  541.170931] 3ba0: e6513c50 ffffffc3 006b1f14 ffffffc0 e6513d20 ffffffc3 e6513de8 ffffffc3
[  541.179066] 3bc0: 00000000 00000000 e6513de8 ffffffc3 efc54f00 ffffffc3 00000005 00000000
[  541.187200] 3be0: 00000119 00000000 0000003f 00000000 00ab8000 ffffffc0 e6510000 ffffffc3
[  541.195335] 3c00: efc54f00 ffffffc3 0000003d 00000000 e6513ba0 ffffffc3 00000040 00000000
[  541.203469] 3c20: e6513d20 ffffffc3 009be400 ffffffc0 92000007 00000000 fe45d400 ffffffc0
[  541.211604] 3c40: eb2fc7e0 ffffffc3 ffffffff 7fffffff e6513ca0 ffffffc3 006241ac ffffffc0
[  541.219738] 3c60: 00000005 00000000 e6513d20 ffffffc3 e6513ca0 ffffffc3 efc54f00 ffffffc3
[  541.227873] 3c80: 00000005 00000000 ffffffff 00000000 e6513d20 ffffffc3 00000005 00000000
[  541.236009] 3ca0: e6513d60 ffffffc3 0062421c ffffffc0 e6513de8 ffffffc3 e99e1d00 ffffffc3
[  541.244144] 3cc0: 00000005 00000000 18006fe3 0000007f 80000000 00000000 00000015 00000000
[  541.252278] 3ce0: e6513ec8 ffffffc3 e99e1d00 ffffffc3 0000003d 00000000 00000000 00000005
[  541.260413] 3d00: efc54f00 ffffffc3 00000015 00000000 00000000 00000000 e6513d20 ffffffc3
[  541.268547] 3d20: 00000000 00000000 00000000 ffffffc3 e6513dd8 ffffffc3 00000001 00000000
[  541.276682] 3d40: 00000000 00000000 00000000 00000000 00000000 00000000 e6513de8 ffffffc3
[  541.284817] 3d60: e6513da0 ffffffc3 002006c0 ffffffc0 e6513ec8 ffffffc3 00364ea0 ffffffc0
[  541.292952] 3d80: e99e1d00 ffffffc3 e6513dd8 ffffffc3 00000001 00000000 00000000 00000000
[  541.301086] 3da0: e6513e40 ffffffc3 00201294 ffffffc0 00000005 00000000 e99e1d00 ffffffc3
[  541.309221] 3dc0: 18006fe3 0000007f e6513ec8 ffffffc3 e6513e00 ffffffc3 18006fe3 0000007f
[  541.317355] 3de0: 00000005 00000000 e99e1d00 ffffffc3 00000000 00000000 00000000 00000000
[  541.325490] 3e00: e6513ce8 ffffffc3 fe45d400 ffffffc0 00000000 00000000 00000000 00000000
[  541.333624] 3e20: 00000005 00000000 00000000 00000000 00000000 00000000 00000000 00000000
[  541.341758] 3e40: e6513e80 ffffffc3 00201c38 ffffffc0 e99e1d01 ffffffc3 e99e1d00 ffffffc3
[  541.349893] 3e60: ffffffff ffffffff b273b864 0000007f 80000000 00000000 b2737188 0000007f
[  541.358027] 3e80: 841faef0 0000007f 0008425c ffffffc0 00000000 00000000 00000005 00000000
[  541.366162] 3ea0: ffffffff ffffffff 00000001 00000000 18006fe3 0000007f 00000005 00000000
[  541.374296] 3ec0: 00000000 00000000 00000000 00000000 00000024 00000000 18006fe3 0000007f
[  541.382431] 3ee0: 00000005 00000000 841fbeb8 0000007f 841faeac 0000007f 841fc4a0 0000007f
[  541.390565] 3f00: ffffffbb 00000000 00000000 00000000 0000003f 00000000 93ccf8ed 00e370ef
[  541.398700] 3f20: 0000009e 00000000 00000070 00000000 93ccf8ed 000000ef 00000009 00000000
[  541.406834] 3f40: 0000009b 00000000 00000095 00000000 00000000 00000000 b273b810 0000007f
[  541.414968] 3f60: 000000aa 00000000 180016b0 0000007f 00000005 00000000 18006fe3 0000007f
[  541.423103] 3f80: 00000005 00000000 00000005 00000000 18006fe3 0000007f 00000000 00000000
[  541.431237] 3fa0: 841fc900 0000007f 0000feff 00000000 180012e0 0000007f 841faef0 0000007f
[  541.439372] 3fc0: b273b84c 0000007f 841faee0 0000007f b273b864 0000007f 80000000 00000000
[  541.447506] 3fe0: 00000024 00000000 0000003f 00000000 ed238e70 ffffffbe ed238ea8 ffffffbe
[  541.455640] Call trace:
[  541.458074] [<ffffffc00069b5dc>] tcp_v4_send_reset+0x2ec/0x3e4
[  541.463877] [<ffffffc00069bc04>] tcp_v4_do_rcv+0xfc/0x350
[  541.469247] [<ffffffc000686ff0>] tcp_prequeue_process+0x98/0xdc
[  541.475134] [<ffffffc0006880cc>] tcp_recvmsg+0x4c8/0xa0c
[  541.480419] [<ffffffc0006b1f10>] inet_recvmsg+0x98/0xb4
[  541.485618] [<ffffffc0006241a8>] sock_aio_read.part.12+0xf0/0x118
[  541.491679] [<ffffffc000624218>] sock_aio_read+0x48/0x74
[  541.496964] [<ffffffc0002006bc>] do_sync_read+0x8c/0xd0
[  541.502161] [<ffffffc000201290>] vfs_read+0x128/0x1a8
[  541.507185] [<ffffffc000201c34>] SyS_read+0x50/0xb0
[  541.512037] Code: 927ff884 b9408ba6 910203a5 8b000063 (f9400c80) 
[  541.518108] ---[ end trace 524a277a323ba5bd ]---

^ permalink raw reply

* Re: Antw: Re: Q: need effective backlog for listen()
From: Philippe Troin @ 2014-12-09 15:07 UTC (permalink / raw)
  To: Ulrich Windl; +Cc: netdev
In-Reply-To: <5486AC64020000A1000183D0@gwsmtp1.uni-regensburg.de>

On Tue, 2014-12-09 at 08:01 +0100, Ulrich Windl wrote:
> >>> Philippe Troin <phil@fifi.org> schrieb am 08.12.2014 um 17:35 in Nachricht
> <1418056540.384.5.camel@niobium.home.fifi.org>:
>
> > The argument to listen() specifies how many connections the system is
> > allow to keep waiting to be accept()ed.
> > As soon as you accept() the connection, the count is decremented.
> > So that won't help for your use case.
> > 
> >> However none of the above see ms true. Even if my server delays
> >> accept()ing new connections, no client ever sees a "connection
> >> refused" or "connection timed out". Is there any chance to signal the
> >> client that no more connections are accepted at the moment?
> > 
> > Close the listening socket.  No new connections will be accepted.
> > When you reopen the socket for accepting new connections, you may have
> > to use SO_REUSEADDR before bind()ing to the port.
> 
> This is what I had done, but those connections who are waiting to be
> accepted: If I close the listening socket, will the clients see a
> connection abort, or will they see a connection refused?
> Connection aborts could confuse clients.

The clients that completed the 3-way handshake and are waiting for their
(server-side) socket to be accept()ed will see connection reset I
believe.

You may be able to work something out by having no listen backlog
(listen(0)) and closing and reopening the socket when needed.

Phil.

^ permalink raw reply

* Re: [ovs-dev] OVS Kernel Datapath development
From: Thomas F Herbert @ 2014-12-09 14:59 UTC (permalink / raw)
  To: Pravin Shelar, Thomas Graf; +Cc: dev@openvswitch.org, netdev
In-Reply-To: <CALnjE+p6udF7oPBBjZWcT79iGOWAwLW3eWzEMJw+MX7W3WOjLA@mail.gmail.com>

Thanks.

What is the impact on a developer submitting a patch. Do we now submit 
the linux datapath portion of the patch to both netdev and ovs-dev?

--Tom

On 12/8/14, 1:30 PM, Pravin Shelar wrote:
> On Mon, Dec 8, 2014 at 9:15 AM, Thomas Graf <tgraf@noironetworks.com> wrote:
>> On 12/07/14 at 08:47pm, Pravin Shelar wrote:
>>> Since the beginning OVS kernel datapath development is primarily done
>>> on external OVS repo. Now we have mostly synced upstream and external
>>> OVS. So we have decided to change this process. New process is as
>>> follows.
>>>
>>> 1. OVS feature development that involves kernel datapath should be
>>> done on net-next tree datapath.
>>> 2. Such feature patch series should be posted on netdev and ovs-dev
>>> mailing list.
>>> 3. Once review is done for entire series, kernel and OVS userspace
>>> patches will be merged in respective repo.
>>> 4. After the merge developer is suppose to send patches for external
>>> kernel datapath along with old kernel compatibility code. So that we
>>> can keep external datapath insync.
>> +1
>>
>> Just to be clear, by respective repo do you mean net-next/net or will
>> you maintain a net-next branch on git.kernel.org and continue doing
>> pull requests?
> OVS patches will directly go to net-next/net tree. I am not planning
> on maintaining any tree on git.kernel.org.
> _______________________________________________
> dev mailing list
> dev@openvswitch.org
> http://openvswitch.org/mailman/listinfo/dev


-- 
Thomas F. Herbert

^ permalink raw reply

* Re: Re: [bisected] xfrm: TCP connection initiating PMTU discovery stalls on v3.
From: Thomas Jarosch @ 2014-12-09 14:49 UTC (permalink / raw)
  To: Eric Dumazet
  Cc: Wolfgang Walter, netdev, Eric Dumazet, Herbert Xu,
	Steffen Klassert
In-Reply-To: <1418135209.14835.17.camel@edumazet-glaptop2.roam.corp.google.com>

On Tuesday, 9. December 2014 06:26:49 Eric Dumazet wrote:
> > If it helps, I'm running the reverted patch on five production boxes
> > hitherto without a hiccup. As far as I understood the original commit
> > message, some packet counters might me wrong without it.
> > 
> > @Eric: What could possibly go wrong(tm)? :)
> 
> Crashes in TCP stack, because of packet count mismatches.

alright, that sounds like a pretty good argument.

> ...
> I would disable TSO/GSO on xfrm, and problem should disappear.

I guess you can't explicitly disable this with the "ip xfrm" command?
Or do you mean this should be disabled on the ethX device
serving the xfrm connection?

We are about to push out this code to ten more machines,
so the best time (for me) to do any changes  that increases
stability would be now :o)

Cheers,
Thomas

^ permalink raw reply

* [RFC PATCH net-next 11/11] net: fec: remove disable_irq from netpoll controller, use netpoll_irq_lock
From: Sabrina Dubroca @ 2014-12-09 14:37 UTC (permalink / raw)
  To: davem; +Cc: netdev, Sabrina Dubroca
In-Reply-To: <1418135842-21389-1-git-send-email-sd@queasysnail.net>

disable_irq() may sleep, replace it with a spin_lock in the interrupt
handler and netpoll controller.

No actual testing done, only compiled.

Signed-off-by: Sabrina Dubroca <sd@queasysnail.net>
---
 drivers/net/ethernet/freescale/fec.h      |  2 ++
 drivers/net/ethernet/freescale/fec_main.c | 14 ++++++++++++++
 2 files changed, 16 insertions(+)

diff --git a/drivers/net/ethernet/freescale/fec.h b/drivers/net/ethernet/freescale/fec.h
index 469691ad4a1e..fe8931465a53 100644
--- a/drivers/net/ethernet/freescale/fec.h
+++ b/drivers/net/ethernet/freescale/fec.h
@@ -16,6 +16,7 @@
 #include <linux/clocksource.h>
 #include <linux/net_tstamp.h>
 #include <linux/ptp_clock_kernel.h>
+#include <linux/netpoll.h>
 
 #if defined(CONFIG_M523x) || defined(CONFIG_M527x) || defined(CONFIG_M528x) || \
     defined(CONFIG_M520x) || defined(CONFIG_M532x) || \
@@ -509,6 +510,7 @@ struct fec_enet_private {
 	int	speed;
 	struct	completion mdio_done;
 	int	irq[FEC_IRQ_NUM];
+	struct netpoll_irq_lock netpoll_locks[FEC_IRQ_NUM];
 	bool	bufdesc_ex;
 	int	pause_flag;
 	u32	quirks;
diff --git a/drivers/net/ethernet/freescale/fec_main.c b/drivers/net/ethernet/freescale/fec_main.c
index d2955ce24d0b..b7579c5acedb 100644
--- a/drivers/net/ethernet/freescale/fec_main.c
+++ b/drivers/net/ethernet/freescale/fec_main.c
@@ -1558,6 +1558,18 @@ fec_enet_interrupt(int irq, void *dev_id)
 	const unsigned napi_mask = FEC_ENET_RXF | FEC_ENET_TXF;
 	uint int_events;
 	irqreturn_t ret = IRQ_NONE;
+	int i;
+	struct netpoll_irq_lock *netpoll_lock = NULL;
+
+	for (i = 0; i < FEC_IRQ_NUM; i++) {
+		if (fep->irq[i] == irq) {
+			netpoll_lock = &fep->netpoll_locks[i];
+			netpoll_irq_lock(netpoll_lock);
+			break;
+		}
+	}
+	if (!netpoll_lock)
+		return ret;
 
 	int_events = readl(fep->hwp + FEC_IEVENT);
 	writel(int_events & ~napi_mask, fep->hwp + FEC_IEVENT);
@@ -1579,6 +1591,7 @@ fec_enet_interrupt(int irq, void *dev_id)
 	if (fep->ptp_clock)
 		fec_ptp_check_pps_event(fep);
 
+	netpoll_irq_unlock(netpoll_lock);
 	return ret;
 }
 
@@ -3237,6 +3250,7 @@ fec_probe(struct platform_device *pdev)
 
 	for (i = 0; i < FEC_IRQ_NUM; i++) {
 		irq = platform_get_irq(pdev, i);
+		netpoll_irq_lock_init(&fep->netpoll_locks[i]);
 		if (irq < 0) {
 			if (i)
 				break;
-- 
2.1.3

^ permalink raw reply related

* [RFC PATCH net-next 10/11] gianfar: remove disable_irq from netpoll controller, use netpoll_irq_lock
From: Sabrina Dubroca @ 2014-12-09 14:37 UTC (permalink / raw)
  To: davem; +Cc: netdev, Sabrina Dubroca, Claudiu Manoil
In-Reply-To: <1418135842-21389-1-git-send-email-sd@queasysnail.net>

disable_irq() may sleep, replace it with a spin_lock in the interrupt
handler and netpoll controller.

No actual testing done, only compiled.

Signed-off-by: Sabrina Dubroca <sd@queasysnail.net>
Cc: Claudiu Manoil <claudiu.manoil@freescale.com>
---
 drivers/net/ethernet/freescale/gianfar.c | 38 ++++++++++++++------------------
 drivers/net/ethernet/freescale/gianfar.h |  5 +++++
 2 files changed, 21 insertions(+), 22 deletions(-)

diff --git a/drivers/net/ethernet/freescale/gianfar.c b/drivers/net/ethernet/freescale/gianfar.c
index 86dccb26fecc..c6e85983fb65 100644
--- a/drivers/net/ethernet/freescale/gianfar.c
+++ b/drivers/net/ethernet/freescale/gianfar.c
@@ -2709,6 +2709,7 @@ irqreturn_t gfar_receive(int irq, void *grp_id)
 	unsigned long flags;
 	u32 imask;
 
+	netpoll_irq_lock(&grp->netpoll_rx_lock);
 	if (likely(napi_schedule_prep(&grp->napi_rx))) {
 		spin_lock_irqsave(&grp->grplock, flags);
 		imask = gfar_read(&grp->regs->imask);
@@ -2723,6 +2724,7 @@ irqreturn_t gfar_receive(int irq, void *grp_id)
 		gfar_write(&grp->regs->ievent, IEVENT_RX_MASK);
 	}
 
+	netpoll_irq_unlock(&grp->netpoll_rx_lock);
 	return IRQ_HANDLED;
 }
 
@@ -2733,6 +2735,7 @@ static irqreturn_t gfar_transmit(int irq, void *grp_id)
 	unsigned long flags;
 	u32 imask;
 
+	netpoll_irq_lock(&grp->netpoll_tx_lock);
 	if (likely(napi_schedule_prep(&grp->napi_tx))) {
 		spin_lock_irqsave(&grp->grplock, flags);
 		imask = gfar_read(&grp->regs->imask);
@@ -2747,6 +2750,7 @@ static irqreturn_t gfar_transmit(int irq, void *grp_id)
 		gfar_write(&grp->regs->ievent, IEVENT_TX_MASK);
 	}
 
+	netpoll_irq_unlock(&grp->netpoll_tx_lock);
 	return IRQ_HANDLED;
 }
 
@@ -3073,27 +3077,10 @@ static void gfar_netpoll(struct net_device *dev)
 	struct gfar_private *priv = netdev_priv(dev);
 	int i;
 
-	/* If the device has multiple interrupts, run tx/rx */
-	if (priv->device_flags & FSL_GIANFAR_DEV_HAS_MULTI_INTR) {
-		for (i = 0; i < priv->num_grps; i++) {
-			struct gfar_priv_grp *grp = &priv->gfargrp[i];
-
-			disable_irq(gfar_irq(grp, TX)->irq);
-			disable_irq(gfar_irq(grp, RX)->irq);
-			disable_irq(gfar_irq(grp, ER)->irq);
-			gfar_interrupt(gfar_irq(grp, TX)->irq, grp);
-			enable_irq(gfar_irq(grp, ER)->irq);
-			enable_irq(gfar_irq(grp, RX)->irq);
-			enable_irq(gfar_irq(grp, TX)->irq);
-		}
-	} else {
-		for (i = 0; i < priv->num_grps; i++) {
-			struct gfar_priv_grp *grp = &priv->gfargrp[i];
+	for (i = 0; i < priv->num_grps; i++) {
+		struct gfar_priv_grp *grp = &priv->gfargrp[i];
 
-			disable_irq(gfar_irq(grp, TX)->irq);
-			gfar_interrupt(gfar_irq(grp, TX)->irq, grp);
-			enable_irq(gfar_irq(grp, TX)->irq);
-		}
+		gfar_interrupt(gfar_irq(grp, TX)->irq, grp);
 	}
 }
 #endif
@@ -3102,9 +3089,11 @@ static void gfar_netpoll(struct net_device *dev)
 static irqreturn_t gfar_interrupt(int irq, void *grp_id)
 {
 	struct gfar_priv_grp *gfargrp = grp_id;
+	u32 events;
 
+	netpoll_irq_lock(&gfargrp->netpoll_intr_lock);
 	/* Save ievent for future reference */
-	u32 events = gfar_read(&gfargrp->regs->ievent);
+	events = gfar_read(&gfargrp->regs->ievent);
 
 	/* Check for reception */
 	if (events & IEVENT_RX_MASK)
@@ -3118,6 +3107,7 @@ static irqreturn_t gfar_interrupt(int irq, void *grp_id)
 	if (events & IEVENT_ERR_MASK)
 		gfar_error(irq, grp_id);
 
+	netpoll_irq_unlock(&gfargrp->netpoll_intr_lock);
 	return IRQ_HANDLED;
 }
 
@@ -3306,9 +3296,11 @@ static irqreturn_t gfar_error(int irq, void *grp_id)
 	struct gfar __iomem *regs = gfargrp->regs;
 	struct gfar_private *priv= gfargrp->priv;
 	struct net_device *dev = priv->ndev;
+	u32 events;
 
+	netpoll_irq_lock(&gfargrp->netpoll_err_lock);
 	/* Save ievent for future reference */
-	u32 events = gfar_read(&regs->ievent);
+	events = gfar_read(&regs->ievent);
 
 	/* Clear IEVENT */
 	gfar_write(&regs->ievent, events & IEVENT_ERR_MASK);
@@ -3377,6 +3369,8 @@ static irqreturn_t gfar_error(int irq, void *grp_id)
 		atomic64_inc(&priv->extra_stats.tx_babt);
 		netif_dbg(priv, tx_err, dev, "babbling TX error\n");
 	}
+
+	netpoll_irq_unlock(&gfargrp->netpoll_err_lock);
 	return IRQ_HANDLED;
 }
 
diff --git a/drivers/net/ethernet/freescale/gianfar.h b/drivers/net/ethernet/freescale/gianfar.h
index b581b8823a2a..4da559dd772d 100644
--- a/drivers/net/ethernet/freescale/gianfar.h
+++ b/drivers/net/ethernet/freescale/gianfar.h
@@ -37,6 +37,7 @@
 #include <linux/mm.h>
 #include <linux/mii.h>
 #include <linux/phy.h>
+#include <linux/netpoll.h>
 
 #include <asm/io.h>
 #include <asm/irq.h>
@@ -1079,6 +1080,10 @@ struct gfar_priv_grp {
 	unsigned long rx_bit_map;
 
 	struct gfar_irqinfo *irqinfo[GFAR_NUM_IRQS];
+	struct netpoll_irq_lock netpoll_intr_lock;
+	struct netpoll_irq_lock netpoll_rx_lock;
+	struct netpoll_irq_lock netpoll_tx_lock;
+	struct netpoll_irq_lock netpoll_err_lock;
 };
 
 #define gfar_irq(grp, ID) \
-- 
2.1.3

^ permalink raw reply related

* [RFC PATCH net-next 09/11] xilinx/axienet: remove disable_irq from netpoll controller, use netpoll_irq_lock
From: Sabrina Dubroca @ 2014-12-09 14:37 UTC (permalink / raw)
  To: davem
  Cc: netdev, Sabrina Dubroca, Anirudha Sarangi, John Linn,
	Michal Simek, Sören Brinkmann
In-Reply-To: <1418135842-21389-1-git-send-email-sd@queasysnail.net>

disable_irq() may sleep, replace it with a spin_lock in the interrupt
handler and netpoll controller.

No actual testing done, only compiled.

Signed-off-by: Sabrina Dubroca <sd@queasysnail.net>
Cc: Anirudha Sarangi <anirudh@xilinx.com>
Cc: John Linn <John.Linn@xilinx.com>
Cc: Michal Simek <michal.simek@xilinx.com>
Cc: "Sören Brinkmann" <soren.brinkmann@xilinx.com>
---
 drivers/net/ethernet/xilinx/xilinx_axienet.h      |  3 +++
 drivers/net/ethernet/xilinx/xilinx_axienet_main.c | 15 +++++++++------
 2 files changed, 12 insertions(+), 6 deletions(-)

diff --git a/drivers/net/ethernet/xilinx/xilinx_axienet.h b/drivers/net/ethernet/xilinx/xilinx_axienet.h
index 44b8d2bad8c3..b871857cb258 100644
--- a/drivers/net/ethernet/xilinx/xilinx_axienet.h
+++ b/drivers/net/ethernet/xilinx/xilinx_axienet.h
@@ -9,6 +9,7 @@
 #define XILINX_AXIENET_H
 
 #include <linux/netdevice.h>
+#include <linux/netpoll.h>
 #include <linux/spinlock.h>
 #include <linux/interrupt.h>
 
@@ -455,6 +456,8 @@ struct axienet_local {
 
 	u32 coalesce_count_rx;
 	u32 coalesce_count_tx;
+
+	struct netpoll_irq_lock netpoll_lock;
 };
 
 /**
diff --git a/drivers/net/ethernet/xilinx/xilinx_axienet_main.c b/drivers/net/ethernet/xilinx/xilinx_axienet_main.c
index 4ea2d4e6f1d1..ff6be3d82618 100644
--- a/drivers/net/ethernet/xilinx/xilinx_axienet_main.c
+++ b/drivers/net/ethernet/xilinx/xilinx_axienet_main.c
@@ -806,6 +806,7 @@ static irqreturn_t axienet_tx_irq(int irq, void *_ndev)
 	struct net_device *ndev = _ndev;
 	struct axienet_local *lp = netdev_priv(ndev);
 
+	netpoll_irq_lock(&lp->netpoll_lock);
 	status = axienet_dma_in32(lp, XAXIDMA_TX_SR_OFFSET);
 	if (status & (XAXIDMA_IRQ_IOC_MASK | XAXIDMA_IRQ_DELAY_MASK)) {
 		axienet_start_xmit_done(lp->ndev);
@@ -834,6 +835,7 @@ static irqreturn_t axienet_tx_irq(int irq, void *_ndev)
 	}
 out:
 	axienet_dma_out32(lp, XAXIDMA_TX_SR_OFFSET, status);
+	netpoll_irq_unlock(&lp->netpoll_lock);
 	return IRQ_HANDLED;
 }
 
@@ -854,6 +856,7 @@ static irqreturn_t axienet_rx_irq(int irq, void *_ndev)
 	struct net_device *ndev = _ndev;
 	struct axienet_local *lp = netdev_priv(ndev);
 
+	netpoll_irq_lock(&lp->netpoll_lock);
 	status = axienet_dma_in32(lp, XAXIDMA_RX_SR_OFFSET);
 	if (status & (XAXIDMA_IRQ_IOC_MASK | XAXIDMA_IRQ_DELAY_MASK)) {
 		axienet_recv(lp->ndev);
@@ -882,6 +885,7 @@ static irqreturn_t axienet_rx_irq(int irq, void *_ndev)
 	}
 out:
 	axienet_dma_out32(lp, XAXIDMA_RX_SR_OFFSET, status);
+	netpoll_irq_unlock(&lp->netpoll_lock);
 	return IRQ_HANDLED;
 }
 
@@ -1035,18 +1039,15 @@ static int axienet_change_mtu(struct net_device *ndev, int new_mtu)
  * axienet_poll_controller - Axi Ethernet poll mechanism.
  * @ndev:	Pointer to net_device structure
  *
- * This implements Rx/Tx ISR poll mechanisms. The interrupts are disabled prior
- * to polling the ISRs and are enabled back after the polling is done.
+ * This implements Rx/Tx ISR poll mechanisms. The ISRs use a spinlock to
+ * protect against reentrancy when polling.
  */
 static void axienet_poll_controller(struct net_device *ndev)
 {
 	struct axienet_local *lp = netdev_priv(ndev);
-	disable_irq(lp->tx_irq);
-	disable_irq(lp->rx_irq);
+
 	axienet_rx_irq(lp->tx_irq, ndev);
 	axienet_tx_irq(lp->rx_irq, ndev);
-	enable_irq(lp->tx_irq);
-	enable_irq(lp->rx_irq);
 }
 #endif
 
@@ -1602,6 +1603,8 @@ static int axienet_of_probe(struct platform_device *op)
 	if (ret)
 		dev_warn(&op->dev, "error registering MDIO bus\n");
 
+	netpoll_irq_lock_init(&lp->netpoll_lock);
+
 	ret = register_netdev(lp->ndev);
 	if (ret) {
 		dev_err(lp->dev, "register_netdev() error (%i)\n", ret);
-- 
2.1.3

^ permalink raw reply related

* [RFC PATCH net-next 08/11] ll_temac: remove disable_irq from netpoll controller, use netpoll_irq_lock
From: Sabrina Dubroca @ 2014-12-09 14:37 UTC (permalink / raw)
  To: davem; +Cc: netdev, Sabrina Dubroca, Michal Simek, Sören Brinkmann
In-Reply-To: <1418135842-21389-1-git-send-email-sd@queasysnail.net>

disable_irq() may sleep, replace it with a spin_lock in the interrupt
handler and netpoll controller.

No actual testing done, only compiled.

Signed-off-by: Sabrina Dubroca <sd@queasysnail.net>
Cc: Michal Simek <michal.simek@xilinx.com>
Cc: "Sören Brinkmann" <soren.brinkmann@xilinx.com>
---
 drivers/net/ethernet/xilinx/ll_temac.h      |  3 +++
 drivers/net/ethernet/xilinx/ll_temac_main.c | 13 +++++++------
 2 files changed, 10 insertions(+), 6 deletions(-)

diff --git a/drivers/net/ethernet/xilinx/ll_temac.h b/drivers/net/ethernet/xilinx/ll_temac.h
index 522abe2ff25a..09906958a689 100644
--- a/drivers/net/ethernet/xilinx/ll_temac.h
+++ b/drivers/net/ethernet/xilinx/ll_temac.h
@@ -3,6 +3,7 @@
 #define XILINX_LL_TEMAC_H
 
 #include <linux/netdevice.h>
+#include <linux/netpoll.h>
 #include <linux/of.h>
 #include <linux/spinlock.h>
 
@@ -368,6 +369,8 @@ struct temac_local {
 	int tx_bd_next;
 	int tx_bd_tail;
 	int rx_bd_ci;
+
+	struct netpoll_irq_lock netpoll_lock;
 };
 
 /* xilinx_temac.c */
diff --git a/drivers/net/ethernet/xilinx/ll_temac_main.c b/drivers/net/ethernet/xilinx/ll_temac_main.c
index 9c2d91ea0af4..37c3f9588208 100644
--- a/drivers/net/ethernet/xilinx/ll_temac_main.c
+++ b/drivers/net/ethernet/xilinx/ll_temac_main.c
@@ -815,6 +815,7 @@ static irqreturn_t ll_temac_tx_irq(int irq, void *_ndev)
 	struct temac_local *lp = netdev_priv(ndev);
 	unsigned int status;
 
+	netpoll_irq_lock(&lp->netpoll_lock);
 	status = lp->dma_in(lp, TX_IRQ_REG);
 	lp->dma_out(lp, TX_IRQ_REG, status);
 
@@ -823,6 +824,8 @@ static irqreturn_t ll_temac_tx_irq(int irq, void *_ndev)
 	if (status & 0x080)
 		dev_err(&ndev->dev, "DMA error 0x%x\n", status);
 
+	netpoll_irq_unlock(&lp->netpoll_lock);
+
 	return IRQ_HANDLED;
 }
 
@@ -832,6 +835,7 @@ static irqreturn_t ll_temac_rx_irq(int irq, void *_ndev)
 	struct temac_local *lp = netdev_priv(ndev);
 	unsigned int status;
 
+	netpoll_irq_lock(&lp->netpoll_lock);
 	/* Read and clear the status registers */
 	status = lp->dma_in(lp, RX_IRQ_REG);
 	lp->dma_out(lp, RX_IRQ_REG, status);
@@ -839,6 +843,8 @@ static irqreturn_t ll_temac_rx_irq(int irq, void *_ndev)
 	if (status & (IRQ_COAL | IRQ_DLY))
 		ll_temac_recv(lp->ndev);
 
+	netpoll_irq_unlock(&lp->netpoll_lock);
+
 	return IRQ_HANDLED;
 }
 
@@ -905,14 +911,8 @@ temac_poll_controller(struct net_device *ndev)
 {
 	struct temac_local *lp = netdev_priv(ndev);
 
-	disable_irq(lp->tx_irq);
-	disable_irq(lp->rx_irq);
-
 	ll_temac_rx_irq(lp->tx_irq, ndev);
 	ll_temac_tx_irq(lp->rx_irq, ndev);
-
-	enable_irq(lp->tx_irq);
-	enable_irq(lp->rx_irq);
 }
 #endif
 
@@ -1037,6 +1037,7 @@ static int temac_of_probe(struct platform_device *op)
 	lp->dev = &op->dev;
 	lp->options = XTE_OPTION_DEFAULTS;
 	spin_lock_init(&lp->rx_lock);
+	netpoll_irq_lock_init(&lp->netpoll_lock);
 	mutex_init(&lp->indirect_mutex);
 
 	/* map device registers */
-- 
2.1.3

^ permalink raw reply related

* [RFC PATCH net-next 07/11] pasemi: remove disable_irq from netpoll controller, use netpoll_irq_lock
From: Sabrina Dubroca @ 2014-12-09 14:37 UTC (permalink / raw)
  To: davem; +Cc: netdev, Sabrina Dubroca, Olof Johansson
In-Reply-To: <1418135842-21389-1-git-send-email-sd@queasysnail.net>

disable_irq() may sleep, replace it with a spin_lock in the interrupt
handlers and netpoll controller.

No actual testing done, only compiled.

Signed-off-by: Sabrina Dubroca <sd@queasysnail.net>
Cc: Olof Johansson <olof@lixom.net>
---
 drivers/net/ethernet/pasemi/pasemi_mac.c | 25 +++++++++++++++----------
 drivers/net/ethernet/pasemi/pasemi_mac.h |  3 +++
 2 files changed, 18 insertions(+), 10 deletions(-)

diff --git a/drivers/net/ethernet/pasemi/pasemi_mac.c b/drivers/net/ethernet/pasemi/pasemi_mac.c
index 30d934d66356..da937a1e3b9b 100644
--- a/drivers/net/ethernet/pasemi/pasemi_mac.c
+++ b/drivers/net/ethernet/pasemi/pasemi_mac.c
@@ -426,6 +426,7 @@ static int pasemi_mac_setup_rx_resources(const struct net_device *dev)
 	chno = ring->chan.chno;
 
 	spin_lock_init(&ring->lock);
+	netpoll_irq_lock_init(&ring->netpoll_lock);
 
 	ring->size = RX_RING_SIZE;
 	ring->ring_info = kzalloc(sizeof(struct pasemi_mac_buffer) *
@@ -509,6 +510,7 @@ pasemi_mac_setup_tx_resources(const struct net_device *dev)
 	chno = ring->chan.chno;
 
 	spin_lock_init(&ring->lock);
+	netpoll_irq_lock_init(&ring->netpoll_lock);
 
 	ring->size = TX_RING_SIZE;
 	ring->ring_info = kzalloc(sizeof(struct pasemi_mac_buffer) *
@@ -954,13 +956,16 @@ restart:
 
 static irqreturn_t pasemi_mac_rx_intr(int irq, void *data)
 {
-	const struct pasemi_mac_rxring *rxring = data;
+	struct pasemi_mac_rxring *rxring = data;
 	struct pasemi_mac *mac = rxring->mac;
 	const struct pasemi_dmachan *chan = &rxring->chan;
 	unsigned int reg;
 
-	if (!(*chan->status & PAS_STATUS_CAUSE_M))
+	netpoll_irq_lock(&rxring->netpoll_lock);
+	if (!(*chan->status & PAS_STATUS_CAUSE_M)) {
+		netpoll_irq_unlock(&rxring->netpoll_lock);
 		return IRQ_NONE;
+	}
 
 	/* Don't reset packet count so it won't fire again but clear
 	 * all others.
@@ -976,6 +981,7 @@ static irqreturn_t pasemi_mac_rx_intr(int irq, void *data)
 
 	write_iob_reg(PAS_IOB_DMA_RXCH_RESET(chan->chno), reg);
 
+	netpoll_irq_unlock(&rxring->netpoll_lock);
 	return IRQ_HANDLED;
 }
 
@@ -1000,8 +1006,11 @@ static irqreturn_t pasemi_mac_tx_intr(int irq, void *data)
 	struct pasemi_mac *mac = txring->mac;
 	unsigned int reg;
 
-	if (!(*chan->status & PAS_STATUS_CAUSE_M))
+	netpoll_irq_lock(&txring->netpoll_lock);
+	if (!(*chan->status & PAS_STATUS_CAUSE_M)) {
+		netpoll_irq_unlock(&txring->netpoll_lock);
 		return IRQ_NONE;
+	}
 
 	reg = 0;
 
@@ -1017,6 +1026,7 @@ static irqreturn_t pasemi_mac_tx_intr(int irq, void *data)
 	if (reg)
 		write_iob_reg(PAS_IOB_DMA_TXCH_RESET(chan->chno), reg);
 
+	netpoll_irq_unlock(&txring->netpoll_lock);
 	return IRQ_HANDLED;
 }
 
@@ -1628,20 +1638,15 @@ static int pasemi_mac_poll(struct napi_struct *napi, int budget)
 #ifdef CONFIG_NET_POLL_CONTROLLER
 /*
  * Polling 'interrupt' - used by things like netconsole to send skbs
- * without having to re-enable interrupts. It's not called while
- * the interrupt routine is executing.
+ * without having to re-enable interrupts. The interrupt routine
+ * protects itself with netpoll_irq_lock.
  */
 static void pasemi_mac_netpoll(struct net_device *dev)
 {
 	const struct pasemi_mac *mac = netdev_priv(dev);
 
-	disable_irq(mac->tx->chan.irq);
 	pasemi_mac_tx_intr(mac->tx->chan.irq, mac->tx);
-	enable_irq(mac->tx->chan.irq);
-
-	disable_irq(mac->rx->chan.irq);
 	pasemi_mac_rx_intr(mac->rx->chan.irq, mac->rx);
-	enable_irq(mac->rx->chan.irq);
 }
 #endif
 
diff --git a/drivers/net/ethernet/pasemi/pasemi_mac.h b/drivers/net/ethernet/pasemi/pasemi_mac.h
index a5807703ab96..78ff0c6947b4 100644
--- a/drivers/net/ethernet/pasemi/pasemi_mac.h
+++ b/drivers/net/ethernet/pasemi/pasemi_mac.h
@@ -22,6 +22,7 @@
 
 #include <linux/ethtool.h>
 #include <linux/netdevice.h>
+#include <linux/netpoll.h>
 #include <linux/spinlock.h>
 #include <linux/phy.h>
 
@@ -43,6 +44,7 @@ struct pasemi_mac_txring {
 	struct pasemi_mac_buffer *ring_info;
 	struct pasemi_mac *mac;	/* Needed in intr handler */
 	struct timer_list clean_timer;
+	struct netpoll_irq_lock netpoll_lock;
 };
 
 struct pasemi_mac_rxring {
@@ -55,6 +57,7 @@ struct pasemi_mac_rxring {
 	unsigned int	 next_to_clean;
 	struct pasemi_mac_buffer *ring_info;
 	struct pasemi_mac *mac;	/* Needed in intr handler */
+	struct netpoll_irq_lock netpoll_lock;
 };
 
 struct pasemi_mac_csring {
-- 
2.1.3

^ permalink raw reply related

* [RFC PATCH net-next 06/11] s2io: remove disable_irq from netpoll controller, use netpoll_irq_lock
From: Sabrina Dubroca @ 2014-12-09 14:37 UTC (permalink / raw)
  To: davem; +Cc: netdev, Sabrina Dubroca, Jon Mason
In-Reply-To: <1418135842-21389-1-git-send-email-sd@queasysnail.net>

disable_irq() may sleep, replace it with a spin_lock in the interrupt
handler and netpoll controller.

No actual testing done, only compiled.

Signed-off-by: Sabrina Dubroca <sd@queasysnail.net>
Cc: Jon Mason <jdmason@kudzu.us>
---
 drivers/net/ethernet/neterion/s2io.c | 27 ++++++++++++++++-----------
 drivers/net/ethernet/neterion/s2io.h |  4 ++++
 2 files changed, 20 insertions(+), 11 deletions(-)

diff --git a/drivers/net/ethernet/neterion/s2io.c b/drivers/net/ethernet/neterion/s2io.c
index f5e4b820128b..6730630b7181 100644
--- a/drivers/net/ethernet/neterion/s2io.c
+++ b/drivers/net/ethernet/neterion/s2io.c
@@ -2838,7 +2838,6 @@ static int s2io_poll_inta(struct napi_struct *napi, int budget)
 static void s2io_netpoll(struct net_device *dev)
 {
 	struct s2io_nic *nic = netdev_priv(dev);
-	const int irq = nic->pdev->irq;
 	struct XENA_dev_config __iomem *bar0 = nic->bar0;
 	u64 val64 = 0xFFFFFFFFFFFFFFFFULL;
 	int i;
@@ -2848,7 +2847,8 @@ static void s2io_netpoll(struct net_device *dev)
 	if (pci_channel_offline(nic->pdev))
 		return;
 
-	disable_irq(irq);
+	/* protects against interrupts from the device */
+	netpoll_irq_lock(&nic->netpoll_lock);
 
 	writeq(val64, &bar0->rx_traffic_int);
 	writeq(val64, &bar0->tx_traffic_int);
@@ -2877,7 +2877,7 @@ static void s2io_netpoll(struct net_device *dev)
 			break;
 		}
 	}
-	enable_irq(irq);
+	netpoll_irq_unlock(&nic->netpoll_lock);
 }
 #endif
 
@@ -4717,13 +4717,16 @@ static irqreturn_t s2io_isr(int irq, void *dev_id)
 	u64 reason = 0;
 	struct mac_info *mac_control;
 	struct config_param *config;
+	irqreturn_t handled = IRQ_NONE;
+
+	netpoll_irq_lock(&sp->netpoll_lock);
 
 	/* Pretend we handled any irq's from a disconnected card */
 	if (pci_channel_offline(sp->pdev))
-		return IRQ_NONE;
+		goto out;
 
 	if (!is_s2io_card_up(sp))
-		return IRQ_NONE;
+		goto out;
 
 	config = &sp->config;
 	mac_control = &sp->mac_control;
@@ -4737,8 +4740,9 @@ static irqreturn_t s2io_isr(int irq, void *dev_id)
 	 */
 	reason = readq(&bar0->general_int_status);
 
+	handled = IRQ_HANDLED;
 	if (unlikely(reason == S2IO_MINUS_ONE))
-		return IRQ_HANDLED;	/* Nothing much can be done. Get out */
+		goto out;	/* Nothing much can be done. Get out */
 
 	if (reason &
 	    (GEN_INTR_RXTRAFFIC | GEN_INTR_TXTRAFFIC | GEN_INTR_TXPIC)) {
@@ -4793,15 +4797,14 @@ static irqreturn_t s2io_isr(int irq, void *dev_id)
 		}
 		writeq(sp->general_int_mask, &bar0->general_int_mask);
 		readl(&bar0->general_int_status);
-
-		return IRQ_HANDLED;
-
 	} else if (!reason) {
 		/* The interrupt was not raised by us */
-		return IRQ_NONE;
+		handled = IRQ_NONE;
 	}
 
-	return IRQ_HANDLED;
+out:
+	netpoll_irq_unlock(&sp->netpoll_lock);
+	return handled;
 }
 
 /**
@@ -7040,6 +7043,7 @@ static int s2io_add_isr(struct s2io_nic *sp)
 				  "MSI-X-TX entries enabled through alarm vector\n");
 		}
 	}
+
 	if (sp->config.intr_type == INTA) {
 		err = request_irq(sp->pdev->irq, s2io_isr, IRQF_SHARED,
 				  sp->name, dev);
@@ -8047,6 +8051,7 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre)
 
 		spin_lock_init(&fifo->tx_lock);
 	}
+	netpoll_irq_lock_init(&sp->netpoll_lock);
 
 	/*
 	 * SXE-002: Configure link and activity LED to init state
diff --git a/drivers/net/ethernet/neterion/s2io.h b/drivers/net/ethernet/neterion/s2io.h
index d89b6ed82c51..bcfc5e91b926 100644
--- a/drivers/net/ethernet/neterion/s2io.h
+++ b/drivers/net/ethernet/neterion/s2io.h
@@ -13,6 +13,8 @@
 #ifndef _S2IO_H
 #define _S2IO_H
 
+#include <linux/netpoll.h>
+
 #define TBD 0
 #define s2BIT(loc)		(0x8000000000000000ULL >> (loc))
 #define vBIT(val, loc, sz)	(((u64)val) << (64-loc-sz))
@@ -965,6 +967,8 @@ struct s2io_nic {
 #define VPD_STRING_LEN 80
 	u8  product_name[VPD_STRING_LEN];
 	u8  serial_num[VPD_STRING_LEN];
+
+	struct netpoll_irq_lock netpoll_lock;
 };
 
 #define RESET_ERROR 1
-- 
2.1.3

^ permalink raw reply related

* [RFC PATCH net-next 05/11] bnx2: remove disable_irq from netpoll controller, use netpoll_irq_lock
From: Sabrina Dubroca @ 2014-12-09 14:37 UTC (permalink / raw)
  To: davem; +Cc: netdev, Sabrina Dubroca, Sony Chacko, Dept-HSGLinuxNICDev
In-Reply-To: <1418135842-21389-1-git-send-email-sd@queasysnail.net>

disable_irq() may sleep, replace it with a spin_lock in the interrupt
handlers.

No actual testing done, only compiled.

Signed-off-by: Sabrina Dubroca <sd@queasysnail.net>
Cc: Sony Chacko <sony.chacko@qlogic.com>
Cc: Dept-HSGLinuxNICDev@qlogic.com
---
 drivers/net/ethernet/broadcom/bnx2.c | 24 ++++++++++++++++++------
 drivers/net/ethernet/broadcom/bnx2.h |  4 ++++
 2 files changed, 22 insertions(+), 6 deletions(-)

diff --git a/drivers/net/ethernet/broadcom/bnx2.c b/drivers/net/ethernet/broadcom/bnx2.c
index 823d01c5684c..675d90849d10 100644
--- a/drivers/net/ethernet/broadcom/bnx2.c
+++ b/drivers/net/ethernet/broadcom/bnx2.c
@@ -39,6 +39,7 @@
 #include <linux/mii.h>
 #include <linux/if.h>
 #include <linux/if_vlan.h>
+#include <linux/netpoll.h>
 #include <net/ip.h>
 #include <net/tcp.h>
 #include <net/checksum.h>
@@ -864,6 +865,7 @@ bnx2_alloc_mem(struct bnx2 *bp)
 		&bnapi->status_blk.msi->status_tx_quick_consumer_index0;
 	bnapi->hw_rx_cons_ptr =
 		&bnapi->status_blk.msi->status_rx_quick_consumer_index0;
+	netpoll_irq_lock_init(&bnapi->netpoll_lock);
 	if (bp->flags & BNX2_FLAG_MSIX_CAP) {
 		for (i = 1; i < bp->irq_nvecs; i++) {
 			struct status_block_msix *sblk;
@@ -876,6 +878,7 @@ bnx2_alloc_mem(struct bnx2 *bp)
 				&sblk->status_tx_quick_consumer_index;
 			bnapi->hw_rx_cons_ptr =
 				&sblk->status_rx_quick_consumer_index;
+			netpoll_irq_lock_init(&bnapi->netpoll_lock);
 			bnapi->int_num = i << 24;
 		}
 	}
@@ -3302,6 +3305,7 @@ bnx2_msi(int irq, void *dev_instance)
 	struct bnx2_napi *bnapi = dev_instance;
 	struct bnx2 *bp = bnapi->bp;
 
+	netpoll_irq_lock(&bnapi->netpoll_lock);
 	prefetch(bnapi->status_blk.msi);
 	BNX2_WR(bp, BNX2_PCICFG_INT_ACK_CMD,
 		BNX2_PCICFG_INT_ACK_CMD_USE_INT_HC_PARAM |
@@ -3309,10 +3313,12 @@ bnx2_msi(int irq, void *dev_instance)
 
 	/* Return here if interrupt is disabled. */
 	if (unlikely(atomic_read(&bp->intr_sem) != 0))
-		return IRQ_HANDLED;
+		goto out;
 
 	napi_schedule(&bnapi->napi);
 
+out:
+	netpoll_irq_unlock(&bnapi->netpoll_lock);
 	return IRQ_HANDLED;
 }
 
@@ -3322,14 +3328,17 @@ bnx2_msi_1shot(int irq, void *dev_instance)
 	struct bnx2_napi *bnapi = dev_instance;
 	struct bnx2 *bp = bnapi->bp;
 
+	netpoll_irq_lock(&bnapi->netpoll_lock);
 	prefetch(bnapi->status_blk.msi);
 
 	/* Return here if interrupt is disabled. */
 	if (unlikely(atomic_read(&bp->intr_sem) != 0))
-		return IRQ_HANDLED;
+		goto out;
 
 	napi_schedule(&bnapi->napi);
 
+out:
+	netpoll_irq_unlock(&bnapi->netpoll_lock);
 	return IRQ_HANDLED;
 }
 
@@ -3340,6 +3349,7 @@ bnx2_interrupt(int irq, void *dev_instance)
 	struct bnx2 *bp = bnapi->bp;
 	struct status_block *sblk = bnapi->status_blk.msi;
 
+	netpoll_irq_lock(&bnapi->netpoll_lock);
 	/* When using INTx, it is possible for the interrupt to arrive
 	 * at the CPU before the status block posted prior to the
 	 * interrupt. Reading a register will flush the status block.
@@ -3348,8 +3358,10 @@ bnx2_interrupt(int irq, void *dev_instance)
 	 */
 	if ((sblk->status_idx == bnapi->last_status_idx) &&
 	    (BNX2_RD(bp, BNX2_PCICFG_MISC_STATUS) &
-	     BNX2_PCICFG_MISC_STATUS_INTA_VALUE))
+	     BNX2_PCICFG_MISC_STATUS_INTA_VALUE)) {
+		netpoll_irq_unlock(&bnapi->netpoll_lock);
 		return IRQ_NONE;
+	}
 
 	BNX2_WR(bp, BNX2_PCICFG_INT_ACK_CMD,
 		BNX2_PCICFG_INT_ACK_CMD_USE_INT_HC_PARAM |
@@ -3362,13 +3374,15 @@ bnx2_interrupt(int irq, void *dev_instance)
 
 	/* Return here if interrupt is shared and is disabled. */
 	if (unlikely(atomic_read(&bp->intr_sem) != 0))
-		return IRQ_HANDLED;
+		goto out;
 
 	if (napi_schedule_prep(&bnapi->napi)) {
 		bnapi->last_status_idx = sblk->status_idx;
 		__napi_schedule(&bnapi->napi);
 	}
 
+out:
+	netpoll_irq_unlock(&bnapi->netpoll_lock);
 	return IRQ_HANDLED;
 }
 
@@ -7915,9 +7929,7 @@ poll_bnx2(struct net_device *dev)
 	for (i = 0; i < bp->irq_nvecs; i++) {
 		struct bnx2_irq *irq = &bp->irq_tbl[i];
 
-		disable_irq(irq->vector);
 		irq->handler(irq->vector, &bp->bnx2_napi[i]);
-		enable_irq(irq->vector);
 	}
 }
 #endif
diff --git a/drivers/net/ethernet/broadcom/bnx2.h b/drivers/net/ethernet/broadcom/bnx2.h
index 28df35d35893..a9ee8c2e1847 100644
--- a/drivers/net/ethernet/broadcom/bnx2.h
+++ b/drivers/net/ethernet/broadcom/bnx2.h
@@ -14,6 +14,8 @@
 #ifndef BNX2_H
 #define BNX2_H
 
+#include <linux/netpoll.h>
+
 /* Hardware data structures and register definitions automatically
  * generated from RTL code. Do not modify.
  */
@@ -6780,6 +6782,8 @@ struct bnx2_napi {
 
 	struct bnx2_rx_ring_info	rx_ring;
 	struct bnx2_tx_ring_info	tx_ring;
+
+	struct netpoll_irq_lock netpoll_lock;
 };
 
 struct bnx2 {
-- 
2.1.3

^ permalink raw reply related

* [RFC PATCH net-next 04/11] atl1c: remove disable_irq from netpoll controller, use netpoll_irq_lock
From: Sabrina Dubroca @ 2014-12-09 14:37 UTC (permalink / raw)
  To: davem; +Cc: netdev, Sabrina Dubroca, Jay Cliburn, Chris Snook
In-Reply-To: <1418135842-21389-1-git-send-email-sd@queasysnail.net>

disable_irq() may sleep, replace it with a spin_lock in the interrupt handler.

No actual testing done, only compiled.

Signed-off-by: Sabrina Dubroca <sd@queasysnail.net>
Cc: Jay Cliburn <jcliburn@gmail.com>
Cc: Chris Snook <chris.snook@gmail.com>
---
 drivers/net/ethernet/atheros/atl1c/atl1c.h      |  3 +++
 drivers/net/ethernet/atheros/atl1c/atl1c_main.c | 12 ++++++++----
 2 files changed, 11 insertions(+), 4 deletions(-)

diff --git a/drivers/net/ethernet/atheros/atl1c/atl1c.h b/drivers/net/ethernet/atheros/atl1c/atl1c.h
index b9203d928938..8d97791e1516 100644
--- a/drivers/net/ethernet/atheros/atl1c/atl1c.h
+++ b/drivers/net/ethernet/atheros/atl1c/atl1c.h
@@ -49,6 +49,7 @@
 #include <linux/workqueue.h>
 #include <net/checksum.h>
 #include <net/ip6_checksum.h>
+#include <linux/netpoll.h>
 
 #include "atl1c_hw.h"
 
@@ -555,6 +556,8 @@ struct atl1c_adapter {
 	struct atl1c_rfd_ring rfd_ring;
 	struct atl1c_rrd_ring rrd_ring;
 	u32 bd_number;     /* board number;*/
+
+	struct netpoll_irq_lock netpoll_lock;
 };
 
 #define AT_WRITE_REG(a, reg, value) ( \
diff --git a/drivers/net/ethernet/atheros/atl1c/atl1c_main.c b/drivers/net/ethernet/atheros/atl1c/atl1c_main.c
index 72fb86b9aa24..7a1b11eb8e4e 100644
--- a/drivers/net/ethernet/atheros/atl1c/atl1c_main.c
+++ b/drivers/net/ethernet/atheros/atl1c/atl1c_main.c
@@ -826,6 +826,7 @@ static int atl1c_sw_init(struct atl1c_adapter *adapter)
 	atomic_set(&adapter->irq_sem, 1);
 	spin_lock_init(&adapter->mdio_lock);
 	spin_lock_init(&adapter->tx_lock);
+	netpoll_irq_lock_init(&adapter->netpoll_lock);
 	set_bit(__AT_DOWN, &adapter->flags);
 
 	return 0;
@@ -1584,10 +1585,11 @@ static irqreturn_t atl1c_intr(int irq, void *data)
 	struct pci_dev *pdev = adapter->pdev;
 	struct atl1c_hw *hw = &adapter->hw;
 	int max_ints = AT_MAX_INT_WORK;
-	int handled = IRQ_NONE;
+	irqreturn_t handled = IRQ_NONE;
 	u32 status;
 	u32 reg_data;
 
+	netpoll_irq_lock(&adapter->netpoll_lock);
 	do {
 		AT_READ_REG(hw, REG_ISR, &reg_data);
 		status = reg_data & hw->intr_mask;
@@ -1622,7 +1624,8 @@ static irqreturn_t atl1c_intr(int irq, void *data)
 			/* reset MAC */
 			set_bit(ATL1C_WORK_EVENT_RESET, &adapter->work_event);
 			schedule_work(&adapter->common_task);
-			return IRQ_HANDLED;
+			handled = IRQ_HANDLED;
+			goto out;
 		}
 
 		if (status & ISR_OVER)
@@ -1641,6 +1644,9 @@ static irqreturn_t atl1c_intr(int irq, void *data)
 	} while (--max_ints > 0);
 	/* re-enable Interrupt*/
 	AT_WRITE_REG(&adapter->hw, REG_ISR, 0);
+
+out:
+	netpoll_irq_unlock(&adapter->netpoll_lock);
 	return handled;
 }
 
@@ -1900,9 +1906,7 @@ static void atl1c_netpoll(struct net_device *netdev)
 {
 	struct atl1c_adapter *adapter = netdev_priv(netdev);
 
-	disable_irq(adapter->pdev->irq);
 	atl1c_intr(adapter->pdev->irq, netdev);
-	enable_irq(adapter->pdev->irq);
 }
 #endif
 
-- 
2.1.3

^ permalink raw reply related

* [RFC PATCH net-next 03/11] 8139cp/too: remove disable_irq from netpoll controller
From: Sabrina Dubroca @ 2014-12-09 14:37 UTC (permalink / raw)
  To: davem; +Cc: netdev, Sabrina Dubroca
In-Reply-To: <1418135842-21389-1-git-send-email-sd@queasysnail.net>

disable_irq() may sleep. The interrupt handlers for 8139 take the
device lock, so no need for additional protection.

Signed-off-by: Sabrina Dubroca <sd@queasysnail.net>
---
 drivers/net/ethernet/realtek/8139cp.c  | 3 +--
 drivers/net/ethernet/realtek/8139too.c | 3 +--
 2 files changed, 2 insertions(+), 4 deletions(-)

diff --git a/drivers/net/ethernet/realtek/8139cp.c b/drivers/net/ethernet/realtek/8139cp.c
index 75b1693ec8bf..6a296c5c3860 100644
--- a/drivers/net/ethernet/realtek/8139cp.c
+++ b/drivers/net/ethernet/realtek/8139cp.c
@@ -581,6 +581,7 @@ static irqreturn_t cp_interrupt (int irq, void *dev_instance)
 		return IRQ_NONE;
 	cp = netdev_priv(dev);
 
+	/* also protects against reentrancy from cp_poll_controller */
 	spin_lock(&cp->lock);
 
 	status = cpr16(IntrStatus);
@@ -639,9 +640,7 @@ static void cp_poll_controller(struct net_device *dev)
 	struct cp_private *cp = netdev_priv(dev);
 	const int irq = cp->pdev->irq;
 
-	disable_irq(irq);
 	cp_interrupt(irq, dev);
-	enable_irq(irq);
 }
 #endif
 
diff --git a/drivers/net/ethernet/realtek/8139too.c b/drivers/net/ethernet/realtek/8139too.c
index 63dc0f95d050..f4437112984b 100644
--- a/drivers/net/ethernet/realtek/8139too.c
+++ b/drivers/net/ethernet/realtek/8139too.c
@@ -2162,6 +2162,7 @@ static irqreturn_t rtl8139_interrupt (int irq, void *dev_instance)
 	int link_changed = 0; /* avoid bogus "uninit" warning */
 	int handled = 0;
 
+	/* also protects against reentrancy from rtl8139_poll_controller */
 	spin_lock (&tp->lock);
 	status = RTL_R16 (IntrStatus);
 
@@ -2227,9 +2228,7 @@ static void rtl8139_poll_controller(struct net_device *dev)
 	struct rtl8139_private *tp = netdev_priv(dev);
 	const int irq = tp->pci_dev->irq;
 
-	disable_irq(irq);
 	rtl8139_interrupt(irq, dev);
-	enable_irq(irq);
 }
 #endif
 
-- 
2.1.3

^ permalink raw reply related

* [RFC PATCH net-next 02/11] e1000: remove disable_irq from netpoll controller, use netpoll_irq_lock
From: Sabrina Dubroca @ 2014-12-09 14:37 UTC (permalink / raw)
  To: davem; +Cc: netdev, Sabrina Dubroca, Jeff Kirsher, Linux NICS
In-Reply-To: <1418135842-21389-1-git-send-email-sd@queasysnail.net>

disable_irq() may sleep, replace it with a spin_lock in the interrupt handler.

Signed-off-by: Sabrina Dubroca <sd@queasysnail.net>
Cc: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
Cc: Linux NICS <linux.nics@intel.com>
---
 drivers/net/ethernet/intel/e1000/e1000.h      |  3 +++
 drivers/net/ethernet/intel/e1000/e1000_main.c | 21 ++++++++++++++++-----
 2 files changed, 19 insertions(+), 5 deletions(-)

diff --git a/drivers/net/ethernet/intel/e1000/e1000.h b/drivers/net/ethernet/intel/e1000/e1000.h
index 69707108d23c..79444125b9bd 100644
--- a/drivers/net/ethernet/intel/e1000/e1000.h
+++ b/drivers/net/ethernet/intel/e1000/e1000.h
@@ -68,6 +68,7 @@
 #include <linux/mii.h>
 #include <linux/ethtool.h>
 #include <linux/if_vlan.h>
+#include <linux/netpoll.h>
 
 #define BAR_0		0
 #define BAR_1		1
@@ -323,6 +324,8 @@ struct e1000_adapter {
 	struct delayed_work watchdog_task;
 	struct delayed_work fifo_stall_task;
 	struct delayed_work phy_info_task;
+
+	struct netpoll_irq_lock netpoll_lock;
 };
 
 enum e1000_state_t {
diff --git a/drivers/net/ethernet/intel/e1000/e1000_main.c b/drivers/net/ethernet/intel/e1000/e1000_main.c
index 24f3986cfae2..5749a27e5c5e 100644
--- a/drivers/net/ethernet/intel/e1000/e1000_main.c
+++ b/drivers/net/ethernet/intel/e1000/e1000_main.c
@@ -32,6 +32,7 @@
 #include <linux/prefetch.h>
 #include <linux/bitops.h>
 #include <linux/if_vlan.h>
+#include <linux/netpoll.h>
 
 char e1000_driver_name[] = "e1000";
 static char e1000_driver_string[] = "Intel(R) PRO/1000 Network Driver";
@@ -1313,6 +1314,7 @@ static int e1000_sw_init(struct e1000_adapter *adapter)
 	e1000_irq_disable(adapter);
 
 	spin_lock_init(&adapter->stats_lock);
+	netpoll_irq_lock_init(&adapter->netpoll_lock);
 
 	set_bit(__E1000_DOWN, &adapter->flags);
 
@@ -3751,10 +3753,8 @@ void e1000_update_stats(struct e1000_adapter *adapter)
  * @irq: interrupt number
  * @data: pointer to a network interface device structure
  **/
-static irqreturn_t e1000_intr(int irq, void *data)
+static irqreturn_t __e1000_intr(int irq, struct e1000_adapter *adapter)
 {
-	struct net_device *netdev = data;
-	struct e1000_adapter *adapter = netdev_priv(netdev);
 	struct e1000_hw *hw = &adapter->hw;
 	u32 icr = er32(ICR);
 
@@ -3796,6 +3796,19 @@ static irqreturn_t e1000_intr(int irq, void *data)
 	return IRQ_HANDLED;
 }
 
+static irqreturn_t e1000_intr(int irq, void *data)
+{
+	struct net_device *netdev = data;
+	struct e1000_adapter *adapter = netdev_priv(netdev);
+	irqreturn_t ret;
+
+	netpoll_irq_lock(&adapter->netpoll_lock);
+	ret = __e1000_intr(irq, adapter);
+	netpoll_irq_unlock(&adapter->netpoll_lock);
+
+	return ret;
+}
+
 /**
  * e1000_clean - NAPI Rx polling callback
  * @adapter: board private structure
@@ -5220,9 +5233,7 @@ static void e1000_netpoll(struct net_device *netdev)
 {
 	struct e1000_adapter *adapter = netdev_priv(netdev);
 
-	disable_irq(adapter->pdev->irq);
 	e1000_intr(adapter->pdev->irq, netdev);
-	enable_irq(adapter->pdev->irq);
 }
 #endif
 
-- 
2.1.3

^ 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