Netdev List
 help / color / mirror / Atom feed
* Re: [PATCH net-next] drivers: net: cpsw: make cpsw_ale.c a module to allow re-use on Keystone
From: Tony Lindgren @ 2015-02-02 16:40 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: Murali Karicheri, w-kwok2, davem, mugunthanvnm, prabhakar.csengg,
	grygorii.strashko, lokeshvutla, mpa, lsorense, netdev,
	linux-kernel
In-Reply-To: <1802322.NDR3d5ZRSA@wuerfel>

* Arnd Bergmann <arnd@arndb.de> [150129 15:51]:
> On Thursday 29 January 2015 18:15:51 Murali Karicheri wrote:
> > NetCP on Keystone has cpsw ale function similar to other TI SoCs
> > and this driver is re-used. To allow both ti cpsw and keystone netcp
> > to re-use the driver, convert the cpsw ale to a module and configure
> > it through Kconfig option CONFIG_TI_CPSW_ALE. Currently it is statically
> > linked to both TI CPSW and NetCP and this causes issues when the above
> > drivers are built as dynamic modules. This patch addresses this issue
> > 
> > While at it, fix the Makefile and code to build both netcp_core and
> > netcp_ethss as dynamic modules. This is needed to support arm allmodconfig.
> > This also requires exporting of API calls provided by netcp_core so that
> > both the above can be dynamic modules.
> > 
> > Signed-off-by: Murali Karicheri <m-karicheri2@ti.com>
> > ---
> >  drivers/net/ethernet/ti/Kconfig       |   19 +++++++++++++++++--
> >  drivers/net/ethernet/ti/Makefile      |    8 +++++---
> >  drivers/net/ethernet/ti/cpsw_ale.c    |   26 ++++++++++++++++++++++++--
> >  drivers/net/ethernet/ti/netcp_core.c  |    8 ++++++++
> >  drivers/net/ethernet/ti/netcp_ethss.c |    5 +++++
> >  5 files changed, 59 insertions(+), 7 deletions(-)
> 
> I was hoping there would be a way without exporting all those symbols, but
> I also couldn't come up with a better solution. I'm putting this into the
> randconfig build test for now, but I'm guessing it's fine.

Probably the best way in the long run is to add a single exported
function to cpsw-common.c I just added for the MAC address function.

Then all the cpsw like drivers can register with that instead of
having tons of custom exported functions.

But before doing that, we should have a clear idea what all can
be shared. Murali, maybe you can take a look at that?

Regards,

Tony

^ permalink raw reply

* Re: [PATCH 0/3] crypto: algif - change algif_skcipher to be asynchronous
From: Stephan Mueller @ 2015-02-02 16:40 UTC (permalink / raw)
  To: Tadeusz Struk
  Cc: herbert, linux-crypto, netdev, davem, qat-linux, linux-kernel
In-Reply-To: <54CF91A6.2020100@intel.com>

Am Montag, 2. Februar 2015, 07:03:02 schrieb Tadeusz Struk:

Hi Tadeusz,

>On 02/01/2015 10:31 AM, Stephan Mueller wrote:
>> Hi Tadeusz,
>> 
>>> > The way the algif_skcipher works currently is that on
>>> > sendmsg/sendpage it builds an sgl for the input data and then on
>>> > read/recvmsg it sends the job for encryption putting the user to
>>> > sleep till the data is processed. This way it can only handle one
>>> > job at a given time.
>>> > To be able to fuly utilize the potential of existing crypto
>>> > hardware
>>> > accelerators it is required to submit multiple jobs in
>>> > asynchronously.
>>> > First patch enables asynchronous read and write on socket.
>>> > Second patch enables af_alg sgl to be linked.
>>> > Third patch implement asynch read for skcipher.
>> 
>> Do you have a code fragment on how to test that patch? I would like
>> to see whether I can test that with my libkcapi.
>
>Hi Stephan,
>This is what I'm using.

Thanks for the listing.

Are you aware of the speed tester that I added to libkcapi? See [1] 
subdir speed-test/

If you want to play with it, all you need to do is to add your 
init/encryption/fini code into cryptoperf-skcipher.c.

The key is that cp_ablkcipher_enc_test/cp_ablkcipher_dec_test performs 
only the encryption/decryption operation (setkey, etc is done in the 
init call). The speed measuring is done only over that function.

[1] http://www.chronox.de/libkcapi.html

Ciao
Stephan

^ permalink raw reply

* Re: [PATCH net-next 2/8] cxgb4: Added support in debugfs to display tp_la stats
From: Or Gerlitz @ 2015-02-02 16:34 UTC (permalink / raw)
  To: Hariprasad Shenai
  Cc: Linux Netdev List, David Miller, leedom, anish, nirranjan,
	praveenm
In-Reply-To: <1422888789-12016-3-git-send-email-hariprasad@chelsio.com>

On Mon, Feb 2, 2015 at 4:53 PM, Hariprasad Shenai
<hariprasad@chelsio.com> wrote:

same two comments as for patch #7

> Signed-off-by: Hariprasad Shenai <hariprasad@chelsio.com>

^ permalink raw reply

* Re: [PATCH net-next 7/8] cxgb4: Added support in debugfs to display tp_err_stats
From: Or Gerlitz @ 2015-02-02 16:32 UTC (permalink / raw)
  To: Hariprasad Shenai
  Cc: Linux Netdev List, David Miller, leedom, anish, nirranjan,
	praveenm
In-Reply-To: <1422888789-12016-8-git-send-email-hariprasad@chelsio.com>

On Mon, Feb 2, 2015 at 4:53 PM, Hariprasad Shenai
<hariprasad@chelsio.com> wrote:

> SNIP - empty change log... please try to avoid such commits

Anything wrong with retrieving these with ethtool statistics?

^ permalink raw reply

* Re: [PATCH net-next 0/3] openvswitch: Add STT support.
From: Tom Herbert @ 2015-02-02 16:23 UTC (permalink / raw)
  To: Jesse Gross; +Cc: Pravin Shelar, David Miller, Linux Netdev List
In-Reply-To: <CAEP_g=-3GXJfawPb4jevkZhqmzTttsO1Rv_2J6GwpG=PR_a-0g@mail.gmail.com>

> I would recommend you take a look at the draft if you haven't already:
> http://tools.ietf.org/html/draft-davie-stt-06
>
> It is currently in the final stages of the RFC publication process.

Sorry, but this statement is completely wrong and misleading.
According to datatracker this draft has been expired since October,
there's been no discussion on it in IETF, and this has not gone to
IESG. You cannot say this is an IETF standard nor that it is about to
be published as one.  See
https://datatracker.ietf.org/doc/draft-davie-stt/ and please read the
Internet Standards process in RFC2026.

I suggest that you update the draft and post it on both nvo3 and tsvwg
so there can be some real discussion on the implications of
repurposing an IP protocol number and breaking TCP protocol standards.

Tom

^ permalink raw reply

* Re: [PATCH net-next 0/3] openvswitch: Add STT support.
From: Tom Herbert @ 2015-02-02 16:15 UTC (permalink / raw)
  To: Jesse Gross; +Cc: Pravin B Shelar, David Miller, Linux Netdev List
In-Reply-To: <CAEP_g=-Yn849TmrN5xFLJVxuux0fBuYGFSM7K-psg=pdxgPR9w@mail.gmail.com>

Here is my data running STT and comparing against VXLAN, GUE, and
native (no encapsulation). This is using bnx2x.

TCP_STREAM IPv4 1 connection
  STT
    2.33% TX CPU utilization
    3.63% RX CPU utilization
    8790 Mbps
  GRE/GUE (RCO, GSO, GRO)
    5.55% TX CPU utilization
    6.67% RX CPU utilization
    9106 Mbps
  VXLAN (RCO, GSO, GRO)
    5.07% TX CPU utilization
    5.95% RX CPU utilization
    9061 Mbps
  Native (no ecapsulation)
    2.48% TX CPU utilization
    3.96% RX CPU utilization
    9411 Mbps

TCP_STREAM IPv4 200 connections
  STT
    8.36% TX CPU utilization
    9.29% RX CPU utilization
    9389 Mbps
  GUE/GRE (RCO, GSO, GRO)
    9.98% TX CPU utilization
    13.69% RX CPU utilization
    9132 Mbps
  VXLAN (RCO, GSO, GRO)
    11.79% TX CPU utilization
    13.88% RX CPU utilization
    9093 Mbps
  Native (no ecapsulation)
    6.05% TX CPU utilization
    7.27% RX CPU utilization
    9378 Mbps

TCP_RR IPv4 200 connections
  STT
    41.91% CPU utilization
    345/406/594 90/95/99% latencies
    562560 tps
  GUE/GRE (RCO, GSO, GRO)
    93.03% CPU utilization
    160/255/467 90/95/99% latencies
    1.1401e+06 tps
  VXLAN (RCO, GSO, GRO)
    93.73% CPU utilization
    157/249/448 90/95/99% latencies
    1.15655e+06 tps
  Native (no ecapsulation)
    87.46% CPU utilization
    120/178/292 90/95/99% latencies
    1.51747e+06 tps

^ permalink raw reply

* Re: [PATCH net 0/2] netns: audit netdevice creation with IFLA_NET_NS_[PID|FD]
From: Nicolas Dichtel @ 2015-02-02 15:58 UTC (permalink / raw)
  To: Arvid Brodin, netdev; +Cc: davem, dmitry.tarnyagin, alex.aring, linux-wpan
In-Reply-To: <54CBE2EF.7050003@alten.se>

Le 30/01/2015 21:00, Arvid Brodin a écrit :
> On 2015-01-26 22:28, Nicolas Dichtel wrote:
> *snip*
>> - HSR subsystem uses src_net to parse IFLA_HSR_SLAVE[1|2], but the netdevice has
>>    the flag NETIF_F_NETNS_LOCAL, so the question is: does this netdevice really
>>    supports x-netns? If not, the newlink handler should use the dest_net instead
>>    of src_net, I can provide the patch.
> *snip*
>
> As the author of the HSR driver, I'd like to answer this question, but unfortunately
> I don't know what x-netns is. Neither Google nor Documentation/ has been particularly
> helpful.
>
> Care to elaborate? (Maybe this is a moot point now that the patch has been accepted,
> but I'd still like to understand, if you have the time to explain.)
Basically, network namespaces (netns) allow you to run several independant
instances of the linux networking stack.
Network interfaces are bound to one netns. By default, only one netns exists
(named init_net) when you boot your kernel.
For logical interfaces, they are usually bound to a link layer. For example, if
I understand well, hsr network interfaces receive and send their packets from
two physical interfaces (IFLA_HSR_SLAVE[1|2]).
Now imagine that these slaves are in a netns foo and the logical hsr interfaces
in netns bar. You have a x-netns interface, the link layer part of the interface
is not in the same netns than the upper part. A user will see the hsr interface
in netns bar, but this interface will send a receive packet in netns foo.
Usually, to configure an interface like this, you create it in netns foo and you
move it later to netns bar (ip link set hsr1 netns bar). The flag
NETIF_F_NETNS_LOCAL forbids this operation, you cannot move it to another netns.
But you still can create a x-netns interface:
ip netns add foo
ip link add hsr1 netns foo type hsr slave1 eth0 slave2 eth1
ip netns exec foo ip link ls hsr1

=> eth0 and eth1 are took from the current netns (because in the code, src_net
is the current netns) but hsr1 is built in netns foo.

Now, the question is: does HSR really work across netns? Why is the flag
NETIF_F_NETNS_LOCAL set?
dev_forward_skb() may be used to forward an skbuff to another netns.

Note, that I got a panic when playing with hsr:
ip link add hsr1 type hsr slave1 eth1 slave2 eth0
ip link del hsr1
=> panic

I dig a bit:
1/ hsr_netdev_notify() supposes that the port will always be available when the
notification is for an hsr interface. It's wrong. For example,
netdev_wait_allrefs() may resend NETDEV_UNREGISTER.
2/ with a patch that ignores the notification when the port is NULL, I got a
refcnt problem:
[  327.372099] unregister_netdevice: waiting for hsr1 to become free. Usage 
count = -1

Regards,
Nicolas

^ permalink raw reply

* RE: [PATCH net-next 0/4] enic: improve rq buff allocation and reduce dma mapping
From: David Laight @ 2015-02-02 15:56 UTC (permalink / raw)
  To: 'Govindarajulu Varadarajan', davem@davemloft.net,
	netdev@vger.kernel.org
  Cc: ssujith@cisco.com, benve@cisco.com, edumazet@google.com,
	ben@decadent.org.uk
In-Reply-To: <1422707290-939-1-git-send-email-_govind@gmx.com>

From: Govindarajulu Varadarajan
> The following series tries to address these two problem in rq buff allocation.
> 
> * Memory wastage because of large 9k allocation using kmalloc:
>   For 9k mtu buffer, netdev_alloc_skb_ip_align internally calls kmalloc for
>   size > 4096. In case of 9k buff, kmalloc returns pages for order 2, 16k.
>   And we use only ~9k of 16k. 7k memory wasted. Using the frag the frag
>   allocator in patch 1/2, we can allocate three 9k buffs in a 32k page size.
>   Typical enic configuration has 8 rq, and desc ring of size 4096.
>   Thats 8 * 4096 * (16*1024) = 512 MB. Using this frag allocator:
>   8 * 4096 * (32*1024/3) = 341 MB. Thats 171 MB of memory save.
> 
> * frequent dma_map() calls:
>   we call dma_map() for every buff we allocate. When iommu is on, This is very
>   cpu time consuming. From my testing, most of the cpu cycles are wasted
>   spinning on spin_lock_irqsave(&iovad->iova_rbtree_lock, flags) in
>   intel_map_page() .. -> ..__alloc_and_insert_iova_range()
> 
>   With this patch, we call dma_map() once for 32k page. i.e once for every three
>   9k desc, and once every twenty 1500 bytes desc.

Two questions:
1) How are you handling the skb's true_size ?
2) Memory fragmentation could easily make the allocation of 32k fail.

	David

^ permalink raw reply

* Re: [PATCH v3 3/3] stmmac: pci: add MSI support for Intel Quark X1000
From: Bryan O'Donoghue @ 2015-02-02 15:50 UTC (permalink / raw)
  To: Andy Shevchenko; +Cc: netdev, Kweh, Hock Leong, davem, Ahmad, Josef
In-Reply-To: <1422891987.31903.374.camel@linux.intel.com>

On 02/02/15 15:46, Andy Shevchenko wrote:
> On Mon, 2015-02-02 at 15:17 +0000, Bryan O'Donoghue wrote:
>> Hi guys.
>>
>> Has the issue with PVM masking been addressed ?
>>
>> https://lkml.org/lkml/2014/10/1/221
>>
>> If not then please drop MSIs from this patchset.
>
> I do not see the reason why it should be done on per driver basis.

Agree.

> Care to fix this under arch/x86 then when adding new Quark platform?

Looking into that now.

Hmm - OK -let's aim to get a fix in for the bridge and leave the MSI 
enable in place.

^ permalink raw reply

* Re: [PATCH] tun: orphan an skb on tx
From: David Woodhouse @ 2015-02-02 15:47 UTC (permalink / raw)
  To: Phil Sutter
  Cc: David Miller, mst, herbert, eric.dumazet, jan.kiszka, netdev,
	linux-kernel, qemu-devel
In-Reply-To: <20150202152343.GA15880@orbit.nwl.cc>

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

On Mon, 2015-02-02 at 16:23 +0100, Phil Sutter wrote:
> Since you want to provide connectivity over HTTPS which is not possible
> in kernel space, you are stuck with keeping the tun device. So the
> packet flow in that case is identical to how e.g. OpenVPN does it:
> 
> - tunX holds default route
> - OpenConnect then:
>   - receives packets on /dev/tun
>   - holds TCP socket to VPN concentrator
>   - does encapsulation into TLS
> 
> Speaking of optimisation, the interesting part is the alternative flow
> via IPsec in UDP.

Right. The packet flow you describe is what we already have. Except of
course we already *do* establish the UDP connection (which is DTLS when
we're talking to a Cisco AnyConnect server, and ESP in UDP when we're
talking to Juniper). If we get responses to keepalive packets, we'll
send outbound packets over the UDP connection. If the UDP connectivity
goes AWOL, we'll fall back to sending on TCP. Rekeying of the UDP
connection is handled over the TCP control connection too. Even in the
DTLS case, the master secret and session ID are exchanged over TCP and
the DTLS is actually done as a 'session resume', without the normal DTLS
handshake ever happening.

As you say, I'm stuck with keeping the tun device (or something very
much like it). This *isn't* like vpnc where I can set up an IPSec config
and just let it run.

>  AFAICT, it should be possible to setup an ESP in UDP
> tunnel using XFRM (see ip-xfrm(8) for reference), although I didn't try
> that myself. The funny thing with XFRM is, it applies before the routing
> decision does: If my IPsec policy matches, the packet goes that way no
> matter what the routing table says about the original destination. This
> can be used to override the default route provided via tun0 in the above
> case.

Except it isn't even the default route. We get given a bunch of split
includes or split excludes from the VPN server. We pass them to
vpnc-script or NetworkManager to actually set the routes up, and those
tools may make their own tweaks to what the server requested — denying
the default route and setting up explicit routes, or adding firewall
rules or NAT to incoming/outgoing packets on the tun device.

If it is no longer *just* the single tun device, everything gets really
complicated. Even *before* we talk about changing it on the fly during
normal operation.

> Of course, OpenConnect has to manage all the XFRM/policy stuff on it's
> own, since switching from ESP in UDP back to TLS would mean to tear down
> the XFRM tunnel. OpenConnect would have to setup (a limited) XFRM and
> send test traffic to decide whether to set it up fully (if limited) or
> tear it down (if unlimited) again so traffic arrives at tunX again.

Right. And ideally without CAP_NET_ADMIN.

> In my opinion, this might work. The whole setup is probably about as
> intuitive as the fact that kernel IPsec tunnel mode does not naturally
> provide an own interface. Firewall setup on top of that might become a
> matter of try-and-error. Maybe having a VTI interface and merely moving
> the default route instead of fiddling with policies all the time might
> make things a little easier to comprehend, but surely adds some
> performance overhead.

I think even the latter is sufficiently complex to manage that it's not
worth pursuing. I may throw together my suggested hack using
tun_get_socket() and see how much it makes *me* barf before deciding
whether to show it here for more feedback :)

-- 
dwmw2

[-- Attachment #2: smime.p7s --]
[-- Type: application/x-pkcs7-signature, Size: 5745 bytes --]

^ permalink raw reply

* Re: [PATCH v3 3/3] stmmac: pci: add MSI support for Intel Quark X1000
From: Andy Shevchenko @ 2015-02-02 15:46 UTC (permalink / raw)
  To: Bryan O'Donoghue; +Cc: netdev, Kweh, Hock Leong, davem, Ahmad, Josef
In-Reply-To: <54CF94FF.1050802@nexus-software.ie>

On Mon, 2015-02-02 at 15:17 +0000, Bryan O'Donoghue wrote:
> Hi guys.
> 
> Has the issue with PVM masking been addressed ?
> 
> https://lkml.org/lkml/2014/10/1/221
> 
> If not then please drop MSIs from this patchset.

I do not see the reason why it should be done on per driver basis.
Care to fix this under arch/x86 then when adding new Quark platform?

-- 
Andy Shevchenko <andriy.shevchenko@intel.com>
Intel Finland Oy

^ permalink raw reply

* Re: [PATCH] net: ipv6: Make address flushing on ifdown optional - v2
From: David Ahern @ 2015-02-02 15:33 UTC (permalink / raw)
  To: netdev; +Cc: Hannes Frederic Sowa
In-Reply-To: <1422504065-17445-1-git-send-email-dsahern@gmail.com>

Hi Hannes:

Any comments before I spin a v3 to address Dave's comments?

David

On 1/28/15 9:01 PM, David Ahern wrote:
> Currently, all ipv6 addresses are flushed when the interface is configured
> down, even static address:
>
> [root@f20 ~]# ip -6 addr add dev eth1 2000:11:1:1::1/64
> [root@f20 ~]# ip addr show dev eth1
> 3: eth1: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN group default qlen 1000
>      link/ether 02:04:11:22:33:01 brd ff:ff:ff:ff:ff:ff
>      inet6 2000:11:1:1::1/64 scope global tentative
>         valid_lft forever preferred_lft forever
> [root@f20 ~]# ip link set dev eth1 up
> [root@f20 ~]# ip link set dev eth1 down
> [root@f20 ~]# ip addr show dev eth1
> 3: eth1: <BROADCAST,MULTICAST> mtu 1500 qdisc pfifo_fast state DOWN group default qlen 1000
>      link/ether 02:04:11:22:33:01 brd ff:ff:ff:ff:ff:ff
>
> Add a new sysctl to make this behavior optional. The new setting defaults to
> flush all addresses to maintain backwards compatibility. When the setting is
> reset static addresses are not flushed:
>
> [root@f20 ~]# echo 0 > /proc/sys/net/ipv6/conf/eth1/flush_addr_on_down
> [root@f20 ~]# ip -6 addr add dev eth1 2000:11:1:1::1/64
> [root@f20 ~]# ip addr show dev eth1
> 3: eth1: <BROADCAST,MULTICAST> mtu 1500 qdisc pfifo_fast state DOWN group default qlen 1000
>      link/ether 02:04:11:22:33:01 brd ff:ff:ff:ff:ff:ff
>      inet6 2000:11:1:1::1/64 scope global tentative
>         valid_lft forever preferred_lft forever
> [root@f20 ~]#  ip link set dev eth1 up
> [root@f20 ~]#  ip link set dev eth1 down
> [root@f20 ~]# ip addr show dev eth1
> 3: eth1: <BROADCAST,MULTICAST> mtu 1500 qdisc pfifo_fast state DOWN group default qlen 1000
>      link/ether 02:04:11:22:33:01 brd ff:ff:ff:ff:ff:ff
>      inet6 2000:11:1:1::1/64 scope global
>         valid_lft forever preferred_lft forever
>      inet6 fe80::4:11ff:fe22:3301/64 scope link
>         valid_lft forever preferred_lft forever
>
> v2:
> - only keep static addresses as suggested by Hannes
> - added new managed flag to track configured addresses
> - on ifdown do not remove from configured address from inet6_addr_lst
> - on ifdown reset the TENTATIVE flag and set state to DAD so that DAD is
>    redone when link is brought up again
>
> Suggested-by: Hannes Frederic Sowa <hannes@redhat.com>
> Signed-off-by: David Ahern <dsahern@gmail.com>
> Cc: Hannes Frederic Sowa <hannes@redhat.com>
>
> Signed-off-by: David Ahern <dsahern@gmail.com>
> ---
>   include/linux/ipv6.h      |  1 +
>   include/net/if_inet6.h    |  1 +
>   include/uapi/linux/ipv6.h |  1 +
>   net/ipv6/addrconf.c       | 55 ++++++++++++++++++++++++++++++++++++++---------
>   4 files changed, 48 insertions(+), 10 deletions(-)
>
> diff --git a/include/linux/ipv6.h b/include/linux/ipv6.h
> index 2805062c013f..b91b7c8be023 100644
> --- a/include/linux/ipv6.h
> +++ b/include/linux/ipv6.h
> @@ -53,6 +53,7 @@ struct ipv6_devconf {
>   	__s32           ndisc_notify;
>   	__s32		suppress_frag_ndisc;
>   	__s32		accept_ra_mtu;
> +	__s32		flush_addr_on_down;
>   	void		*sysctl;
>   };
>
> diff --git a/include/net/if_inet6.h b/include/net/if_inet6.h
> index 98e5f9578f86..3b6323111f77 100644
> --- a/include/net/if_inet6.h
> +++ b/include/net/if_inet6.h
> @@ -72,6 +72,7 @@ struct inet6_ifaddr {
>   	int			regen_count;
>
>   	bool			tokenized;
> +	bool			managed;
>
>   	struct rcu_head		rcu;
>   	struct in6_addr		peer_addr;
> diff --git a/include/uapi/linux/ipv6.h b/include/uapi/linux/ipv6.h
> index 437a6a4b125a..ed10d4ba8340 100644
> --- a/include/uapi/linux/ipv6.h
> +++ b/include/uapi/linux/ipv6.h
> @@ -170,6 +170,7 @@ enum {
>   	DEVCONF_ACCEPT_RA_FROM_LOCAL,
>   	DEVCONF_USE_OPTIMISTIC,
>   	DEVCONF_ACCEPT_RA_MTU,
> +	DEVCONF_FLUSH_ON_DOWN,
>   	DEVCONF_MAX
>   };
>
> diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
> index 7dcc065e2160..e0e82aad2116 100644
> --- a/net/ipv6/addrconf.c
> +++ b/net/ipv6/addrconf.c
> @@ -202,6 +202,7 @@ static struct ipv6_devconf ipv6_devconf __read_mostly = {
>   	.accept_dad		= 1,
>   	.suppress_frag_ndisc	= 1,
>   	.accept_ra_mtu		= 1,
> +	.flush_addr_on_down	= 1,
>   };
>
>   static struct ipv6_devconf ipv6_devconf_dflt __read_mostly = {
> @@ -240,6 +241,7 @@ static struct ipv6_devconf ipv6_devconf_dflt __read_mostly = {
>   	.accept_dad		= 1,
>   	.suppress_frag_ndisc	= 1,
>   	.accept_ra_mtu		= 1,
> +	.flush_addr_on_down	= 1,
>   };
>
>   /* Check if a valid qdisc is available */
> @@ -870,6 +872,7 @@ ipv6_add_addr(struct inet6_dev *idev, const struct in6_addr *addr,
>   	ifa->prefered_lft = prefered_lft;
>   	ifa->cstamp = ifa->tstamp = jiffies;
>   	ifa->tokenized = false;
> +	ifa->managed = false;
>
>   	ifa->rt = rt;
>
> @@ -2510,6 +2513,8 @@ static int inet6_addr_add(struct net *net, int ifindex,
>   			    valid_lft, prefered_lft);
>
>   	if (!IS_ERR(ifp)) {
> +		ifp->managed = true;
> +
>   		if (!(ifa_flags & IFA_F_NOPREFIXROUTE)) {
>   			addrconf_prefix_route(&ifp->addr, ifp->prefix_len, dev,
>   					      expires, flags);
> @@ -3032,8 +3037,9 @@ static int addrconf_ifdown(struct net_device *dev, int how)
>   {
>   	struct net *net = dev_net(dev);
>   	struct inet6_dev *idev;
> -	struct inet6_ifaddr *ifa;
> +	struct inet6_ifaddr *ifa, *tmp;
>   	int state, i;
> +	struct list_head del_list;
>
>   	ASSERT_RTNL();
>
> @@ -3067,9 +3073,12 @@ static int addrconf_ifdown(struct net_device *dev, int how)
>   restart:
>   		hlist_for_each_entry_rcu(ifa, h, addr_lst) {
>   			if (ifa->idev == idev) {
> -				hlist_del_init_rcu(&ifa->addr_lst);
>   				addrconf_del_dad_work(ifa);
> -				goto restart;
> +				if (how || idev->cnf.flush_addr_on_down ||
> +				    !ifa->managed) {
> +					hlist_del_init_rcu(&ifa->addr_lst);
> +					goto restart;
> +				}
>   			}
>   		}
>   		spin_unlock_bh(&addrconf_hash_lock);
> @@ -3103,14 +3112,35 @@ restart:
>   		write_lock_bh(&idev->lock);
>   	}
>
> -	while (!list_empty(&idev->addr_list)) {
> -		ifa = list_first_entry(&idev->addr_list,
> +	INIT_LIST_HEAD(&del_list);
> +	list_for_each_entry_safe(ifa, tmp, &idev->addr_list, if_list) {
> +		/*
> +		 * on NETDEV_DOWN events do not flush managed (user configured)
> +		 * addresses unless configured to do so. If the address is not
> +		 * deleted reset flags and state such that DAD is re-done on a
> + 		 * subsequent link up.
> + 		 */
> +		if (!how && !idev->cnf.flush_addr_on_down && ifa->managed) {
> +	    		if (!(ifa->flags & IFA_F_NODAD)) {
> +				ifa->flags |= IFA_F_TENTATIVE;
> +				ifa->state = INET6_IFADDR_STATE_DAD;
> +			}
> +		} else {
> +			list_del(&ifa->if_list);
> +			list_add(&ifa->if_list, &del_list);
> +		}
> +	}
> +
> +	write_unlock_bh(&idev->lock);
> +
> +	while (!list_empty(&del_list)) {
> +		ifa = list_first_entry(&del_list,
>   				       struct inet6_ifaddr, if_list);
> +
>   		addrconf_del_dad_work(ifa);
>
>   		list_del(&ifa->if_list);
>
> -		write_unlock_bh(&idev->lock);
>
>   		spin_lock_bh(&ifa->state_lock);
>   		state = ifa->state;
> @@ -3122,12 +3152,8 @@ restart:
>   			inet6addr_notifier_call_chain(NETDEV_DOWN, ifa);
>   		}
>   		in6_ifa_put(ifa);
> -
> -		write_lock_bh(&idev->lock);
>   	}
>
> -	write_unlock_bh(&idev->lock);
> -
>   	/* Step 5: Discard anycast and multicast list */
>   	if (how) {
>   		ipv6_ac_destroy_dev(idev);
> @@ -4383,6 +4409,7 @@ static inline void ipv6_store_devconf(struct ipv6_devconf *cnf,
>   	array[DEVCONF_SUPPRESS_FRAG_NDISC] = cnf->suppress_frag_ndisc;
>   	array[DEVCONF_ACCEPT_RA_FROM_LOCAL] = cnf->accept_ra_from_local;
>   	array[DEVCONF_ACCEPT_RA_MTU] = cnf->accept_ra_mtu;
> +	array[DEVCONF_FLUSH_ON_DOWN] = cnf->flush_addr_on_down;
>   }
>
>   static inline size_t inet6_ifla6_size(void)
> @@ -5269,6 +5296,14 @@ static struct addrconf_sysctl_table
>   			.proc_handler	= proc_dointvec,
>   		},
>   		{
> +			.procname       = "flush_addr_on_down",
> +			.data           = &ipv6_devconf.flush_addr_on_down,
> +			.maxlen         = sizeof(int),
> +			.mode           = 0644,
> +			.proc_handler   = proc_dointvec,
> +
> +		},
> +		{
>   			/* sentinel */
>   		}
>   	},
>

^ permalink raw reply

* Re: [PATCH] tun: orphan an skb on tx
From: David Woodhouse @ 2015-02-02 15:30 UTC (permalink / raw)
  To: Steffen Klassert
  Cc: David Miller, mst, herbert, eric.dumazet, jan.kiszka, netdev,
	linux-kernel, qemu-devel
In-Reply-To: <20150202082446.GR13046@secunet.com>

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

On Mon, 2015-02-02 at 09:24 +0100, Steffen Klassert wrote:
> 
> Maybe you want to use a virtual tunnel interface (vti) what we have
> already. Everything that is routed through such an interface is
> guaranteed to be either encrypted if a matching xfrm state is present
> or dropped. Same on the rceive side, everything that is received by
> this interface is guaranteed to be IPsec processed. So you can do
> a routing based decision about the IPsec processing.
> 
> While I'm sure it could handle the ESP in UDP encapsulation, I'm not that
> sure about your TCP fallback because this requires a valid xfrm state
> to allow packets to pass. Using the same interface for both is probably
> not possible.

I'm trying to imagine how we could make it work in practice if we end up
exposing two *different* interfaces and having to change the kernel's
routing according to whether we have UDP connectivity at any given
moment in time.

Given how painful it already is to maintain vpnc-script and make it do
the right thing for split-include and split-exclude routing, I'm not
really sure I want to go there.

Even if we could get such a scheme to work, it would probably also
require retaining root privileges to make the changes — and one of the
security benefits over the proprietary VPN clients is that we don't
*need* to run as root. We can either drop privs after running
vpnc-script to do the initial routing setup, or in the NetworkManager
case we *never* run with elevated privileges; we just pass the
IP/routing information back over DBus to NetworkManager.

It occurs to me that for the approach I was thinking about, I wouldn't
even need to touch the internals of the tun driver. It could be a
separate driver which just uses tun_get_socket(). Userspace could hand
it the file descriptors of the tun device and the connected UDP socket,
along with the encryption parameters — and then just stop reading
packets from the tun device for itself.

-- 
dwmw2

[-- Attachment #2: smime.p7s --]
[-- Type: application/x-pkcs7-signature, Size: 5745 bytes --]

^ permalink raw reply

* Re: [PATCH v3 3/3] stmmac: pci: add MSI support for Intel Quark X1000
From: Bryan O'Donoghue @ 2015-02-02 15:17 UTC (permalink / raw)
  To: netdev, Kweh, Hock Leong, Andy Shevchenko, davem, Ahmad, Josef

Hi guys.

Has the issue with PVM masking been addressed ?

https://lkml.org/lkml/2014/10/1/221

If not then please drop MSIs from this patchset.

--
Bryan

^ permalink raw reply

* Re: [Cerowrt-devel] Fwd: Throughput regression with `tcp: refine TSO autosizing`
From: Jim Gettys @ 2015-02-02 15:25 UTC (permalink / raw)
  To: Avery Pennarun
  Cc: Andrew McGregor, David Reed, Jonathan Morton, Dave Taht,
	Matt Mathis, Tim Shepard, dstanley@arubanetworks.com, Kathy Giori,
	Stig Thormodsrud, Derrick Pallas,
	cerowrt-devel@lists.bufferbloat.net, Mahesh Paolini-Subramanya,
	Jesper Dangaard Brouer, linux-wireless, netdev
In-Reply-To: <CAPp0ZBbKu-B3yPf0Et=XByJ1SrnxBgVbRXr9PBe0f6P08w87=Q@mail.gmail.com>

On Sun, Feb 1, 2015 at 11:04 PM, Avery Pennarun <apenwarr@google.com> wrote:
> On Sun, Feb 1, 2015 at 6:34 PM, Andrew McGregor <andrewmcgr@gmail.com> wrote:
>> I missed one item in my list of potential improvements: the most braindead
>> thing 802.11 has to say about rates is that broadcast and multicast packets
>> should be sent at 'the lowest basic rate in the current supported rate set',
>> which is really wasteful.  There are a couple of ways of dealing with this:
>> one, ignore the standard and pick the rate that is most likely to get the
>> frame to as many neighbours as possible (by a scan of the Minstrel tables).
>> Or two, fan it out as unicast, which might well take less airtime (due to
>> aggregation) as well as being much more likely to be delivered, since you
>> get ACKs and retries by doing that.
>
> As far as I can see, the only sensible thing to do with
> multicast/broadcast is some variation of the unicast fanout, unless
> you've got a truly huge number of nodes.  I don't know of any
> protocols (certainly not video streams) that actually work well with
> the kind of packet loss you see at medium/long range with wifi if
> retransmits aren't used.  I've heard that openwrt already has a patch
> included that does this kind of fanout at the bridge layer.

I gather some Windows drivers from some vendors do this unicast fanout
(claim made by one of their engineers in an early homenet meeting).

>
> I've also heard of a new "reliable multicast" in some newer 802.11
> variant, which essentially sends out a single multicast packet and
> expects an ACK from each intended recipient.  Other than adding
> complexity, it seems like the best of both worlds.

So long as it times out in some very small, finite time.  We don't
want a repeat of the infinite retry bugs Dave found in drivers a few
years back...

"Reliable multicast" ultimately is an oxymoron, particularly on a
medium with hundreds/one bandwidth variation.  One remote low
bandwidth station cannot be allowed to drag the entire network to the
basement.
                                     - Jim

^ permalink raw reply

* Re: [PATCH] tun: orphan an skb on tx
From: Phil Sutter @ 2015-02-02 15:23 UTC (permalink / raw)
  To: David Woodhouse
  Cc: David Miller, mst, herbert, eric.dumazet, jan.kiszka, netdev,
	linux-kernel, qemu-devel
In-Reply-To: <1422862030.11044.86.camel@infradead.org>

Hi,

On Mon, Feb 02, 2015 at 07:27:10AM +0000, David Woodhouse wrote:
> On Sun, 2015-02-01 at 21:07 -0800, David Miller wrote:
> > From: David Woodhouse <dwmw2@infradead.org>
> > Date: Sun, 01 Feb 2015 21:29:43 +0000
> > 
> > > I really was looking for some way to push down something like an XFRM
> > > state into the tun device and just say "shove them out here until I tell
> > > you otherwise".
> > 
> > People decided to use TUN and push VPN stuff back into userspace,
> > and there are repercussions for that decision.
> > 
> > I'm not saying this to be mean or whatever, but I was very
> > disappointed when userland IPSEC solutions using TUN started showing
> > up.
> 
> Yeah. That's a valid criticism of vpnc, certainly. I never did
> understand why it reimplemented the IPSec stack.
> 
> For my OpenConnect client it's somewhat more justified though — the
> initial data transport there is over TLS, which the kernel doesn't
> support. And if we *can* establish UDP communication, that's over DTLS
> which the kernel doesn't support either. It's not even the *standard*
> version of DTLS because Cisco are still using a pre-RFC4347 version of
> the protocol. And we also need to probe the UDP connectivity and do
> keepalives and manage the fallback to using the TCP data transport.
> 
> It's not like vpnc where it really is just a case of setting up the ESP
> context and letting it run.
> 
> It's only now I've added Juniper support, which uses ESP-in-UDP for the
> data transport, that I'm doing something that the kernel supports at
> all. And now I'm looking at how to make use of that.
> 
> > We might as well have not have implemented the IPSEC stack at all,
> > because as a result of the userland VPN stuff our IPSEC stack is
> > largely unused except by a very narrow group of users.
> 
> Well, I'd love to make better use of it if I can. I do suspect it makes
> most sense for userspace to continue to manage the probing of UDP
> connectivity, and the fallback to TCP mode — and I suspect it also makes
> sense to continue to use tun for passing packets up to the VPN client
> when it's using the TCP transport.
> 
> So the question would be how we handle redirecting the packet flow to
> the optional UDP transport, when the VPN client determines that it's
> available. For the sake of the user setting up firewall and routing
> rules, I do think it's important that it continues to appear to
> userspace as the *same* device for the entire lifetime of the session,
> regardless of which transport the packets happen to be using at a given
> moment in time. It doesn't *have* to be tun, though. 

Since you want to provide connectivity over HTTPS which is not possible
in kernel space, you are stuck with keeping the tun device. So the
packet flow in that case is identical to how e.g. OpenVPN does it:

- tunX holds default route
- OpenConnect then:
  - receives packets on /dev/tun
  - holds TCP socket to VPN concentrator
  - does encapsulation into TLS

Speaking of optimisation, the interesting part is the alternative flow
via IPsec in UDP. AFAICT, it should be possible to setup an ESP in UDP
tunnel using XFRM (see ip-xfrm(8) for reference), although I didn't try
that myself. The funny thing with XFRM is, it applies before the routing
decision does: If my IPsec policy matches, the packet goes that way no
matter what the routing table says about the original destination. This
can be used to override the default route provided via tun0 in the above
case.

Of course, OpenConnect has to manage all the XFRM/policy stuff on it's
own, since switching from ESP in UDP back to TLS would mean to tear down
the XFRM tunnel. OpenConnect would have to setup (a limited) XFRM and
send test traffic to decide whether to set it up fully (if limited) or
tear it down (if unlimited) again so traffic arrives at tunX again.

In my opinion, this might work. The whole setup is probably about as
intuitive as the fact that kernel IPsec tunnel mode does not naturally
provide an own interface. Firewall setup on top of that might become a
matter of try-and-error. Maybe having a VTI interface and merely moving
the default route instead of fiddling with policies all the time might
make things a little easier to comprehend, but surely adds some
performance overhead.

Cheers, Phil

^ permalink raw reply

* Re: [PATCH v2 0/3] Restore UFO support to virtio_net devices
From: Vlad Yasevich @ 2015-02-02 15:04 UTC (permalink / raw)
  To: David Miller, vyasevich
  Cc: eric.dumazet, mst, netdev, virtualization, hannes, ben
In-Reply-To: <20150201.222834.1543634857152757099.davem@davemloft.net>

On 02/02/2015 01:28 AM, David Miller wrote:
> From: David Miller <davem@davemloft.net>
> Date: Sun, 01 Feb 2015 22:19:35 -0800 (PST)
> 
>> Series applied and queued up for -stable.
> 
> I have to revert, this breaks the build.
> 
> net/built-in.o: In function `udp6_ufo_fragment':
> udp_offload.c:(.text+0x103380): undefined reference to `ipv6_select_ident'
> 

Sorry, Dave.  I am not sure what happened since the patches in my branch build
and boot.

In any case just to make sure, I've rebased on the latest net, rebuilt and reposted
the series.

Thanks
-vlad

^ permalink raw reply

* Re: [PATCH 0/3] crypto: algif - change algif_skcipher to be asynchronous
From: Tadeusz Struk @ 2015-02-02 15:03 UTC (permalink / raw)
  To: Stephan Mueller
  Cc: herbert, linux-crypto, netdev, davem, qat-linux, linux-kernel
In-Reply-To: <1653087.XMGL7JlhQx@tachyon.chronox.de>

On 02/01/2015 10:31 AM, Stephan Mueller wrote:
> Hi Tadeusz,
> 
>> > The way the algif_skcipher works currently is that on sendmsg/sendpage it
>> > builds an sgl for the input data and then on read/recvmsg it sends the job
>> > for encryption putting the user to sleep till the data is processed.
>> > This way it can only handle one job at a given time.
>> > To be able to fuly utilize the potential of existing crypto hardware
>> > accelerators it is required to submit multiple jobs in asynchronously.
>> > First patch enables asynchronous read and write on socket.
>> > Second patch enables af_alg sgl to be linked.
>> > Third patch implement asynch read for skcipher.
> Do you have a code fragment on how to test that patch? I would like to see 
> whether I can test that with my libkcapi.

Hi Stephan,
This is what I'm using.

#include <unistd.h>
#include <fcntl.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <linux/types.h>
#include <linux/aio_abi.h>
#include <sys/syscall.h>
#include <sys/uio.h>

#define SOL_ALG 279

#define SPLICE_F_GIFT	(0x08)	/* pages passed in are a gift */
struct sockaddr_alg {
	__u16	salg_family;
	__u8	salg_type[14];
	__u32	salg_feat;
	__u32	salg_mask;
	__u8	salg_name[64];
};
struct af_alg_iv {
	__u32	ivlen;
	__u8	iv[0];
};
/* Socket options */
#define ALG_SET_KEY			1
#define ALG_SET_IV			2
#define ALG_SET_OP			3
#define ALG_SET_AEAD_ASSOCLEN		4
#define ALG_SET_AEAD_AUTHSIZE		5

/* Operations */
#define ALG_OP_DECRYPT			0
#define ALG_OP_ENCRYPT			1

#define BUFFSIZE (4096)
//#define BUFFSIZE (4096)
#define PKGSIZE (4096)

#define INFLIGTHS 256
#define TO_SEND (1024 * 1024)
//#define OUT_OFFSET 2048;
//#define IN_OFFSET 4064;
#define OUT_OFFSET 0;
#define IN_OFFSET 0;

static char buf[BUFFSIZE] __attribute__((__aligned__(BUFFSIZE)));
static char *buf_out = buf;

static inline int io_setup(unsigned n, aio_context_t *ctx)
{
	return syscall(__NR_io_setup, n, ctx);
}

static inline int io_destroy(aio_context_t ctx)
{
	return syscall(__NR_io_destroy, ctx);
}

static inline int io_read(aio_context_t ctx, long n,  struct iocb **iocb)
{
	return syscall(__NR_io_submit, ctx, n, iocb);
}

static inline int io_getevents(aio_context_t ctx, long min, long max,
			struct io_event *events, struct timespec *timeout)
{
	return syscall(__NR_io_getevents, ctx, min, max, events, timeout);
}

static inline int eventfd(int n)
{
	return syscall(__NR_eventfd, n);
}

static int crypt_kernel(const char *key, char *oiv, int zcp)
{
	int opfd;
	int tfmfd;
	int efd;
	struct timespec timeout;
	fd_set rfds;
        struct timeval tv;
	struct sockaddr_alg sa = {
		.salg_family = AF_ALG,
		.salg_type = "skcipher",
		.salg_name = "cbc(aes)"
	};
	struct msghdr msg = {};
	struct cmsghdr *cmsg;
	char cbuf[CMSG_SPACE(4) + CMSG_SPACE(20)] = {};
	struct aes_iv {
		__u32 len;
		__u8 iv[16];
	} *iv;
	struct iovec iov;
	int pipes[2];
	aio_context_t aio_ctx;
	struct iocb *cb;
	struct iocb cbt[INFLIGTHS];
	struct io_event events[INFLIGTHS];
	unsigned int received = 0;
	int i, r;

	timeout.tv_sec = 0;
	timeout.tv_nsec = 0;
	pipe(pipes);
	memset(cbt, 0, sizeof(cbt));
	efd = eventfd(0);
	tfmfd = socket(AF_ALG, SOCK_SEQPACKET, 0);
	bind(tfmfd, (struct sockaddr *)&sa, sizeof(sa));
	setsockopt(tfmfd, SOL_ALG, ALG_SET_KEY, key, 16);
	opfd = accept(tfmfd, NULL, 0);

	msg.msg_control = cbuf;
	msg.msg_controllen = sizeof(cbuf);

	cmsg = CMSG_FIRSTHDR(&msg);
	cmsg->cmsg_level = SOL_ALG;
	cmsg->cmsg_type = ALG_SET_OP;
	cmsg->cmsg_len = CMSG_LEN(4);
	*(__u32 *)CMSG_DATA(cmsg) = ALG_OP_ENCRYPT;

	cmsg = CMSG_NXTHDR(&msg, cmsg);
	cmsg->cmsg_level = SOL_ALG;
	cmsg->cmsg_type = ALG_SET_IV;
	cmsg->cmsg_len = CMSG_LEN(20);
	iv = (void *)CMSG_DATA(cmsg);
	iv->len = 16;
	memcpy(iv->iv, oiv, 16);

	iov.iov_base = buf + IN_OFFSET;
	iov.iov_len = PKGSIZE;
	msg.msg_flags = MSG_MORE;

	aio_ctx = 0;
	r = io_setup(INFLIGTHS, &aio_ctx);
	if (r < 0) {
		perror("io_setup error");
		return -1;
	}

	for (i = 0; i < TO_SEND; i++) {
		if (zcp) {
			msg.msg_iovlen = 0;
			msg.msg_iov = NULL;

			r = sendmsg(opfd, &msg, 0);
			if (r < 0)
				printf("sendmsg returned Error: %d\n", errno);

			r = vmsplice(pipes[1], &iov, 1, SPLICE_F_GIFT);
			if (r < 0)
				printf("vmsplice returned Error: %d\n", errno);

			r = splice(pipes[0], NULL, opfd, NULL, PKGSIZE, 0);
			if (r < 0)
				printf("splice returned Error: %d\n", errno);
		} else {
			msg.msg_iovlen = 1;
			msg.msg_iov = &iov;
			r = sendmsg(opfd, &msg, PKGSIZE);
			if (r < 0)
				printf("zero cp sendmsg returned Error: %d\n", errno);
		}

		cb = &cbt[i % INFLIGTHS];
		if (cb->aio_fildes) {
			printf("req %d not processed yet???\n", i - INFLIGTHS);
			return -1;
		}
		memset(cb, '\0', sizeof(*cb));
		cb->aio_fildes = opfd;
		cb->aio_lio_opcode = IOCB_CMD_PREAD;
		cb->aio_buf = (unsigned long)buf_out + OUT_OFFSET;
		cb->aio_offset = 0;
		cb->aio_nbytes = PKGSIZE;
		cb->aio_flags = IOCB_FLAG_RESFD;
		cb->aio_resfd = efd;
		r = io_read(aio_ctx, 1, &cb);
		if (r != 1) {
			if (r < 0) {
				printf("io_read Error: %d\n", errno);
				return -1;
			} else {
				printf("Could not sumbit AIO read\n");
				return -1;
			}
		}

		FD_ZERO(&rfds);
		FD_SET(efd, &rfds);
		tv.tv_sec = 0;
		tv.tv_usec = 0;
		r = select(efd + 1, &rfds, NULL, NULL, &tv);

		if (r == -1) {
			printf("Select Error: %d\n", errno);
			return -1;
		} else if (FD_ISSET(efd, &rfds)) {
			r = io_getevents(aio_ctx, 1, INFLIGTHS, events + (received % INFLIGTHS),
					 &timeout);
			if (r > 0) {
				int y;

				for (y = 0; y < r; y++) {
					cb = (void*) events[(received + y) % INFLIGTHS].obj;
					cb->aio_fildes = 0;
					if (events[(received + y) % INFLIGTHS].res)
						printf("req %d failed\n", received + y);
				}
				received += r;
			} else if (r < 0) {
				printf("io_getevents Error: %d\n", errno);
				return -1;
			}
		}

		if (i == 0) {
			msg.msg_control = NULL;
			msg.msg_controllen = 0;
		}
	}

	while (received != TO_SEND) {
		r = io_getevents(aio_ctx, 1, TO_SEND - received,
				events + (received % INFLIGTHS), NULL);
		if (r > 0)
			received += r;
	}
	printf("All done!\n");
	close(efd);
	close(opfd);
	close(tfmfd);
	close(pipes[0]);
	close(pipes[1]);
	io_destroy(aio_ctx);
	return 0;
}

int main(int argc, char **argv)
{
	const char key[16] =
		"\x06\xa9\x21\x40\x36\xb8\xa1\x5b"
		"\x51\x2e\x03\xd5\x34\x12\x00\x06";
	char iv[16] =
		"\x3d\xaf\xba\x42\x9d\x9e\xb4\x30"
		"\xb4\x22\xda\x80\x2c\x9f\xac\x41";

	memcpy(buf, "Single block msg", 16);

	if (argc == 2) {
		printf("zero copy\n");
		crypt_kernel(key, iv, 1);
	}
	else {
		printf("copy\n");
		crypt_kernel(key, iv, 0);
	}
	return 0;
}

^ permalink raw reply

* [PATCH net v3 3/3] Revert "drivers/net: Disable UFO through virtio"
From: Vladislav Yasevich @ 2015-02-02 15:01 UTC (permalink / raw)
  To: netdev; +Cc: virtualization, mst, ben, eric.dumazet, hannes,
	Vladislav Yasevich
In-Reply-To: <1422889269-16007-1-git-send-email-vyasevic@redhat.com>

This reverts commit 3d0ad09412ffe00c9afa201d01effdb6023d09b4.

Now that GSO functionality can correctly track if the fragment
id has been selected and select a fragment id if necessary,
we can re-enable UFO on tap/macvap and virtio devices.

Signed-off-by: Vladislav Yasevich <vyasevic@redhat.com>
---
 drivers/net/macvtap.c    | 13 ++++++++-----
 drivers/net/tun.c        | 19 ++++++++-----------
 drivers/net/virtio_net.c | 24 ++++++++++--------------
 3 files changed, 26 insertions(+), 30 deletions(-)

diff --git a/drivers/net/macvtap.c b/drivers/net/macvtap.c
index 0b86e46..919f4fc 100644
--- a/drivers/net/macvtap.c
+++ b/drivers/net/macvtap.c
@@ -80,7 +80,7 @@ static struct cdev macvtap_cdev;
 static const struct proto_ops macvtap_socket_ops;
 
 #define TUN_OFFLOADS (NETIF_F_HW_CSUM | NETIF_F_TSO_ECN | NETIF_F_TSO | \
-		      NETIF_F_TSO6)
+		      NETIF_F_TSO6 | NETIF_F_UFO)
 #define RX_OFFLOADS (NETIF_F_GRO | NETIF_F_LRO)
 #define TAP_FEATURES (NETIF_F_GSO | NETIF_F_SG)
 
@@ -585,8 +585,6 @@ static int macvtap_skb_from_vnet_hdr(struct macvtap_queue *q,
 			gso_type = SKB_GSO_TCPV6;
 			break;
 		case VIRTIO_NET_HDR_GSO_UDP:
-			pr_warn_once("macvtap: %s: using disabled UFO feature; please fix this program\n",
-				     current->comm);
 			gso_type = SKB_GSO_UDP;
 			break;
 		default:
@@ -633,6 +631,8 @@ static void macvtap_skb_to_vnet_hdr(struct macvtap_queue *q,
 			vnet_hdr->gso_type = VIRTIO_NET_HDR_GSO_TCPV4;
 		else if (sinfo->gso_type & SKB_GSO_TCPV6)
 			vnet_hdr->gso_type = VIRTIO_NET_HDR_GSO_TCPV6;
+		else if (sinfo->gso_type & SKB_GSO_UDP)
+			vnet_hdr->gso_type = VIRTIO_NET_HDR_GSO_UDP;
 		else
 			BUG();
 		if (sinfo->gso_type & SKB_GSO_TCP_ECN)
@@ -962,6 +962,9 @@ static int set_offload(struct macvtap_queue *q, unsigned long arg)
 			if (arg & TUN_F_TSO6)
 				feature_mask |= NETIF_F_TSO6;
 		}
+
+		if (arg & TUN_F_UFO)
+			feature_mask |= NETIF_F_UFO;
 	}
 
 	/* tun/tap driver inverts the usage for TSO offloads, where
@@ -972,7 +975,7 @@ static int set_offload(struct macvtap_queue *q, unsigned long arg)
 	 * When user space turns off TSO, we turn off GSO/LRO so that
 	 * user-space will not receive TSO frames.
 	 */
-	if (feature_mask & (NETIF_F_TSO | NETIF_F_TSO6))
+	if (feature_mask & (NETIF_F_TSO | NETIF_F_TSO6 | NETIF_F_UFO))
 		features |= RX_OFFLOADS;
 	else
 		features &= ~RX_OFFLOADS;
@@ -1087,7 +1090,7 @@ static long macvtap_ioctl(struct file *file, unsigned int cmd,
 	case TUNSETOFFLOAD:
 		/* let the user check for future flags */
 		if (arg & ~(TUN_F_CSUM | TUN_F_TSO4 | TUN_F_TSO6 |
-			    TUN_F_TSO_ECN))
+			    TUN_F_TSO_ECN | TUN_F_UFO))
 			return -EINVAL;
 
 		rtnl_lock();
diff --git a/drivers/net/tun.c b/drivers/net/tun.c
index 5ca42b7..10f9e40 100644
--- a/drivers/net/tun.c
+++ b/drivers/net/tun.c
@@ -186,7 +186,7 @@ struct tun_struct {
 	struct net_device	*dev;
 	netdev_features_t	set_features;
 #define TUN_USER_FEATURES (NETIF_F_HW_CSUM|NETIF_F_TSO_ECN|NETIF_F_TSO| \
-			  NETIF_F_TSO6)
+			  NETIF_F_TSO6|NETIF_F_UFO)
 
 	int			vnet_hdr_sz;
 	int			sndbuf;
@@ -1176,18 +1176,8 @@ static ssize_t tun_get_user(struct tun_struct *tun, struct tun_file *tfile,
 			skb_shinfo(skb)->gso_type = SKB_GSO_TCPV6;
 			break;
 		case VIRTIO_NET_HDR_GSO_UDP:
-		{
-			static bool warned;
-
-			if (!warned) {
-				warned = true;
-				netdev_warn(tun->dev,
-					    "%s: using disabled UFO feature; please fix this program\n",
-					    current->comm);
-			}
 			skb_shinfo(skb)->gso_type = SKB_GSO_UDP;
 			break;
-		}
 		default:
 			tun->dev->stats.rx_frame_errors++;
 			kfree_skb(skb);
@@ -1294,6 +1284,8 @@ static ssize_t tun_put_user(struct tun_struct *tun,
 				gso.gso_type = VIRTIO_NET_HDR_GSO_TCPV4;
 			else if (sinfo->gso_type & SKB_GSO_TCPV6)
 				gso.gso_type = VIRTIO_NET_HDR_GSO_TCPV6;
+			else if (sinfo->gso_type & SKB_GSO_UDP)
+				gso.gso_type = VIRTIO_NET_HDR_GSO_UDP;
 			else {
 				pr_err("unexpected GSO type: "
 				       "0x%x, gso_size %d, hdr_len %d\n",
@@ -1742,6 +1734,11 @@ static int set_offload(struct tun_struct *tun, unsigned long arg)
 				features |= NETIF_F_TSO6;
 			arg &= ~(TUN_F_TSO4|TUN_F_TSO6);
 		}
+
+		if (arg & TUN_F_UFO) {
+			features |= NETIF_F_UFO;
+			arg &= ~TUN_F_UFO;
+		}
 	}
 
 	/* This gives the user a way to test for new features in future by
diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
index 5ca9771..059fdf1 100644
--- a/drivers/net/virtio_net.c
+++ b/drivers/net/virtio_net.c
@@ -490,17 +490,8 @@ static void receive_buf(struct virtnet_info *vi, struct receive_queue *rq,
 			skb_shinfo(skb)->gso_type = SKB_GSO_TCPV4;
 			break;
 		case VIRTIO_NET_HDR_GSO_UDP:
-		{
-			static bool warned;
-
-			if (!warned) {
-				warned = true;
-				netdev_warn(dev,
-					    "host using disabled UFO feature; please fix it\n");
-			}
 			skb_shinfo(skb)->gso_type = SKB_GSO_UDP;
 			break;
-		}
 		case VIRTIO_NET_HDR_GSO_TCPV6:
 			skb_shinfo(skb)->gso_type = SKB_GSO_TCPV6;
 			break;
@@ -888,6 +879,8 @@ static int xmit_skb(struct send_queue *sq, struct sk_buff *skb)
 			hdr->hdr.gso_type = VIRTIO_NET_HDR_GSO_TCPV4;
 		else if (skb_shinfo(skb)->gso_type & SKB_GSO_TCPV6)
 			hdr->hdr.gso_type = VIRTIO_NET_HDR_GSO_TCPV6;
+		else if (skb_shinfo(skb)->gso_type & SKB_GSO_UDP)
+			hdr->hdr.gso_type = VIRTIO_NET_HDR_GSO_UDP;
 		else
 			BUG();
 		if (skb_shinfo(skb)->gso_type & SKB_GSO_TCP_ECN)
@@ -1748,7 +1741,7 @@ static int virtnet_probe(struct virtio_device *vdev)
 			dev->features |= NETIF_F_HW_CSUM|NETIF_F_SG|NETIF_F_FRAGLIST;
 
 		if (virtio_has_feature(vdev, VIRTIO_NET_F_GSO)) {
-			dev->hw_features |= NETIF_F_TSO
+			dev->hw_features |= NETIF_F_TSO | NETIF_F_UFO
 				| NETIF_F_TSO_ECN | NETIF_F_TSO6;
 		}
 		/* Individual feature bits: what can host handle? */
@@ -1758,9 +1751,11 @@ static int virtnet_probe(struct virtio_device *vdev)
 			dev->hw_features |= NETIF_F_TSO6;
 		if (virtio_has_feature(vdev, VIRTIO_NET_F_HOST_ECN))
 			dev->hw_features |= NETIF_F_TSO_ECN;
+		if (virtio_has_feature(vdev, VIRTIO_NET_F_HOST_UFO))
+			dev->hw_features |= NETIF_F_UFO;
 
 		if (gso)
-			dev->features |= dev->hw_features & NETIF_F_ALL_TSO;
+			dev->features |= dev->hw_features & (NETIF_F_ALL_TSO|NETIF_F_UFO);
 		/* (!csum && gso) case will be fixed by register_netdev() */
 	}
 	if (virtio_has_feature(vdev, VIRTIO_NET_F_GUEST_CSUM))
@@ -1798,7 +1793,8 @@ static int virtnet_probe(struct virtio_device *vdev)
 	/* If we can receive ANY GSO packets, we must allocate large ones. */
 	if (virtio_has_feature(vdev, VIRTIO_NET_F_GUEST_TSO4) ||
 	    virtio_has_feature(vdev, VIRTIO_NET_F_GUEST_TSO6) ||
-	    virtio_has_feature(vdev, VIRTIO_NET_F_GUEST_ECN))
+	    virtio_has_feature(vdev, VIRTIO_NET_F_GUEST_ECN) ||
+	    virtio_has_feature(vdev, VIRTIO_NET_F_GUEST_UFO))
 		vi->big_packets = true;
 
 	if (virtio_has_feature(vdev, VIRTIO_NET_F_MRG_RXBUF))
@@ -1994,9 +1990,9 @@ static struct virtio_device_id id_table[] = {
 static unsigned int features[] = {
 	VIRTIO_NET_F_CSUM, VIRTIO_NET_F_GUEST_CSUM,
 	VIRTIO_NET_F_GSO, VIRTIO_NET_F_MAC,
-	VIRTIO_NET_F_HOST_TSO4, VIRTIO_NET_F_HOST_TSO6,
+	VIRTIO_NET_F_HOST_TSO4, VIRTIO_NET_F_HOST_UFO, VIRTIO_NET_F_HOST_TSO6,
 	VIRTIO_NET_F_HOST_ECN, VIRTIO_NET_F_GUEST_TSO4, VIRTIO_NET_F_GUEST_TSO6,
-	VIRTIO_NET_F_GUEST_ECN,
+	VIRTIO_NET_F_GUEST_ECN, VIRTIO_NET_F_GUEST_UFO,
 	VIRTIO_NET_F_MRG_RXBUF, VIRTIO_NET_F_STATUS, VIRTIO_NET_F_CTRL_VQ,
 	VIRTIO_NET_F_CTRL_RX, VIRTIO_NET_F_CTRL_VLAN,
 	VIRTIO_NET_F_GUEST_ANNOUNCE, VIRTIO_NET_F_MQ,
-- 
1.9.3

^ permalink raw reply related

* [PATCH net v3 2/3] Revert "drivers/net, ipv6: Select IPv6 fragment idents for virtio UFO packets"
From: Vladislav Yasevich @ 2015-02-02 15:01 UTC (permalink / raw)
  To: netdev; +Cc: virtualization, mst, ben, eric.dumazet, hannes,
	Vladislav Yasevich
In-Reply-To: <1422889269-16007-1-git-send-email-vyasevic@redhat.com>

This reverts commit 5188cd44c55db3e92cd9e77a40b5baa7ed4340f7.

Now that GSO layer can track if fragment id has been selected
and can allocate one if necessary, we don't need to do this in
tap and macvtap.  This reverts most of the code and only keeps
the new ipv6 fragment id generation function that is still needed.

Fixes: 3d0ad09412ff (drivers/net: Disable UFO through virtio)
Signed-off-by: Vladislav Yasevich <vyasevic@redhat.com>
---
 drivers/net/macvtap.c | 3 ---
 drivers/net/tun.c     | 6 +-----
 2 files changed, 1 insertion(+), 8 deletions(-)

diff --git a/drivers/net/macvtap.c b/drivers/net/macvtap.c
index 7df2217..0b86e46 100644
--- a/drivers/net/macvtap.c
+++ b/drivers/net/macvtap.c
@@ -17,7 +17,6 @@
 #include <linux/fs.h>
 #include <linux/uio.h>
 
-#include <net/ipv6.h>
 #include <net/net_namespace.h>
 #include <net/rtnetlink.h>
 #include <net/sock.h>
@@ -589,8 +588,6 @@ static int macvtap_skb_from_vnet_hdr(struct macvtap_queue *q,
 			pr_warn_once("macvtap: %s: using disabled UFO feature; please fix this program\n",
 				     current->comm);
 			gso_type = SKB_GSO_UDP;
-			if (skb->protocol == htons(ETH_P_IPV6))
-				ipv6_proxy_select_ident(skb);
 			break;
 		default:
 			return -EINVAL;
diff --git a/drivers/net/tun.c b/drivers/net/tun.c
index 8c8dc16..5ca42b7 100644
--- a/drivers/net/tun.c
+++ b/drivers/net/tun.c
@@ -65,7 +65,6 @@
 #include <linux/nsproxy.h>
 #include <linux/virtio_net.h>
 #include <linux/rcupdate.h>
-#include <net/ipv6.h>
 #include <net/net_namespace.h>
 #include <net/netns/generic.h>
 #include <net/rtnetlink.h>
@@ -1167,8 +1166,6 @@ static ssize_t tun_get_user(struct tun_struct *tun, struct tun_file *tfile,
 		break;
 	}
 
-	skb_reset_network_header(skb);
-
 	if (gso.gso_type != VIRTIO_NET_HDR_GSO_NONE) {
 		pr_debug("GSO!\n");
 		switch (gso.gso_type & ~VIRTIO_NET_HDR_GSO_ECN) {
@@ -1189,8 +1186,6 @@ static ssize_t tun_get_user(struct tun_struct *tun, struct tun_file *tfile,
 					    current->comm);
 			}
 			skb_shinfo(skb)->gso_type = SKB_GSO_UDP;
-			if (skb->protocol == htons(ETH_P_IPV6))
-				ipv6_proxy_select_ident(skb);
 			break;
 		}
 		default:
@@ -1221,6 +1216,7 @@ static ssize_t tun_get_user(struct tun_struct *tun, struct tun_file *tfile,
 		skb_shinfo(skb)->tx_flags |= SKBTX_SHARED_FRAG;
 	}
 
+	skb_reset_network_header(skb);
 	skb_probe_transport_header(skb, 0);
 
 	rxhash = skb_get_hash(skb);
-- 
1.9.3

^ permalink raw reply related

* [PATCH net v3 1/3] ipv6: Select fragment id during UFO segmentation if not set.
From: Vladislav Yasevich @ 2015-02-02 15:01 UTC (permalink / raw)
  To: netdev; +Cc: virtualization, mst, ben, eric.dumazet, hannes,
	Vladislav Yasevich
In-Reply-To: <1422889269-16007-1-git-send-email-vyasevic@redhat.com>

If the IPv6 fragment id has not been set and we perform
fragmentation due to UFO, select a new fragment id.
We now consider a fragment id of 0 as unset and if id selection
process returns 0 (after all the pertrubations), we set it to
0x80000000, thus giving us ample space not to create collisions
with the next packet we may have to fragment.

When doing UFO integrity checking, we also select the
fragment id if it has not be set yet.   This is stored into
the skb_shinfo() thus allowing UFO to function correclty.

This patch also removes duplicate fragment id generation code
and moves ipv6_select_ident() into the header as it may be
used during GSO.

Signed-off-by: Vladislav Yasevich <vyasevic@redhat.com>
---
 include/net/ipv6.h     |  3 +++
 net/ipv6/ip6_output.c  | 10 ++++------
 net/ipv6/output_core.c | 28 ++++++++++++++++++++++------
 net/ipv6/udp_offload.c | 10 +++++++++-
 4 files changed, 38 insertions(+), 13 deletions(-)

diff --git a/include/net/ipv6.h b/include/net/ipv6.h
index 4292929..9bf85d3 100644
--- a/include/net/ipv6.h
+++ b/include/net/ipv6.h
@@ -671,6 +671,9 @@ static inline int ipv6_addr_diff(const struct in6_addr *a1, const struct in6_add
 	return __ipv6_addr_diff(a1, a2, sizeof(struct in6_addr));
 }
 
+u32 __ipv6_select_ident(u32 hashrnd, struct in6_addr *dst,
+			struct in6_addr *src);
+void ipv6_select_ident(struct frag_hdr *fhdr, struct rt6_info *rt);
 void ipv6_proxy_select_ident(struct sk_buff *skb);
 
 int ip6_dst_hoplimit(struct dst_entry *dst);
diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c
index ce69a12..5dc91fe 100644
--- a/net/ipv6/ip6_output.c
+++ b/net/ipv6/ip6_output.c
@@ -537,17 +537,15 @@ static void ip6_copy_metadata(struct sk_buff *to, struct sk_buff *from)
 	skb_copy_secmark(to, from);
 }
 
-static void ipv6_select_ident(struct frag_hdr *fhdr, struct rt6_info *rt)
+void ipv6_select_ident(struct frag_hdr *fhdr, struct rt6_info *rt)
 {
 	static u32 ip6_idents_hashrnd __read_mostly;
-	u32 hash, id;
+	u32 id;
 
 	net_get_random_once(&ip6_idents_hashrnd, sizeof(ip6_idents_hashrnd));
 
-	hash = __ipv6_addr_jhash(&rt->rt6i_dst.addr, ip6_idents_hashrnd);
-	hash = __ipv6_addr_jhash(&rt->rt6i_src.addr, hash);
-
-	id = ip_idents_reserve(hash, 1);
+	id = __ipv6_select_ident(ip6_idents_hashrnd, &rt->rt6i_dst.addr,
+				 &rt->rt6i_src.addr);
 	fhdr->identification = htonl(id);
 }
 
diff --git a/net/ipv6/output_core.c b/net/ipv6/output_core.c
index 97f41a3..ceb857d 100644
--- a/net/ipv6/output_core.c
+++ b/net/ipv6/output_core.c
@@ -9,6 +9,24 @@
 #include <net/addrconf.h>
 #include <net/secure_seq.h>
 
+u32 __ipv6_select_ident(u32 hashrnd, struct in6_addr *dst, struct in6_addr *src)
+{
+	u32 hash, id;
+
+	hash = __ipv6_addr_jhash(dst, hashrnd);
+	hash = __ipv6_addr_jhash(src, hash);
+
+	/* Treat id of 0 as unset and if we get 0 back from ip_idents_reserve,
+	 * set the hight order instead thus minimizing possible future
+	 * collisions.      
+	*/
+	id = ip_idents_reserve(hash, 1);
+	if (unlikely(!id))
+		id = 1 << 31;
+
+	return id;
+}
+
 /* This function exists only for tap drivers that must support broken
  * clients requesting UFO without specifying an IPv6 fragment ID.
  *
@@ -22,7 +40,7 @@ void ipv6_proxy_select_ident(struct sk_buff *skb)
 	static u32 ip6_proxy_idents_hashrnd __read_mostly;
 	struct in6_addr buf[2];
 	struct in6_addr *addrs;
-	u32 hash, id;
+	u32 id;
 
 	addrs = skb_header_pointer(skb,
 				   skb_network_offset(skb) +
@@ -34,11 +52,9 @@ void ipv6_proxy_select_ident(struct sk_buff *skb)
 	net_get_random_once(&ip6_proxy_idents_hashrnd,
 			    sizeof(ip6_proxy_idents_hashrnd));
 
-	hash = __ipv6_addr_jhash(&addrs[1], ip6_proxy_idents_hashrnd);
-	hash = __ipv6_addr_jhash(&addrs[0], hash);
-
-	id = ip_idents_reserve(hash, 1);
-	skb_shinfo(skb)->ip6_frag_id = htonl(id);
+	id = __ipv6_select_ident(ip6_proxy_idents_hashrnd,
+				 &addrs[1], &addrs[0]);
+	skb_shinfo(skb)->ip6_frag_id = id;
 }
 EXPORT_SYMBOL_GPL(ipv6_proxy_select_ident);
 
diff --git a/net/ipv6/udp_offload.c b/net/ipv6/udp_offload.c
index b6aa8ed..a562769 100644
--- a/net/ipv6/udp_offload.c
+++ b/net/ipv6/udp_offload.c
@@ -52,6 +52,10 @@ static struct sk_buff *udp6_ufo_fragment(struct sk_buff *skb,
 
 		skb_shinfo(skb)->gso_segs = DIV_ROUND_UP(skb->len, mss);
 
+		/* Set the IPv6 fragment id if not set yet */
+		if (!skb_shinfo(skb)->ip6_frag_id)
+			ipv6_proxy_select_ident(skb);
+
 		segs = NULL;
 		goto out;
 	}
@@ -108,7 +112,11 @@ static struct sk_buff *udp6_ufo_fragment(struct sk_buff *skb,
 		fptr = (struct frag_hdr *)(skb_network_header(skb) + unfrag_ip6hlen);
 		fptr->nexthdr = nexthdr;
 		fptr->reserved = 0;
-		fptr->identification = skb_shinfo(skb)->ip6_frag_id;
+		if (skb_shinfo(skb)->ip6_frag_id)
+			fptr->identification = skb_shinfo(skb)->ip6_frag_id;
+		else
+			ipv6_select_ident(fptr,
+					  (struct rt6_info *)skb_dst(skb));
 
 		/* Fragment the skb. ipv6 header and the remaining fields of the
 		 * fragment header are updated in ipv6_gso_segment()
-- 
1.9.3

^ permalink raw reply related

* [PATCH v3 0/3] Restore UFO support to virtio_net devices
From: Vladislav Yasevich @ 2015-02-02 15:01 UTC (permalink / raw)
  To: netdev; +Cc: eric.dumazet, mst, virtualization, hannes, ben

commit 3d0ad09412ffe00c9afa201d01effdb6023d09b4
Author: Ben Hutchings <ben@decadent.org.uk>
Date:   Thu Oct 30 18:27:12 2014 +0000

    drivers/net: Disable UFO through virtio

Turned off UFO support to virtio-net based devices due to issues
with IPv6 fragment id generation for UFO packets.  The issue
was that IPv6 UFO/GSO implementation expects the fragment id
to be supplied in skb_shinfo().  However, for packets generated
by the VMs, the fragment id is not supplied which causes all
IPv6 fragments to have the id of 0.

The problem is that turning off UFO support on tap/macvtap
as well as virtio devices caused issues with migrations.  
Migrations would fail when moving a vm from a kernel supporting
expecting UFO to work to the newer kernels that disabled UFO.

This series provides a partial solution to address the migration
issue.  The series allows us to track whether skb_shinfo()->ip6_frag_id
has been set by treating value of 0 as unset.
This lets GSO code to generate fragment ids if they are necessary
(ex: packet was generated by VM or packet socket).

Since v2:
  - Rebase and rebuild to make sure everything works.  No changes
    to the patches were done.

Since v1:
  - Removed the skb bit and use value of 0 as tracker.
  - Used Eric's suggestion to set fragment id as 0x80000000 if id
    generation procedure yeilded a 0 result.
  - Consolidated ipv6 id genration code.

Vladislav Yasevich (3):
  ipv6: Select fragment id during UFO segmentation if not set.
  Revert "drivers/net, ipv6: Select IPv6 fragment idents for virtio UFO
    packets"
  Revert "drivers/net: Disable UFO through virtio"

 drivers/net/macvtap.c    | 16 ++++++++--------
 drivers/net/tun.c        | 25 +++++++++----------------
 drivers/net/virtio_net.c | 24 ++++++++++--------------
 include/net/ipv6.h       |  3 +++
 net/ipv6/ip6_output.c    | 10 ++++------
 net/ipv6/output_core.c   | 28 ++++++++++++++++++++++------
 net/ipv6/udp_offload.c   | 10 +++++++++-
 7 files changed, 65 insertions(+), 51 deletions(-)

-- 
1.9.3

^ permalink raw reply

* [PATCH net-next 8/8] cxgb4: Add low latency socket busy_poll support
From: Hariprasad Shenai @ 2015-02-02 14:53 UTC (permalink / raw)
  To: netdev; +Cc: davem, leedom, anish, nirranjan, praveenm, Hariprasad Shenai
In-Reply-To: <1422888789-12016-1-git-send-email-hariprasad@chelsio.com>

cxgb_busy_poll, corresponding to ndo_busy_poll, gets called by the socket
waiting for data.

With busy_poll enabled, improvement is seen in latency numbers as observed by
collecting netperf TCP_RR numbers.

Based on original work by Kumar Sanghvi <kumaras@chelsio.com>

Signed-off-by: Hariprasad Shenai <hariprasad@chelsio.com>
---
 drivers/net/ethernet/chelsio/cxgb4/cxgb4.h      |  113 +++++++++++++++++++++++
 drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c |   16 +++-
 drivers/net/ethernet/chelsio/cxgb4/sge.c        |   47 +++++++++-
 drivers/net/ethernet/chelsio/cxgb4/t4_values.h  |    1 +
 4 files changed, 174 insertions(+), 3 deletions(-)

diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h b/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h
index 87fe265..63603f5 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h
+++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h
@@ -477,6 +477,22 @@ struct sge_rspq {                   /* state for an SGE response queue */
 	struct adapter *adap;
 	struct net_device *netdev;  /* associated net device */
 	rspq_handler_t handler;
+#ifdef CONFIG_NET_RX_BUSY_POLL
+#define CXGB_POLL_STATE_IDLE		0
+#define CXGB_POLL_STATE_NAPI		BIT(0) /* NAPI owns this poll */
+#define CXGB_POLL_STATE_POLL		BIT(1) /* poll owns this poll */
+#define CXGB_POLL_STATE_NAPI_YIELD	BIT(2) /* NAPI yielded this poll */
+#define CXGB_POLL_STATE_POLL_YIELD	BIT(3) /* poll yielded this poll */
+#define CXGB_POLL_YIELD			(CXGB_POLL_STATE_NAPI_YIELD |   \
+					 CXGB_POLL_STATE_POLL_YIELD)
+#define CXGB_POLL_LOCKED		(CXGB_POLL_STATE_NAPI |         \
+					 CXGB_POLL_STATE_POLL)
+#define CXGB_POLL_USER_PEND		(CXGB_POLL_STATE_POLL |         \
+					 CXGB_POLL_STATE_POLL_YIELD)
+	unsigned int bpoll_state;
+	spinlock_t bpoll_lock;		/* lock for busy poll */
+#endif /* CONFIG_NET_RX_BUSY_POLL */
+
 };
 
 struct sge_eth_stats {              /* Ethernet queue statistics */
@@ -881,6 +897,102 @@ static inline struct adapter *netdev2adap(const struct net_device *dev)
 	return netdev2pinfo(dev)->adapter;
 }
 
+#ifdef CONFIG_NET_RX_BUSY_POLL
+static inline void cxgb_busy_poll_init_lock(struct sge_rspq *q)
+{
+	spin_lock_init(&q->bpoll_lock);
+	q->bpoll_state = CXGB_POLL_STATE_IDLE;
+}
+
+static inline bool cxgb_poll_lock_napi(struct sge_rspq *q)
+{
+	bool rc = true;
+
+	spin_lock(&q->bpoll_lock);
+	if (q->bpoll_state & CXGB_POLL_LOCKED) {
+		q->bpoll_state |= CXGB_POLL_STATE_NAPI_YIELD;
+		rc = false;
+	} else {
+		q->bpoll_state = CXGB_POLL_STATE_NAPI;
+	}
+	spin_unlock(&q->bpoll_lock);
+	return rc;
+}
+
+static inline bool cxgb_poll_unlock_napi(struct sge_rspq *q)
+{
+	bool rc = false;
+
+	spin_lock(&q->bpoll_lock);
+	if (q->bpoll_state & CXGB_POLL_STATE_POLL_YIELD)
+		rc = true;
+	q->bpoll_state = CXGB_POLL_STATE_IDLE;
+	spin_unlock(&q->bpoll_lock);
+	return rc;
+}
+
+static inline bool cxgb_poll_lock_poll(struct sge_rspq *q)
+{
+	bool rc = true;
+
+	spin_lock_bh(&q->bpoll_lock);
+	if (q->bpoll_state & CXGB_POLL_LOCKED) {
+		q->bpoll_state |= CXGB_POLL_STATE_POLL_YIELD;
+		rc = false;
+	} else {
+		q->bpoll_state |= CXGB_POLL_STATE_POLL;
+	}
+	spin_unlock_bh(&q->bpoll_lock);
+	return rc;
+}
+
+static inline bool cxgb_poll_unlock_poll(struct sge_rspq *q)
+{
+	bool rc = false;
+
+	spin_lock_bh(&q->bpoll_lock);
+	if (q->bpoll_state & CXGB_POLL_STATE_POLL_YIELD)
+		rc = true;
+	q->bpoll_state = CXGB_POLL_STATE_IDLE;
+	spin_unlock_bh(&q->bpoll_lock);
+	return rc;
+}
+
+static inline bool cxgb_poll_busy_polling(struct sge_rspq *q)
+{
+	return q->bpoll_state & CXGB_POLL_USER_PEND;
+}
+#else
+static inline void cxgb_busy_poll_init_lock(struct sge_rspq *q)
+{
+}
+
+static inline bool cxgb_poll_lock_napi(struct sge_rspq *q)
+{
+	return true;
+}
+
+static inline bool cxgb_poll_unlock_napi(struct sge_rspq *q)
+{
+	return false;
+}
+
+static inline bool cxgb_poll_lock_poll(struct sge_rspq *q)
+{
+	return false;
+}
+
+static inline bool cxgb_poll_unlock_poll(struct sge_rspq *q)
+{
+	return false;
+}
+
+static inline bool cxgb_poll_busy_polling(struct sge_rspq *q)
+{
+	return false;
+}
+#endif /* CONFIG_NET_RX_BUSY_POLL */
+
 void t4_os_portmod_changed(const struct adapter *adap, int port_id);
 void t4_os_link_changed(struct adapter *adap, int port_id, int link_stat);
 
@@ -909,6 +1021,7 @@ irqreturn_t t4_sge_intr_msix(int irq, void *cookie);
 int t4_sge_init(struct adapter *adap);
 void t4_sge_start(struct adapter *adap);
 void t4_sge_stop(struct adapter *adap);
+int cxgb_busy_poll(struct napi_struct *napi);
 extern int dbfifo_int_thresh;
 
 #define for_each_port(adapter, iter) \
diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c
index 5bf490a..041742b 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c
+++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c
@@ -923,8 +923,14 @@ static void quiesce_rx(struct adapter *adap)
 	for (i = 0; i < ARRAY_SIZE(adap->sge.ingr_map); i++) {
 		struct sge_rspq *q = adap->sge.ingr_map[i];
 
-		if (q && q->handler)
+		if (q && q->handler) {
 			napi_disable(&q->napi);
+			local_bh_disable();
+			while (!cxgb_poll_lock_napi(q))
+				mdelay(1);
+			local_bh_enable();
+		}
+
 	}
 }
 
@@ -940,8 +946,10 @@ static void enable_rx(struct adapter *adap)
 
 		if (!q)
 			continue;
-		if (q->handler)
+		if (q->handler) {
+			cxgb_busy_poll_init_lock(q);
 			napi_enable(&q->napi);
+		}
 		/* 0-increment GTS to start the timer and enable interrupts */
 		t4_write_reg(adap, MYPF_REG(SGE_PF_GTS_A),
 			     SEINTARM_V(q->intr_params) |
@@ -4563,6 +4571,10 @@ static const struct net_device_ops cxgb4_netdev_ops = {
 #ifdef CONFIG_NET_POLL_CONTROLLER
 	.ndo_poll_controller  = cxgb_netpoll,
 #endif
+#ifdef CONFIG_NET_RX_BUSY_POLL
+	.ndo_busy_poll        = cxgb_busy_poll,
+#endif
+
 };
 
 void t4_fatal_err(struct adapter *adap)
diff --git a/drivers/net/ethernet/chelsio/cxgb4/sge.c b/drivers/net/ethernet/chelsio/cxgb4/sge.c
index 6191561..7b1a140 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/sge.c
+++ b/drivers/net/ethernet/chelsio/cxgb4/sge.c
@@ -43,6 +43,9 @@
 #include <linux/export.h>
 #include <net/ipv6.h>
 #include <net/tcp.h>
+#ifdef CONFIG_NET_RX_BUSY_POLL
+#include <net/busy_poll.h>
+#endif /* CONFIG_NET_RX_BUSY_POLL */
 #include "cxgb4.h"
 #include "t4_regs.h"
 #include "t4_values.h"
@@ -1720,6 +1723,7 @@ static void do_gro(struct sge_eth_rxq *rxq, const struct pkt_gl *gl,
 	skb->truesize += skb->data_len;
 	skb->ip_summed = CHECKSUM_UNNECESSARY;
 	skb_record_rx_queue(skb, rxq->rspq.idx);
+	skb_mark_napi_id(skb, &rxq->rspq.napi);
 	if (rxq->rspq.netdev->features & NETIF_F_RXHASH)
 		skb_set_hash(skb, (__force u32)pkt->rsshdr.hash_val,
 			     PKT_HASH_TYPE_L3);
@@ -1763,6 +1767,7 @@ int t4_ethrx_handler(struct sge_rspq *q, const __be64 *rsp,
 	csum_ok = pkt->csum_calc && !pkt->err_vec &&
 		  (q->netdev->features & NETIF_F_RXCSUM);
 	if ((pkt->l2info & htonl(RXF_TCP_F)) &&
+	    !(cxgb_poll_busy_polling(q)) &&
 	    (q->netdev->features & NETIF_F_GRO) && csum_ok && !pkt->ip_frag) {
 		do_gro(rxq, si, pkt);
 		return 0;
@@ -1801,6 +1806,7 @@ int t4_ethrx_handler(struct sge_rspq *q, const __be64 *rsp,
 		__vlan_hwaccel_put_tag(skb, htons(ETH_P_8021Q), ntohs(pkt->vlan));
 		rxq->stats.vlan_ex++;
 	}
+	skb_mark_napi_id(skb, &q->napi);
 	netif_receive_skb(skb);
 	return 0;
 }
@@ -1963,6 +1969,38 @@ static int process_responses(struct sge_rspq *q, int budget)
 	return budget - budget_left;
 }
 
+#ifdef CONFIG_NET_RX_BUSY_POLL
+int cxgb_busy_poll(struct napi_struct *napi)
+{
+	struct sge_rspq *q = container_of(napi, struct sge_rspq, napi);
+	unsigned int params, work_done;
+	u32 val;
+
+	if (!cxgb_poll_lock_poll(q))
+		return LL_FLUSH_BUSY;
+
+	work_done = process_responses(q, 4);
+	params = QINTR_TIMER_IDX(TIMERREG_COUNTER0_X) | QINTR_CNT_EN;
+	q->next_intr_params = params;
+	val = CIDXINC_V(work_done) | SEINTARM_V(params);
+
+	/* If we don't have access to the new User GTS (T5+), use the old
+	 * doorbell mechanism; otherwise use the new BAR2 mechanism.
+	 */
+	if (unlikely(!q->bar2_addr))
+		t4_write_reg(q->adap, MYPF_REG(SGE_PF_GTS_A),
+			     val | INGRESSQID_V((u32)q->cntxt_id));
+	else {
+		writel(val | INGRESSQID_V(q->bar2_qid),
+		       q->bar2_addr + SGE_UDB_GTS);
+		wmb();
+	}
+
+	cxgb_poll_unlock_poll(q);
+	return work_done;
+}
+#endif /* CONFIG_NET_RX_BUSY_POLL */
+
 /**
  *	napi_rx_handler - the NAPI handler for Rx processing
  *	@napi: the napi instance
@@ -1978,9 +2016,13 @@ static int napi_rx_handler(struct napi_struct *napi, int budget)
 {
 	unsigned int params;
 	struct sge_rspq *q = container_of(napi, struct sge_rspq, napi);
-	int work_done = process_responses(q, budget);
+	int work_done = 0;
 	u32 val;
 
+	if (!cxgb_poll_lock_napi(q))
+		return work_done;
+
+	work_done = process_responses(q, budget);
 	if (likely(work_done < budget)) {
 		int timer_index;
 
@@ -2018,6 +2060,7 @@ static int napi_rx_handler(struct napi_struct *napi, int budget)
 		       q->bar2_addr + SGE_UDB_GTS);
 		wmb();
 	}
+	cxgb_poll_unlock_napi(q);
 	return work_done;
 }
 
@@ -2341,6 +2384,7 @@ int t4_sge_alloc_rxq(struct adapter *adap, struct sge_rspq *iq, bool fwevtq,
 		goto err;
 
 	netif_napi_add(dev, &iq->napi, napi_rx_handler, 64);
+	napi_hash_add(&iq->napi);
 	iq->cur_desc = iq->desc;
 	iq->cidx = 0;
 	iq->gen = 1;
@@ -2598,6 +2642,7 @@ static void free_rspq_fl(struct adapter *adap, struct sge_rspq *rq,
 		   rq->cntxt_id, fl_id, 0xffff);
 	dma_free_coherent(adap->pdev_dev, (rq->size + 1) * rq->iqe_len,
 			  rq->desc, rq->phys_addr);
+	napi_hash_del(&rq->napi);
 	netif_napi_del(&rq->napi);
 	rq->netdev = NULL;
 	rq->cntxt_id = rq->abs_id = 0;
diff --git a/drivers/net/ethernet/chelsio/cxgb4/t4_values.h b/drivers/net/ethernet/chelsio/cxgb4/t4_values.h
index 01a31a5..19b2dcf 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/t4_values.h
+++ b/drivers/net/ethernet/chelsio/cxgb4/t4_values.h
@@ -59,6 +59,7 @@
 
 /* GTS register */
 #define SGE_TIMERREGS			6
+#define TIMERREG_COUNTER0_X		0
 
 /* T5 and later support a new BAR2-based doorbell mechanism for Egress Queues.
  * The User Doorbells are each 128 bytes in length with a Simple Doorbell at
-- 
1.7.1

^ permalink raw reply related

* [PATCH net-next 7/8] cxgb4: Added support in debugfs to display tp_err_stats
From: Hariprasad Shenai @ 2015-02-02 14:53 UTC (permalink / raw)
  To: netdev; +Cc: davem, leedom, anish, nirranjan, praveenm, Hariprasad Shenai
In-Reply-To: <1422888789-12016-1-git-send-email-hariprasad@chelsio.com>

Signed-off-by: Hariprasad Shenai <hariprasad@chelsio.com>
---
 drivers/net/ethernet/chelsio/cxgb4/cxgb4.h         |   21 +++++-----
 drivers/net/ethernet/chelsio/cxgb4/cxgb4_debugfs.c |   43 ++++++++++++++++++++
 drivers/net/ethernet/chelsio/cxgb4/t4_hw.c         |   23 ++++++++++
 3 files changed, 77 insertions(+), 10 deletions(-)

diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h b/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h
index e4e0199..87fe265 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h
+++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h
@@ -200,16 +200,16 @@ struct tp_tcp_stats {
 };
 
 struct tp_err_stats {
-	u32 macInErrs[4];
-	u32 hdrInErrs[4];
-	u32 tcpInErrs[4];
-	u32 tnlCongDrops[4];
-	u32 ofldChanDrops[4];
-	u32 tnlTxDrops[4];
-	u32 ofldVlanDrops[4];
-	u32 tcp6InErrs[4];
-	u32 ofldNoNeigh;
-	u32 ofldCongDefer;
+	u32 mac_in_errs[4];
+	u32 hdr_in_errs[4];
+	u32 tcp_in_errs[4];
+	u32 tnl_cong_drops[4];
+	u32 ofld_chan_drops[4];
+	u32 tnl_tx_drops[4];
+	u32 ofld_vlan_drops[4];
+	u32 tcp6_in_errs[4];
+	u32 ofld_no_neigh;
+	u32 ofld_cong_defer;
 };
 
 struct sge_params {
@@ -1066,6 +1066,7 @@ void t4_tp_wr_bits_indirect(struct adapter *adap, unsigned int addr,
 void t4_tp_read_la(struct adapter *adap, u64 *la_buf, unsigned int *wrptr);
 void t4_tp_get_tcp_stats(struct adapter *adap, struct tp_tcp_stats *v4,
 			 struct tp_tcp_stats *v6);
+void t4_tp_get_err_stats(struct adapter *adap, struct tp_err_stats *st);
 void t4_load_mtus(struct adapter *adap, const unsigned short *mtus,
 		  const unsigned short *alpha, const unsigned short *beta);
 
diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_debugfs.c b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_debugfs.c
index 904f36d..da939f2 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_debugfs.c
+++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_debugfs.c
@@ -1271,6 +1271,48 @@ static int tp_tcp_stats_show(struct seq_file *seq, void *v)
 
 DEFINE_SIMPLE_DEBUGFS_FILE(tp_tcp_stats);
 
+static int tp_err_stats_show(struct seq_file *seq, void *v)
+{
+	struct tp_err_stats stats;
+	struct adapter *adap = seq->private;
+
+	spin_lock(&adap->stats_lock);
+	t4_tp_get_err_stats(adap, &stats);
+	spin_unlock(&adap->stats_lock);
+
+	seq_puts(seq, "                 channel 0  channel 1  "
+		 "channel 2  channel 3\n");
+	seq_printf(seq, "mac_in_errs:      %10u %10u %10u %10u\n",
+		   stats.mac_in_errs[0], stats.mac_in_errs[1],
+		   stats.mac_in_errs[2], stats.mac_in_errs[3]);
+	seq_printf(seq, "hdr_in_errs:      %10u %10u %10u %10u\n",
+		   stats.hdr_in_errs[0], stats.hdr_in_errs[1],
+		   stats.hdr_in_errs[2], stats.hdr_in_errs[3]);
+	seq_printf(seq, "tcp_in_errs:      %10u %10u %10u %10u\n",
+		   stats.tcp_in_errs[0], stats.tcp_in_errs[1],
+		   stats.tcp_in_errs[2], stats.tcp_in_errs[3]);
+	seq_printf(seq, "tcp6_in_errs:     %10u %10u %10u %10u\n",
+		   stats.tcp6_in_errs[0], stats.tcp6_in_errs[1],
+		   stats.tcp6_in_errs[2], stats.tcp6_in_errs[3]);
+	seq_printf(seq, "tnl_cong_drops:   %10u %10u %10u %10u\n",
+		   stats.tnl_cong_drops[0], stats.tnl_cong_drops[1],
+		   stats.tnl_cong_drops[2], stats.tnl_cong_drops[3]);
+	seq_printf(seq, "tnl_tx_drops:     %10u %10u %10u %10u\n",
+		   stats.tnl_tx_drops[0], stats.tnl_tx_drops[1],
+		   stats.tnl_tx_drops[2], stats.tnl_tx_drops[3]);
+	seq_printf(seq, "ofld_vlan_drops:  %10u %10u %10u %10u\n",
+		   stats.ofld_vlan_drops[0], stats.ofld_vlan_drops[1],
+		   stats.ofld_vlan_drops[2], stats.ofld_vlan_drops[3]);
+	seq_printf(seq, "ofld_chan_drops:  %10u %10u %10u %10u\n\n",
+		   stats.ofld_chan_drops[0], stats.ofld_chan_drops[1],
+		   stats.ofld_chan_drops[2], stats.ofld_chan_drops[3]);
+	seq_printf(seq, "ofld_no_neigh:    %u\nofld_cong_defer:  %u\n",
+		   stats.ofld_no_neigh, stats.ofld_cong_defer);
+	return 0;
+}
+
+DEFINE_SIMPLE_DEBUGFS_FILE(tp_err_stats);
+
 #if IS_ENABLED(CONFIG_IPV6)
 static int clip_tbl_open(struct inode *inode, struct file *file)
 {
@@ -2052,6 +2094,7 @@ int t4_setup_debugfs(struct adapter *adap)
 		{ "obq_ncsi", &cim_obq_fops, S_IRUSR, 5 },
 		{ "tp_la", &tp_la_fops, S_IRUSR, 0 },
 		{ "tp_tcp_stats", &tp_tcp_stats_debugfs_fops, S_IRUSR, 0 },
+		{ "tp_err_stats", &tp_err_stats_debugfs_fops, S_IRUSR, 0 },
 		{ "ulprx_la", &ulprx_la_fops, S_IRUSR, 0 },
 		{ "sensors", &sensors_debugfs_fops, S_IRUSR, 0 },
 		{ "lb_stats", &lb_stats_debugfs_fops, S_IRUSR, 0 },
diff --git a/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c b/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c
index 2603b64..7e0db7a 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c
+++ b/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c
@@ -2396,6 +2396,29 @@ void t4_tp_get_tcp_stats(struct adapter *adap, struct tp_tcp_stats *v4,
 }
 
 /**
+ *	t4_tp_get_err_stats - read TP's error MIB counters
+ *	@adap: the adapter
+ *	@st: holds the counter values
+ *
+ *	Returns the values of TP's error counters.
+ */
+void t4_tp_get_err_stats(struct adapter *adap, struct tp_err_stats *st)
+{
+	t4_read_indirect(adap, TP_MIB_INDEX_A, TP_MIB_DATA_A,
+			 st->mac_in_errs, 12, TP_MIB_MAC_IN_ERR_0_A);
+	t4_read_indirect(adap, TP_MIB_INDEX_A, TP_MIB_DATA_A,
+			 st->tnl_cong_drops, 8, TP_MIB_TNL_CNG_DROP_0_A);
+	t4_read_indirect(adap, TP_MIB_INDEX_A, TP_MIB_DATA_A,
+			 st->tnl_tx_drops, 4, TP_MIB_TNL_DROP_0_A);
+	t4_read_indirect(adap, TP_MIB_INDEX_A, TP_MIB_DATA_A,
+			 st->ofld_vlan_drops, 4, TP_MIB_OFD_VLN_DROP_0_A);
+	t4_read_indirect(adap, TP_MIB_INDEX_A, TP_MIB_DATA_A,
+			 st->tcp6_in_errs, 4, TP_MIB_TCP_V6IN_ERR_0_A);
+	t4_read_indirect(adap, TP_MIB_INDEX_A, TP_MIB_DATA_A,
+			 &st->ofld_no_neigh, 2, TP_MIB_OFD_ARP_DROP_A);
+}
+
+/**
  *	t4_read_mtu_tbl - returns the values in the HW path MTU table
  *	@adap: the adapter
  *	@mtus: where to store the MTU values
-- 
1.7.1

^ permalink raw reply related

* [PATCH net-next 6/8] cxgb4: Add support to display TP module tcp stats in debugfs
From: Hariprasad Shenai @ 2015-02-02 14:53 UTC (permalink / raw)
  To: netdev; +Cc: davem, leedom, anish, nirranjan, praveenm, Hariprasad Shenai
In-Reply-To: <1422888789-12016-1-git-send-email-hariprasad@chelsio.com>

Signed-off-by: Hariprasad Shenai <hariprasad@chelsio.com>
---
 drivers/net/ethernet/chelsio/cxgb4/cxgb4_debugfs.c |   28 ++++++++++++++++++++
 1 files changed, 28 insertions(+), 0 deletions(-)

diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_debugfs.c b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_debugfs.c
index 5341a00..904f36d 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_debugfs.c
+++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_debugfs.c
@@ -1244,6 +1244,33 @@ static int lb_stats_show(struct seq_file *seq, void *v)
 
 DEFINE_SIMPLE_DEBUGFS_FILE(lb_stats);
 
+static int tp_tcp_stats_show(struct seq_file *seq, void *v)
+{
+	struct tp_tcp_stats v4, v6;
+	struct adapter *adap = seq->private;
+
+	spin_lock(&adap->stats_lock);
+	t4_tp_get_tcp_stats(adap, &v4, &v6);
+	spin_unlock(&adap->stats_lock);
+
+	seq_puts(seq,
+		 "                                IP                 IPv6\n");
+	seq_printf(seq, "OutRsts:      %20u %20u\n",
+		   v4.tcpOutRsts, v6.tcpOutRsts);
+	seq_printf(seq, "InSegs:       %20llu %20llu\n",
+		   (unsigned long long)v4.tcpInSegs,
+		   (unsigned long long)v6.tcpInSegs);
+	seq_printf(seq, "OutSegs:      %20llu %20llu\n",
+		   (unsigned long long)v4.tcpOutSegs,
+		   (unsigned long long)v6.tcpOutSegs);
+	seq_printf(seq, "RetransSegs:  %20llu %20llu\n",
+		   (unsigned long long)v4.tcpRetransSegs,
+		   (unsigned long long)v6.tcpRetransSegs);
+	return 0;
+}
+
+DEFINE_SIMPLE_DEBUGFS_FILE(tp_tcp_stats);
+
 #if IS_ENABLED(CONFIG_IPV6)
 static int clip_tbl_open(struct inode *inode, struct file *file)
 {
@@ -2024,6 +2051,7 @@ int t4_setup_debugfs(struct adapter *adap)
 		{ "obq_sge",  &cim_obq_fops, S_IRUSR, 4 },
 		{ "obq_ncsi", &cim_obq_fops, S_IRUSR, 5 },
 		{ "tp_la", &tp_la_fops, S_IRUSR, 0 },
+		{ "tp_tcp_stats", &tp_tcp_stats_debugfs_fops, S_IRUSR, 0 },
 		{ "ulprx_la", &ulprx_la_fops, S_IRUSR, 0 },
 		{ "sensors", &sensors_debugfs_fops, S_IRUSR, 0 },
 		{ "lb_stats", &lb_stats_debugfs_fops, S_IRUSR, 0 },
-- 
1.7.1

^ permalink raw reply related


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