* [patch] sfc: check for allocation failure
From: Dan Carpenter @ 2013-09-02 9:04 UTC (permalink / raw)
To: Solarflare linux maintainers; +Cc: Ben Hutchings, netdev, kernel-janitors
It upsets static analyzers when we don't check for allocation failure.
Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com>
diff --git a/drivers/net/ethernet/sfc/mtd.c b/drivers/net/ethernet/sfc/mtd.c
index ba6c87a..aac6897 100644
--- a/drivers/net/ethernet/sfc/mtd.c
+++ b/drivers/net/ethernet/sfc/mtd.c
@@ -384,6 +384,8 @@ static int falcon_mtd_probe(struct efx_nic *efx)
/* Allocate space for maximum number of partitions */
parts = kcalloc(2, sizeof(*parts), GFP_KERNEL);
+ if (!parts)
+ return -ENOMEM;
n_parts = 0;
spi = &nic_data->spi_flash;
^ permalink raw reply related
* linux-next: build failure after merge of the final tree (net-next tree related)
From: Stephen Rothwell @ 2013-09-02 9:11 UTC (permalink / raw)
To: David Miller, netdev; +Cc: linux-next, linux-kernel, Cong Wang
[-- Attachment #1: Type: text/plain, Size: 1204 bytes --]
Hi all,
After merging the final tree, today's linux-next build (powerpc
allyesconfig) failed like this:
drivers/net/vxlan.c: In function 'vxlan6_xmit_skb':
drivers/net/vxlan.c:1441:3: error: implicit declaration of function 'csum_ipv6_magic' [-Werror=implicit-function-declaration]
uh->check = csum_ipv6_magic(saddr, daddr, skb->len,
^
Caused by commit e4c7ed415387 ("vxlan: add ipv6 support").
Please read Rule 1 in Documentation/SubmitChecklist.
I added the following patch for today:
From: Stephen Rothwell <sfr@canb.auug.org.au>
Date: Mon, 2 Sep 2013 19:04:51 +1000
Subject: [PATCH] vxlan: include the file that declares csum_ipv6_magic
Signed-off-by: Stephen Rothwell <sfr@canb.auug.org.au>
---
drivers/net/vxlan.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/net/vxlan.c b/drivers/net/vxlan.c
index 3ffb22d..35c78b3 100644
--- a/drivers/net/vxlan.c
+++ b/drivers/net/vxlan.c
@@ -44,6 +44,7 @@
#include <net/ipv6.h>
#include <net/addrconf.h>
#include <net/ip6_tunnel.h>
+#include <net/ip6_checksum.h>
#endif
#define VXLAN_VERSION "0.1"
--
1.8.4.rc3
--
Cheers,
Stephen Rothwell sfr@canb.auug.org.au
[-- Attachment #2: Type: application/pgp-signature, Size: 836 bytes --]
^ permalink raw reply related
* Re: linux-next: build failure after merge of the final tree (net-next tree related)
From: Cong Wang @ 2013-09-02 9:18 UTC (permalink / raw)
To: Stephen Rothwell; +Cc: David Miller, netdev, linux-next, linux-kernel
In-Reply-To: <20130902191120.645dab701e2a68bb2ac6ba33@canb.auug.org.au>
On Mon, 2013-09-02 at 19:11 +1000, Stephen Rothwell wrote:
> Hi all,
>
> After merging the final tree, today's linux-next build (powerpc
> allyesconfig) failed like this:
>
> drivers/net/vxlan.c: In function 'vxlan6_xmit_skb':
> drivers/net/vxlan.c:1441:3: error: implicit declaration of function 'csum_ipv6_magic' [-Werror=implicit-function-declaration]
> uh->check = csum_ipv6_magic(saddr, daddr, skb->len,
> ^
>
> Caused by commit e4c7ed415387 ("vxlan: add ipv6 support").
>
> Please read Rule 1 in Documentation/SubmitChecklist.
>
> I added the following patch for today:
Hi, Stephen
I sent a same patch this morning:
http://marc.info/?l=linux-netdev&m=137808763132336&w=2
Thanks!
^ permalink raw reply
* Re: Realtek r8168 hangs when sending data at full speed on a gigabit link
From: Frédéric Leroy @ 2013-09-02 9:46 UTC (permalink / raw)
To: Francois Romieu; +Cc: netdev, Realtek linux nic maintainers
In-Reply-To: <20130901213610.GA25211@electric-eye.fr.zoreil.com>
Hello Francois,
Le 01/09/2013 23:36, Francois Romieu a écrit :
> Frédéric Leroy <fredo@starox.org> :
> [...]
> > For triggering the bug, I use iperf, which either works, or hangs almost
> > immediately
> > with multiple threads :
> >
> > iperf -c myiperfserver -P 3 -t 60
> >
> > Could you help me to fix this ?
>
> Does it behave the same if you don't load the vbox modules at all ?
>
When I don't load the vbox modules, it behaves the same.
I forget to say that with an unique tcp stream, it hangs after a longer
time.
I took one capture of a hanged tcp stream.
You can find it there : http://www.starox.org/pub/linux/r8169/
Regards,
--
Frédéric Leroy
^ permalink raw reply
* [PATCH 0/2] delete premature free_irq
From: Julia Lawall @ 2013-09-02 9:54 UTC (permalink / raw)
To: linux-spi; +Cc: kernel-janitors, linux-kernel, linux-arm-kernel, netdev
platform_get_request, or its wrapper platform_get_irq, doesn't allocate
anything, so there is nothing to free. Free_irq matches up with
request_irq and related functions.
The complete semantic patch used is as follows
(http://coccinelle.lip6.fr/)
// <smpl>
@@
identifier l;
statement S1;
expression e,e1;
@@
*e = platform_get_irq(...);
... when != request_irq(e,...)
when != request_threaded_irq(e,...)
when != request_any_context_irq(e,...)
when != if (...) { <+... request_irq(e,...) ...+> } else S1
when != if (...) { <+... request_threaded_irq(e,...) ...+> } else S1
when != if (...) { <+... request_any_context_irq(e,...) ...+> } else S1
when != e1 = e
*goto l;
...
*free_irq(e,...)
@@
identifier l;
statement S,S1;
expression e,e1;
@@
*e = platform_get_irq(...);
... when != request_irq(e,...)
when != request_threaded_irq(e,...)
when != request_any_context_irq(e,...)
when != if (...) { <+... request_irq(e,...) ...+> } else S1
when != if (...) { <+... request_threaded_irq(e,...) ...+> } else S1
when != if (...) { <+... request_any_context_irq(e,...) ...+> } else S1
*e1 = e;
... when != request_irq(\(e\|e1\),...)
when != request_threaded_irq(\(e\|e1\),...)
when != request_any_context_irq(\(e\|e1\),...)
when != if (...) { <+... request_irq(\(e\|e1\),...) ...+> } else S
when != if (...) { <+... request_threaded_irq(\(e\|e1\),...) ...+> } else S
when != if (...) { <+... request_any_context_irq(\(e\|e1\),...) ...+> } else S
*goto l;
...
*free_irq(\(e\|e1\),...)
@@
identifier l;
statement S;
expression e,e1;
@@
*e1 = e = platform_get_irq(...);
... when != request_irq(\(e\|e1\),...)
when != request_threaded_irq(\(e\|e1\),...)
when != request_any_context_irq(\(e\|e1\),...)
when != if (...) { <+... request_irq(\(e\|e1\),...) ...+> } else S
when != if (...) { <+... request_threaded_irq(\(e\|e1\),...) ...+> } else S
when != if (...) { <+... request_any_context_irq(\(e\|e1\),...) ...+> } else S
*goto l;
...
*free_irq(\(e\|e1\),...)
// -------------------------------------------------------------------------
@@
identifier l;
statement S,S1;
expression e,e2,e3;
@@
*e = platform_get_resource(e2,IORESOURCE_IRQ,e3);
... when != request_irq(e->start,...)
when != request_threaded_irq(e->start,...)
when != request_any_context_irq(e->start,...)
when != if (...) { <+... request_irq(e->start,...) ...+> } else S1
when != if (...) { <+... request_threaded_irq(e->start,...) ...+> } else S1
when != if (...) { <+... request_any_context_irq(e->start,...) ...+> } else S1
*goto l;
...
*free_irq(e->start,...)
@@
identifier l;
statement S,S1;
expression e,e1,e2,e3;
@@
*e = platform_get_resource(e2,IORESOURCE_IRQ,e3);
... when != request_irq(e->start,...)
when != request_threaded_irq(e->start,...)
when != request_any_context_irq(e->start,...)
when != if (...) { <+... request_irq(e->start,...) ...+> } else S1
when != if (...) { <+... request_threaded_irq(e->start,...) ...+> } else S1
when != if (...) { <+... request_any_context_irq(e->start,...) ...+> } else S1
e1 = e->start;
... when != request_irq(\(e->start\|e1\),...)
when != request_threaded_irq(\(e->start\|e1\),...)
when != request_any_context_irq(\(e->start\|e1\),...)
when != if (...) { <+... request_irq(\(e->start\|e1\),...) ...+> } else S
when != if (...) { <+... request_threaded_irq(\(e->start\|e1\),...) ...+> } else S
when != if (...) { <+... request_any_context_irq(\(e->start\|e1\),...) ...+> } else S
*goto l;
...
*free_irq(\(e->start\|e1\),...)
// </smpl>
^ permalink raw reply
* [PATCH 2/2] drivers:net: delete premature free_irq
From: Julia Lawall @ 2013-09-02 9:54 UTC (permalink / raw)
To: Wan ZongShun; +Cc: kernel-janitors, linux-arm-kernel, netdev, linux-kernel
In-Reply-To: <1378115661-5371-1-git-send-email-Julia.Lawall@lip6.fr>
From: Julia Lawall <Julia.Lawall@lip6.fr>
Free_irq is not needed if there has been no request_irq. Free_irq is
removed from both the probe and remove functions. The correct request_irq
and free_irq are found in the open and close functions.
A simplified version of the semantic match that finds this problem is as
follows: (http://coccinelle.lip6.fr/)
// <smpl>
@@
expression e;
@@
*e = platform_get_irq(...);
... when != request_irq(e,...)
*free_irq(e,...)
// </smpl>
Signed-off-by: Julia Lawall <Julia.Lawall@lip6.fr>
---
Not tested.
drivers/net/ethernet/nuvoton/w90p910_ether.c | 11 ++---------
1 file changed, 2 insertions(+), 9 deletions(-)
diff --git a/drivers/net/ethernet/nuvoton/w90p910_ether.c b/drivers/net/ethernet/nuvoton/w90p910_ether.c
index dcfe58f..79645f7 100644
--- a/drivers/net/ethernet/nuvoton/w90p910_ether.c
+++ b/drivers/net/ethernet/nuvoton/w90p910_ether.c
@@ -1014,7 +1014,7 @@ static int w90p910_ether_probe(struct platform_device *pdev)
if (ether->rxirq < 0) {
dev_err(&pdev->dev, "failed to get ether rx irq\n");
error = -ENXIO;
- goto failed_free_txirq;
+ goto failed_free_io;
}
platform_set_drvdata(pdev, dev);
@@ -1023,7 +1023,7 @@ static int w90p910_ether_probe(struct platform_device *pdev)
if (IS_ERR(ether->clk)) {
dev_err(&pdev->dev, "failed to get ether clock\n");
error = PTR_ERR(ether->clk);
- goto failed_free_rxirq;
+ goto failed_free_io;
}
ether->rmiiclk = clk_get(&pdev->dev, "RMII");
@@ -1049,10 +1049,6 @@ failed_put_rmiiclk:
clk_put(ether->rmiiclk);
failed_put_clk:
clk_put(ether->clk);
-failed_free_rxirq:
- free_irq(ether->rxirq, pdev);
-failed_free_txirq:
- free_irq(ether->txirq, pdev);
failed_free_io:
iounmap(ether->reg);
failed_free_mem:
@@ -1075,9 +1071,6 @@ static int w90p910_ether_remove(struct platform_device *pdev)
iounmap(ether->reg);
release_mem_region(ether->res->start, resource_size(ether->res));
- free_irq(ether->txirq, dev);
- free_irq(ether->rxirq, dev);
-
del_timer_sync(ðer->check_timer);
free_netdev(dev);
^ permalink raw reply related
* [PATCH] net: fec: fix the error to get the previous BD entry
From: Fugang Duan @ 2013-09-02 11:35 UTC (permalink / raw)
To: b20596, davem; +Cc: netdev, bhutchings, stephen
Bug: error to get the previous BD entry. When the current BD
is the first BD, the previous BD entry must be the last BD,
not "bdp - 1" in current logic.
V2:
Add tx_ring_size and rx_ring_size to struct fec_enet_private.
Replace api fec_enet_get_nextdesc() with next_bd().
Replace api fec_enet_get_prevdesc() with pre_bd().
Move all ring size check logic to next_bd() and pre_bd, which
simplifies the code redundancy.
V1:
Add BD ring size check to get the previous BD entry in correctly.
Signed-off-by: Fugang Duan <B38611@freescale.com>
---
drivers/net/ethernet/freescale/fec.h | 3 +
drivers/net/ethernet/freescale/fec_main.c | 94 +++++++++++++++-------------
2 files changed, 53 insertions(+), 44 deletions(-)
diff --git a/drivers/net/ethernet/freescale/fec.h b/drivers/net/ethernet/freescale/fec.h
index ae23600..0120217 100644
--- a/drivers/net/ethernet/freescale/fec.h
+++ b/drivers/net/ethernet/freescale/fec.h
@@ -296,6 +296,9 @@ struct fec_enet_private {
/* The ring entries to be free()ed */
struct bufdesc *dirty_tx;
+ unsigned short tx_ring_size;
+ unsigned short rx_ring_size;
+
struct platform_device *pdev;
int opened;
diff --git a/drivers/net/ethernet/freescale/fec_main.c b/drivers/net/ethernet/freescale/fec_main.c
index 4ea1555..9894dd3 100644
--- a/drivers/net/ethernet/freescale/fec_main.c
+++ b/drivers/net/ethernet/freescale/fec_main.c
@@ -239,22 +239,35 @@ MODULE_PARM_DESC(macaddr, "FEC Ethernet MAC address");
static int mii_cnt;
-static struct bufdesc *fec_enet_get_nextdesc(struct bufdesc *bdp, int is_ex)
+static inline
+struct bufdesc *next_bd(struct bufdesc *bdp, struct bufdesc *base,
+ int ring_size, int is_ex)
{
- struct bufdesc_ex *ex = (struct bufdesc_ex *)bdp;
+ struct bufdesc *new_bd = bdp + 1;
+ struct bufdesc_ex *ex_new_bd = (struct bufdesc_ex *)bdp + 1;
+ struct bufdesc_ex *ex_base = (struct bufdesc_ex *)base;
+
if (is_ex)
- return (struct bufdesc *)(ex + 1);
+ return (struct bufdesc *)((ex_new_bd >= (ex_base + ring_size)) ?
+ (ex_new_bd - ring_size) : ex_new_bd);
else
- return bdp + 1;
+ return (new_bd >= (base + ring_size)) ?
+ (new_bd - ring_size) : new_bd;
}
-static struct bufdesc *fec_enet_get_prevdesc(struct bufdesc *bdp, int is_ex)
+static inline
+struct bufdesc *pre_bd(struct bufdesc *bdp, struct bufdesc *base,
+ int ring_size, int is_ex)
{
- struct bufdesc_ex *ex = (struct bufdesc_ex *)bdp;
+ struct bufdesc *new_bd = bdp - 1;
+ struct bufdesc_ex *ex_new_bd = (struct bufdesc_ex *)bdp - 1;
+ struct bufdesc_ex *ex_base = (struct bufdesc_ex *)base;
+
if (is_ex)
- return (struct bufdesc *)(ex - 1);
+ return (struct bufdesc *)((ex_new_bd < ex_base) ?
+ (ex_new_bd + ring_size) : ex_new_bd);
else
- return bdp - 1;
+ return (new_bd < base) ? (new_bd + ring_size) : new_bd;
}
static void *swap_buffer(void *bufaddr, int len)
@@ -380,7 +393,7 @@ fec_enet_start_xmit(struct sk_buff *skb, struct net_device *ndev)
}
}
- bdp_pre = fec_enet_get_prevdesc(bdp, fep->bufdesc_ex);
+ bdp_pre = pre_bd(bdp, fep->tx_bd_base, fep->tx_ring_size, fep->bufdesc_ex);
if ((id_entry->driver_data & FEC_QUIRK_ERR006358) &&
!(bdp_pre->cbd_sc & BD_ENET_TX_READY)) {
fep->delay_work.trig_tx = true;
@@ -389,10 +402,7 @@ fec_enet_start_xmit(struct sk_buff *skb, struct net_device *ndev)
}
/* If this was the last BD in the ring, start at the beginning again. */
- if (status & BD_ENET_TX_WRAP)
- bdp = fep->tx_bd_base;
- else
- bdp = fec_enet_get_nextdesc(bdp, fep->bufdesc_ex);
+ bdp = next_bd(bdp, fep->tx_bd_base, fep->tx_ring_size, fep->bufdesc_ex);
fep->cur_tx = bdp;
@@ -417,18 +427,18 @@ static void fec_enet_bd_init(struct net_device *dev)
/* Initialize the receive buffer descriptors. */
bdp = fep->rx_bd_base;
- for (i = 0; i < RX_RING_SIZE; i++) {
+ for (i = 0; i < fep->rx_ring_size; i++) {
/* Initialize the BD for every fragment in the page. */
if (bdp->cbd_bufaddr)
bdp->cbd_sc = BD_ENET_RX_EMPTY;
else
bdp->cbd_sc = 0;
- bdp = fec_enet_get_nextdesc(bdp, fep->bufdesc_ex);
+ bdp = next_bd(bdp, fep->rx_bd_base, fep->rx_ring_size, fep->bufdesc_ex);
}
/* Set the last buffer to wrap */
- bdp = fec_enet_get_prevdesc(bdp, fep->bufdesc_ex);
+ bdp = pre_bd(bdp, fep->rx_bd_base, fep->rx_ring_size, fep->bufdesc_ex);
bdp->cbd_sc |= BD_SC_WRAP;
fep->cur_rx = fep->rx_bd_base;
@@ -436,7 +446,7 @@ static void fec_enet_bd_init(struct net_device *dev)
/* ...and the same for transmit */
bdp = fep->tx_bd_base;
fep->cur_tx = bdp;
- for (i = 0; i < TX_RING_SIZE; i++) {
+ for (i = 0; i < fep->tx_ring_size; i++) {
/* Initialize the BD for every fragment in the page. */
bdp->cbd_sc = 0;
@@ -445,11 +455,11 @@ static void fec_enet_bd_init(struct net_device *dev)
fep->tx_skbuff[i] = NULL;
}
bdp->cbd_bufaddr = 0;
- bdp = fec_enet_get_nextdesc(bdp, fep->bufdesc_ex);
+ bdp = next_bd(bdp, fep->tx_bd_base, fep->tx_ring_size, fep->bufdesc_ex);
}
/* Set the last buffer to wrap */
- bdp = fec_enet_get_prevdesc(bdp, fep->bufdesc_ex);
+ bdp = pre_bd(bdp, fep->tx_bd_base, fep->tx_ring_size, fep->bufdesc_ex);
bdp->cbd_sc |= BD_SC_WRAP;
fep->dirty_tx = bdp;
}
@@ -510,10 +520,10 @@ fec_restart(struct net_device *ndev, int duplex)
writel(fep->bd_dma, fep->hwp + FEC_R_DES_START);
if (fep->bufdesc_ex)
writel((unsigned long)fep->bd_dma + sizeof(struct bufdesc_ex)
- * RX_RING_SIZE, fep->hwp + FEC_X_DES_START);
+ * fep->rx_ring_size, fep->hwp + FEC_X_DES_START);
else
writel((unsigned long)fep->bd_dma + sizeof(struct bufdesc)
- * RX_RING_SIZE, fep->hwp + FEC_X_DES_START);
+ * fep->rx_ring_size, fep->hwp + FEC_X_DES_START);
for (i = 0; i <= TX_RING_MOD_MASK; i++) {
@@ -727,10 +737,7 @@ fec_enet_tx(struct net_device *ndev)
bdp = fep->dirty_tx;
/* get next bdp of dirty_tx */
- if (bdp->cbd_sc & BD_ENET_TX_WRAP)
- bdp = fep->tx_bd_base;
- else
- bdp = fec_enet_get_nextdesc(bdp, fep->bufdesc_ex);
+ bdp = next_bd(bdp, fep->tx_bd_base, fep->tx_ring_size, fep->bufdesc_ex);
while (((status = bdp->cbd_sc) & BD_ENET_TX_READY) == 0) {
@@ -800,10 +807,7 @@ fec_enet_tx(struct net_device *ndev)
fep->dirty_tx = bdp;
/* Update pointer to next buffer descriptor to be transmitted */
- if (status & BD_ENET_TX_WRAP)
- bdp = fep->tx_bd_base;
- else
- bdp = fec_enet_get_nextdesc(bdp, fep->bufdesc_ex);
+ bdp = next_bd(bdp, fep->tx_bd_base, fep->tx_ring_size, fep->bufdesc_ex);
/* Since we have freed up a buffer, the ring is no longer full
*/
@@ -994,10 +998,8 @@ rx_processing_done:
}
/* Update BD pointer to next entry */
- if (status & BD_ENET_RX_WRAP)
- bdp = fep->rx_bd_base;
- else
- bdp = fec_enet_get_nextdesc(bdp, fep->bufdesc_ex);
+ bdp = next_bd(bdp, fep->rx_bd_base, fep->rx_ring_size, fep->bufdesc_ex);
+
/* Doing this here will keep the FEC running while we process
* incoming frames. On a heavily loaded network, we should be
* able to keep up at the expense of system resources.
@@ -1663,7 +1665,7 @@ static void fec_enet_free_buffers(struct net_device *ndev)
struct bufdesc *bdp;
bdp = fep->rx_bd_base;
- for (i = 0; i < RX_RING_SIZE; i++) {
+ for (i = 0; i < fep->rx_ring_size; i++) {
skb = fep->rx_skbuff[i];
if (bdp->cbd_bufaddr)
@@ -1671,11 +1673,11 @@ static void fec_enet_free_buffers(struct net_device *ndev)
FEC_ENET_RX_FRSIZE, DMA_FROM_DEVICE);
if (skb)
dev_kfree_skb(skb);
- bdp = fec_enet_get_nextdesc(bdp, fep->bufdesc_ex);
+ bdp = next_bd(bdp, fep->rx_bd_base, fep->rx_ring_size, fep->bufdesc_ex);
}
bdp = fep->tx_bd_base;
- for (i = 0; i < TX_RING_SIZE; i++)
+ for (i = 0; i < fep->tx_ring_size; i++)
kfree(fep->tx_bounce[i]);
}
@@ -1687,7 +1689,7 @@ static int fec_enet_alloc_buffers(struct net_device *ndev)
struct bufdesc *bdp;
bdp = fep->rx_bd_base;
- for (i = 0; i < RX_RING_SIZE; i++) {
+ for (i = 0; i < fep->rx_ring_size; i++) {
skb = netdev_alloc_skb(ndev, FEC_ENET_RX_FRSIZE);
if (!skb) {
fec_enet_free_buffers(ndev);
@@ -1704,15 +1706,15 @@ static int fec_enet_alloc_buffers(struct net_device *ndev)
ebdp->cbd_esc = BD_ENET_RX_INT;
}
- bdp = fec_enet_get_nextdesc(bdp, fep->bufdesc_ex);
+ bdp = next_bd(bdp, fep->rx_bd_base, fep->rx_ring_size, fep->bufdesc_ex);
}
/* Set the last buffer to wrap. */
- bdp = fec_enet_get_prevdesc(bdp, fep->bufdesc_ex);
+ bdp = pre_bd(bdp, fep->rx_bd_base, fep->rx_ring_size, fep->bufdesc_ex);
bdp->cbd_sc |= BD_SC_WRAP;
bdp = fep->tx_bd_base;
- for (i = 0; i < TX_RING_SIZE; i++) {
+ for (i = 0; i < fep->tx_ring_size; i++) {
fep->tx_bounce[i] = kmalloc(FEC_ENET_TX_FRSIZE, GFP_KERNEL);
bdp->cbd_sc = 0;
@@ -1723,11 +1725,11 @@ static int fec_enet_alloc_buffers(struct net_device *ndev)
ebdp->cbd_esc = BD_ENET_TX_INT;
}
- bdp = fec_enet_get_nextdesc(bdp, fep->bufdesc_ex);
+ bdp = next_bd(bdp, fep->tx_bd_base, fep->tx_ring_size, fep->bufdesc_ex);
}
/* Set the last buffer to wrap. */
- bdp = fec_enet_get_prevdesc(bdp, fep->bufdesc_ex);
+ bdp = pre_bd(bdp, fep->tx_bd_base, fep->tx_ring_size, fep->bufdesc_ex);
bdp->cbd_sc |= BD_SC_WRAP;
return 0;
@@ -1967,13 +1969,17 @@ static int fec_enet_init(struct net_device *ndev)
/* Get the Ethernet address */
fec_get_mac(ndev);
+ /* init the tx & rx ring size */
+ fep->tx_ring_size = TX_RING_SIZE;
+ fep->rx_ring_size = RX_RING_SIZE;
+
/* Set receive and transmit descriptor base. */
fep->rx_bd_base = cbd_base;
if (fep->bufdesc_ex)
fep->tx_bd_base = (struct bufdesc *)
- (((struct bufdesc_ex *)cbd_base) + RX_RING_SIZE);
+ (((struct bufdesc_ex *)cbd_base) + fep->rx_ring_size);
else
- fep->tx_bd_base = cbd_base + RX_RING_SIZE;
+ fep->tx_bd_base = cbd_base + fep->rx_ring_size;
/* The FEC Ethernet specific entries in the device structure */
ndev->watchdog_timeo = TX_TIMEOUT;
--
1.7.1
^ permalink raw reply related
* [PATCH net-next 0/5] bonding: locking simplifications and cleanup
From: Nikolay Aleksandrov @ 2013-09-02 11:51 UTC (permalink / raw)
To: netdev; +Cc: andy, fubar, davem
Hello,
This small patchset aims to remove some use cases of bond->lock for mutual
exclusion which will help in the RCUfication of the function users. It also
does some small style cleanups and fixes.
Patch 01 - Drops the use of bond->lock as mutual exclusion for peer
notification and relies on RTNL being held when send_peer_notif is modified
Patch 02 - trivial outdated comment removal
Patch 03 - Drops the use of bond->lock as mutual exclusion for lacp rate
update and relies on RTNL, also fixes possible races with mode change
Patch 04 - Drops read_lock in bond_fix_features because RTNL is held
Patch 05 - Drops read_lock in bond_compute_features because RTNL is held
whenever it's called
Best regards,
Nikolay Aleksandrov
Nikolay Aleksandrov (5):
bonding: simplify and fix peer notification
bonding: trivial: remove outdated comment and braces
bonding: simplify bond_3ad_update_lacp_rate and use RTNL for sync
bonding: drop read_lock in bond_fix_features
bonding: drop read_lock in bond_compute_features
drivers/net/bonding/bond_3ad.c | 8 +------
drivers/net/bonding/bond_main.c | 48 ++++++++++++----------------------------
drivers/net/bonding/bond_sysfs.c | 7 +++++-
3 files changed, 21 insertions(+), 42 deletions(-)
--
1.8.1.4
^ permalink raw reply
* [PATCH net-next 1/5] bonding: simplify and fix peer notification
From: Nikolay Aleksandrov @ 2013-09-02 11:51 UTC (permalink / raw)
To: netdev; +Cc: andy, fubar, davem
In-Reply-To: <1378122702-28943-1-git-send-email-nikolay@redhat.com>
This patch aims to remove a use of the bond->lock for mutual exclusion
which will later allow easier migration to RCU of the users of this
functionality. We use RTNL as a synchronizing mechanism since it's
always held when send_peer_notif is set, and when it is decremented from
the notifier function. We can also drop some locking, and fix the
leakage of the send_peer_notif counter.
Signed-off-by: Nikolay Aleksandrov <nikolay@redhat.com>
---
drivers/net/bonding/bond_main.c | 22 +++++++---------------
1 file changed, 7 insertions(+), 15 deletions(-)
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
index c50679f..05e638b 100644
--- a/drivers/net/bonding/bond_main.c
+++ b/drivers/net/bonding/bond_main.c
@@ -828,7 +828,6 @@ static bool bond_should_notify_peers(struct bonding *bond)
test_bit(__LINK_STATE_LINKWATCH_PENDING, &slave->dev->state))
return false;
- bond->send_peer_notif--;
return true;
}
@@ -2259,12 +2258,8 @@ re_arm:
read_unlock(&bond->lock);
if (should_notify_peers) {
- if (!rtnl_trylock()) {
- read_lock(&bond->lock);
- bond->send_peer_notif++;
- read_unlock(&bond->lock);
+ if (!rtnl_trylock())
return;
- }
call_netdevice_notifiers(NETDEV_NOTIFY_PEERS, bond->dev);
rtnl_unlock();
}
@@ -2876,12 +2871,8 @@ re_arm:
read_unlock(&bond->lock);
if (should_notify_peers) {
- if (!rtnl_trylock()) {
- read_lock(&bond->lock);
- bond->send_peer_notif++;
- read_unlock(&bond->lock);
+ if (!rtnl_trylock())
return;
- }
call_netdevice_notifiers(NETDEV_NOTIFY_PEERS, bond->dev);
rtnl_unlock();
}
@@ -2916,6 +2907,10 @@ static int bond_master_netdev_event(unsigned long event,
case NETDEV_REGISTER:
bond_create_proc_entry(event_bond);
break;
+ case NETDEV_NOTIFY_PEERS:
+ if (event_bond->send_peer_notif)
+ event_bond->send_peer_notif--;
+ break;
default:
break;
}
@@ -3213,11 +3208,8 @@ static int bond_close(struct net_device *bond_dev)
{
struct bonding *bond = netdev_priv(bond_dev);
- write_lock_bh(&bond->lock);
- bond->send_peer_notif = 0;
- write_unlock_bh(&bond->lock);
-
bond_work_cancel_all(bond);
+ bond->send_peer_notif = 0;
if (bond_is_lb(bond)) {
/* Must be called only after all
* slaves have been released
--
1.8.1.4
^ permalink raw reply related
* [PATCH net-next 2/5] bonding: trivial: remove outdated comment and braces
From: Nikolay Aleksandrov @ 2013-09-02 11:51 UTC (permalink / raw)
To: netdev; +Cc: andy, fubar, davem
In-Reply-To: <1378122702-28943-1-git-send-email-nikolay@redhat.com>
We don't have to release all slaves when closing the bond dev, so remove
the outdated comment and the braces around the left single statement.
Signed-off-by: Nikolay Aleksandrov <nikolay@redhat.com>
---
drivers/net/bonding/bond_main.c | 6 +-----
1 file changed, 1 insertion(+), 5 deletions(-)
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
index 05e638b..486e041 100644
--- a/drivers/net/bonding/bond_main.c
+++ b/drivers/net/bonding/bond_main.c
@@ -3210,12 +3210,8 @@ static int bond_close(struct net_device *bond_dev)
bond_work_cancel_all(bond);
bond->send_peer_notif = 0;
- if (bond_is_lb(bond)) {
- /* Must be called only after all
- * slaves have been released
- */
+ if (bond_is_lb(bond))
bond_alb_deinitialize(bond);
- }
bond->recv_probe = NULL;
return 0;
--
1.8.1.4
^ permalink raw reply related
* [PATCH net-next 4/5] bonding: drop read_lock in bond_fix_features
From: Nikolay Aleksandrov @ 2013-09-02 11:51 UTC (permalink / raw)
To: netdev; +Cc: andy, fubar, davem
In-Reply-To: <1378122702-28943-1-git-send-email-nikolay@redhat.com>
We're protected by RTNL so nothing can happen and we can safely drop the
read bond->lock.
Signed-off-by: Nikolay Aleksandrov <nikolay@redhat.com>
---
drivers/net/bonding/bond_main.c | 10 +++-------
1 file changed, 3 insertions(+), 7 deletions(-)
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
index 486e041..c5ebdc5 100644
--- a/drivers/net/bonding/bond_main.c
+++ b/drivers/net/bonding/bond_main.c
@@ -1084,18 +1084,16 @@ static void bond_netpoll_cleanup(struct net_device *bond_dev)
/*---------------------------------- IOCTL ----------------------------------*/
static netdev_features_t bond_fix_features(struct net_device *dev,
- netdev_features_t features)
+ netdev_features_t features)
{
- struct slave *slave;
struct bonding *bond = netdev_priv(dev);
netdev_features_t mask;
-
- read_lock(&bond->lock);
+ struct slave *slave;
if (list_empty(&bond->slave_list)) {
/* Disable adding VLANs to empty bond. But why? --mq */
features |= NETIF_F_VLAN_CHALLENGED;
- goto out;
+ return features;
}
mask = features;
@@ -1109,8 +1107,6 @@ static netdev_features_t bond_fix_features(struct net_device *dev,
}
features = netdev_add_tso_features(features, mask);
-out:
- read_unlock(&bond->lock);
return features;
}
--
1.8.1.4
^ permalink raw reply related
* [PATCH net-next 5/5] bonding: drop read_lock in bond_compute_features
From: Nikolay Aleksandrov @ 2013-09-02 11:51 UTC (permalink / raw)
To: netdev; +Cc: andy, fubar, davem
In-Reply-To: <1378122702-28943-1-git-send-email-nikolay@redhat.com>
bond_compute_features is always called with RTNL held, so we can safely
drop the read bond->lock.
Signed-off-by: Nikolay Aleksandrov <nikolay@redhat.com>
---
drivers/net/bonding/bond_main.c | 10 +++-------
1 file changed, 3 insertions(+), 7 deletions(-)
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
index c5ebdc5..39e5b1c 100644
--- a/drivers/net/bonding/bond_main.c
+++ b/drivers/net/bonding/bond_main.c
@@ -1116,15 +1116,13 @@ static netdev_features_t bond_fix_features(struct net_device *dev,
static void bond_compute_features(struct bonding *bond)
{
- struct slave *slave;
- struct net_device *bond_dev = bond->dev;
+ unsigned int flags, dst_release_flag = IFF_XMIT_DST_RELEASE;
netdev_features_t vlan_features = BOND_VLAN_FEATURES;
unsigned short max_hard_header_len = ETH_HLEN;
unsigned int gso_max_size = GSO_MAX_SIZE;
+ struct net_device *bond_dev = bond->dev;
u16 gso_max_segs = GSO_MAX_SEGS;
- unsigned int flags, dst_release_flag = IFF_XMIT_DST_RELEASE;
-
- read_lock(&bond->lock);
+ struct slave *slave;
if (list_empty(&bond->slave_list))
goto done;
@@ -1150,8 +1148,6 @@ done:
flags = bond_dev->priv_flags & ~IFF_XMIT_DST_RELEASE;
bond_dev->priv_flags = flags | dst_release_flag;
- read_unlock(&bond->lock);
-
netdev_change_features(bond_dev);
}
--
1.8.1.4
^ permalink raw reply related
* [PATCH net-next 3/5] bonding: simplify bond_3ad_update_lacp_rate and use RTNL for sync
From: Nikolay Aleksandrov @ 2013-09-02 11:51 UTC (permalink / raw)
To: netdev; +Cc: andy, fubar, davem
In-Reply-To: <1378122702-28943-1-git-send-email-nikolay@redhat.com>
We can drop the use of bond->lock for mutual exclusion in
bond_3ad_update_lacp_rate and use RTNL in the sysfs store function
instead. This way we'll prevent races with mode change and interface
up/down as well as simplify update_lacp_rate by removing the check for
port->slave because it'll always be initialized (done while enslaving
with RTNL). This change will also help in the future removal of reader
bond->lock from bond_enslave.
Signed-off-by: Nikolay Aleksandrov <nikolay@redhat.com>
---
drivers/net/bonding/bond_3ad.c | 8 +-------
drivers/net/bonding/bond_sysfs.c | 7 ++++++-
2 files changed, 7 insertions(+), 8 deletions(-)
diff --git a/drivers/net/bonding/bond_3ad.c b/drivers/net/bonding/bond_3ad.c
index 9010265..0d8f427 100644
--- a/drivers/net/bonding/bond_3ad.c
+++ b/drivers/net/bonding/bond_3ad.c
@@ -2514,17 +2514,13 @@ int bond_3ad_lacpdu_recv(const struct sk_buff *skb, struct bonding *bond,
*/
void bond_3ad_update_lacp_rate(struct bonding *bond)
{
- struct slave *slave;
struct port *port = NULL;
+ struct slave *slave;
int lacp_fast;
- write_lock_bh(&bond->lock);
lacp_fast = bond->params.lacp_fast;
-
bond_for_each_slave(bond, slave) {
port = &(SLAVE_AD_INFO(slave).port);
- if (port->slave == NULL)
- continue;
__get_state_machine_lock(port);
if (lacp_fast)
port->actor_oper_port_state |= AD_STATE_LACP_TIMEOUT;
@@ -2532,6 +2528,4 @@ void bond_3ad_update_lacp_rate(struct bonding *bond)
port->actor_oper_port_state &= ~AD_STATE_LACP_TIMEOUT;
__release_state_machine_lock(port);
}
-
- write_unlock_bh(&bond->lock);
}
diff --git a/drivers/net/bonding/bond_sysfs.c b/drivers/net/bonding/bond_sysfs.c
index 0f539de..ce46776 100644
--- a/drivers/net/bonding/bond_sysfs.c
+++ b/drivers/net/bonding/bond_sysfs.c
@@ -852,8 +852,11 @@ static ssize_t bonding_store_lacp(struct device *d,
struct device_attribute *attr,
const char *buf, size_t count)
{
- int new_value, ret = count;
struct bonding *bond = to_bond(d);
+ int new_value, ret = count;
+
+ if (!rtnl_trylock())
+ return restart_syscall();
if (bond->dev->flags & IFF_UP) {
pr_err("%s: Unable to update LACP rate because interface is up.\n",
@@ -883,6 +886,8 @@ static ssize_t bonding_store_lacp(struct device *d,
ret = -EINVAL;
}
out:
+ rtnl_unlock();
+
return ret;
}
static DEVICE_ATTR(lacp_rate, S_IRUGO | S_IWUSR,
--
1.8.1.4
^ permalink raw reply related
* Re: 3.11-rc7:BUG: soft lockup
From: Baoquan He @ 2013-09-02 12:09 UTC (permalink / raw)
To: Ding Tianhong
Cc: Hillf Danton, Cong Wang, LKML, Linux Kernel Network Developers
In-Reply-To: <5224548C.8000603@huawei.com>
On 09/02/2013 05:04 PM, Ding Tianhong wrote:
> On 2013/9/2 16:24, Baoquan He wrote:
>> Hi Tianhong,
>>
>> I applied your patch and execute below cmd.
>> Then keyboard inputting problems happened,
>> I can't enter user/password correctly, then reboot again, it's OK now.
> Thanks for your work, I don't understand that the keyboard problem is the patch fault or your system problem,
> if it is not happen again, I think the problem is fixed.
Yeah, I will wait and see if it will happen again. Up to now, it's OK.
Thank you all for help.
Baoquan
Thanks
>
>> The original bug still can't be reproduced.
>>
>> make SUBDIRS=net/bridge/netfilter/
>> cp /net/bridge/netfilter/ebtables.ko
>> /lib/modules/3.11.0-rc7+/kernel/net/bridge/netfilter/ebtables.ko
>> depmod
>> modprobe ebtables.ko
>> reboot
>>
>> Baoquan
>> Thanks
>>
>>> please try this patch and give me the result, thanks.
>>>
>>> Return the correct value if mutex_lock_interruptible() failed, avoid
>>> confusion with that the modules is not exist, and deal with the return
>>> value in right way.
>>>
>>> if mutex_lock_interrupt() failed, sh
>>>
>>> Signed-off-by: root <root@linux-yocto.site>
>>> ---
>>> net/bridge/netfilter/ebtables.c | 17 +++++++----------
>>> 1 file changed, 7 insertions(+), 10 deletions(-)
>>>
>>> diff --git a/net/bridge/netfilter/ebtables.c b/net/bridge/netfilter/ebtables.c
>>> index ac78024..e7fe9f8 100644
>>> --- a/net/bridge/netfilter/ebtables.c
>>> +++ b/net/bridge/netfilter/ebtables.c
>>> @@ -322,17 +322,14 @@ static inline void *
>>> find_inlist_lock_noload(struct list_head *head, const char *name, int *error,
>>> struct mutex *mutex)
>>> {
>>> - struct {
>>> - struct list_head list;
>>> - char name[EBT_FUNCTION_MAXNAMELEN];
>>> - } *e;
>>> + struct ebt_table *e;
>>>
>>> *error = mutex_lock_interruptible(mutex);
>>> if (*error != 0)
>>> - return NULL;
>>> + return ERR_PTR(-EINTR);
>>>
>>> list_for_each_entry(e, head, list) {
>>> - if (strcmp(e->name, name) == 0)
>>> + if (strcmp(e->name, name) == 0 && try_module_get(e->me))
>>> return e;
>>> }
>>> *error = -ENOENT;
>>> @@ -1005,7 +1002,7 @@ static int do_replace_finish(struct net *net, struct ebt_replace *repl,
>>> goto free_counterstmp;
>>>
>>> t = find_table_lock(net, repl->name, &ret, &ebt_mutex);
>>> - if (!t) {
>>> + if (IS_ERR_OR_NULL(t)) {
>>> ret = -ENOENT;
>>> goto free_iterate;
>>> }
>>> @@ -1284,7 +1281,7 @@ static int do_update_counters(struct net *net, const char *name,
>>> return -ENOMEM;
>>>
>>> t = find_table_lock(net, name, &ret, &ebt_mutex);
>>> - if (!t)
>>> + if (IS_ERR_OR_NULL(t))
>>> goto free_tmp;
>>>
>>> if (num_counters != t->private->nentries) {
>>> @@ -1504,7 +1501,7 @@ static int do_ebt_get_ctl(struct sock *sk, int cmd, void __user *user, int *len)
>>> return -EFAULT;
>>>
>>> t = find_table_lock(net, tmp.name, &ret, &ebt_mutex);
>>> - if (!t)
>>> + if (IS_ERR_OR_NULL(t))
>>> return ret;
>>>
>>> switch(cmd) {
>>> @@ -2319,7 +2316,7 @@ static int compat_do_ebt_get_ctl(struct sock *sk, int cmd,
>>> return -EFAULT;
>>>
>>> t = find_table_lock(net, tmp.name, &ret, &ebt_mutex);
>>> - if (!t)
>>> + if (IS_ERR_OR_NULL(t))
>>> return ret;
>>>
>>> xt_compat_lock(NFPROTO_BRIDGE);
>>
>> .
>>
>
^ permalink raw reply
* Re: BQL support in gianfar causes network hiccup
From: Per Dalén @ 2013-09-02 13:21 UTC (permalink / raw)
To: netdev
> On Mo, 2013-04-29 at 15:20 +0200, Tino Keitel wrote:
> > On Mo, 2013-04-29 at 15:14 +0200, Claudiu Manoil wrote:
> >
> > > The proposed fix (passes this test):
> > > http://patchwork.ozlabs.org/patch/240365/
> > >
> > > Does it work for you?
Hi,
This patch do not work for me. I have the same problems that Tino on my
card. My card is a Freescale P2020 and I use "iperf -c 10.10.51.36 -n
100M -P 50" to trigger the error.
The network interface is set to 100M half duplex.
I have tested this using 3.4.35 and 3.4.60 kernel.
NETDEV WATCHDOG: eth0 (fsl-gianfar): transmit queue 0 timed out
------------[ cut here ]------------
WARNING: at net/sched/sch_generic.c:256
Modules linked in:
NIP: c039bb94 LR: c039bb94 CTR: c02ee500
REGS: dffe7e60 TRAP: 0700 Not tainted (3.4.60+)
MSR: 00029000 <CE,EE,ME> CR: 40000084 XER: 20000000
TASK = df843200[0] 'swapper/1' THREAD: df864000 CPU: 1
GPR00: c039bb94 dffe7f10 df843200 00000046 00021000 ffffffff c02eecf0
00029000
GPR08: 00000001 00008000 00463000 00003fff 80000028 00000000 00000000
00000004
GPR16: 00000001 df858e14 c051f1f4 00000001 df858c14 df858a14 df858814
ffffffff
GPR24: 00000001 df813234 00000004 df8f9a00 c05e0000 c05e0000 df813000
00000000
NIP [c039bb94] dev_watchdog+0x2d4/0x2e4
LR [c039bb94] dev_watchdog+0x2d4/0x2e4
Call Trace:
[dffe7f10] [c039bb94] dev_watchdog+0x2d4/0x2e4 (unreliable)
[dffe7f40] [c003e944] run_timer_softirq+0x11c/0x20c
[dffe7fa0] [c00377dc] __do_softirq+0xe4/0x16c
[dffe7ff0] [c000c408] call_do_softirq+0x14/0x24
[df865e80] [c00043c4] do_softirq+0xb4/0xe4
[df865ea0] [c0037b4c] irq_exit+0xb0/0xcc
[df865eb0] [c0008958] timer_interrupt+0x188/0x1a4
[df865ee0] [c000db68] ret_from_except+0x0/0x18
--- Exception: 901 at cpu_idle+0x90/0xf4
LR = cpu_idle+0x90/0xf4
[df865fa0] [c0007b30] cpu_idle+0x5c/0xf4 (unreliable)
[df865fc0] [c049d68c] start_secondary+0x2b0/0x2b4
[df865ff0] [c0001cf8] __secondary_start+0x30/0x84
Instruction dump:
4e800421 80fe0244 4bffff40 7fc3f378 4bfeab6d 7fc4f378 7c651b78 3c60c055
7fe6fb78 38633108 4cc63182 480fc889 <0fe00000> 39200001 993cea1a 4bffffb4
---[ end trace 4be011773b23dae3 ]---
When I revert "gianfar: Add support for byte queue limits.", commit
d8a0f1b0af67679bba886784de10d8c21acc4e0e, the network test work fine
without any "hiccup".
If the network interface is set to 1000M full duplex there's also no
"hiccup".
>
> Hi,
>
> I tested the patch over the weekend and it looks fine. I then re-checked
> without the patch and got the bug immediately. So the patch seems to
> work fine.
>
Thanks,
Per Dalén
^ permalink raw reply
* [PATCH net-next 0/5] tunnels: harmonize skb scrubbing during encapsulation/decapsulation
From: Nicolas Dichtel @ 2013-09-02 13:34 UTC (permalink / raw)
To: pshelar-l0M0P4e3n4LQT0dZR+AlfA
Cc: dev-yBygre7rU0TnMu66kgdUjQ, netdev-u79uwXL29TY76Z2rM5mHXA,
davem-fT/PcQaiUtIeIZ0/mPfg9Q
In-Reply-To: <CALnjE+pKi=p0y2ot2qWG1w=pxEUcPUKY+_UUi0RXbnGqVk9poA-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
We talk recently about harmonizing tunnels so they behave consistently wrt. SKB
orphaning, cleaning netfilter state, etc.
The goal of this serie is to achieve this.
Note that I test only ipip, sit and ip6_tunnels modules.
v2: add patch 2/5
rebase on head
remove 'RFC' prefix
drivers/net/vxlan.c | 15 ++++++++-------
include/linux/skbuff.h | 2 +-
include/net/dst.h | 12 +++++++-----
include/net/ip6_tunnel.h | 1 -
include/net/ip_tunnels.h | 5 ++---
include/net/vxlan.h | 2 +-
net/core/dev.c | 2 +-
net/core/skbuff.c | 19 ++++++++++++-------
net/ipv4/ip_tunnel.c | 12 ++++--------
net/ipv4/ip_tunnel_core.c | 10 ++++------
net/ipv4/ipmr.c | 3 +--
net/ipv6/ip6_gre.c | 9 +++------
net/ipv6/ip6_tunnel.c | 11 ++---------
net/ipv6/ip6mr.c | 3 +--
net/ipv6/sit.c | 13 +++----------
net/openvswitch/vport-gre.c | 4 ++--
net/openvswitch/vport-vxlan.c | 2 +-
17 files changed, 53 insertions(+), 72 deletions(-)
Comments are welcome.
Regards,
Nicolas
^ permalink raw reply
* [PATCH net-next v2 1/5] iptunnels: remove net arg from iptunnel_xmit()
From: Nicolas Dichtel @ 2013-09-02 13:34 UTC (permalink / raw)
To: pshelar-l0M0P4e3n4LQT0dZR+AlfA
Cc: dev-yBygre7rU0TnMu66kgdUjQ, netdev-u79uwXL29TY76Z2rM5mHXA,
Nicolas Dichtel, davem-fT/PcQaiUtIeIZ0/mPfg9Q
In-Reply-To: <1378128898-15136-1-git-send-email-nicolas.dichtel-pdR9zngts4EAvxtiuMwx3w@public.gmane.org>
This argument is not used, let's remove it.
Signed-off-by: Nicolas Dichtel <nicolas.dichtel-pdR9zngts4EAvxtiuMwx3w@public.gmane.org>
---
drivers/net/vxlan.c | 3 +--
include/net/ip_tunnels.h | 3 +--
net/ipv4/ip_tunnel.c | 3 +--
net/ipv4/ip_tunnel_core.c | 3 +--
net/ipv6/sit.c | 4 ++--
net/openvswitch/vport-gre.c | 2 +-
6 files changed, 7 insertions(+), 11 deletions(-)
diff --git a/drivers/net/vxlan.c b/drivers/net/vxlan.c
index 3ffb22d684a9..18165c02d614 100644
--- a/drivers/net/vxlan.c
+++ b/drivers/net/vxlan.c
@@ -1528,8 +1528,7 @@ int vxlan_xmit_skb(struct net *net, struct vxlan_sock *vs,
if (err)
return err;
- return iptunnel_xmit(net, rt, skb, src, dst,
- IPPROTO_UDP, tos, ttl, df);
+ return iptunnel_xmit(rt, skb, src, dst, IPPROTO_UDP, tos, ttl, df);
}
EXPORT_SYMBOL_GPL(vxlan_xmit_skb);
diff --git a/include/net/ip_tunnels.h b/include/net/ip_tunnels.h
index 0ce316bb3c65..94fe8fd07bc9 100644
--- a/include/net/ip_tunnels.h
+++ b/include/net/ip_tunnels.h
@@ -146,8 +146,7 @@ static inline u8 ip_tunnel_ecn_encap(u8 tos, const struct iphdr *iph,
}
int iptunnel_pull_header(struct sk_buff *skb, int hdr_len, __be16 inner_proto);
-int iptunnel_xmit(struct net *net, struct rtable *rt,
- struct sk_buff *skb,
+int iptunnel_xmit(struct rtable *rt, struct sk_buff *skb,
__be32 src, __be32 dst, __u8 proto,
__u8 tos, __u8 ttl, __be16 df);
diff --git a/net/ipv4/ip_tunnel.c b/net/ipv4/ip_tunnel.c
index 830de3f4e293..0a6cf0e69478 100644
--- a/net/ipv4/ip_tunnel.c
+++ b/net/ipv4/ip_tunnel.c
@@ -654,8 +654,7 @@ void ip_tunnel_xmit(struct sk_buff *skb, struct net_device *dev,
}
}
- err = iptunnel_xmit(tunnel->net, rt, skb,
- fl4.saddr, fl4.daddr, protocol,
+ err = iptunnel_xmit(rt, skb, fl4.saddr, fl4.daddr, protocol,
ip_tunnel_ecn_encap(tos, inner_iph, skb), ttl, df);
iptunnel_xmit_stats(err, &dev->stats, dev->tstats);
diff --git a/net/ipv4/ip_tunnel_core.c b/net/ipv4/ip_tunnel_core.c
index 850525b34899..e82045842351 100644
--- a/net/ipv4/ip_tunnel_core.c
+++ b/net/ipv4/ip_tunnel_core.c
@@ -46,8 +46,7 @@
#include <net/netns/generic.h>
#include <net/rtnetlink.h>
-int iptunnel_xmit(struct net *net, struct rtable *rt,
- struct sk_buff *skb,
+int iptunnel_xmit(struct rtable *rt, struct sk_buff *skb,
__be32 src, __be32 dst, __u8 proto,
__u8 tos, __u8 ttl, __be16 df)
{
diff --git a/net/ipv6/sit.c b/net/ipv6/sit.c
index f18f842ac893..1d1458a3b7c4 100644
--- a/net/ipv6/sit.c
+++ b/net/ipv6/sit.c
@@ -888,8 +888,8 @@ static netdev_tx_t ipip6_tunnel_xmit(struct sk_buff *skb,
ttl = iph6->hop_limit;
tos = INET_ECN_encapsulate(tos, ipv6_get_dsfield(iph6));
- err = iptunnel_xmit(dev_net(dev), rt, skb, fl4.saddr, fl4.daddr,
- IPPROTO_IPV6, tos, ttl, df);
+ err = iptunnel_xmit(rt, skb, fl4.saddr, fl4.daddr, IPPROTO_IPV6, tos,
+ ttl, df);
iptunnel_xmit_stats(err, &dev->stats, dev->tstats);
return NETDEV_TX_OK;
diff --git a/net/openvswitch/vport-gre.c b/net/openvswitch/vport-gre.c
index 21d5073e148e..9b3713ef831e 100644
--- a/net/openvswitch/vport-gre.c
+++ b/net/openvswitch/vport-gre.c
@@ -176,7 +176,7 @@ static int gre_tnl_send(struct vport *vport, struct sk_buff *skb)
skb->local_df = 1;
- return iptunnel_xmit(net, rt, skb, fl.saddr,
+ return iptunnel_xmit(rt, skb, fl.saddr,
OVS_CB(skb)->tun_key->ipv4_dst, IPPROTO_GRE,
OVS_CB(skb)->tun_key->ipv4_tos,
OVS_CB(skb)->tun_key->ipv4_ttl, df);
--
1.8.2.1
^ permalink raw reply related
* [PATCH net-next v2 2/5] vxlan: remove net arg from vxlan[6]_xmit_skb()
From: Nicolas Dichtel @ 2013-09-02 13:34 UTC (permalink / raw)
To: pshelar-l0M0P4e3n4LQT0dZR+AlfA
Cc: dev-yBygre7rU0TnMu66kgdUjQ, netdev-u79uwXL29TY76Z2rM5mHXA,
Nicolas Dichtel, davem-fT/PcQaiUtIeIZ0/mPfg9Q
In-Reply-To: <1378128898-15136-1-git-send-email-nicolas.dichtel-pdR9zngts4EAvxtiuMwx3w@public.gmane.org>
This argument is not used, let's remove it.
Signed-off-by: Nicolas Dichtel <nicolas.dichtel-pdR9zngts4EAvxtiuMwx3w@public.gmane.org>
---
drivers/net/vxlan.c | 8 ++++----
include/net/vxlan.h | 2 +-
net/openvswitch/vport-vxlan.c | 2 +-
3 files changed, 6 insertions(+), 6 deletions(-)
diff --git a/drivers/net/vxlan.c b/drivers/net/vxlan.c
index 18165c02d614..5f46d2f3222f 100644
--- a/drivers/net/vxlan.c
+++ b/drivers/net/vxlan.c
@@ -1380,7 +1380,7 @@ static int handle_offloads(struct sk_buff *skb)
}
#if IS_ENABLED(CONFIG_IPV6)
-static int vxlan6_xmit_skb(struct net *net, struct vxlan_sock *vs,
+static int vxlan6_xmit_skb(struct vxlan_sock *vs,
struct dst_entry *dst, struct sk_buff *skb,
struct net_device *dev, struct in6_addr *saddr,
struct in6_addr *daddr, __u8 prio, __u8 ttl,
@@ -1475,7 +1475,7 @@ static int vxlan6_xmit_skb(struct net *net, struct vxlan_sock *vs,
}
#endif
-int vxlan_xmit_skb(struct net *net, struct vxlan_sock *vs,
+int vxlan_xmit_skb(struct vxlan_sock *vs,
struct rtable *rt, struct sk_buff *skb,
__be32 src, __be32 dst, __u8 tos, __u8 ttl, __be16 df,
__be16 src_port, __be16 dst_port, __be32 vni)
@@ -1651,7 +1651,7 @@ static void vxlan_xmit_one(struct sk_buff *skb, struct net_device *dev,
tos = ip_tunnel_ecn_encap(tos, old_iph, skb);
ttl = ttl ? : ip4_dst_hoplimit(&rt->dst);
- err = vxlan_xmit_skb(dev_net(dev), vxlan->vn_sock, rt, skb,
+ err = vxlan_xmit_skb(vxlan->vn_sock, rt, skb,
fl4.saddr, dst->sin.sin_addr.s_addr,
tos, ttl, df, src_port, dst_port,
htonl(vni << 8));
@@ -1703,7 +1703,7 @@ static void vxlan_xmit_one(struct sk_buff *skb, struct net_device *dev,
ttl = ttl ? : ip6_dst_hoplimit(ndst);
- err = vxlan6_xmit_skb(dev_net(dev), vxlan->vn_sock, ndst, skb,
+ err = vxlan6_xmit_skb(vxlan->vn_sock, ndst, skb,
dev, &fl6.saddr, &fl6.daddr, 0, ttl,
src_port, dst_port, htonl(vni << 8));
#endif
diff --git a/include/net/vxlan.h b/include/net/vxlan.h
index d2b88cafa7a2..e09c40b68027 100644
--- a/include/net/vxlan.h
+++ b/include/net/vxlan.h
@@ -29,7 +29,7 @@ struct vxlan_sock *vxlan_sock_add(struct net *net, __be16 port,
void vxlan_sock_release(struct vxlan_sock *vs);
-int vxlan_xmit_skb(struct net *net, struct vxlan_sock *vs,
+int vxlan_xmit_skb(struct vxlan_sock *vs,
struct rtable *rt, struct sk_buff *skb,
__be32 src, __be32 dst, __u8 tos, __u8 ttl, __be16 df,
__be16 src_port, __be16 dst_port, __be32 vni);
diff --git a/net/openvswitch/vport-vxlan.c b/net/openvswitch/vport-vxlan.c
index a0060245b4e1..a481c03e2861 100644
--- a/net/openvswitch/vport-vxlan.c
+++ b/net/openvswitch/vport-vxlan.c
@@ -176,7 +176,7 @@ static int vxlan_tnl_send(struct vport *vport, struct sk_buff *skb)
inet_get_local_port_range(&port_min, &port_max);
src_port = vxlan_src_port(port_min, port_max, skb);
- err = vxlan_xmit_skb(net, vxlan_port->vs, rt, skb,
+ err = vxlan_xmit_skb(vxlan_port->vs, rt, skb,
fl.saddr, OVS_CB(skb)->tun_key->ipv4_dst,
OVS_CB(skb)->tun_key->ipv4_tos,
OVS_CB(skb)->tun_key->ipv4_ttl, df,
--
1.8.2.1
^ permalink raw reply related
* [PATCH net-next v2 5/5] tunnels: harmonize cleanup done on skb on rx path
From: Nicolas Dichtel @ 2013-09-02 13:34 UTC (permalink / raw)
To: pshelar-l0M0P4e3n4LQT0dZR+AlfA
Cc: dev-yBygre7rU0TnMu66kgdUjQ, netdev-u79uwXL29TY76Z2rM5mHXA,
Nicolas Dichtel, davem-fT/PcQaiUtIeIZ0/mPfg9Q
In-Reply-To: <1378128898-15136-1-git-send-email-nicolas.dichtel-pdR9zngts4EAvxtiuMwx3w@public.gmane.org>
The goal of this patch is to harmonize cleanup done on a skbuff on rx path.
Before this patch, behaviors were different depending of the tunnel type.
Signed-off-by: Nicolas Dichtel <nicolas.dichtel-pdR9zngts4EAvxtiuMwx3w@public.gmane.org>
---
include/net/dst.h | 12 +++++++-----
net/ipv4/ip_tunnel.c | 3 +--
net/ipv4/ipmr.c | 3 +--
net/ipv6/ip6_gre.c | 5 +----
net/ipv6/ip6_tunnel.c | 7 +------
net/ipv6/ip6mr.c | 3 +--
net/ipv6/sit.c | 6 +-----
7 files changed, 13 insertions(+), 26 deletions(-)
diff --git a/include/net/dst.h b/include/net/dst.h
index 1f8fd109e225..3bc4865f8267 100644
--- a/include/net/dst.h
+++ b/include/net/dst.h
@@ -311,11 +311,13 @@ static inline void skb_dst_force(struct sk_buff *skb)
* __skb_tunnel_rx - prepare skb for rx reinsert
* @skb: buffer
* @dev: tunnel device
+ * @net: netns for packet i/o
*
* After decapsulation, packet is going to re-enter (netif_rx()) our stack,
* so make some cleanups. (no accounting done)
*/
-static inline void __skb_tunnel_rx(struct sk_buff *skb, struct net_device *dev)
+static inline void __skb_tunnel_rx(struct sk_buff *skb, struct net_device *dev,
+ struct net *net)
{
skb->dev = dev;
@@ -327,8 +329,7 @@ static inline void __skb_tunnel_rx(struct sk_buff *skb, struct net_device *dev)
if (!skb->l4_rxhash)
skb->rxhash = 0;
skb_set_queue_mapping(skb, 0);
- skb_dst_drop(skb);
- nf_reset(skb);
+ skb_scrub_packet(skb, !net_eq(net, dev_net(dev)));
}
/**
@@ -340,12 +341,13 @@ static inline void __skb_tunnel_rx(struct sk_buff *skb, struct net_device *dev)
* so make some cleanups, and perform accounting.
* Note: this accounting is not SMP safe.
*/
-static inline void skb_tunnel_rx(struct sk_buff *skb, struct net_device *dev)
+static inline void skb_tunnel_rx(struct sk_buff *skb, struct net_device *dev,
+ struct net *net)
{
/* TODO : stats should be SMP safe */
dev->stats.rx_packets++;
dev->stats.rx_bytes += skb->len;
- __skb_tunnel_rx(skb, dev);
+ __skb_tunnel_rx(skb, dev, net);
}
/* Children define the path of the packet through the
diff --git a/net/ipv4/ip_tunnel.c b/net/ipv4/ip_tunnel.c
index 88d7d7d1eccb..ac9fabe0300f 100644
--- a/net/ipv4/ip_tunnel.c
+++ b/net/ipv4/ip_tunnel.c
@@ -461,8 +461,7 @@ int ip_tunnel_rcv(struct ip_tunnel *tunnel, struct sk_buff *skb,
skb->dev = tunnel->dev;
}
- if (!net_eq(tunnel->net, dev_net(tunnel->dev)))
- skb_scrub_packet(skb, true);
+ skb_scrub_packet(skb, !net_eq(tunnel->net, dev_net(tunnel->dev)));
gro_cells_receive(&tunnel->gro_cells, skb);
return 0;
diff --git a/net/ipv4/ipmr.c b/net/ipv4/ipmr.c
index bacc0bcf48ce..9ae54b09254f 100644
--- a/net/ipv4/ipmr.c
+++ b/net/ipv4/ipmr.c
@@ -2067,9 +2067,8 @@ static int __pim_rcv(struct mr_table *mrt, struct sk_buff *skb,
skb_reset_network_header(skb);
skb->protocol = htons(ETH_P_IP);
skb->ip_summed = CHECKSUM_NONE;
- skb->pkt_type = PACKET_HOST;
- skb_tunnel_rx(skb, reg_dev);
+ skb_tunnel_rx(skb, reg_dev, dev_net(reg_dev));
netif_rx(skb);
diff --git a/net/ipv6/ip6_gre.c b/net/ipv6/ip6_gre.c
index f179ff1f56ec..db992a373011 100644
--- a/net/ipv6/ip6_gre.c
+++ b/net/ipv6/ip6_gre.c
@@ -509,8 +509,6 @@ static int ip6gre_rcv(struct sk_buff *skb)
goto drop;
}
- secpath_reset(skb);
-
skb->protocol = gre_proto;
/* WCCP version 1 and 2 protocol decoding.
* - Change protocol to IP
@@ -525,7 +523,6 @@ static int ip6gre_rcv(struct sk_buff *skb)
skb->mac_header = skb->network_header;
__pskb_pull(skb, offset);
skb_postpull_rcsum(skb, skb_transport_header(skb), offset);
- skb->pkt_type = PACKET_HOST;
if (((flags&GRE_CSUM) && csum) ||
(!(flags&GRE_CSUM) && tunnel->parms.i_flags&GRE_CSUM)) {
@@ -557,7 +554,7 @@ static int ip6gre_rcv(struct sk_buff *skb)
skb_postpull_rcsum(skb, eth_hdr(skb), ETH_HLEN);
}
- __skb_tunnel_rx(skb, tunnel->dev);
+ __skb_tunnel_rx(skb, tunnel->dev, tunnel->net);
skb_reset_network_header(skb);
diff --git a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c
index ecbcdbd4bc4f..55999d923f26 100644
--- a/net/ipv6/ip6_tunnel.c
+++ b/net/ipv6/ip6_tunnel.c
@@ -802,14 +802,12 @@ static int ip6_tnl_rcv(struct sk_buff *skb, __u16 protocol,
rcu_read_unlock();
goto discard;
}
- secpath_reset(skb);
skb->mac_header = skb->network_header;
skb_reset_network_header(skb);
skb->protocol = htons(protocol);
- skb->pkt_type = PACKET_HOST;
memset(skb->cb, 0, sizeof(struct inet6_skb_parm));
- __skb_tunnel_rx(skb, t->dev);
+ __skb_tunnel_rx(skb, t->dev, t->net);
err = dscp_ecn_decapsulate(t, ipv6h, skb);
if (unlikely(err)) {
@@ -829,9 +827,6 @@ static int ip6_tnl_rcv(struct sk_buff *skb, __u16 protocol,
tstats->rx_packets++;
tstats->rx_bytes += skb->len;
- if (!net_eq(t->net, dev_net(t->dev)))
- skb_scrub_packet(skb, true);
-
netif_rx(skb);
rcu_read_unlock();
diff --git a/net/ipv6/ip6mr.c b/net/ipv6/ip6mr.c
index a60a84ef04f7..f365310bfcca 100644
--- a/net/ipv6/ip6mr.c
+++ b/net/ipv6/ip6mr.c
@@ -672,9 +672,8 @@ static int pim6_rcv(struct sk_buff *skb)
skb_reset_network_header(skb);
skb->protocol = htons(ETH_P_IPV6);
skb->ip_summed = CHECKSUM_NONE;
- skb->pkt_type = PACKET_HOST;
- skb_tunnel_rx(skb, reg_dev);
+ skb_tunnel_rx(skb, reg_dev, dev_net(reg_dev));
netif_rx(skb);
diff --git a/net/ipv6/sit.c b/net/ipv6/sit.c
index 82b425b9b7d2..19abcc9d6a1a 100644
--- a/net/ipv6/sit.c
+++ b/net/ipv6/sit.c
@@ -581,12 +581,10 @@ static int ipip6_rcv(struct sk_buff *skb)
tunnel->parms.iph.protocol != 0)
goto out;
- secpath_reset(skb);
skb->mac_header = skb->network_header;
skb_reset_network_header(skb);
IPCB(skb)->flags = 0;
skb->protocol = htons(ETH_P_IPV6);
- skb->pkt_type = PACKET_HOST;
if (tunnel->dev->priv_flags & IFF_ISATAP) {
if (!isatap_chksrc(skb, iph, tunnel)) {
@@ -603,7 +601,7 @@ static int ipip6_rcv(struct sk_buff *skb)
}
}
- __skb_tunnel_rx(skb, tunnel->dev);
+ __skb_tunnel_rx(skb, tunnel->dev, tunnel->net);
err = IP_ECN_decapsulate(iph, skb);
if (unlikely(err)) {
@@ -621,8 +619,6 @@ static int ipip6_rcv(struct sk_buff *skb)
tstats->rx_packets++;
tstats->rx_bytes += skb->len;
- if (!net_eq(tunnel->net, dev_net(tunnel->dev)))
- skb_scrub_packet(skb, true);
netif_rx(skb);
return 0;
--
1.8.2.1
^ permalink raw reply related
* [PATCH net-next v2 3/5] skb: allow skb_scrub_packet() to be used by tunnels
From: Nicolas Dichtel @ 2013-09-02 13:34 UTC (permalink / raw)
To: pshelar; +Cc: netdev, davem, jesse, dev, Nicolas Dichtel
In-Reply-To: <1378128898-15136-1-git-send-email-nicolas.dichtel@6wind.com>
This function was only used when a packet was sent to another netns. Now, it can
also be used after tunnel encapsulation or decapsulation.
Only skb_orphan() should not be done when a packet is not crossing netns.
Signed-off-by: Nicolas Dichtel <nicolas.dichtel@6wind.com>
---
include/linux/skbuff.h | 2 +-
net/core/dev.c | 2 +-
net/core/skbuff.c | 19 ++++++++++++-------
net/ipv4/ip_tunnel.c | 4 ++--
net/ipv6/ip6_tunnel.c | 4 ++--
net/ipv6/sit.c | 4 ++--
6 files changed, 20 insertions(+), 15 deletions(-)
diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h
index 5ac96f31d546..a3eeabe7c04b 100644
--- a/include/linux/skbuff.h
+++ b/include/linux/skbuff.h
@@ -2392,7 +2392,7 @@ extern void skb_split(struct sk_buff *skb,
struct sk_buff *skb1, const u32 len);
extern int skb_shift(struct sk_buff *tgt, struct sk_buff *skb,
int shiftlen);
-extern void skb_scrub_packet(struct sk_buff *skb);
+extern void skb_scrub_packet(struct sk_buff *skb, bool xnet);
extern struct sk_buff *skb_segment(struct sk_buff *skb,
netdev_features_t features);
diff --git a/net/core/dev.c b/net/core/dev.c
index 6fbb0c90849b..07684e880a5d 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -1697,7 +1697,7 @@ int dev_forward_skb(struct net_device *dev, struct sk_buff *skb)
* call skb_scrub_packet() after it to clear pkt_type _after_ calling
* eth_type_trans().
*/
- skb_scrub_packet(skb);
+ skb_scrub_packet(skb, true);
return netif_rx(skb);
}
diff --git a/net/core/skbuff.c b/net/core/skbuff.c
index 2c3d0f53d198..d81cff119f73 100644
--- a/net/core/skbuff.c
+++ b/net/core/skbuff.c
@@ -3500,17 +3500,22 @@ bool skb_try_coalesce(struct sk_buff *to, struct sk_buff *from,
EXPORT_SYMBOL(skb_try_coalesce);
/**
- * skb_scrub_packet - scrub an skb before sending it to another netns
+ * skb_scrub_packet - scrub an skb
*
* @skb: buffer to clean
- *
- * skb_scrub_packet can be used to clean an skb before injecting it in
- * another namespace. We have to clear all information in the skb that
- * could impact namespace isolation.
+ * @xnet: packet is crossing netns
+ *
+ * skb_scrub_packet can be used after encapsulating or decapsulting a packet
+ * into/from a tunnel. Some information have to be cleared during these
+ * operations.
+ * skb_scrub_packet can also be used to clean a skb before injecting it in
+ * another namespace (@xnet == true). We have to clear all information in the
+ * skb that could impact namespace isolation.
*/
-void skb_scrub_packet(struct sk_buff *skb)
+void skb_scrub_packet(struct sk_buff *skb, bool xnet)
{
- skb_orphan(skb);
+ if (xnet)
+ skb_orphan(skb);
skb->tstamp.tv64 = 0;
skb->pkt_type = PACKET_HOST;
skb->skb_iif = 0;
diff --git a/net/ipv4/ip_tunnel.c b/net/ipv4/ip_tunnel.c
index 0a6cf0e69478..b0e74e17088f 100644
--- a/net/ipv4/ip_tunnel.c
+++ b/net/ipv4/ip_tunnel.c
@@ -462,7 +462,7 @@ int ip_tunnel_rcv(struct ip_tunnel *tunnel, struct sk_buff *skb,
}
if (!net_eq(tunnel->net, dev_net(tunnel->dev)))
- skb_scrub_packet(skb);
+ skb_scrub_packet(skb, true);
gro_cells_receive(&tunnel->gro_cells, skb);
return 0;
@@ -615,7 +615,7 @@ void ip_tunnel_xmit(struct sk_buff *skb, struct net_device *dev,
}
if (!net_eq(tunnel->net, dev_net(dev)))
- skb_scrub_packet(skb);
+ skb_scrub_packet(skb, true);
if (tunnel->err_count > 0) {
if (time_before(jiffies,
diff --git a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c
index d6e00a39274c..72372ac90159 100644
--- a/net/ipv6/ip6_tunnel.c
+++ b/net/ipv6/ip6_tunnel.c
@@ -830,7 +830,7 @@ static int ip6_tnl_rcv(struct sk_buff *skb, __u16 protocol,
tstats->rx_bytes += skb->len;
if (!net_eq(t->net, dev_net(t->dev)))
- skb_scrub_packet(skb);
+ skb_scrub_packet(skb, true);
netif_rx(skb);
@@ -1002,7 +1002,7 @@ static int ip6_tnl_xmit2(struct sk_buff *skb,
}
if (!net_eq(t->net, dev_net(dev)))
- skb_scrub_packet(skb);
+ skb_scrub_packet(skb, true);
/*
* Okay, now see if we can stuff it in the buffer as-is.
diff --git a/net/ipv6/sit.c b/net/ipv6/sit.c
index 1d1458a3b7c4..b2e44f478e14 100644
--- a/net/ipv6/sit.c
+++ b/net/ipv6/sit.c
@@ -622,7 +622,7 @@ static int ipip6_rcv(struct sk_buff *skb)
tstats->rx_bytes += skb->len;
if (!net_eq(tunnel->net, dev_net(tunnel->dev)))
- skb_scrub_packet(skb);
+ skb_scrub_packet(skb, true);
netif_rx(skb);
return 0;
@@ -861,7 +861,7 @@ static netdev_tx_t ipip6_tunnel_xmit(struct sk_buff *skb,
}
if (!net_eq(tunnel->net, dev_net(dev)))
- skb_scrub_packet(skb);
+ skb_scrub_packet(skb, true);
/*
* Okay, now see if we can stuff it in the buffer as-is.
--
1.8.2.1
^ permalink raw reply related
* [PATCH net-next v2 4/5] tunnels: harmonize cleanup done on skb on xmit path
From: Nicolas Dichtel @ 2013-09-02 13:34 UTC (permalink / raw)
To: pshelar; +Cc: netdev, davem, jesse, dev, Nicolas Dichtel
In-Reply-To: <1378128898-15136-1-git-send-email-nicolas.dichtel@6wind.com>
The goal of this patch is to harmonize cleanup done on a skbuff on xmit path.
Before this patch, behaviors were different depending of the tunnel type.
Signed-off-by: Nicolas Dichtel <nicolas.dichtel@6wind.com>
---
drivers/net/vxlan.c | 6 ++++--
include/net/ip6_tunnel.h | 1 -
include/net/ip_tunnels.h | 2 +-
net/ipv4/ip_tunnel.c | 6 ++----
net/ipv4/ip_tunnel_core.c | 7 +++----
net/ipv6/ip6_gre.c | 4 ++--
net/ipv6/ip6_tunnel.c | 4 +---
net/ipv6/sit.c | 5 +----
net/openvswitch/vport-gre.c | 2 +-
9 files changed, 15 insertions(+), 22 deletions(-)
diff --git a/drivers/net/vxlan.c b/drivers/net/vxlan.c
index 5f46d2f3222f..f85a770d5d56 100644
--- a/drivers/net/vxlan.c
+++ b/drivers/net/vxlan.c
@@ -1397,6 +1397,8 @@ static int vxlan6_xmit_skb(struct vxlan_sock *vs,
skb->encapsulation = 1;
}
+ skb_scrub_packet(skb, false);
+
min_headroom = LL_RESERVED_SPACE(dst->dev) + dst->header_len
+ VXLAN_HLEN + sizeof(struct ipv6hdr)
+ (vlan_tx_tag_present(skb) ? VLAN_HLEN : 0);
@@ -1432,7 +1434,6 @@ static int vxlan6_xmit_skb(struct vxlan_sock *vs,
memset(&(IPCB(skb)->opt), 0, sizeof(IPCB(skb)->opt));
IPCB(skb)->flags &= ~(IPSKB_XFRM_TUNNEL_SIZE | IPSKB_XFRM_TRANSFORMED |
IPSKB_REROUTED);
- skb_dst_drop(skb);
skb_dst_set(skb, dst);
if (!skb_is_gso(skb) && !(dst->dev->features & NETIF_F_IPV6_CSUM)) {
@@ -1528,7 +1529,8 @@ int vxlan_xmit_skb(struct vxlan_sock *vs,
if (err)
return err;
- return iptunnel_xmit(rt, skb, src, dst, IPPROTO_UDP, tos, ttl, df);
+ return iptunnel_xmit(rt, skb, src, dst, IPPROTO_UDP, tos, ttl, df,
+ false);
}
EXPORT_SYMBOL_GPL(vxlan_xmit_skb);
diff --git a/include/net/ip6_tunnel.h b/include/net/ip6_tunnel.h
index 2265b0bf97e5..6d1549c4893c 100644
--- a/include/net/ip6_tunnel.h
+++ b/include/net/ip6_tunnel.h
@@ -75,7 +75,6 @@ static inline void ip6tunnel_xmit(struct sk_buff *skb, struct net_device *dev)
struct net_device_stats *stats = &dev->stats;
int pkt_len, err;
- nf_reset(skb);
pkt_len = skb->len;
err = ip6_local_out(skb);
diff --git a/include/net/ip_tunnels.h b/include/net/ip_tunnels.h
index 94fe8fd07bc9..a0a4a100f5c9 100644
--- a/include/net/ip_tunnels.h
+++ b/include/net/ip_tunnels.h
@@ -148,7 +148,7 @@ static inline u8 ip_tunnel_ecn_encap(u8 tos, const struct iphdr *iph,
int iptunnel_pull_header(struct sk_buff *skb, int hdr_len, __be16 inner_proto);
int iptunnel_xmit(struct rtable *rt, struct sk_buff *skb,
__be32 src, __be32 dst, __u8 proto,
- __u8 tos, __u8 ttl, __be16 df);
+ __u8 tos, __u8 ttl, __be16 df, bool xnet);
static inline void iptunnel_xmit_stats(int err,
struct net_device_stats *err_stats,
diff --git a/net/ipv4/ip_tunnel.c b/net/ipv4/ip_tunnel.c
index b0e74e17088f..88d7d7d1eccb 100644
--- a/net/ipv4/ip_tunnel.c
+++ b/net/ipv4/ip_tunnel.c
@@ -614,9 +614,6 @@ void ip_tunnel_xmit(struct sk_buff *skb, struct net_device *dev,
goto tx_error;
}
- if (!net_eq(tunnel->net, dev_net(dev)))
- skb_scrub_packet(skb, true);
-
if (tunnel->err_count > 0) {
if (time_before(jiffies,
tunnel->err_time + IPTUNNEL_ERR_TIMEO)) {
@@ -655,7 +652,8 @@ void ip_tunnel_xmit(struct sk_buff *skb, struct net_device *dev,
}
err = iptunnel_xmit(rt, skb, fl4.saddr, fl4.daddr, protocol,
- ip_tunnel_ecn_encap(tos, inner_iph, skb), ttl, df);
+ ip_tunnel_ecn_encap(tos, inner_iph, skb), ttl, df,
+ !net_eq(tunnel->net, dev_net(dev)));
iptunnel_xmit_stats(err, &dev->stats, dev->tstats);
return;
diff --git a/net/ipv4/ip_tunnel_core.c b/net/ipv4/ip_tunnel_core.c
index e82045842351..d6c856b17fd4 100644
--- a/net/ipv4/ip_tunnel_core.c
+++ b/net/ipv4/ip_tunnel_core.c
@@ -48,16 +48,15 @@
int iptunnel_xmit(struct rtable *rt, struct sk_buff *skb,
__be32 src, __be32 dst, __u8 proto,
- __u8 tos, __u8 ttl, __be16 df)
+ __u8 tos, __u8 ttl, __be16 df, bool xnet)
{
int pkt_len = skb->len;
struct iphdr *iph;
int err;
- nf_reset(skb);
- secpath_reset(skb);
+ skb_scrub_packet(skb, xnet);
+
skb->rxhash = 0;
- skb_dst_drop(skb);
skb_dst_set(skb, &rt->dst);
memset(IPCB(skb), 0, sizeof(*IPCB(skb)));
diff --git a/net/ipv6/ip6_gre.c b/net/ipv6/ip6_gre.c
index f2d0a42f8057..f179ff1f56ec 100644
--- a/net/ipv6/ip6_gre.c
+++ b/net/ipv6/ip6_gre.c
@@ -694,6 +694,8 @@ static netdev_tx_t ip6gre_xmit2(struct sk_buff *skb,
tunnel->err_count = 0;
}
+ skb_scrub_packet(skb, !net_eq(tunnel->net, dev_net(dev)));
+
max_headroom = LL_RESERVED_SPACE(tdev) + gre_hlen + dst->header_len;
if (skb_headroom(skb) < max_headroom || skb_shared(skb) ||
@@ -710,8 +712,6 @@ static netdev_tx_t ip6gre_xmit2(struct sk_buff *skb,
skb = new_skb;
}
- skb_dst_drop(skb);
-
if (fl6->flowi6_mark) {
skb_dst_set(skb, dst);
ndst = NULL;
diff --git a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c
index 72372ac90159..ecbcdbd4bc4f 100644
--- a/net/ipv6/ip6_tunnel.c
+++ b/net/ipv6/ip6_tunnel.c
@@ -1001,8 +1001,7 @@ static int ip6_tnl_xmit2(struct sk_buff *skb,
goto tx_err_dst_release;
}
- if (!net_eq(t->net, dev_net(dev)))
- skb_scrub_packet(skb, true);
+ skb_scrub_packet(skb, !net_eq(t->net, dev_net(dev)));
/*
* Okay, now see if we can stuff it in the buffer as-is.
@@ -1021,7 +1020,6 @@ static int ip6_tnl_xmit2(struct sk_buff *skb,
consume_skb(skb);
skb = new_skb;
}
- skb_dst_drop(skb);
if (fl6->flowi6_mark) {
skb_dst_set(skb, dst);
ndst = NULL;
diff --git a/net/ipv6/sit.c b/net/ipv6/sit.c
index b2e44f478e14..82b425b9b7d2 100644
--- a/net/ipv6/sit.c
+++ b/net/ipv6/sit.c
@@ -860,9 +860,6 @@ static netdev_tx_t ipip6_tunnel_xmit(struct sk_buff *skb,
tunnel->err_count = 0;
}
- if (!net_eq(tunnel->net, dev_net(dev)))
- skb_scrub_packet(skb, true);
-
/*
* Okay, now see if we can stuff it in the buffer as-is.
*/
@@ -889,7 +886,7 @@ static netdev_tx_t ipip6_tunnel_xmit(struct sk_buff *skb,
tos = INET_ECN_encapsulate(tos, ipv6_get_dsfield(iph6));
err = iptunnel_xmit(rt, skb, fl4.saddr, fl4.daddr, IPPROTO_IPV6, tos,
- ttl, df);
+ ttl, df, !net_eq(tunnel->net, dev_net(dev)));
iptunnel_xmit_stats(err, &dev->stats, dev->tstats);
return NETDEV_TX_OK;
diff --git a/net/openvswitch/vport-gre.c b/net/openvswitch/vport-gre.c
index 9b3713ef831e..c99dea543d64 100644
--- a/net/openvswitch/vport-gre.c
+++ b/net/openvswitch/vport-gre.c
@@ -179,7 +179,7 @@ static int gre_tnl_send(struct vport *vport, struct sk_buff *skb)
return iptunnel_xmit(rt, skb, fl.saddr,
OVS_CB(skb)->tun_key->ipv4_dst, IPPROTO_GRE,
OVS_CB(skb)->tun_key->ipv4_tos,
- OVS_CB(skb)->tun_key->ipv4_ttl, df);
+ OVS_CB(skb)->tun_key->ipv4_ttl, df, false);
err_free_rt:
ip_rt_put(rt);
error:
--
1.8.2.1
^ permalink raw reply related
* Re: BQL support in gianfar causes network hiccup
From: Claudiu Manoil @ 2013-09-02 13:53 UTC (permalink / raw)
To: Per Dalén; +Cc: netdev
In-Reply-To: <522490CB.60008@appeartv.com>
On 9/2/2013 4:21 PM, Per Dalén wrote:
> > On Mo, 2013-04-29 at 15:20 +0200, Tino Keitel wrote:
> > > On Mo, 2013-04-29 at 15:14 +0200, Claudiu Manoil wrote:
> > >
> > > > The proposed fix (passes this test):
> > > > http://patchwork.ozlabs.org/patch/240365/
> > > >
> > > > Does it work for you?
>
> Hi,
>
> This patch do not work for me. I have the same problems that Tino on my
> card. My card is a Freescale P2020 and I use "iperf -c 10.10.51.36 -n
> 100M -P 50" to trigger the error.
> The network interface is set to 100M half duplex.
> I have tested this using 3.4.35 and 3.4.60 kernel.
>
> NETDEV WATCHDOG: eth0 (fsl-gianfar): transmit queue 0 timed out
> ------------[ cut here ]------------
> WARNING: at net/sched/sch_generic.c:256
> Modules linked in:
> NIP: c039bb94 LR: c039bb94 CTR: c02ee500
> REGS: dffe7e60 TRAP: 0700 Not tainted (3.4.60+)
> MSR: 00029000 <CE,EE,ME> CR: 40000084 XER: 20000000
> TASK = df843200[0] 'swapper/1' THREAD: df864000 CPU: 1
> GPR00: c039bb94 dffe7f10 df843200 00000046 00021000 ffffffff c02eecf0
> 00029000
> GPR08: 00000001 00008000 00463000 00003fff 80000028 00000000 00000000
> 00000004
> GPR16: 00000001 df858e14 c051f1f4 00000001 df858c14 df858a14 df858814
> ffffffff
> GPR24: 00000001 df813234 00000004 df8f9a00 c05e0000 c05e0000 df813000
> 00000000
> NIP [c039bb94] dev_watchdog+0x2d4/0x2e4
> LR [c039bb94] dev_watchdog+0x2d4/0x2e4
> Call Trace:
> [dffe7f10] [c039bb94] dev_watchdog+0x2d4/0x2e4 (unreliable)
> [dffe7f40] [c003e944] run_timer_softirq+0x11c/0x20c
> [dffe7fa0] [c00377dc] __do_softirq+0xe4/0x16c
> [dffe7ff0] [c000c408] call_do_softirq+0x14/0x24
> [df865e80] [c00043c4] do_softirq+0xb4/0xe4
> [df865ea0] [c0037b4c] irq_exit+0xb0/0xcc
> [df865eb0] [c0008958] timer_interrupt+0x188/0x1a4
> [df865ee0] [c000db68] ret_from_except+0x0/0x18
> --- Exception: 901 at cpu_idle+0x90/0xf4
> LR = cpu_idle+0x90/0xf4
> [df865fa0] [c0007b30] cpu_idle+0x5c/0xf4 (unreliable)
> [df865fc0] [c049d68c] start_secondary+0x2b0/0x2b4
> [df865ff0] [c0001cf8] __secondary_start+0x30/0x84
> Instruction dump:
> 4e800421 80fe0244 4bffff40 7fc3f378 4bfeab6d 7fc4f378 7c651b78 3c60c055
> 7fe6fb78 38633108 4cc63182 480fc889 <0fe00000> 39200001 993cea1a 4bffffb4
> ---[ end trace 4be011773b23dae3 ]---
>
>
> When I revert "gianfar: Add support for byte queue limits.", commit
> d8a0f1b0af67679bba886784de10d8c21acc4e0e, the network test work fine
> without any "hiccup".
> If the network interface is set to 1000M full duplex there's also no
> "hiccup".
>
Hi,
That patch wasn't approved (for good reasons).
The proposed fix is currently under review:
http://patchwork.ozlabs.org/patch/271242/
"gianfar: Fix reported number of sent bytes to BQL"
Does this one work for you? You might need to pull
one recent gianfar clean-up patch from net-next in order
to apply this one without incidents.
Thanks,
Claudiu
^ permalink raw reply
* [PATCH] net: sctp: Fix data chunk fragmentation for MTU values which are not multiple of 4
From: Alexander Sverdlin @ 2013-09-02 13:58 UTC (permalink / raw)
To: linux-sctp, davem, vyasevich
Cc: Glavinic-Pecotic, Matija (EXT-Other - DE/Ulm), netdev
From: Alexander Sverdlin <alexander.sverdlin@nsn.com>
net: sctp: Fix data chunk fragmentation for MTU values which are not multiple of 4
Initially the problem was observed with ipsec, but later it became clear that
SCTP data chunk fragmentation algorithm has problems with MTU values which are
not multiple of 4. Test program was used which just transmits 2000 bytes long
packets to other host. tcpdump was used to observe re-fragmentation in IP layer
after SCTP already fragmented data chunks.
With MTU 1500:
12:54:34.082904 IP (tos 0x2,ECT(0), ttl 64, id 0, offset 0, flags [DF], proto SCTP (132), length 1500)
10.151.38.153.39303 > 10.151.24.91.54321: sctp (1) [DATA] (B) [TSN: 2366088589] [SID: 0] [SSEQ 1] [PPID 0x0]
12:54:34.082933 IP (tos 0x2,ECT(0), ttl 64, id 0, offset 0, flags [DF], proto SCTP (132), length 596)
10.151.38.153.39303 > 10.151.24.91.54321: sctp (1) [DATA] (E) [TSN: 2366088590] [SID: 0] [SSEQ 1] [PPID 0x0]
12:54:34.090576 IP (tos 0x2,ECT(0), ttl 63, id 0, offset 0, flags [DF], proto SCTP (132), length 48)
10.151.24.91.54321 > 10.151.38.153.39303: sctp (1) [SACK] [cum ack 2366088590] [a_rwnd 79920] [#gap acks 0] [#dup tsns 0]
With MTU 1499:
13:02:49.955220 IP (tos 0x2,ECT(0), ttl 64, id 48215, offset 0, flags [+], proto SCTP (132), length 1492)
10.151.38.153.39084 > 10.151.24.91.54321: sctp[|sctp]
13:02:49.955249 IP (tos 0x2,ECT(0), ttl 64, id 48215, offset 1472, flags [none], proto SCTP (132), length 28)
10.151.38.153 > 10.151.24.91: ip-proto-132
13:02:49.955262 IP (tos 0x2,ECT(0), ttl 64, id 0, offset 0, flags [DF], proto SCTP (132), length 600)
10.151.38.153.39084 > 10.151.24.91.54321: sctp (1) [DATA] (E) [TSN: 404355346] [SID: 0] [SSEQ 1] [PPID 0x0]
13:02:49.956770 IP (tos 0x2,ECT(0), ttl 63, id 0, offset 0, flags [DF], proto SCTP (132), length 48)
10.151.24.91.54321 > 10.151.38.153.39084: sctp (1) [SACK] [cum ack 404355346] [a_rwnd 79920] [#gap acks 0] [#dup tsns 0]
Here problem in data portion limit calculation leads to re-fragmentation in IP,
which is sub-optimal. The problem is max_data initial value, which doesn't take
into account the fact, that data chunk must be padded to 4-bytes boundary.
It's enough to correct max_data, because all later adjustments are correctly
aligned to 4-bytes boundary.
After the fix is applied, everything is fragmented correctly for uneven MTUs:
15:16:27.083881 IP (tos 0x2,ECT(0), ttl 64, id 0, offset 0, flags [DF], proto SCTP (132), length 1496)
10.151.38.153.53417 > 10.151.24.91.54321: sctp (1) [DATA] (B) [TSN: 3077098183] [SID: 0] [SSEQ 1] [PPID 0x0]
15:16:27.083907 IP (tos 0x2,ECT(0), ttl 64, id 0, offset 0, flags [DF], proto SCTP (132), length 600)
10.151.38.153.53417 > 10.151.24.91.54321: sctp (1) [DATA] (E) [TSN: 3077098184] [SID: 0] [SSEQ 1] [PPID 0x0]
15:16:27.085640 IP (tos 0x2,ECT(0), ttl 63, id 0, offset 0, flags [DF], proto SCTP (132), length 48)
10.151.24.91.54321 > 10.151.38.153.53417: sctp (1) [SACK] [cum ack 3077098184] [a_rwnd 79920] [#gap acks 0] [#dup tsns 0]
The bug was there for years already, but
- is a performance issue, the packets are still transmitted
- doesn't show up with default MTU 1500, but possibly with ipsec (MTU 1438)
Signed-off-by: Alexander Sverdlin <alexander.sverdlin@nsn.com>
---
--- linux-3.10.orig/net/sctp/chunk.c
+++ linux-3.10/net/sctp/chunk.c
@@ -200,9 +200,9 @@ struct sctp_datamsg *sctp_datamsg_from_u
/* This is the biggest possible DATA chunk that can fit into
* the packet
*/
- max_data = asoc->pathmtu -
+ max_data = (asoc->pathmtu -
sctp_sk(asoc->base.sk)->pf->af->net_header_len -
- sizeof(struct sctphdr) - sizeof(struct sctp_data_chunk);
+ sizeof(struct sctphdr) - sizeof(struct sctp_data_chunk)) & ~3;
max = asoc->frag_point;
/* If the the peer requested that we authenticate DATA chunks
^ permalink raw reply
* [PATCH net-next] net: correctly interlink lower/upper devices
From: Veaceslav Falico @ 2013-09-02 14:26 UTC (permalink / raw)
To: netdev
Cc: Veaceslav Falico, David S. Miller, Eric Dumazet, Jiri Pirko,
Alexander Duyck, Cong Wang
Currently we're linking upper devices to lower ones, which results in
upside-down relationship: upper devices seeing lower devices via its upper
lists.
Fix this by correctly linking lower devices to the upper ones.
CC: "David S. Miller" <davem@davemloft.net>
CC: Eric Dumazet <edumazet@google.com>
CC: Jiri Pirko <jiri@resnulli.us>
CC: Alexander Duyck <alexander.h.duyck@intel.com>
CC: Cong Wang <amwang@redhat.com>
Signed-off-by: Veaceslav Falico <vfalico@redhat.com>
---
net/core/dev.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/net/core/dev.c b/net/core/dev.c
index 6fbb0c9..743620e 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -4679,8 +4679,8 @@ static int __netdev_upper_dev_link(struct net_device *dev,
* versa, and don't forget the devices itself. All of these
* links are non-neighbours.
*/
- list_for_each_entry(i, &upper_dev->upper_dev_list, list) {
- list_for_each_entry(j, &dev->lower_dev_list, list) {
+ list_for_each_entry(i, &dev->lower_dev_list, list) {
+ list_for_each_entry(j, &upper_dev->upper_dev_list, list) {
ret = __netdev_adjacent_dev_link(i->dev, j->dev);
if (ret)
goto rollback_mesh;
--
1.8.4
^ permalink raw reply related
* RE: [PATCH] net: fec: fix the error to get the previous BD entry
From: Li Frank-B20596 @ 2013-09-02 14:30 UTC (permalink / raw)
To: Duan Fugang-B38611, davem@davemloft.net
Cc: netdev@vger.kernel.org, bhutchings@solarflare.com,
stephen@networkplumber.org
In-Reply-To: <1378121735-5681-1-git-send-email-B38611@freescale.com>
> -----Original Message-----
> From: Duan Fugang-B38611
> Sent: Monday, September 02, 2013 6:36 AM
> To: Li Frank-B20596; davem@davemloft.net
> Cc: netdev@vger.kernel.org; bhutchings@solarflare.com;
> stephen@networkplumber.org
> Subject: [PATCH] net: fec: fix the error to get the previous BD entry
>
> Bug: error to get the previous BD entry. When the current BD is the first BD,
> the previous BD entry must be the last BD, not "bdp - 1" in current logic.
>
> V2:
> Add tx_ring_size and rx_ring_size to struct fec_enet_private.
> Replace api fec_enet_get_nextdesc() with next_bd().
> Replace api fec_enet_get_prevdesc() with pre_bd().
>
> Move all ring size check logic to next_bd() and pre_bd, which
> simplifies the code redundancy.
>
> V1:
> Add BD ring size check to get the previous BD entry in correctly.
>
> Signed-off-by: Fugang Duan <B38611@freescale.com>
> ---
> drivers/net/ethernet/freescale/fec.h | 3 +
> drivers/net/ethernet/freescale/fec_main.c | 94 +++++++++++++++------------
> -
> 2 files changed, 53 insertions(+), 44 deletions(-)
>
> diff --git a/drivers/net/ethernet/freescale/fec.h
> b/drivers/net/ethernet/freescale/fec.h
> index ae23600..0120217 100644
> --- a/drivers/net/ethernet/freescale/fec.h
> +++ b/drivers/net/ethernet/freescale/fec.h
> @@ -296,6 +296,9 @@ struct fec_enet_private {
> /* The ring entries to be free()ed */
> struct bufdesc *dirty_tx;
>
> + unsigned short tx_ring_size;
> + unsigned short rx_ring_size;
> +
> struct platform_device *pdev;
>
> int opened;
> diff --git a/drivers/net/ethernet/freescale/fec_main.c
> b/drivers/net/ethernet/freescale/fec_main.c
> index 4ea1555..9894dd3 100644
> --- a/drivers/net/ethernet/freescale/fec_main.c
> +++ b/drivers/net/ethernet/freescale/fec_main.c
> @@ -239,22 +239,35 @@ MODULE_PARM_DESC(macaddr, "FEC Ethernet MAC address");
>
> static int mii_cnt;
>
> -static struct bufdesc *fec_enet_get_nextdesc(struct bufdesc *bdp, int is_ex)
> +static inline
> +struct bufdesc *next_bd(struct bufdesc *bdp, struct bufdesc *base,
> + int ring_size, int is_ex)
David suggest use fec_enet_ prefix for all function in fec driver when
I upstream it.
How about use
Fec_enet_next_bd(struct bufdesc *bdp, *fep)
The parameter will become little and easy to call.
> {
> - struct bufdesc_ex *ex = (struct bufdesc_ex *)bdp;
> + struct bufdesc *new_bd = bdp + 1;
> + struct bufdesc_ex *ex_new_bd = (struct bufdesc_ex *)bdp + 1;
> + struct bufdesc_ex *ex_base = (struct bufdesc_ex *)base;
> +
If pass down fep,
If( bdp > fep->rx_base) {
Ex_base = fep->rx_base;
Ring_size = fep->rx_ring_size;
}
Else {
Ex_base = fep->tx_base.
Ring_size = fep->tx_ring_size;
}
Because RX always behind of TX.
> if (is_ex)
> - return (struct bufdesc *)(ex + 1);
> + return (struct bufdesc *)((ex_new_bd >= (ex_base + ring_size)) ?
> + (ex_new_bd - ring_size) : ex_new_bd);
> else
> - return bdp + 1;
> + return (new_bd >= (base + ring_size)) ?
> + (new_bd - ring_size) : new_bd;
> }
>
> -static struct bufdesc *fec_enet_get_prevdesc(struct bufdesc *bdp, int is_ex)
> +static inline
> +struct bufdesc *pre_bd(struct bufdesc *bdp, struct bufdesc *base,
> + int ring_size, int is_ex)
> {
> - struct bufdesc_ex *ex = (struct bufdesc_ex *)bdp;
> + struct bufdesc *new_bd = bdp - 1;
> + struct bufdesc_ex *ex_new_bd = (struct bufdesc_ex *)bdp - 1;
> + struct bufdesc_ex *ex_base = (struct bufdesc_ex *)base;
> +
> if (is_ex)
> - return (struct bufdesc *)(ex - 1);
> + return (struct bufdesc *)((ex_new_bd < ex_base) ?
> + (ex_new_bd + ring_size) : ex_new_bd);
> else
> - return bdp - 1;
> + return (new_bd < base) ? (new_bd + ring_size) : new_bd;
> }
>
> static void *swap_buffer(void *bufaddr, int len) @@ -380,7 +393,7 @@
> fec_enet_start_xmit(struct sk_buff *skb, struct net_device *ndev)
> }
> }
>
> - bdp_pre = fec_enet_get_prevdesc(bdp, fep->bufdesc_ex);
> + bdp_pre = pre_bd(bdp, fep->tx_bd_base, fep->tx_ring_size,
> +fep->bufdesc_ex);
> if ((id_entry->driver_data & FEC_QUIRK_ERR006358) &&
> !(bdp_pre->cbd_sc & BD_ENET_TX_READY)) {
> fep->delay_work.trig_tx = true;
> @@ -389,10 +402,7 @@ fec_enet_start_xmit(struct sk_buff *skb, struct
> net_device *ndev)
> }
>
> /* If this was the last BD in the ring, start at the beginning again.
> */
> - if (status & BD_ENET_TX_WRAP)
> - bdp = fep->tx_bd_base;
> - else
> - bdp = fec_enet_get_nextdesc(bdp, fep->bufdesc_ex);
> + bdp = next_bd(bdp, fep->tx_bd_base, fep->tx_ring_size,
> +fep->bufdesc_ex);
>
> fep->cur_tx = bdp;
>
> @@ -417,18 +427,18 @@ static void fec_enet_bd_init(struct net_device *dev)
>
> /* Initialize the receive buffer descriptors. */
> bdp = fep->rx_bd_base;
> - for (i = 0; i < RX_RING_SIZE; i++) {
> + for (i = 0; i < fep->rx_ring_size; i++) {
>
> /* Initialize the BD for every fragment in the page. */
> if (bdp->cbd_bufaddr)
> bdp->cbd_sc = BD_ENET_RX_EMPTY;
> else
> bdp->cbd_sc = 0;
> - bdp = fec_enet_get_nextdesc(bdp, fep->bufdesc_ex);
> + bdp = next_bd(bdp, fep->rx_bd_base, fep->rx_ring_size,
> +fep->bufdesc_ex);
> }
>
> /* Set the last buffer to wrap */
> - bdp = fec_enet_get_prevdesc(bdp, fep->bufdesc_ex);
> + bdp = pre_bd(bdp, fep->rx_bd_base, fep->rx_ring_size,
> +fep->bufdesc_ex);
> bdp->cbd_sc |= BD_SC_WRAP;
>
> fep->cur_rx = fep->rx_bd_base;
> @@ -436,7 +446,7 @@ static void fec_enet_bd_init(struct net_device *dev)
> /* ...and the same for transmit */
> bdp = fep->tx_bd_base;
> fep->cur_tx = bdp;
> - for (i = 0; i < TX_RING_SIZE; i++) {
> + for (i = 0; i < fep->tx_ring_size; i++) {
>
> /* Initialize the BD for every fragment in the page. */
> bdp->cbd_sc = 0;
> @@ -445,11 +455,11 @@ static void fec_enet_bd_init(struct net_device *dev)
> fep->tx_skbuff[i] = NULL;
> }
> bdp->cbd_bufaddr = 0;
> - bdp = fec_enet_get_nextdesc(bdp, fep->bufdesc_ex);
> + bdp = next_bd(bdp, fep->tx_bd_base, fep->tx_ring_size,
> +fep->bufdesc_ex);
> }
>
> /* Set the last buffer to wrap */
> - bdp = fec_enet_get_prevdesc(bdp, fep->bufdesc_ex);
> + bdp = pre_bd(bdp, fep->tx_bd_base, fep->tx_ring_size,
> +fep->bufdesc_ex);
> bdp->cbd_sc |= BD_SC_WRAP;
> fep->dirty_tx = bdp;
> }
> @@ -510,10 +520,10 @@ fec_restart(struct net_device *ndev, int duplex)
> writel(fep->bd_dma, fep->hwp + FEC_R_DES_START);
> if (fep->bufdesc_ex)
> writel((unsigned long)fep->bd_dma + sizeof(struct bufdesc_ex)
> - * RX_RING_SIZE, fep->hwp + FEC_X_DES_START);
> + * fep->rx_ring_size, fep->hwp + FEC_X_DES_START);
> else
> writel((unsigned long)fep->bd_dma + sizeof(struct bufdesc)
> - * RX_RING_SIZE, fep->hwp + FEC_X_DES_START);
> + * fep->rx_ring_size, fep->hwp + FEC_X_DES_START);
>
>
> for (i = 0; i <= TX_RING_MOD_MASK; i++) { @@ -727,10 +737,7 @@
> fec_enet_tx(struct net_device *ndev)
> bdp = fep->dirty_tx;
>
> /* get next bdp of dirty_tx */
> - if (bdp->cbd_sc & BD_ENET_TX_WRAP)
> - bdp = fep->tx_bd_base;
> - else
> - bdp = fec_enet_get_nextdesc(bdp, fep->bufdesc_ex);
> + bdp = next_bd(bdp, fep->tx_bd_base, fep->tx_ring_size,
> +fep->bufdesc_ex);
>
> while (((status = bdp->cbd_sc) & BD_ENET_TX_READY) == 0) {
>
> @@ -800,10 +807,7 @@ fec_enet_tx(struct net_device *ndev)
> fep->dirty_tx = bdp;
>
> /* Update pointer to next buffer descriptor to be transmitted */
> - if (status & BD_ENET_TX_WRAP)
> - bdp = fep->tx_bd_base;
> - else
> - bdp = fec_enet_get_nextdesc(bdp, fep->bufdesc_ex);
> + bdp = next_bd(bdp, fep->tx_bd_base, fep->tx_ring_size,
> +fep->bufdesc_ex);
>
> /* Since we have freed up a buffer, the ring is no longer full
> */
> @@ -994,10 +998,8 @@ rx_processing_done:
> }
>
> /* Update BD pointer to next entry */
> - if (status & BD_ENET_RX_WRAP)
> - bdp = fep->rx_bd_base;
> - else
> - bdp = fec_enet_get_nextdesc(bdp, fep->bufdesc_ex);
> + bdp = next_bd(bdp, fep->rx_bd_base, fep->rx_ring_size,
> +fep->bufdesc_ex);
> +
> /* Doing this here will keep the FEC running while we process
> * incoming frames. On a heavily loaded network, we should be
> * able to keep up at the expense of system resources.
> @@ -1663,7 +1665,7 @@ static void fec_enet_free_buffers(struct net_device
> *ndev)
> struct bufdesc *bdp;
>
> bdp = fep->rx_bd_base;
> - for (i = 0; i < RX_RING_SIZE; i++) {
> + for (i = 0; i < fep->rx_ring_size; i++) {
> skb = fep->rx_skbuff[i];
>
> if (bdp->cbd_bufaddr)
> @@ -1671,11 +1673,11 @@ static void fec_enet_free_buffers(struct net_device
> *ndev)
> FEC_ENET_RX_FRSIZE, DMA_FROM_DEVICE);
> if (skb)
> dev_kfree_skb(skb);
> - bdp = fec_enet_get_nextdesc(bdp, fep->bufdesc_ex);
> + bdp = next_bd(bdp, fep->rx_bd_base, fep->rx_ring_size,
> +fep->bufdesc_ex);
> }
>
> bdp = fep->tx_bd_base;
> - for (i = 0; i < TX_RING_SIZE; i++)
> + for (i = 0; i < fep->tx_ring_size; i++)
> kfree(fep->tx_bounce[i]);
> }
>
> @@ -1687,7 +1689,7 @@ static int fec_enet_alloc_buffers(struct net_device
> *ndev)
> struct bufdesc *bdp;
>
> bdp = fep->rx_bd_base;
> - for (i = 0; i < RX_RING_SIZE; i++) {
> + for (i = 0; i < fep->rx_ring_size; i++) {
> skb = netdev_alloc_skb(ndev, FEC_ENET_RX_FRSIZE);
> if (!skb) {
> fec_enet_free_buffers(ndev);
> @@ -1704,15 +1706,15 @@ static int fec_enet_alloc_buffers(struct net_device
> *ndev)
> ebdp->cbd_esc = BD_ENET_RX_INT;
> }
>
> - bdp = fec_enet_get_nextdesc(bdp, fep->bufdesc_ex);
> + bdp = next_bd(bdp, fep->rx_bd_base, fep->rx_ring_size,
> +fep->bufdesc_ex);
> }
>
> /* Set the last buffer to wrap. */
> - bdp = fec_enet_get_prevdesc(bdp, fep->bufdesc_ex);
> + bdp = pre_bd(bdp, fep->rx_bd_base, fep->rx_ring_size,
> +fep->bufdesc_ex);
> bdp->cbd_sc |= BD_SC_WRAP;
>
> bdp = fep->tx_bd_base;
> - for (i = 0; i < TX_RING_SIZE; i++) {
> + for (i = 0; i < fep->tx_ring_size; i++) {
> fep->tx_bounce[i] = kmalloc(FEC_ENET_TX_FRSIZE, GFP_KERNEL);
>
> bdp->cbd_sc = 0;
> @@ -1723,11 +1725,11 @@ static int fec_enet_alloc_buffers(struct net_device
> *ndev)
> ebdp->cbd_esc = BD_ENET_TX_INT;
> }
>
> - bdp = fec_enet_get_nextdesc(bdp, fep->bufdesc_ex);
> + bdp = next_bd(bdp, fep->tx_bd_base, fep->tx_ring_size,
> +fep->bufdesc_ex);
> }
>
> /* Set the last buffer to wrap. */
> - bdp = fec_enet_get_prevdesc(bdp, fep->bufdesc_ex);
> + bdp = pre_bd(bdp, fep->tx_bd_base, fep->tx_ring_size,
> +fep->bufdesc_ex);
> bdp->cbd_sc |= BD_SC_WRAP;
>
> return 0;
> @@ -1967,13 +1969,17 @@ static int fec_enet_init(struct net_device *ndev)
> /* Get the Ethernet address */
> fec_get_mac(ndev);
>
> + /* init the tx & rx ring size */
> + fep->tx_ring_size = TX_RING_SIZE;
> + fep->rx_ring_size = RX_RING_SIZE;
> +
> /* Set receive and transmit descriptor base. */
> fep->rx_bd_base = cbd_base;
> if (fep->bufdesc_ex)
> fep->tx_bd_base = (struct bufdesc *)
> - (((struct bufdesc_ex *)cbd_base) + RX_RING_SIZE);
> + (((struct bufdesc_ex *)cbd_base) + fep->rx_ring_size);
> else
> - fep->tx_bd_base = cbd_base + RX_RING_SIZE;
> + fep->tx_bd_base = cbd_base + fep->rx_ring_size;
>
> /* The FEC Ethernet specific entries in the device structure */
> ndev->watchdog_timeo = TX_TIMEOUT;
> --
> 1.7.1
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox