Netdev List
 help / color / mirror / Atom feed
* Re: [PATCH v4] net: sh_eth: Add support of device tree probe
From: Simon Horman @ 2013-02-16  2:26 UTC (permalink / raw)
  To: Nobuhiro Iwamatsu
  Cc: netdev, horms+renesas, magnus.damm, devicetree-discuss, kda,
	kuninori.morimoto.gx, Nobuhiro Iwamatsu
In-Reply-To: <1360893205-12004-1-git-send-email-iwamatsu@nigauri.org>

On Fri, Feb 15, 2013 at 10:53:25AM +0900, Nobuhiro Iwamatsu wrote:
> From: Nobuhiro Iwamatsu <nobuhiro.iwamatsu.yj@renesas.com>
> 
> This adds support of device tree probe for Renesas sh-ether driver.

Hi Iwamatsu-san,

I do not expect this code to go through the renesas tree.  However, in
order to provide a basis for work on renesas SoCs I have added this patch
to the topic/sh_eth topic branch in the reneas tree on kernel.org and
merged it into topic/all+next.

In other words, I am not picking this patch up to merge it or add it to
linux-next, rather I am storing it for reference.

Also, I do note that there have already been some comments made on this
patch and I plan to date topic/sh_eth topic branch as new versions are
posted.

> Signed-off-by: Nobuhiro Iwamatsu <nobuhiro.iwamatsu.yj@renesas.com>
> 
> V4: - Remove empty sh_eth_parse_dt().
> V3: - Removed sentnece of "needs-init" from document.
> V2: - Removed ether_setup().
>     - Fixed typo from "sh-etn" to "sh-eth".
> 	- Removed "needs-init" and sh-eth,endian from definition of DT.
> 	- Changed "sh-eth,edmac-endian" instead of "sh-eth,edmac-big-endain"
> 	  in definition of DT.
> ---
>  Documentation/devicetree/bindings/net/sh_ether.txt |   39 +++++
>  drivers/net/ethernet/renesas/sh_eth.c              |  150 ++++++++++++++++----
>  2 files changed, 165 insertions(+), 24 deletions(-)
>  create mode 100644 Documentation/devicetree/bindings/net/sh_ether.txt
> 
> diff --git a/Documentation/devicetree/bindings/net/sh_ether.txt b/Documentation/devicetree/bindings/net/sh_ether.txt
> new file mode 100644
> index 0000000..f20d66a
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/net/sh_ether.txt
> @@ -0,0 +1,39 @@
> +* Renesas Electronics SuperH EMAC
> +
> +This file provides information, what the device node
> +for the sh_eth interface contains.
> +
> +Required properties:
> +- compatible:                   "renesas,sh-eth";
> +- interrupt-parent:             The phandle for the interrupt controller that
> +                                services interrupts for this device.
> +- reg:                          Offset and length of the register set for the
> +                                device.
> +- interrupts:                   Interrupt mapping for the sh_eth interrupt
> +                                sources (vector id).
> +- phy-mode:                     String, operation mode of the PHY interface.
> +- sh-eth,register-type:         String, register type of sh_eth.
> +                                Please select "gigabit", "fast-sh4" or
> +                                "fast-sh3-sh2".
> +- sh-eth,phy-id:                PHY id.
> +
> +Optional properties:
> +- local-mac-address:            6 bytes, mac address
> +- sh-eth,no-ether-link:         Set link control by software. When device does
> +                                not support ether-link, set.
> +- sh-eth,ether-link-active-low: Set link check method.
> +                                When detection of link is treated as active-low,
> +                                set.
> +- sh-eth,edmac-big-endian:      Set big endian for sh_eth dmac.
> +                                It work as little endian when this is not set.
> +
> +Example (armadillo800eva):
> +	sh-eth@e9a00000 {
> +		compatible = "renesas,sh-eth";
> +		interrupt-parent = <&intca>;
> +		reg = <0xe9a00000 0x800>, <0xe9a01800 0x800>;
> +		interrupts = <0x500>;
> +		phy-mode = "mii";
> +		sh-eth,register-type = "gigabit";
> +		sh-eth,phy-id = <0>;
> +	};
> diff --git a/drivers/net/ethernet/renesas/sh_eth.c b/drivers/net/ethernet/renesas/sh_eth.c
> index 3d70586..b41249a 100644
> --- a/drivers/net/ethernet/renesas/sh_eth.c
> +++ b/drivers/net/ethernet/renesas/sh_eth.c
> @@ -1,7 +1,7 @@
>  /*
>   *  SuperH Ethernet device driver
>   *
> - *  Copyright (C) 2006-2012 Nobuhiro Iwamatsu
> + *  Copyright (C) 2006-2013 Nobuhiro Iwamatsu
>   *  Copyright (C) 2008-2012 Renesas Solutions Corp.
>   *
>   *  This program is free software; you can redistribute it and/or modify it
> @@ -31,6 +31,12 @@
>  #include <linux/platform_device.h>
>  #include <linux/mdio-bitbang.h>
>  #include <linux/netdevice.h>
> +#include <linux/of.h>
> +#include <linux/of_device.h>
> +#include <linux/of_platform.h>
> +#include <linux/of_address.h>
> +#include <linux/of_irq.h>
> +#include <linux/of_net.h>
>  #include <linux/phy.h>
>  #include <linux/cache.h>
>  #include <linux/io.h>
> @@ -2347,26 +2353,103 @@ static const struct net_device_ops sh_eth_netdev_ops = {
>  	.ndo_change_mtu		= eth_change_mtu,
>  };
>  
> +#ifdef CONFIG_OF
> +
> +static int
> +sh_eth_of_get_register_type(struct device_node *np)
> +{
> +	const char *of_str;
> +	int ret = of_property_read_string(np, "sh-eth,register-type", &of_str);
> +	if (ret)
> +		return ret;
> +
> +	if (of_str && !strcmp(of_str, "gigabit"))
> +		return SH_ETH_REG_GIGABIT;
> +
> +	else if (of_str && !strcmp(of_str, "fast-sh4"))
> +		return SH_ETH_REG_FAST_SH4;
> +	else if (of_str && !strcmp(of_str, "fast-sh3-sh2"))
> +		return SH_ETH_REG_FAST_SH3_SH2;
> +	else
> +		return -EINVAL;
> +}
> +
> +static struct sh_eth_plat_data *
> +sh_eth_parse_dt(struct device *dev, struct net_device *ndev)
> +{
> +	int ret;
> +	struct device_node *np = dev->of_node;
> +	struct sh_eth_plat_data *pdata;
> +
> +	pdata = devm_kzalloc(dev, sizeof(struct sh_eth_plat_data),
> +					GFP_KERNEL);
> +	if (!pdata) {
> +		dev_err(dev, "%s: failed to allocate config data\n", __func__);
> +		return NULL;
> +	}
> +
> +	pdata->phy_interface = of_get_phy_mode(np);
> +
> +	of_property_read_u32(np, "sh-eth,phy-id", &pdata->phy);
> +
> +	if (of_find_property(np, "sh-eth,edmac-big-endian", NULL))
> +		pdata->edmac_endian = EDMAC_BIG_ENDIAN;
> +	else
> +		pdata->edmac_endian = EDMAC_LITTLE_ENDIAN;
> +
> +	if (of_find_property(np, "sh-eth,no-ether-link", NULL))
> +		pdata->no_ether_link = 1;
> +	else
> +		pdata->no_ether_link = 0;
> +
> +	if (of_find_property(np, "sh-eth,ether-link-active-low", NULL))
> +		pdata->ether_link_active_low = 1;
> +	else
> +		pdata->ether_link_active_low = 0;
> +
> +	ret = sh_eth_of_get_register_type(np);
> +	if (ret < 0)
> +		goto error;
> +	pdata->register_type = ret;
> +
> +#ifdef CONFIG_OF_NET
> +	if (!is_valid_ether_addr(ndev->dev_addr)) {
> +		const char *macaddr = of_get_mac_address(np);
> +		if (macaddr)
> +			memcpy(pdata->mac_addr, macaddr, ETH_ALEN);
> +	}
> +#endif
> +
> +	return pdata;
> +
> +error:
> +	devm_kfree(dev, pdata);
> +	return NULL;
> +}
> +#endif
> +
>  static int sh_eth_drv_probe(struct platform_device *pdev)
>  {
> -	int ret, devno = 0;
> +	int ret = 0, devno = 0;
>  	struct resource *res;
>  	struct net_device *ndev = NULL;
>  	struct sh_eth_private *mdp = NULL;
>  	struct sh_eth_plat_data *pd;
> +	struct device_node *np = pdev->dev.of_node;
> +
> +	ndev = alloc_etherdev(sizeof(struct sh_eth_private));
> +	if (!ndev) {
> +		ret = -ENOMEM;
> +		goto out;
> +	}
>  
> +	mdp = netdev_priv(ndev);
>  	/* get base addr */
>  	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
>  	if (unlikely(res == NULL)) {
>  		dev_err(&pdev->dev, "invalid resource\n");
>  		ret = -EINVAL;
> -		goto out;
> -	}
> -
> -	ndev = alloc_etherdev(sizeof(struct sh_eth_private));
> -	if (!ndev) {
> -		ret = -ENOMEM;
> -		goto out;
> +		goto out_release;
>  	}
>  
>  	/* The sh Ether-specific entries in the device structure. */
> @@ -2383,27 +2466,41 @@ static int sh_eth_drv_probe(struct platform_device *pdev)
>  	}
>  	ndev->irq = ret;
>  
> -	SET_NETDEV_DEV(ndev, &pdev->dev);
> -
> -	/* Fill in the fields of the device structure with ethernet values. */
> -	ether_setup(ndev);
> -
> -	mdp = netdev_priv(ndev);
> -	mdp->num_tx_ring = TX_RING_SIZE;
> -	mdp->num_rx_ring = RX_RING_SIZE;
>  	mdp->addr = ioremap(res->start, resource_size(res));
>  	if (mdp->addr == NULL) {
>  		ret = -ENOMEM;
>  		dev_err(&pdev->dev, "ioremap failed.\n");
>  		goto out_release;
>  	}
> +#ifdef CONFIG_OF
> +	if (np && of_device_is_available(np)) {
> +		pd = sh_eth_parse_dt(&pdev->dev, ndev);
> +		if (pdev->dev.platform_data) {
> +			struct sh_eth_plat_data *tmp =
> +				pdev->dev.platform_data;
> +			pd->set_mdio_gate = tmp->set_mdio_gate;
> +			pd->needs_init = tmp->needs_init;
> +		}
> +	} else
> +#endif
> +		pd = (struct sh_eth_plat_data *)(pdev->dev.platform_data);
> +
> +	if (!pd) {
> +		dev_err(&pdev->dev, "no setup data defined\n");
> +		ret = -EINVAL;
> +		goto out_release;
> +	}
> +
> +	SET_NETDEV_DEV(ndev, &pdev->dev);
> +
> +	mdp->num_tx_ring = TX_RING_SIZE;
> +	mdp->num_rx_ring = RX_RING_SIZE;
>  
>  	spin_lock_init(&mdp->lock);
>  	mdp->pdev = pdev;
>  	pm_runtime_enable(&pdev->dev);
>  	pm_runtime_resume(&pdev->dev);
>  
> -	pd = (struct sh_eth_plat_data *)(pdev->dev.platform_data);
>  	/* get PHY ID */
>  	mdp->phy_id = pd->phy;
>  	mdp->phy_interface = pd->phy_interface;
> @@ -2412,6 +2509,8 @@ static int sh_eth_drv_probe(struct platform_device *pdev)
>  	mdp->no_ether_link = pd->no_ether_link;
>  	mdp->ether_link_active_low = pd->ether_link_active_low;
>  	mdp->reg_offset = sh_eth_get_register_offset(pd->register_type);
> +	/* read and set MAC address */
> +	read_mac_address(ndev, pd->mac_addr);
>  
>  	/* set cpu data */
>  #if defined(SH_ETH_HAS_BOTH_MODULES)
> @@ -2429,20 +2528,16 @@ static int sh_eth_drv_probe(struct platform_device *pdev)
>  	/* debug message level */
>  	mdp->msg_enable = SH_ETH_DEF_MSG_ENABLE;
>  
> -	/* read and set MAC address */
> -	read_mac_address(ndev, pd->mac_addr);
> -
>  	/* ioremap the TSU registers */
>  	if (mdp->cd->tsu) {
>  		struct resource *rtsu;
>  		rtsu = platform_get_resource(pdev, IORESOURCE_MEM, 1);
>  		if (!rtsu) {
>  			dev_err(&pdev->dev, "Not found TSU resource\n");
> -			ret = -ENODEV;
>  			goto out_release;
>  		}
>  		mdp->tsu_addr = ioremap(rtsu->start,
> -					resource_size(rtsu));
> +				resource_size(rtsu));
>  		mdp->port = devno % 2;
>  		ndev->features = NETIF_F_HW_VLAN_FILTER;
>  	}
> @@ -2522,17 +2617,24 @@ static int sh_eth_runtime_nop(struct device *dev)
>  	return 0;
>  }
>  
> -static struct dev_pm_ops sh_eth_dev_pm_ops = {
> +static const struct dev_pm_ops sh_eth_dev_pm_ops = {
>  	.runtime_suspend = sh_eth_runtime_nop,
>  	.runtime_resume = sh_eth_runtime_nop,
>  };
>  
> +static struct of_device_id sh_eth_match[] = {
> +	{ .compatible = "renesas,sh-eth",},
> +	{},
> +};
> +MODULE_DEVICE_TABLE(of, sh_eth_match);
> +
>  static struct platform_driver sh_eth_driver = {
>  	.probe = sh_eth_drv_probe,
>  	.remove = sh_eth_drv_remove,
>  	.driver = {
>  		   .name = CARDNAME,
>  		   .pm = &sh_eth_dev_pm_ops,
> +		   .of_match_table = sh_eth_match,
>  	},
>  };
>  
> -- 
> 1.7.10.4
> 
> --
> To unsubscribe from this list: send the line "unsubscribe netdev" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> 

^ permalink raw reply

* Re: [MacVLAN] failure to deliver reassembled IPv6 multicast traffic
From: Vlad Yasevich @ 2013-02-16  2:25 UTC (permalink / raw)
  To: Eric Dumazet; +Cc: Ben Greear, Erik Hugne, netdev, kaber, ataschner
In-Reply-To: <1360956930.19353.24.camel@edumazet-glaptop>

On 02/15/2013 02:35 PM, Eric Dumazet wrote:
> On Fri, 2013-02-15 at 11:27 -0800, Ben Greear wrote:
>
>> For some reason I was thinking this wasn't fully fixed for IPv4, but
>> maybe it is..the bug in our internal tracker only mentions IPv6
>> as having issues...
>>
>> We'll do some testing on IPv4 sometime soon to make sure, and can test
>> IPv6 patches as well...
>
> This worries me a bit, as I wrote this patch because you reported the
> issue.
>
> commit bc416d9768aa9a2e46eb11354a9c58399dafeb01
> Author: Eric Dumazet <eric.dumazet@gmail.com>
> Date:   Thu Oct 6 10:28:31 2011 +0000
>
>      macvlan: handle fragmented multicast frames
>
>      Fragmented multicast frames are delivered to a single macvlan port,
>      because ip defrag logic considers other samples are redundant.
>
>      Implement a defrag step before trying to send the multicast frame.
>
>      Reported-by: Ben Greear <greearb@candelatech.com>
>      Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>
>      Signed-off-by: David S. Miller <davem@davemloft.net>
>
>

Yep, IPv4 is there.  IPv6 is not and is a lot harder/more interesting 
since IPv6 may be disable, but reassembly may still need to work to
service the taps connected to VMs.  :(

The only reason I say this is because I've ran into too many people who
turn IPv6 off for "security reasons".

-vlad

>
> --
> To unsubscribe from this list: send the line "unsubscribe netdev" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>

^ permalink raw reply

* Re: [PATCH net-next 0/3] v3 GRE: TCP segmentation offload
From: David Miller @ 2013-02-16  1:53 UTC (permalink / raw)
  To: eric.dumazet; +Cc: pshelar, netdev, edumazet, jesse, bhutchings, mirqus
In-Reply-To: <1360975955.19353.32.camel@edumazet-glaptop>

From: Eric Dumazet <eric.dumazet@gmail.com>
Date: Fri, 15 Feb 2013 16:52:35 -0800

> There is this "tx-nocache-copy" issue : 

That scheme has so many system and device dependencies, but when
it does help it's nice to have.

Unfortunately I don't know the best way to proceed about that.

^ permalink raw reply

* Re: [PATCH net-next 0/3] v3 GRE: TCP segmentation offload
From: Eric Dumazet @ 2013-02-16  1:43 UTC (permalink / raw)
  To: Pravin Shelar; +Cc: David Miller, netdev, edumazet, jesse, bhutchings, mirqus
In-Reply-To: <CALnjE+qsY14H2=PhdPi3yFX7UgBHJgm79z_amw54A4BhEm5hkA@mail.gmail.com>

On Fri, 2013-02-15 at 17:41 -0800, Pravin Shelar wrote:

> 
> I am not seeing such big difference with these setting, are you
> running this test on special hardware or in VM?

Thats bare metal actually...

processor	: 0
vendor_id	: GenuineIntel
cpu family	: 6
model		: 44
model name	: Intel(R) Xeon(R) CPU           X5660  @ 2.80GHz
stepping	: 2
microcode	: 0x13
cpu MHz		: 2800.330
cache size	: 12288 KB

...

^ permalink raw reply

* Re: [PATCH net-next 0/3] v3 GRE: TCP segmentation offload
From: Pravin Shelar @ 2013-02-16  1:41 UTC (permalink / raw)
  To: Eric Dumazet; +Cc: David Miller, netdev, edumazet, jesse, bhutchings, mirqus
In-Reply-To: <1360975955.19353.32.camel@edumazet-glaptop>

On Fri, Feb 15, 2013 at 4:52 PM, Eric Dumazet <eric.dumazet@gmail.com> wrote:
> On Fri, 2013-02-15 at 15:18 -0500, David Miller wrote:
>
>> All applied, incorporating the suggestions/fixes from Eric.  Specifically,
>> using skb_reset_mac_len() in patch #2 and computing pkt_len before ip_local_out()
>> in patch #3.
>
> Thanks David
>
> There is this "tx-nocache-copy" issue :
>
> We currently enable the nocache copy for all devices but loopback.
>
> But its a loss of performance with tunnel devices
>
> Actually, it seems a loss even for regular ethernet devices :(
>
>
>
> # ethtool -K gre1 tx-nocache-copy on
> # perf stat netperf -H 7.7.8.84
> MIGRATED TCP STREAM TEST from 0.0.0.0 (0.0.0.0) port 0 AF_INET to 7.7.8.84 () port 0 AF_INET
> Recv   Send    Send
> Socket Socket  Message  Elapsed
> Size   Size    Size     Time     Throughput
> bytes  bytes   bytes    secs.    10^6bits/sec
>
>  87380  16384  16384    10.00    4252.42
>
>  Performance counter stats for 'netperf -H 7.7.8.84':
>
>        9967.965824 task-clock                #    0.996 CPUs utilized
>                 54 context-switches          #    0.005 K/sec
>                  3 CPU-migrations            #    0.000 K/sec
>                261 page-faults               #    0.026 K/sec
>     27,964,187,393 cycles                    #    2.805 GHz
>     20,902,040,632 stalled-cycles-frontend   #   74.75% frontend cycles idle
>     13,524,565,776 stalled-cycles-backend    #   48.36% backend  cycles idle
>     15,929,463,578 instructions              #    0.57  insns per cycle
>                                              #    1.31  stalled cycles per insn
>      2,065,830,063 branches                  #  207.247 M/sec
>         35,891,035 branch-misses             #    1.74% of all branches
>
>       10.003882959 seconds time elapsed
>
>
> Now we use regular memory copy :
>
> # ethtool -K gre1 tx-nocache-copy off
> # perf stat netperf -H 7.7.8.84
> MIGRATED TCP STREAM TEST from 0.0.0.0 (0.0.0.0) port 0 AF_INET to 7.7.8.84 () port 0 AF_INET
> Recv   Send    Send
> Socket Socket  Message  Elapsed
> Size   Size    Size     Time     Throughput
> bytes  bytes   bytes    secs.    10^6bits/sec
>
>  87380  16384  16384    10.00    7706.50
>
>  Performance counter stats for 'netperf -H 7.7.8.84':
>
>        5708.284991 task-clock                #    0.571 CPUs utilized
>              5,138 context-switches          #    0.900 K/sec
>                 24 CPU-migrations            #    0.004 K/sec
>                260 page-faults               #    0.046 K/sec
>     15,990,404,388 cycles                    #    2.801 GHz
>     10,903,764,099 stalled-cycles-frontend   #   68.19% frontend cycles idle
>      6,089,332,139 stalled-cycles-backend    #   38.08% backend  cycles idle
>     10,680,845,426 instructions              #    0.67  insns per cycle
>                                              #    1.02  stalled cycles per insn
>      1,401,663,288 branches                  #  245.549 M/sec
>         15,380,428 branch-misses             #    1.10% of all branches
>
>       10.004025020 seconds time elapsed
>
>

I am not seeing such big difference with these setting, are you
running this test on special hardware or in VM?

Thanks,
Pravin.

^ permalink raw reply

* Re: [PATCH net-next 3/4] tunneling: Add generic UDP-Tunnel TSO.
From: Pravin Shelar @ 2013-02-16  1:39 UTC (permalink / raw)
  To: Eric Dumazet; +Cc: netdev, edumazet, jesse, stephen
In-Reply-To: <1360978480.19353.36.camel@edumazet-glaptop>

On Fri, Feb 15, 2013 at 5:34 PM, Eric Dumazet <eric.dumazet@gmail.com> wrote:
> On Fri, 2013-02-15 at 17:06 -0800, Pravin B Shelar wrote:
>
>> +     /* segment inner packet. */
>> +     segs = skb_mac_gso_segment(skb, skb->dev->hw_enc_features);
>> +     if (!segs || IS_ERR(segs))
>> +             goto out;
>> +
>
> It seems that hw_enc_features is 0 for all devices.
>
right.

> We should at least inherit NETIF_F_SG
>
ok.

> (and presumably netdev_fix_features() should not remove NETIF_F_SG if
> CSUM is not supported, as we now copy the data _if_ needed in
> skb_checksum_help())
>
yes, that is useful. I have separate patch to kill this dependency, I
will sent it.

Thanks.

^ permalink raw reply

* Re: [PATCH net-next 3/4] tunneling: Add generic UDP-Tunnel TSO.
From: Eric Dumazet @ 2013-02-16  1:34 UTC (permalink / raw)
  To: Pravin B Shelar; +Cc: netdev, edumazet, jesse, stephen
In-Reply-To: <1360976774-1891-1-git-send-email-pshelar@nicira.com>

On Fri, 2013-02-15 at 17:06 -0800, Pravin B Shelar wrote:

> +	/* segment inner packet. */
> +	segs = skb_mac_gso_segment(skb, skb->dev->hw_enc_features);
> +	if (!segs || IS_ERR(segs))
> +		goto out;
> +

It seems that hw_enc_features is 0 for all devices.

We should at least inherit NETIF_F_SG

(and presumably netdev_fix_features() should not remove NETIF_F_SG if
CSUM is not supported, as we now copy the data _if_ needed in
skb_checksum_help())

^ permalink raw reply

* Re: [BUG arm-soc] mvneta: tx queue done sometimes causes kernel panic
From: Thomas Petazzoni @ 2013-02-16  1:20 UTC (permalink / raw)
  To: Eric Dumazet
  Cc: Masami Hiramatsu, linux-arm-kernel, yrl.pp-manager.tt@hitachi.com,
	linux-kernel, David S. Miller, netdev
In-Reply-To: <1360947132.19353.15.camel@edumazet-glaptop>

Hello,

On Fri, 15 Feb 2013 08:52:12 -0800, Eric Dumazet wrote:

> Driver is buggy, as TX completion can happen both from ndo_start_xmit()
> and a timer, and there is no spinlock or appropriate synchro.

Yes, it is a known issue. I did post a patch fixing the problem on
netdev@ a while ago [1], but while it was fixing the problem, it wasn't
considered the right approach. Being busy with other Marvell Armada
370/XP developments, I haven't yet had the time to investigate the
issue again.

[1] https://patchwork.kernel.org/patch/1941601/

Best regards,

Thomas
-- 
Thomas Petazzoni, Free Electrons
Kernel, drivers, real-time and embedded Linux
development, consulting, training and support.
http://free-electrons.com

^ permalink raw reply

* [PATCH net-next 4/4] VXLAN: Use UDP Tunnel segmention.
From: Pravin B Shelar @ 2013-02-16  1:06 UTC (permalink / raw)
  To: netdev; +Cc: edumazet, jesse, stephen, Pravin B Shelar

Enable TSO for VXLAN devices and use UDP_TUNNEL offload support.

Signed-off-by: Pravin B Shelar <pshelar@nicira.com>
---
 drivers/net/vxlan.c |   23 +++++++++++++++++++----
 1 files changed, 19 insertions(+), 4 deletions(-)

diff --git a/drivers/net/vxlan.c b/drivers/net/vxlan.c
index 9d70421..61b7cd0 100644
--- a/drivers/net/vxlan.c
+++ b/drivers/net/vxlan.c
@@ -823,6 +823,20 @@ static u16 vxlan_src_port(const struct vxlan_dev *vxlan, struct sk_buff *skb)
 	return (((u64) hash * range) >> 32) + vxlan->port_min;
 }
 
+static int handle_offloads(struct sk_buff *skb)
+{
+	if (skb_is_gso(skb)) {
+		int err = skb_unclone(skb, GFP_ATOMIC);
+		if (unlikely(err))
+			return err;
+
+		skb_shinfo(skb)->gso_type |= (SKB_GSO_UDP_TUNNEL | SKB_GSO_UDP);
+	} else if (skb->ip_summed != CHECKSUM_PARTIAL)
+		skb->ip_summed = CHECKSUM_NONE;
+
+	return 0;
+}
+
 /* Transmit local packets over Vxlan
  *
  * Outer IP header inherits ECN and DF from inner header.
@@ -962,13 +976,12 @@ static netdev_tx_t vxlan_xmit(struct sk_buff *skb, struct net_device *dev)
 	iph->daddr	= dst;
 	iph->saddr	= fl4.saddr;
 	iph->ttl	= ttl ? : ip4_dst_hoplimit(&rt->dst);
+	ip_select_ident(iph, &rt->dst, NULL);
 
 	vxlan_set_owner(dev, skb);
 
-	/* See iptunnel_xmit() */
-	if (skb->ip_summed != CHECKSUM_PARTIAL)
-		skb->ip_summed = CHECKSUM_NONE;
-	ip_select_ident(iph, &rt->dst, NULL);
+	if (handle_offloads(skb))
+		goto drop;
 
 	err = ip_local_out(skb);
 	if (likely(net_xmit_eval(err) == 0)) {
@@ -1190,8 +1203,10 @@ static void vxlan_setup(struct net_device *dev)
 	dev->features	|= NETIF_F_NETNS_LOCAL;
 	dev->features	|= NETIF_F_SG | NETIF_F_HW_CSUM;
 	dev->features   |= NETIF_F_RXCSUM;
+	dev->features   |= NETIF_F_GSO_SOFTWARE;
 
 	dev->hw_features |= NETIF_F_SG | NETIF_F_HW_CSUM | NETIF_F_RXCSUM;
+	dev->hw_features |= NETIF_F_GSO_SOFTWARE;
 	dev->priv_flags	&= ~IFF_XMIT_DST_RELEASE;
 	dev->priv_flags |= IFF_LIVE_ADDR_CHANGE;
 
-- 
1.7.1

^ permalink raw reply related

* [PATCH net-next 3/4] tunneling: Add generic UDP-Tunnel TSO.
From: Pravin B Shelar @ 2013-02-16  1:06 UTC (permalink / raw)
  To: netdev; +Cc: edumazet, jesse, stephen, Pravin B Shelar

Adds generic tunneling TCP segment offloading support for IPv4-UDP
based tunnels.
GSO type is added to request this offload for a skb.
netdev feature NETIF_F_UDP_TUNNEL is added for hardware offloaded
udp-tunnel support. Currently no device supports this feature,
software offload is used.

This can be used by tunneling protocols like VXLAN.

CC: Jesse Gross <jesse@nicira.com>
Signed-off-by: Pravin B Shelar <pshelar@nicira.com>
---
 include/linux/netdev_features.h |    7 ++-
 include/linux/skbuff.h          |    2 +
 net/ipv4/af_inet.c              |    6 ++-
 net/ipv4/tcp.c                  |    1 +
 net/ipv4/udp.c                  |  113 ++++++++++++++++++++++++++++++---------
 net/ipv6/ip6_offload.c          |    1 +
 net/ipv6/udp_offload.c          |   10 +++-
 7 files changed, 109 insertions(+), 31 deletions(-)

diff --git a/include/linux/netdev_features.h b/include/linux/netdev_features.h
index 3dd3934..6d7c474 100644
--- a/include/linux/netdev_features.h
+++ b/include/linux/netdev_features.h
@@ -42,9 +42,9 @@ enum {
 	NETIF_F_TSO6_BIT,		/* ... TCPv6 segmentation */
 	NETIF_F_FSO_BIT,		/* ... FCoE segmentation */
 	NETIF_F_GSO_GRE_BIT,		/* ... GRE with TSO */
-	/**/NETIF_F_GSO_LAST,		/* [can't be last bit, see GSO_MASK] */
-	NETIF_F_GSO_RESERVED2		/* ... free (fill GSO_MASK to 8 bits) */
-		= NETIF_F_GSO_LAST,
+	NETIF_F_GSO_UDP_TUNNEL_BIT,	/* ... UDP TUNNEL with TSO */
+	/**/NETIF_F_GSO_LAST = 		/* last bit, see GSO_MASK */
+		NETIF_F_GSO_UDP_TUNNEL_BIT,
 
 	NETIF_F_FCOE_CRC_BIT,		/* FCoE CRC32 */
 	NETIF_F_SCTP_CSUM_BIT,		/* SCTP checksum offload */
@@ -103,6 +103,7 @@ enum {
 #define NETIF_F_RXFCS		__NETIF_F(RXFCS)
 #define NETIF_F_RXALL		__NETIF_F(RXALL)
 #define NETIF_F_GRE_GSO		__NETIF_F(GSO_GRE)
+#define NETIF_F_UDP_TUNNEL	__NETIF_F(UDP_TUNNEL)
 
 /* Features valid for ethtool to change */
 /* = all defined minus driver/device-class-related */
diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h
index d7f96ff..eb2106f 100644
--- a/include/linux/skbuff.h
+++ b/include/linux/skbuff.h
@@ -316,6 +316,8 @@ enum {
 	SKB_GSO_FCOE = 1 << 5,
 
 	SKB_GSO_GRE = 1 << 6,
+
+	SKB_GSO_UDP_TUNNEL = 1 << 7,
 };
 
 #if BITS_PER_LONG > 32
diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c
index e225a4e..57831a7 100644
--- a/net/ipv4/af_inet.c
+++ b/net/ipv4/af_inet.c
@@ -1278,6 +1278,7 @@ static struct sk_buff *inet_gso_segment(struct sk_buff *skb,
 	int ihl;
 	int id;
 	unsigned int offset = 0;
+	bool tunnel;
 
 	if (!(features & NETIF_F_V4_CSUM))
 		features &= ~NETIF_F_SG;
@@ -1288,6 +1289,7 @@ static struct sk_buff *inet_gso_segment(struct sk_buff *skb,
 		       SKB_GSO_DODGY |
 		       SKB_GSO_TCP_ECN |
 		       SKB_GSO_GRE |
+		       SKB_GSO_UDP_TUNNEL |
 		       0)))
 		goto out;
 
@@ -1302,6 +1304,8 @@ static struct sk_buff *inet_gso_segment(struct sk_buff *skb,
 	if (unlikely(!pskb_may_pull(skb, ihl)))
 		goto out;
 
+	tunnel = !!skb->encapsulation;
+
 	__skb_pull(skb, ihl);
 	skb_reset_transport_header(skb);
 	iph = ip_hdr(skb);
@@ -1321,7 +1325,7 @@ static struct sk_buff *inet_gso_segment(struct sk_buff *skb,
 	skb = segs;
 	do {
 		iph = ip_hdr(skb);
-		if (proto == IPPROTO_UDP) {
+		if (!tunnel && proto == IPPROTO_UDP) {
 			iph->id = htons(id);
 			iph->frag_off = htons(offset >> 3);
 			if (skb->next != NULL)
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
index 7a5ba48..8fe8ee9 100644
--- a/net/ipv4/tcp.c
+++ b/net/ipv4/tcp.c
@@ -3044,6 +3044,7 @@ struct sk_buff *tcp_tso_segment(struct sk_buff *skb,
 			       SKB_GSO_TCP_ECN |
 			       SKB_GSO_TCPV6 |
 			       SKB_GSO_GRE |
+			       SKB_GSO_UDP_TUNNEL |
 			       0) ||
 			     !(type & (SKB_GSO_TCPV4 | SKB_GSO_TCPV6))))
 			goto out;
diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c
index 39a5e7a..9802408 100644
--- a/net/ipv4/udp.c
+++ b/net/ipv4/udp.c
@@ -2272,31 +2272,86 @@ void __init udp_init(void)
 
 int udp4_ufo_send_check(struct sk_buff *skb)
 {
-	const struct iphdr *iph;
-	struct udphdr *uh;
-
-	if (!pskb_may_pull(skb, sizeof(*uh)))
+	if (!pskb_may_pull(skb, sizeof(struct udphdr)))
 		return -EINVAL;
 
-	iph = ip_hdr(skb);
-	uh = udp_hdr(skb);
+	if (!skb->encapsulation) {
+		const struct iphdr *iph;
+		struct udphdr *uh;
 
-	uh->check = ~csum_tcpudp_magic(iph->saddr, iph->daddr, skb->len,
-				       IPPROTO_UDP, 0);
-	skb->csum_start = skb_transport_header(skb) - skb->head;
-	skb->csum_offset = offsetof(struct udphdr, check);
-	skb->ip_summed = CHECKSUM_PARTIAL;
+		iph = ip_hdr(skb);
+		uh = udp_hdr(skb);
+
+		uh->check = ~csum_tcpudp_magic(iph->saddr, iph->daddr, skb->len,
+				IPPROTO_UDP, 0);
+		skb->csum_start = skb_transport_header(skb) - skb->head;
+		skb->csum_offset = offsetof(struct udphdr, check);
+		skb->ip_summed = CHECKSUM_PARTIAL;
+	}
 	return 0;
 }
 
+static struct sk_buff *skb_udp_tunnel_segment(struct sk_buff *skb,
+		netdev_features_t features)
+{
+	struct sk_buff *segs = ERR_PTR(-EINVAL);
+	int mac_len = skb->mac_len;
+	int tnl_hlen = skb_inner_mac_header(skb) - skb_transport_header(skb);
+	int outer_hlen;
+
+	if (unlikely(!pskb_may_pull(skb, tnl_hlen)))
+		goto out;
+
+	skb->encapsulation = 0;
+	__skb_pull(skb, tnl_hlen);
+	skb_reset_mac_header(skb);
+	skb_set_network_header(skb, skb_inner_network_offset(skb));
+	skb->mac_len = skb_inner_network_offset(skb);
+
+	/* segment inner packet. */
+	segs = skb_mac_gso_segment(skb, skb->dev->hw_enc_features);
+	if (!segs || IS_ERR(segs))
+		goto out;
+
+	outer_hlen = skb_tnl_header_len(skb);
+	skb = segs;
+	do {
+		struct udphdr *uh;
+		int udp_offset = outer_hlen - tnl_hlen;
+
+		skb->mac_len = mac_len;
+
+		skb_push(skb, outer_hlen);
+		skb_reset_mac_header(skb);
+		skb_set_network_header(skb, mac_len);
+		skb_set_transport_header(skb, udp_offset);
+		uh = udp_hdr(skb);
+		uh->len = htons(skb->len - udp_offset);
+
+		/* csum segment if tunnel sets skb with csum. */
+		if (uh->check) {
+			struct iphdr *iph = ip_hdr(skb);
+
+			uh->check = ~csum_tcpudp_magic(iph->saddr, iph->daddr,
+						       skb->len - udp_offset,
+						       IPPROTO_UDP, 0);
+			uh->check = csum_fold(skb_checksum(skb, udp_offset,
+							   skb->len - udp_offset, 0));
+			if (uh->check == 0)
+				uh->check = CSUM_MANGLED_0;
+
+		}
+		skb->ip_summed = CHECKSUM_NONE;
+	} while ((skb = skb->next));
+out:
+	return segs;
+}
+
 struct sk_buff *udp4_ufo_fragment(struct sk_buff *skb,
 	netdev_features_t features)
 {
 	struct sk_buff *segs = ERR_PTR(-EINVAL);
 	unsigned int mss;
-	int offset;
-	__wsum csum;
-
 	mss = skb_shinfo(skb)->gso_size;
 	if (unlikely(skb->len <= mss))
 		goto out;
@@ -2306,6 +2361,7 @@ struct sk_buff *udp4_ufo_fragment(struct sk_buff *skb,
 		int type = skb_shinfo(skb)->gso_type;
 
 		if (unlikely(type & ~(SKB_GSO_UDP | SKB_GSO_DODGY |
+				      SKB_GSO_UDP_TUNNEL |
 				      SKB_GSO_GRE) ||
 			     !(type & (SKB_GSO_UDP))))
 			goto out;
@@ -2316,20 +2372,27 @@ struct sk_buff *udp4_ufo_fragment(struct sk_buff *skb,
 		goto out;
 	}
 
-	/* Do software UFO. Complete and fill in the UDP checksum as HW cannot
-	 * do checksum of UDP packets sent as multiple IP fragments.
-	 */
-	offset = skb_checksum_start_offset(skb);
-	csum = skb_checksum(skb, offset, skb->len - offset, 0);
-	offset += skb->csum_offset;
-	*(__sum16 *)(skb->data + offset) = csum_fold(csum);
-	skb->ip_summed = CHECKSUM_NONE;
-
 	/* Fragment the skb. IP headers of the fragments are updated in
 	 * inet_gso_segment()
 	 */
-	segs = skb_segment(skb, features);
+	if (skb->encapsulation && skb_shinfo(skb)->gso_type & SKB_GSO_UDP_TUNNEL)
+		segs = skb_udp_tunnel_segment(skb, features);
+	else {
+		int offset;
+		__wsum csum;
+
+		/* Do software UFO. Complete and fill in the UDP checksum as
+		 * HW cannot do checksum of UDP packets sent as multiple
+		 * IP fragments.
+		 */
+		offset = skb_checksum_start_offset(skb);
+		csum = skb_checksum(skb, offset, skb->len - offset, 0);
+		offset += skb->csum_offset;
+		*(__sum16 *)(skb->data + offset) = csum_fold(csum);
+		skb->ip_summed = CHECKSUM_NONE;
+
+		segs = skb_segment(skb, features);
+	}
 out:
 	return segs;
 }
-
diff --git a/net/ipv6/ip6_offload.c b/net/ipv6/ip6_offload.c
index 8234c1d..e02a65a 100644
--- a/net/ipv6/ip6_offload.c
+++ b/net/ipv6/ip6_offload.c
@@ -100,6 +100,7 @@ static struct sk_buff *ipv6_gso_segment(struct sk_buff *skb,
 		       SKB_GSO_DODGY |
 		       SKB_GSO_TCP_ECN |
 		       SKB_GSO_GRE |
+		       SKB_GSO_UDP_TUNNEL |
 		       SKB_GSO_TCPV6 |
 		       0)))
 		goto out;
diff --git a/net/ipv6/udp_offload.c b/net/ipv6/udp_offload.c
index cf05cf0..3ced14e 100644
--- a/net/ipv6/udp_offload.c
+++ b/net/ipv6/udp_offload.c
@@ -21,6 +21,10 @@ static int udp6_ufo_send_check(struct sk_buff *skb)
 	const struct ipv6hdr *ipv6h;
 	struct udphdr *uh;
 
+	/* UDP Tunnel offload on ipv6 is not yet supported. */
+	if (skb->encapsulation)
+		return -EINVAL;
+
 	if (!pskb_may_pull(skb, sizeof(*uh)))
 		return -EINVAL;
 
@@ -56,8 +60,10 @@ static struct sk_buff *udp6_ufo_fragment(struct sk_buff *skb,
 		/* Packet is from an untrusted source, reset gso_segs. */
 		int type = skb_shinfo(skb)->gso_type;
 
-		if (unlikely(type & ~(SKB_GSO_UDP | SKB_GSO_DODGY |
-				      SKB_GSO_GRE) ||
+		if (unlikely(type & ~(SKB_GSO_UDP |
+				      SKB_GSO_DODGY |
+				      SKB_GSO_UDP_TUNNEL |
+ 				      SKB_GSO_GRE) ||
 			     !(type & (SKB_GSO_UDP))))
 			goto out;
 
-- 
1.7.1

^ permalink raw reply related

* [PATCH net-next 2/4] tunneling: Capture inner mac header during encapsulation.
From: Pravin B Shelar @ 2013-02-16  1:06 UTC (permalink / raw)
  To: netdev; +Cc: edumazet, jesse, stephen, Pravin B Shelar

This patch adds missing inner mac header. This will be used in
next patch.

Signed-off-by: Pravin B Shelar <pshelar@nicira.com>
---
 include/linux/skbuff.h |   34 ++++++++++++++++++++++++++++++++++
 net/core/skbuff.c      |    2 ++
 2 files changed, 36 insertions(+), 0 deletions(-)

diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h
index 821c7f4..d7f96ff 100644
--- a/include/linux/skbuff.h
+++ b/include/linux/skbuff.h
@@ -387,6 +387,7 @@ typedef unsigned char *sk_buff_data_t;
  *	@vlan_tci: vlan tag control information
  *	@inner_transport_header: Inner transport layer header (encapsulation)
  *	@inner_network_header: Network layer header (encapsulation)
+ *	@inner_mac_header: Link layer header (encapsulation)
  *	@transport_header: Transport layer header
  *	@network_header: Network layer header
  *	@mac_header: Link layer header
@@ -505,6 +506,7 @@ struct sk_buff {
 
 	sk_buff_data_t		inner_transport_header;
 	sk_buff_data_t		inner_network_header;
+	sk_buff_data_t		inner_mac_header;
 	sk_buff_data_t		transport_header;
 	sk_buff_data_t		network_header;
 	sk_buff_data_t		mac_header;
@@ -1466,6 +1468,7 @@ static inline void skb_reserve(struct sk_buff *skb, int len)
 
 static inline void skb_reset_inner_headers(struct sk_buff *skb)
 {
+	skb->inner_mac_header = skb->mac_header;
 	skb->inner_network_header = skb->network_header;
 	skb->inner_transport_header = skb->transport_header;
 }
@@ -1511,6 +1514,22 @@ static inline void skb_set_inner_network_header(struct sk_buff *skb,
 	skb->inner_network_header += offset;
 }
 
+static inline unsigned char *skb_inner_mac_header(const struct sk_buff *skb)
+{
+	return skb->head + skb->inner_mac_header;
+}
+
+static inline void skb_reset_inner_mac_header(struct sk_buff *skb)
+{
+	skb->inner_mac_header = skb->data - skb->head;
+}
+
+static inline void skb_set_inner_mac_header(struct sk_buff *skb,
+					    const int offset)
+{
+	skb_reset_inner_mac_header(skb);
+	skb->inner_mac_header += offset;
+}
 static inline bool skb_transport_header_was_set(const struct sk_buff *skb)
 {
 	return skb->transport_header != ~0U;
@@ -1604,6 +1623,21 @@ static inline void skb_set_inner_network_header(struct sk_buff *skb,
 	skb->inner_network_header = skb->data + offset;
 }
 
+static inline unsigned char *skb_inner_mac_header(const struct sk_buff *skb)
+{
+	return skb->inner_mac_header;
+}
+
+static inline void skb_reset_inner_mac_header(struct sk_buff *skb)
+{
+	skb->inner_mac_header = skb->data;
+}
+
+static inline void skb_set_inner_mac_header(struct sk_buff *skb,
+						const int offset)
+{
+	skb->inner_mac_header = skb->data + offset;
+}
 static inline bool skb_transport_header_was_set(const struct sk_buff *skb)
 {
 	return skb->transport_header != NULL;
diff --git a/net/core/skbuff.c b/net/core/skbuff.c
index d388e77..ba8f89c 100644
--- a/net/core/skbuff.c
+++ b/net/core/skbuff.c
@@ -673,6 +673,7 @@ static void __copy_skb_header(struct sk_buff *new, const struct sk_buff *old)
 	new->mac_header		= old->mac_header;
 	new->inner_transport_header = old->inner_transport_header;
 	new->inner_network_header = old->inner_network_header;
+	new->inner_mac_header = old->inner_mac_header;
 	skb_dst_copy(new, old);
 	new->rxhash		= old->rxhash;
 	new->ooo_okay		= old->ooo_okay;
@@ -876,6 +877,7 @@ static void skb_headers_offset_update(struct sk_buff *skb, int off)
 		skb->mac_header += off;
 	skb->inner_transport_header += off;
 	skb->inner_network_header += off;
+	skb->inner_mac_header += off;
 }
 
 static void copy_skb_header(struct sk_buff *new, const struct sk_buff *old)
-- 
1.7.1

^ permalink raw reply related

* [PATCH net-next 1/4] net: Add skb_headers_offset_update helper function.
From: Pravin B Shelar @ 2013-02-16  1:06 UTC (permalink / raw)
  To: netdev; +Cc: edumazet, jesse, stephen, Pravin B Shelar

This function will be used in next VXLAN-TSO patch. This patch does
not change any functionality.

Signed-off-by: Pravin B Shelar <pshelar@nicira.com>
---
 net/core/skbuff.c |   34 ++++++++++++++--------------------
 1 files changed, 14 insertions(+), 20 deletions(-)

diff --git a/net/core/skbuff.c b/net/core/skbuff.c
index 2a3ca33..d388e77 100644
--- a/net/core/skbuff.c
+++ b/net/core/skbuff.c
@@ -867,6 +867,17 @@ struct sk_buff *skb_clone(struct sk_buff *skb, gfp_t gfp_mask)
 }
 EXPORT_SYMBOL(skb_clone);
 
+static void skb_headers_offset_update(struct sk_buff *skb, int off)
+{
+	/* {transport,network,mac}_header and tail are relative to skb->head */
+	skb->transport_header += off;
+	skb->network_header   += off;
+	if (skb_mac_header_was_set(skb))
+		skb->mac_header += off;
+	skb->inner_transport_header += off;
+	skb->inner_network_header += off;
+}
+
 static void copy_skb_header(struct sk_buff *new, const struct sk_buff *old)
 {
 #ifndef NET_SKBUFF_DATA_USES_OFFSET
@@ -879,13 +890,7 @@ static void copy_skb_header(struct sk_buff *new, const struct sk_buff *old)
 	__copy_skb_header(new, old);
 
 #ifndef NET_SKBUFF_DATA_USES_OFFSET
-	/* {transport,network,mac}_header are relative to skb->head */
-	new->transport_header += offset;
-	new->network_header   += offset;
-	if (skb_mac_header_was_set(new))
-		new->mac_header	      += offset;
-	new->inner_transport_header += offset;
-	new->inner_network_header   += offset;
+	skb_headers_offset_update(new, offset);
 #endif
 	skb_shinfo(new)->gso_size = skb_shinfo(old)->gso_size;
 	skb_shinfo(new)->gso_segs = skb_shinfo(old)->gso_segs;
@@ -1077,14 +1082,8 @@ int pskb_expand_head(struct sk_buff *skb, int nhead, int ntail,
 #else
 	skb->end      = skb->head + size;
 #endif
-	/* {transport,network,mac}_header and tail are relative to skb->head */
 	skb->tail	      += off;
-	skb->transport_header += off;
-	skb->network_header   += off;
-	if (skb_mac_header_was_set(skb))
-		skb->mac_header += off;
-	skb->inner_transport_header += off;
-	skb->inner_network_header += off;
+	skb_headers_offset_update(skb, off);
 	/* Only adjust this if it actually is csum_start rather than csum */
 	if (skb->ip_summed == CHECKSUM_PARTIAL)
 		skb->csum_start += nhead;
@@ -1180,12 +1179,7 @@ struct sk_buff *skb_copy_expand(const struct sk_buff *skb,
 	if (n->ip_summed == CHECKSUM_PARTIAL)
 		n->csum_start += off;
 #ifdef NET_SKBUFF_DATA_USES_OFFSET
-	n->transport_header += off;
-	n->network_header   += off;
-	if (skb_mac_header_was_set(skb))
-		n->mac_header += off;
-	n->inner_transport_header += off;
-	n->inner_network_header	   += off;
+	skb_headers_offset_update(n, off);
 #endif
 
 	return n;
-- 
1.7.1

^ permalink raw reply related

* [PATCH net-next 0/4] VXLAN: TCP segmentation offload
From: Pravin B Shelar @ 2013-02-16  1:05 UTC (permalink / raw)
  To: netdev; +Cc: edumazet, jesse, stephen, Pravin B Shelar

Following patches add TCP segmentation offload to VXLAN. These
patches shows performance improvement from 3.8G to 5.8G (+50%)
with netperf single process TCP_STREAM test on 10G network.

Pravin B Shelar (4):
  net: Add skb_headers_offset_update helper function.
  tunneling: Capture inner mac header during encapsulation.
  tunneling: Add generic Tunnel segmentation.
  VXLAN: Use UDP Tunnel segmention.

 drivers/net/vxlan.c             |   23 +++++++--
 include/linux/netdev_features.h |    7 ++-
 include/linux/skbuff.h          |   36 ++++++++++++
 net/core/skbuff.c               |   36 ++++++-------
 net/ipv4/af_inet.c              |    6 ++-
 net/ipv4/udp.c                  |  113 ++++++++++++++++++++++++++++++---------
 net/ipv6/ip6_offload.c          |    1 +
 net/ipv6/udp_offload.c          |   10 +++-
 8 files changed, 177 insertions(+), 55 deletions(-)

^ permalink raw reply

* Re: [PATCH net-next 0/3] v3 GRE: TCP segmentation offload
From: Eric Dumazet @ 2013-02-16  0:52 UTC (permalink / raw)
  To: David Miller; +Cc: pshelar, netdev, edumazet, jesse, bhutchings, mirqus
In-Reply-To: <20130215.151824.1125629773152171791.davem@davemloft.net>

On Fri, 2013-02-15 at 15:18 -0500, David Miller wrote:

> All applied, incorporating the suggestions/fixes from Eric.  Specifically,
> using skb_reset_mac_len() in patch #2 and computing pkt_len before ip_local_out()
> in patch #3.

Thanks David

There is this "tx-nocache-copy" issue : 

We currently enable the nocache copy for all devices but loopback.

But its a loss of performance with tunnel devices 

Actually, it seems a loss even for regular ethernet devices :(



# ethtool -K gre1 tx-nocache-copy on 
# perf stat netperf -H 7.7.8.84
MIGRATED TCP STREAM TEST from 0.0.0.0 (0.0.0.0) port 0 AF_INET to 7.7.8.84 () port 0 AF_INET
Recv   Send    Send                          
Socket Socket  Message  Elapsed              
Size   Size    Size     Time     Throughput  
bytes  bytes   bytes    secs.    10^6bits/sec  

 87380  16384  16384    10.00    4252.42   

 Performance counter stats for 'netperf -H 7.7.8.84':

       9967.965824 task-clock                #    0.996 CPUs utilized          
                54 context-switches          #    0.005 K/sec                  
                 3 CPU-migrations            #    0.000 K/sec                  
               261 page-faults               #    0.026 K/sec                  
    27,964,187,393 cycles                    #    2.805 GHz                    
    20,902,040,632 stalled-cycles-frontend   #   74.75% frontend cycles idle   
    13,524,565,776 stalled-cycles-backend    #   48.36% backend  cycles idle   
    15,929,463,578 instructions              #    0.57  insns per cycle        
                                             #    1.31  stalled cycles per insn
     2,065,830,063 branches                  #  207.247 M/sec                  
        35,891,035 branch-misses             #    1.74% of all branches        

      10.003882959 seconds time elapsed


Now we use regular memory copy :

# ethtool -K gre1 tx-nocache-copy off
# perf stat netperf -H 7.7.8.84
MIGRATED TCP STREAM TEST from 0.0.0.0 (0.0.0.0) port 0 AF_INET to 7.7.8.84 () port 0 AF_INET
Recv   Send    Send                          
Socket Socket  Message  Elapsed              
Size   Size    Size     Time     Throughput  
bytes  bytes   bytes    secs.    10^6bits/sec  

 87380  16384  16384    10.00    7706.50   

 Performance counter stats for 'netperf -H 7.7.8.84':

       5708.284991 task-clock                #    0.571 CPUs utilized          
             5,138 context-switches          #    0.900 K/sec                  
                24 CPU-migrations            #    0.004 K/sec                  
               260 page-faults               #    0.046 K/sec                  
    15,990,404,388 cycles                    #    2.801 GHz                    
    10,903,764,099 stalled-cycles-frontend   #   68.19% frontend cycles idle   
     6,089,332,139 stalled-cycles-backend    #   38.08% backend  cycles idle   
    10,680,845,426 instructions              #    0.67  insns per cycle        
                                             #    1.02  stalled cycles per insn
     1,401,663,288 branches                  #  245.549 M/sec                  
        15,380,428 branch-misses             #    1.10% of all branches        

      10.004025020 seconds time elapsed

^ permalink raw reply

* Re: 3.7 networking regression - bisected
From: Eric Dumazet @ 2013-02-15 23:43 UTC (permalink / raw)
  To: Phil Oester; +Cc: netdev
In-Reply-To: <20130215232752.GA19796@linuxace.com>

On Fri, 2013-02-15 at 15:27 -0800, Phil Oester wrote:
> Since upgrading a box to 3.7, I've been seeing e1000e issues on one box:
> 
> 	e1000e 0000:00:19.0: eth2: Detected Hardware Unit Hang
> 
> While 3.6 worked fine.  I bisected the problem down to commit
> 69b08f62e17439ee3d436faf0b9a7ca6fffb78db ("net: use bigger pages in
> __netdev_alloc_frag").  Running 3.7.x without that commit is 
> currently working fine.  
> 
> I have other boxes on 3.7 with e1000e that are not experiencing this
> problem.  The difference on this box is it runs at 100mb, which
> disables TSO:
> 
> 	e1000e 0000:00:19.0 eth2: 10/100 speed: disabling TSO
> 
> So maybe the problem doesn't occur with TSO enabled?  Either that,
> or there is something unique about the traffic pattern this box is seeing.

You could try disabling TSO on other boxes.

And CC Intel guys, as it sounds like hardware bug or driver bug.

^ permalink raw reply

* 3.7 networking regression - bisected
From: Phil Oester @ 2013-02-15 23:27 UTC (permalink / raw)
  To: netdev; +Cc: eric.dumazet

Since upgrading a box to 3.7, I've been seeing e1000e issues on one box:

	e1000e 0000:00:19.0: eth2: Detected Hardware Unit Hang

While 3.6 worked fine.  I bisected the problem down to commit
69b08f62e17439ee3d436faf0b9a7ca6fffb78db ("net: use bigger pages in
__netdev_alloc_frag").  Running 3.7.x without that commit is 
currently working fine.  

I have other boxes on 3.7 with e1000e that are not experiencing this
problem.  The difference on this box is it runs at 100mb, which
disables TSO:

	e1000e 0000:00:19.0 eth2: 10/100 speed: disabling TSO

So maybe the problem doesn't occur with TSO enabled?  Either that,
or there is something unique about the traffic pattern this box is seeing.

Full log entries below.

Phil Oester



Feb 15 17:38:19 char1 kernel: e1000e 0000:00:19.0: eth2: Detected Hardware Unit Hang:
Feb 15 17:38:19 char1 kernel:  TDH                  <f>
Feb 15 17:38:19 char1 kernel:  TDT                  <22>
Feb 15 17:38:19 char1 kernel:  next_to_use          <22>
Feb 15 17:38:19 char1 kernel:  next_to_clean        <d>
Feb 15 17:38:19 char1 kernel: buffer_info[next_to_clean]:
Feb 15 17:38:19 char1 kernel:  time_stamp           <10001bb67>
Feb 15 17:38:19 char1 kernel:  next_to_watch        <f>
Feb 15 17:38:19 char1 kernel:  jiffies              <10001bfa9>
Feb 15 17:38:19 char1 kernel:  next_to_watch.status <0>
Feb 15 17:38:19 char1 kernel: MAC Status             <80243>
Feb 15 17:38:19 char1 kernel: PHY Status             <792d>
Feb 15 17:38:19 char1 kernel: PHY 1000BASE-T Status  <0>
Feb 15 17:38:19 char1 kernel: PHY Extended Status    <3000>
Feb 15 17:38:19 char1 kernel: PCI Status             <10>
Feb 15 17:38:21 char1 kernel: e1000e 0000:00:19.0: eth2: Detected Hardware Unit Hang:
Feb 15 17:38:21 char1 kernel:  TDH                  <f>
Feb 15 17:38:21 char1 kernel:  TDT                  <22>
Feb 15 17:38:21 char1 kernel:  next_to_use          <22>
Feb 15 17:38:21 char1 kernel:  next_to_clean        <d>
Feb 15 17:38:21 char1 kernel: buffer_info[next_to_clean]:
Feb 15 17:38:21 char1 kernel:  time_stamp           <10001bb67>
Feb 15 17:38:21 char1 kernel:  next_to_watch        <f>
Feb 15 17:38:21 char1 kernel:  jiffies              <10001c071>
Feb 15 17:38:21 char1 kernel:  next_to_watch.status <0>
Feb 15 17:38:21 char1 kernel: MAC Status             <80243>
Feb 15 17:38:21 char1 kernel: PHY Status             <792d>
Feb 15 17:38:21 char1 kernel: PHY 1000BASE-T Status  <0>
Feb 15 17:38:21 char1 kernel: PHY Extended Status    <3000>
Feb 15 17:38:21 char1 kernel: PCI Status             <10>
Feb 15 17:38:23 char1 kernel: e1000e 0000:00:19.0: eth2: Detected Hardware Unit Hang:
Feb 15 17:38:23 char1 kernel:  TDH                  <f>
Feb 15 17:38:23 char1 kernel:  TDT                  <22>
Feb 15 17:38:23 char1 kernel:  next_to_use          <22>
Feb 15 17:38:23 char1 kernel:  next_to_clean        <d>
Feb 15 17:38:23 char1 kernel: buffer_info[next_to_clean]:
Feb 15 17:38:23 char1 kernel:  time_stamp           <10001bb67>
Feb 15 17:38:23 char1 kernel:  next_to_watch        <f>
Feb 15 17:38:23 char1 kernel:  jiffies              <10001c139>
Feb 15 17:38:23 char1 kernel:  next_to_watch.status <0>
Feb 15 17:38:23 char1 kernel: MAC Status             <80243>
Feb 15 17:38:23 char1 kernel: PHY Status             <792d>
Feb 15 17:38:23 char1 kernel: PHY 1000BASE-T Status  <0>
Feb 15 17:38:23 char1 kernel: PHY Extended Status    <3000>
Feb 15 17:38:23 char1 kernel: PCI Status             <10>
Feb 15 17:38:25 char1 kernel: e1000e 0000:00:19.0: eth2: Detected Hardware Unit Hang:
Feb 15 17:38:25 char1 kernel:  TDH                  <f>
Feb 15 17:38:25 char1 kernel:  TDT                  <22>
Feb 15 17:38:25 char1 kernel:  next_to_use          <22>
Feb 15 17:38:25 char1 kernel:  next_to_clean        <d>
Feb 15 17:38:25 char1 kernel: buffer_info[next_to_clean]:
Feb 15 17:38:25 char1 kernel:  time_stamp           <10001bb67>
Feb 15 17:38:25 char1 kernel:  next_to_watch        <f>
Feb 15 17:38:25 char1 kernel:  jiffies              <10001c201>
Feb 15 17:38:25 char1 kernel:  next_to_watch.status <0>
Feb 15 17:38:25 char1 kernel: MAC Status             <80243>
Feb 15 17:38:25 char1 kernel: PHY Status             <792d>
Feb 15 17:38:25 char1 kernel: PHY 1000BASE-T Status  <0>
Feb 15 17:38:25 char1 kernel: PHY Extended Status    <3000>
Feb 15 17:38:25 char1 kernel: PCI Status             <10>
Feb 15 17:38:27 char1 kernel: e1000e 0000:00:19.0: eth2: Detected Hardware Unit Hang:
Feb 15 17:38:27 char1 kernel:  TDH                  <f>
Feb 15 17:38:27 char1 kernel:  TDT                  <22>
Feb 15 17:38:27 char1 kernel:  next_to_use          <22>
Feb 15 17:38:27 char1 kernel:  next_to_clean        <d>
Feb 15 17:38:27 char1 kernel: buffer_info[next_to_clean]:
Feb 15 17:38:27 char1 kernel:  time_stamp           <10001bb67>
Feb 15 17:38:27 char1 kernel:  next_to_watch        <f>
Feb 15 17:38:27 char1 kernel:  jiffies              <10001c2c9>
Feb 15 17:38:27 char1 kernel:  next_to_watch.status <0>
Feb 15 17:38:27 char1 kernel: MAC Status             <80243>
Feb 15 17:38:27 char1 kernel: PHY Status             <792d>
Feb 15 17:38:27 char1 kernel: PHY 1000BASE-T Status  <0>
Feb 15 17:38:27 char1 kernel: PHY Extended Status    <3000>
Feb 15 17:38:27 char1 kernel: PCI Status             <10>
Feb 15 17:38:28 char1 kernel: ------------[ cut here ]------------
Feb 15 17:38:28 char1 kernel: WARNING: at net/sched/sch_generic.c:255 dev_watchdog+0x239/0x250()
Feb 15 17:38:28 char1 kernel: Hardware name: OptiPlex 755                 
Feb 15 17:38:28 char1 kernel: NETDEV WATCHDOG: eth2 (e1000e): transmit queue 0 timed out
Feb 15 17:38:28 char1 kernel: Modules linked in: iptable_nat nf_nat_ipv4 xt_LOG xt_limit xt_pkttype xt_tcpudp xt_state xt_iprange xt_multiport iptable_filter ip_tables x_tables nf_nat_tftp nf_nat_ftp nf_nat nf_conntrack_tftp nf_conntrack_ftp nf_conntrack_ipv4 nf_defrag_ipv4 nf_conntrack e1000e e1000 lpc_ich coretemp hwmon mfd_core ahci libahci
Feb 15 17:38:28 char1 kernel: Pid: 0, comm: swapper/1 Not tainted 3.6.0-2.fc16.x86_64 #1
Feb 15 17:38:28 char1 kernel: Call Trace:
Feb 15 17:38:28 char1 kernel: <IRQ>  [<ffffffff8128c300>] ? dev_watchdog+0x170/0x250
Feb 15 17:38:28 char1 kernel: [<ffffffff8102ac6b>] ? warn_slowpath_common+0x7b/0xc0
Feb 15 17:38:28 char1 kernel: [<ffffffff8102ad65>] ? warn_slowpath_fmt+0x45/0x50
Feb 15 17:38:28 char1 kernel: [<ffffffff8128c3c9>] ? dev_watchdog+0x239/0x250
Feb 15 17:38:28 char1 kernel: [<ffffffff81036bb6>] ? run_timer_softirq+0x106/0x230
Feb 15 17:38:28 char1 kernel: [<ffffffff8128c190>] ? pfifo_fast_dequeue+0xe0/0xe0
Feb 15 17:38:28 char1 kernel: [<ffffffff81031af8>] ? __do_softirq+0xa8/0x150
Feb 15 17:38:28 char1 kernel: [<ffffffff812fd3ec>] ? call_softirq+0x1c/0x26
Feb 15 17:38:28 char1 kernel: [<ffffffff81003a1d>] ? do_softirq+0x4d/0x80
Feb 15 17:38:28 char1 kernel: [<ffffffff81031e0e>] ? irq_exit+0x8e/0xb0
Feb 15 17:38:28 char1 kernel: [<ffffffff8101c628>] ? smp_apic_timer_interrupt+0x68/0xa0
Feb 15 17:38:28 char1 kernel: [<ffffffff812fcd07>] ? apic_timer_interrupt+0x67/0x70
Feb 15 17:38:28 char1 kernel: <EOI>  [<ffffffff81061690>] ? __tick_nohz_idle_enter+0x330/0x410
Feb 15 17:38:28 char1 kernel: [<ffffffff810098a1>] ? mwait_idle+0x51/0x70
Feb 15 17:38:28 char1 kernel: [<ffffffff8100a1b6>] ? cpu_idle+0x86/0xd0
Feb 15 17:38:28 char1 kernel: ---[ end trace 50a96207e385a66c ]---
Feb 15 17:38:28 char1 kernel: e1000e 0000:00:19.0: eth2: Reset adapter
Feb 15 17:38:29 char1 kernel: e1000e: eth2 NIC Link is Up 100 Mbps Full Duplex, Flow Control: None

^ permalink raw reply

* [PATCH net-next 2/3] tipc: byte-based overload control on socket receive queue
From: Paul Gortmaker @ 2013-02-15 22:57 UTC (permalink / raw)
  To: David Miller; +Cc: netdev, Jon Maloy, Ying Xue, Neil Horman, Paul Gortmaker
In-Reply-To: <1360969067-29956-1-git-send-email-paul.gortmaker@windriver.com>

From: Ying Xue <ying.xue@windriver.com>

Change overload control to be purely byte-based, using
sk->sk_rmem_alloc as byte counter, and compare it to a calculated
upper limit for the socket receive queue.

For all connection messages, irrespective of message importance,
the overload limit is set to a constant value (i.e, 67MB). This
limit should normally never be reached because of the lower
limit used by the flow control algorithm, and is there only
as a last resort in case a faulty peer doesn't respect the send
window limit.

For datagram messages, message importance is taken into account
when calculating the overload limit. The calculation is based
on sk->sk_rcvbuf, and is hence configurable via the socket option
SO_RCVBUF.

Cc: Neil Horman <nhorman@tuxdriver.com>
Signed-off-by: Ying Xue <ying.xue@windriver.com>
Signed-off-by: Jon Maloy <jon.maloy@ericsson.com>
Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com>
---
 net/tipc/socket.c | 77 ++++++++++++++++++++++++++++---------------------------
 1 file changed, 39 insertions(+), 38 deletions(-)

diff --git a/net/tipc/socket.c b/net/tipc/socket.c
index f6ceecd..cbe2f6e 100644
--- a/net/tipc/socket.c
+++ b/net/tipc/socket.c
@@ -43,7 +43,8 @@
 #define SS_LISTENING	-1	/* socket is listening */
 #define SS_READY	-2	/* socket is connectionless */
 
-#define OVERLOAD_LIMIT_BASE	10000
+#define CONN_OVERLOAD_LIMIT	((TIPC_FLOW_CONTROL_WIN * 2 + 1) * \
+				SKB_TRUESIZE(TIPC_MAX_USER_MSG_SIZE))
 #define CONN_TIMEOUT_DEFAULT	8000	/* default connect timeout = 8s */
 
 struct tipc_sock {
@@ -202,7 +203,6 @@ static int tipc_create(struct net *net, struct socket *sock, int protocol,
 
 	sock_init_data(sock, sk);
 	sk->sk_backlog_rcv = backlog_rcv;
-	sk->sk_rcvbuf = TIPC_FLOW_CONTROL_WIN * 2 * TIPC_MAX_USER_MSG_SIZE * 2;
 	sk->sk_data_ready = tipc_data_ready;
 	sk->sk_write_space = tipc_write_space;
 	tipc_sk(sk)->p = tp_ptr;
@@ -1142,34 +1142,6 @@ static void tipc_data_ready(struct sock *sk, int len)
 }
 
 /**
- * rx_queue_full - determine if receive queue can accept another message
- * @msg: message to be added to queue
- * @queue_size: current size of queue
- * @base: nominal maximum size of queue
- *
- * Returns 1 if queue is unable to accept message, 0 otherwise
- */
-static int rx_queue_full(struct tipc_msg *msg, u32 queue_size, u32 base)
-{
-	u32 threshold;
-	u32 imp = msg_importance(msg);
-
-	if (imp == TIPC_LOW_IMPORTANCE)
-		threshold = base;
-	else if (imp == TIPC_MEDIUM_IMPORTANCE)
-		threshold = base * 2;
-	else if (imp == TIPC_HIGH_IMPORTANCE)
-		threshold = base * 100;
-	else
-		return 0;
-
-	if (msg_connected(msg))
-		threshold *= 4;
-
-	return queue_size >= threshold;
-}
-
-/**
  * filter_connect - Handle all incoming messages for a connection-based socket
  * @tsock: TIPC socket
  * @msg: message
@@ -1247,6 +1219,36 @@ static u32 filter_connect(struct tipc_sock *tsock, struct sk_buff **buf)
 }
 
 /**
+ * rcvbuf_limit - get proper overload limit of socket receive queue
+ * @sk: socket
+ * @buf: message
+ *
+ * For all connection oriented messages, irrespective of importance,
+ * the default overload value (i.e. 67MB) is set as limit.
+ *
+ * For all connectionless messages, by default new queue limits are
+ * as belows:
+ *
+ * TIPC_LOW_IMPORTANCE       (5MB)
+ * TIPC_MEDIUM_IMPORTANCE    (10MB)
+ * TIPC_HIGH_IMPORTANCE      (20MB)
+ * TIPC_CRITICAL_IMPORTANCE  (40MB)
+ *
+ * Returns overload limit according to corresponding message importance
+ */
+static unsigned int rcvbuf_limit(struct sock *sk, struct sk_buff *buf)
+{
+	struct tipc_msg *msg = buf_msg(buf);
+	unsigned int limit;
+
+	if (msg_connected(msg))
+		limit = CONN_OVERLOAD_LIMIT;
+	else
+		limit = sk->sk_rcvbuf << (msg_importance(msg) + 5);
+	return limit;
+}
+
+/**
  * filter_rcv - validate incoming message
  * @sk: socket
  * @buf: message
@@ -1262,7 +1264,7 @@ static u32 filter_rcv(struct sock *sk, struct sk_buff *buf)
 {
 	struct socket *sock = sk->sk_socket;
 	struct tipc_msg *msg = buf_msg(buf);
-	u32 recv_q_len;
+	unsigned int limit = rcvbuf_limit(sk, buf);
 	u32 res = TIPC_OK;
 
 	/* Reject message if it is wrong sort of message for socket */
@@ -1279,15 +1281,13 @@ static u32 filter_rcv(struct sock *sk, struct sk_buff *buf)
 	}
 
 	/* Reject message if there isn't room to queue it */
-	recv_q_len = skb_queue_len(&sk->sk_receive_queue);
-	if (unlikely(recv_q_len >= (OVERLOAD_LIMIT_BASE / 2))) {
-		if (rx_queue_full(msg, recv_q_len, OVERLOAD_LIMIT_BASE / 2))
-			return TIPC_ERR_OVERLOAD;
-	}
+	if (sk_rmem_alloc_get(sk) + buf->truesize >= limit)
+		return TIPC_ERR_OVERLOAD;
 
-	/* Enqueue message (finally!) */
+	/* Enqueue message */
 	TIPC_SKB_CB(buf)->handle = 0;
 	__skb_queue_tail(&sk->sk_receive_queue, buf);
+	skb_set_owner_r(buf, sk);
 
 	sk->sk_data_ready(sk, 0);
 	return TIPC_OK;
@@ -1336,7 +1336,7 @@ static u32 dispatch(struct tipc_port *tport, struct sk_buff *buf)
 	if (!sock_owned_by_user(sk)) {
 		res = filter_rcv(sk, buf);
 	} else {
-		if (sk_add_backlog(sk, buf, sk->sk_rcvbuf))
+		if (sk_add_backlog(sk, buf, rcvbuf_limit(sk, buf)))
 			res = TIPC_ERR_OVERLOAD;
 		else
 			res = TIPC_OK;
@@ -1570,6 +1570,7 @@ static int accept(struct socket *sock, struct socket *new_sock, int flags)
 	} else {
 		__skb_dequeue(&sk->sk_receive_queue);
 		__skb_queue_head(&new_sk->sk_receive_queue, buf);
+		skb_set_owner_r(buf, new_sk);
 	}
 	release_sock(new_sk);
 
-- 
1.8.1.2

^ permalink raw reply related

* [PATCH net-next 1/3] tipc: eliminate duplicated discard_rx_queue routine
From: Paul Gortmaker @ 2013-02-15 22:57 UTC (permalink / raw)
  To: David Miller; +Cc: netdev, Jon Maloy, Ying Xue, Paul Gortmaker
In-Reply-To: <1360969067-29956-1-git-send-email-paul.gortmaker@windriver.com>

From: Ying Xue <ying.xue@windriver.com>

The tipc function discard_rx_queue() is just a duplicated
implementation of __skb_queue_purge().  Remove the former
and directly invoke __skb_queue_purge().

In doing so, the underscores convey to the code reader, more
information about the current locking state that is assumed.

Signed-off-by: Ying Xue <ying.xue@windriver.com>
Signed-off-by: Jon Maloy <jon.maloy@ericsson.com>
Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com>
---
 net/tipc/socket.c | 17 ++---------------
 1 file changed, 2 insertions(+), 15 deletions(-)

diff --git a/net/tipc/socket.c b/net/tipc/socket.c
index 9b4e483..f6ceecd 100644
--- a/net/tipc/socket.c
+++ b/net/tipc/socket.c
@@ -129,19 +129,6 @@ static void advance_rx_queue(struct sock *sk)
 }
 
 /**
- * discard_rx_queue - discard all buffers in socket receive queue
- *
- * Caller must hold socket lock
- */
-static void discard_rx_queue(struct sock *sk)
-{
-	struct sk_buff *buf;
-
-	while ((buf = __skb_dequeue(&sk->sk_receive_queue)))
-		kfree_skb(buf);
-}
-
-/**
  * reject_rx_queue - reject all buffers in socket receive queue
  *
  * Caller must hold socket lock
@@ -292,7 +279,7 @@ static int release(struct socket *sock)
 	res = tipc_deleteport(tport->ref);
 
 	/* Discard any remaining (connection-based) messages in receive queue */
-	discard_rx_queue(sk);
+	__skb_queue_purge(&sk->sk_receive_queue);
 
 	/* Reject any messages that accumulated in backlog queue */
 	sock->state = SS_DISCONNECTING;
@@ -1637,7 +1624,7 @@ restart:
 	case SS_DISCONNECTING:
 
 		/* Discard any unreceived messages */
-		discard_rx_queue(sk);
+		__skb_queue_purge(&sk->sk_receive_queue);
 
 		/* Wake up anyone sleeping in poll */
 		sk->sk_state_change(sk);
-- 
1.8.1.2

^ permalink raw reply related

* [PATCH net-next 0/3] tipc: two cleanups, plus overload respin
From: Paul Gortmaker @ 2013-02-15 22:57 UTC (permalink / raw)
  To: David Miller; +Cc: netdev, Jon Maloy, Ying Xue, Paul Gortmaker, Neil Horman

Two relatively small cleanup patches here, plus a reimplementation
of the patch Neil had questions about[1] in the last development
cycle.

Tested on today's net-next, between 32 and 64 bit x86 machines using
the server/client in tipc-utils, as usual.

[1] http://patchwork.ozlabs.org/patch/204507/

Thanks,
Paul.

Cc: Neil Horman <nhorman@tuxdriver.com>
---

The following changes since commit d887199dc28c46788b155b234274d5ff41afed8e:

  tg3: Update version to 3.130 (2013-02-15 14:02:59 -0500)

are available in the git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/paulg/linux.git tipc_net-next

for you to fetch changes up to 97f8b87e9108485a0b7070645662253561304458:

  tipc: remove redundant checking for the number of iovecs in a send request (2013-02-15 17:03:32 -0500)

----------------------------------------------------------------
Ying Xue (3):
      tipc: eliminate duplicated discard_rx_queue routine
      tipc: byte-based overload control on socket receive queue
      tipc: remove redundant checking for the number of iovecs in a send request

 net/tipc/socket.c | 103 +++++++++++++++++++++++-------------------------------
 1 file changed, 44 insertions(+), 59 deletions(-)

^ permalink raw reply

* [PATCH net-next 3/3] tipc: remove redundant checking for the number of iovecs in a send request
From: Paul Gortmaker @ 2013-02-15 22:57 UTC (permalink / raw)
  To: David Miller; +Cc: netdev, Jon Maloy, Ying Xue, Paul Gortmaker
In-Reply-To: <1360969067-29956-1-git-send-email-paul.gortmaker@windriver.com>

From: Ying Xue <ying.xue@windriver.com>

As the number of iovecs in a send request is already limited within
UIO_MAXIOV(i.e. 1024) in __sys_sendmsg(), it's unnecessary to check it
again in TIPC stack.

Signed-off-by: Ying Xue <ying.xue@windriver.com>
Signed-off-by: Jon Maloy <jon.maloy@ericsson.com>
Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com>
---
 net/tipc/socket.c | 9 +++------
 1 file changed, 3 insertions(+), 6 deletions(-)

diff --git a/net/tipc/socket.c b/net/tipc/socket.c
index cbe2f6e..a9622b6 100644
--- a/net/tipc/socket.c
+++ b/net/tipc/socket.c
@@ -503,8 +503,7 @@ static int send_msg(struct kiocb *iocb, struct socket *sock,
 	if (unlikely((m->msg_namelen < sizeof(*dest)) ||
 		     (dest->family != AF_TIPC)))
 		return -EINVAL;
-	if ((total_len > TIPC_MAX_USER_MSG_SIZE) ||
-	    (m->msg_iovlen > (unsigned int)INT_MAX))
+	if (total_len > TIPC_MAX_USER_MSG_SIZE)
 		return -EMSGSIZE;
 
 	if (iocb)
@@ -612,8 +611,7 @@ static int send_packet(struct kiocb *iocb, struct socket *sock,
 	if (unlikely(dest))
 		return send_msg(iocb, sock, m, total_len);
 
-	if ((total_len > TIPC_MAX_USER_MSG_SIZE) ||
-	    (m->msg_iovlen > (unsigned int)INT_MAX))
+	if (total_len > TIPC_MAX_USER_MSG_SIZE)
 		return -EMSGSIZE;
 
 	if (iocb)
@@ -698,8 +696,7 @@ static int send_stream(struct kiocb *iocb, struct socket *sock,
 		goto exit;
 	}
 
-	if ((total_len > (unsigned int)INT_MAX) ||
-	    (m->msg_iovlen > (unsigned int)INT_MAX)) {
+	if (total_len > (unsigned int)INT_MAX) {
 		res = -EMSGSIZE;
 		goto exit;
 	}
-- 
1.8.1.2

^ permalink raw reply related

* Re: Re: kernel 3.7.6, l2tp, qdisc_tx circular locking
From: Denys Fedoryshchenko @ 2013-02-15 22:54 UTC (permalink / raw)
  To: Eric Dumazet, netdev

Sorry accidentaly deleted my emails, i will try in next 2 days to 
update server with l2tp, and will test everything there, if i can 
reproduce bug.

>diff --git a/net/l2tp/l2tp_core.c b/net/l2tp/l2tp_core.c
>index dcfd64e..7baf88f 100644
>--- a/net/l2tp/l2tp_core.c
>+++ b/net/l2tp/l2tp_core.c
>@@ -1251,8 +1251,11 @@ int l2tp_xmit_skb(struct l2tp_session *session, 
> struct sk_buff *skb, int hdr_len
> 	}
>
> 	l2tp_skb_set_owner_w(skb, sk);
>+	bh_unlock_sock(sk);
>
> 	l2tp_xmit_core(session, skb, fl, data_len);
>+	return ret;
>+
> out_unlock:
> 	bh_unlock_sock(sk);

---
Denys Fedoryshchenko, Network Engineer, Virtual ISP S.A.L.

^ permalink raw reply

* tg3 question: Why use misc_host_ctrl not pci_chip_rev_id here?
From: Joe Perches @ 2013-02-15 22:41 UTC (permalink / raw)
  To: netdev; +Cc: Jeff Garzik, David Miller, Matt Carlson, Michael Chan

This code is in the original 2002 tg3 commit from Jeff.
(line 15764 today)

static int tg3_get_invariants(struct tg3 *tp, const struct pci_device_id *ent)
[]
	if ((pci_state_reg & PCISTATE_CONV_PCI_MODE) == 0 &&
	    !tg3_flag(tp, PCIX_TARGET_HWBUG)) {
(15764)		u32 chiprevid = GET_CHIP_REV_ID(tp->misc_host_ctrl)

		if (chiprevid == CHIPREV_ID_5701_A0 ||
		    chiprevid == CHIPREV_ID_5701_B0 ||
		    chiprevid == CHIPREV_ID_5701_B2 ||
		    chiprevid == CHIPREV_ID_5701_B5) {

This is the only test of GET_CHIP_REV_ID.

Shouldn't that GET_CHIP_REV_ID(tp->misc_host_ctrl)
and the tests below it be converted to tests like

	tp->pci_chip_rev_id == CHIPREV_ID_5701_A0

to be similar to all the pci_chip_rev_id tests that
the code in the same function uses?

It seems to me through a shallow reading that it's
the same value as tg3_detect_asic_rev() sets it.

^ permalink raw reply

* Re: [RFC PATCH 0/6] udp: add encapsulation socket destroy hook
From: David Miller @ 2013-02-15 21:02 UTC (permalink / raw)
  To: tparkin; +Cc: netdev, jchapman, celston
In-Reply-To: <1360923919-7203-1-git-send-email-tparkin@katalix.com>

From: Tom Parkin <tparkin@katalix.com>
Date: Fri, 15 Feb 2013 10:25:13 +0000

> While working on an issue in l2tp relating to tunnel cleanup I discovered a
> problem which I think may require a new hook in udp core to resolve.  The l2tp
> code uses encapsulated udp sockets, and it needs to know when a socket is
> being closed in order to clean up.  Since sessions hold a reference to the
> tunnel socket, hooking sk_destruct isn't sufficient: any tunnel with sessions
> running in it will be pinned open by the sessions.
> 
> To resolve this, the first patch in this series adds a .destroy hook to udp, 
> while the following patches show how I'd use this feature in l2tp.  Essentially 
> the .destroy callback is used to close the sessions in the tunnel, thereby 
> dropping the socket references.
> 
> Does this seem like a reasonable approach?  I'm reluctant to modify udp, but
> I've not managed to discover a safe alternative...

For now this is fine by me.

If we commonly start to encapsulate in other datagram protocols we'll
need to facilitate this more generically, perhaps by having something
that hooks in near the sk_prot->destroy() in sk_release_common().

^ permalink raw reply

* Re: [PATCH net] tipc: fix missing spinlock init in broadcast code
From: David Miller @ 2013-02-15 20:41 UTC (permalink / raw)
  To: paul.gortmaker; +Cc: netdev, erik.hugne
In-Reply-To: <1360889013-4394-1-git-send-email-paul.gortmaker@windriver.com>

From: Paul Gortmaker <paul.gortmaker@windriver.com>
Date: Thu, 14 Feb 2013 19:43:33 -0500

> From: Erik Hugne <erik.hugne@ericsson.com>
> 
> After commit 3c294cb3 "tipc: remove the bearer congestion mechanism",
> we try to grab the broadcast bearer lock when sending multicast
> messages over the broadcast link. This will cause an oops because
> the lock is never initialized. This is an old bug, but the lock
> was never actually used before commit 3c294cb3, so that why it was
> not visible until now.  The oops will look something like:
> 
> 	BUG: spinlock bad magic on CPU#2, daemon/147
> 	lock: bcast_bearer+0x48/0xffffffffffffd19a [tipc],
> 	.magic: 00000000, .owner: <none>/-1, .owner_cpu: 0
> 	Pid: 147, comm: daemon Not tainted 3.8.0-rc3+ #206
> 	Call Trace:
> 	spin_dump+0x8a/0x8f
> 	spin_bug+0x21/0x26
> 	do_raw_spin_lock+0x114/0x150
> 	_raw_spin_lock_bh+0x19/0x20
> 	tipc_bearer_blocked+0x1f/0x40 [tipc]
> 	tipc_link_send_buf+0x82/0x280 [tipc]
> 	? __alloc_skb+0x9f/0x2b0
> 	tipc_bclink_send_msg+0x77/0xa0 [tipc]
> 	tipc_multicast+0x11b/0x1b0 [tipc]
> 	send_msg+0x225/0x530 [tipc]
> 	sock_sendmsg+0xca/0xe0
> 
> The above can be triggered by running the multicast demo program.
> 
> Signed-off-by: Erik Hugne <erik.hugne@ericsson.com>
> Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com>

Applied, thanks.

^ permalink raw reply

* Re: [PATCH net-next] net: use skb_reset_mac_len() in dev_gro_receive()
From: David Miller @ 2013-02-15 20:37 UTC (permalink / raw)
  To: eric.dumazet; +Cc: netdev
In-Reply-To: <1360899108.6884.77.camel@edumazet-glaptop>

From: Eric Dumazet <eric.dumazet@gmail.com>
Date: Thu, 14 Feb 2013 19:31:48 -0800

> From: Eric Dumazet <edumazet@google.com>
> 
> We no longer need to use mac_len, lets cleanup things.
> 
> Signed-off-by: Eric Dumazet <edumazet@google.com>

Applied.

^ permalink raw reply


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