Netdev List
 help / color / mirror / Atom feed
* Re: [PATCH net] af_key: free SKBs under RCU protection
From: Eric Dumazet @ 2018-09-20 13:29 UTC (permalink / raw)
  To: Sean Tranchetti, netdev, steffen.klassert
In-Reply-To: <1537402712-12875-1-git-send-email-stranche@codeaurora.org>



On 09/19/2018 05:18 PM, Sean Tranchetti wrote:
> pfkey_broadcast() can make calls to pfkey_broadcast_one() which
> will clone or copy the passed in SKB. This new SKB will be assigned
> the sock_rfree() function as its destructor, which requires that
> the socket reference the SKB contains is valid when the SKB is freed.
> 
> If this SKB is ever passed to pfkey_broadcast() again by some other
> function (such as pkfey_dump() or pfkey_promisc) it will then be
> freed there. However, since this free occurs outside of RCU protection,
> it is possible that userspace could close the socket and trigger
> pfkey_release() to free the socket before sock_rfree() can run, creating
> the following race condition:
> 
> 1: An SKB belonging to the pfkey socket is passed to pfkey_broadcast().
>    It performs the broadcast to any other sockets, and calls
>    rcu_read_unlock(), but does not yet reach kfree_skb().
> 2: Userspace closes the socket, triggering pfkey_realse(). Since no one
>    holds the RCU lock, synchronize_rcu() returns and it is allowed to
>    continue. It calls sock_put() to free the socket.
> 3: pfkey_broadcast() now calls kfree_skb() on the original SKB it was
>    passed, triggering a call to sock_rfree(). This function now accesses
>    the freed struct sock * via skb->sk, and attempts to update invalid
>    memory.
> 
> By ensuring that the pfkey_broadcast() also frees the SKBs while it holds
> the RCU lock, we can ensure that the socket will remain valid when the SKB
> is freed, avoiding crashes like the following:
> 
> Unable to handle kernel paging request at virtual address 6b6b6b6b6b6c4b
> [006b6b6b6b6b6c4b] address between user and kernel address ranges
> Internal error: Oops: 96000004 [#1] PREEMPT SMP
> task: fffffff78f65b380 task.stack: ffffff8049a88000
> pc : sock_rfree+0x38/0x6c
> lr : skb_release_head_state+0x6c/0xcc
> Process repro (pid: 7117, stack limit = 0xffffff8049a88000)
> Call trace:
> 	sock_rfree+0x38/0x6c
> 	skb_release_head_state+0x6c/0xcc
> 	skb_release_all+0x1c/0x38
> 	__kfree_skb+0x1c/0x30
> 	kfree_skb+0xd0/0xf4
> 	pfkey_broadcast+0x14c/0x18c
> 	pfkey_sendmsg+0x1d8/0x408
> 	sock_sendmsg+0x44/0x60
> 	___sys_sendmsg+0x1d0/0x2a8
> 	__sys_sendmsg+0x64/0xb4
> 	SyS_sendmsg+0x34/0x4c
> 	el0_svc_naked+0x34/0x38
> Kernel panic - not syncing: Fatal exception
> 
> Signed-off-by: Sean Tranchetti <stranche@codeaurora.org>
> ---
>  net/key/af_key.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/net/key/af_key.c b/net/key/af_key.c
> index 9d61266..dd257c7 100644
> --- a/net/key/af_key.c
> +++ b/net/key/af_key.c
> @@ -275,13 +275,13 @@ static int pfkey_broadcast(struct sk_buff *skb, gfp_t allocation,
>  		if ((broadcast_flags & BROADCAST_REGISTERED) && err)
>  			err = err2;
>  	}
> -	rcu_read_unlock();
>  
>  	if (one_sk != NULL)
>  		err = pfkey_broadcast_one(skb, &skb2, allocation, one_sk);
>  
>  	kfree_skb(skb2);
>  	kfree_skb(skb);
> +	rcu_read_unlock();
>  	return err;
>  }
>  
> 

I do not believe the changelog or the patch makes sense.

Having skb still referencing a socket prevents this socket being released.

If you think about it, what would prevent the freeing happening 
_before_ the rcu_read_lock() in pfkey_broadcast() ?

Maybe the correct fix is that pfkey_broadcast_one() should ensure the socket is still valid.

I would suggest something like :

diff --git a/net/key/af_key.c b/net/key/af_key.c
index 9d61266526e767770d9a1ce184ac8cdd59de309a..5ce309d020dda5e46e4426c4a639bfb551e2260d 100644
--- a/net/key/af_key.c
+++ b/net/key/af_key.c
@@ -201,7 +201,9 @@ static int pfkey_broadcast_one(struct sk_buff *skb, struct sk_buff **skb2,
 {
        int err = -ENOBUFS;
 
-       sock_hold(sk);
+       if (!refcount_inc_not_zero(&sk->sk_refcnt))
+               return -ENOENT;
+
        if (*skb2 == NULL) {
                if (refcount_read(&skb->users) != 1) {
                        *skb2 = skb_clone(skb, allocation);

^ permalink raw reply related

* Re: [PATCH bpf-next 2/3] bpf: emit RECORD_MMAP events for bpf prog load/unload
From: Arnaldo Carvalho de Melo @ 2018-09-20 13:25 UTC (permalink / raw)
  To: Alexei Starovoitov
  Cc: Peter Zijlstra, David S . Miller, daniel, netdev, kernel-team
In-Reply-To: <20180920084424.GN24124@hirez.programming.kicks-ass.net>

Em Thu, Sep 20, 2018 at 10:44:24AM +0200, Peter Zijlstra escreveu:
> On Wed, Sep 19, 2018 at 03:39:34PM -0700, Alexei Starovoitov wrote:
> >  void bpf_prog_kallsyms_del(struct bpf_prog *fp)
> >  {
> > +	unsigned long symbol_start, symbol_end;
> > +	/* mmap_record.filename cannot be NULL and has to be u64 aligned */
> > +	char buf[sizeof(u64)] = {};
> > +
> >  	if (!bpf_prog_kallsyms_candidate(fp))
> >  		return;
> >  
> >  	spin_lock_bh(&bpf_lock);
> >  	bpf_prog_ksym_node_del(fp->aux);
> >  	spin_unlock_bh(&bpf_lock);
> > +	bpf_get_prog_addr_region(fp, &symbol_start, &symbol_end);
> > +	perf_event_mmap_bpf_prog(symbol_start, symbol_end - symbol_start,
> > +				 buf, sizeof(buf));
> >  }
> 
> So perf doesn't normally issue unmap events.. We've talked about doing
> that, but so far it's never really need needed I think.
 
> I feels a bit weird to start issuing unmap events for this.

For reference, this surfaced here:

https://lkml.org/lkml/2017/1/27/452

Start of the thread, that involves postgresql, JIT, LLVM, perf is here:

https://lkml.org/lkml/2016/12/10/1

PeterZ provided a patch introducing PERF_RECORD_MUNMAP, went nowhere due
to having to cope with munmapping parts of existing mmaps, etc.

I'm still more in favour of introduce PERF_RECORD_MUNMAP, even if for
now it would be used just in this clean case for undoing a
PERF_RECORD_MMAP for a BPF program.

The ABI is already complicated, starting to use something called
PERF_RECORD_MMAP for unmmaping by just using a NULL name... too clever,
I think.

- Arnaldo

^ permalink raw reply

* Re: [PATCH v3 net-next 07/12] net: ethernet: Add helper to remove a supported link mode
From: Andrew Lunn @ 2018-09-20 13:25 UTC (permalink / raw)
  To: Simon Horman; +Cc: David Miller, netdev, Florian Fainelli
In-Reply-To: <20180918105817.z2o5yybcth7diqsu@verge.net.au>

> 1. net-next: cf7d97e1e54d ("net: mdio: remove duplicated include from mdio_bus.c")
> 
> # mii-tool -vv eth0
> Using SIOCGMIIPHY=0x8947
> eth0: no link
>   registers for MII PHY 0: 
>     1140 7949 0022 1622 0d81 c1e1 000f 0000
>     0000 0300 0000 0000 0000 0000 0000 3000
>     0000 0000 0000 0078 7002 0000 0000 0200
>     0000 0000 0000 0528 0000 0000 0000 0000
>   product info: vendor 00:08:85, model 34 rev 2
>   basic mode:   autonegotiation enabled
>   basic status: no link
>   capabilities: 1000baseT-HD 1000baseT-FD 100baseTx-FD 100baseTx-HD 10baseT-FD 10baseT-HD
>   advertising:  100baseTx-FD 100baseTx-HD flow-control
>   link partner: 100baseTx-FD 100baseTx-HD 10baseT-FD 10baseT-HD
> 
> 2. net-next with this patch reverted
> 
> # mii-tool -vv eth0
> Using SIOCGMIIPHY=0x8947
> eth0: negotiated 100baseTx-FD, link ok
>   registers for MII PHY 0: 
>     1140 796d 0022 1622 0181 c1e1 000f 0000

Hi Simon

Word 5 is what we are advertising. Bits 10 and 11 are Pause and Asym
Pause. In the good case here, neither are set. In this bad case above,
both bits are set.

The patch i asked you to try only cleared the Pause bit, not the
Asymmetric Pause bit. mii-tool only saying 'flow-control' did not
help.

Word 6 is what the partner is advertising. c1e1 indicates the partner
does not support flow control, both bits are 0. I don't see why this
is preventing auto-net though. But in the bad case, the status
register indicates auto-neg has not completed.

Anyway, please can you try this patch, which also removes Aysm Pause.

Thanks
	Andrew

>From 00a061304af51831ca1dc86bf6ce23d01f724229 Mon Sep 17 00:00:00 2001
From: Andrew Lunn <andrew@lunn.ch>
Date: Tue, 18 Sep 2018 18:12:54 -0500
Subject: [PATCH] ravb: Disable Pause Advertisement

The previous commit to ravb had the side effect of making the PHY
advertise Pause. This previously did not happen, and it appears the
MAC does not support Pause. By default, phydev->supported has Pause
enabled, but phydev->advertising does not. Rather than rely on this,
be explicit, and remove the Pause link mode.

Reported-by: Simon Horman <horms@verge.net.au>
Fixes: 41124fa64d4b ("net: ethernet: Add helper to remove a supported link mode")
Signed-off-by: Andrew Lunn <andrew@lunn.ch>
---
 drivers/net/ethernet/renesas/ravb_main.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/renesas/ravb_main.c b/drivers/net/ethernet/renesas/ravb_main.c
index fb2a1125780d..b0f2612ad226 100644
--- a/drivers/net/ethernet/renesas/ravb_main.c
+++ b/drivers/net/ethernet/renesas/ravb_main.c
@@ -1073,9 +1073,11 @@ static int ravb_phy_init(struct net_device *ndev)
 		netdev_info(ndev, "limited PHY to 100Mbit/s\n");
 	}
 
-	/* 10BASE is not supported */
+	/* 10BASE, Pause and Asym Pause is not supported */
 	phy_remove_link_mode(phydev, ETHTOOL_LINK_MODE_10baseT_Half_BIT);
 	phy_remove_link_mode(phydev, ETHTOOL_LINK_MODE_10baseT_Full_BIT);
+	phy_remove_link_mode(phydev, ETHTOOL_LINK_MODE_Pause_BIT);
+	phy_remove_link_mode(phydev, ETHTOOL_LINK_MODE_Asym_Pause_BIT);
 
 	phy_attached_info(phydev);
 
-- 
2.19.0.rc1

^ permalink raw reply related

* Re: [PATCH 00/21] SMMU enablement for NXP LS1043A and LS1046A
From: Li Yang @ 2018-09-20 19:07 UTC (permalink / raw)
  To: Laurentiu Tudor
  Cc: robin.murphy,
	open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
	Netdev, lkml,
	moderated list:ARM/FREESCALE IMX / MXC ARM ARCHITECTURE,
	madalin.bucur, Roy Pledge, Shawn Guo, David Miller
In-Reply-To: <33eac426-cbb7-f899-5a35-aea28f8e5dc4@nxp.com>

On Thu, Sep 20, 2018 at 5:39 AM Laurentiu Tudor <laurentiu.tudor@nxp.com> wrote:
>
>
>
> On 19.09.2018 17:37, Robin Murphy wrote:
> > On 19/09/18 15:18, Laurentiu Tudor wrote:
> >> Hi Robin,
> >>
> >> On 19.09.2018 16:25, Robin Murphy wrote:
> >>> Hi Laurentiu,
> >>>
> >>> On 19/09/18 13:35, laurentiu.tudor@nxp.com wrote:
> >>>> From: Laurentiu Tudor <laurentiu.tudor@nxp.com>
> >>>>
> >>>> This patch series adds SMMU support for NXP LS1043A and LS1046A chips
> >>>> and consists mostly in important driver fixes and the required device
> >>>> tree updates. It touches several subsystems and consists of three main
> >>>> parts:
> >>>>    - changes in soc/drivers/fsl/qbman drivers adding iommu mapping of
> >>>>      reserved memory areas, fixes and defered probe support
> >>>>    - changes in drivers/net/ethernet/freescale/dpaa_eth drivers
> >>>>      consisting in misc dma mapping related fixes and probe ordering
> >>>>    - addition of the actual arm smmu device tree node together with
> >>>>      various adjustments to the device trees
> >>>>
> >>>> Performance impact
> >>>>
> >>>>       Running iperf benchmarks in a back-to-back setup (both sides
> >>>>       having smmu enabled) on a 10GBps port show an important
> >>>>       networking performance degradation of around %40 (9.48Gbps
> >>>>       linerate vs 5.45Gbps). If you need performance but without
> >>>>       SMMU support you can use "iommu.passthrough=1" to disable
> >>>>       SMMU.
> >>>>
> >>>> USB issue and workaround
> >>>>
> >>>>       There's a problem with the usb controllers in these chips
> >>>>       generating smaller, 40-bit wide dma addresses instead of the
> >>>> 48-bit
> >>>>       supported at the smmu input. So you end up in a situation
> >>>> where the
> >>>>       smmu is mapped with 48-bit address translations, but the device
> >>>>       generates transactions with clipped 40-bit addresses, thus smmu
> >>>>       context faults are triggered. I encountered a similar
> >>>> situation for
> >>>>       mmc that I  managed to fix in software [1] however for USB I
> >>>> did not
> >>>>       find a proper place in the code to add a similar fix. The only
> >>>>       workaround I found was to add this kernel parameter which
> >>>> limits the
> >>>>       usb dma to 32-bit size: "xhci-hcd.quirks=0x800000".
> >>>>       This workaround if far from ideal, so any suggestions for a code
> >>>>       based workaround in this area would be greatly appreciated.
> >>>
> >>> If you have a nominally-64-bit device with a
> >>> narrower-than-the-main-interconnect link in front of it, that should
> >>> already be fixed in 4.19-rc by bus_dma_mask picking up DT dma-ranges,
> >>> provided the interconnect hierarchy can be described appropriately (or
> >>> at least massaged sufficiently to satisfy the binding), e.g.:
> >>>
> >>> / {
> >>>       ...
> >>>
> >>>       soc {
> >>>           ranges;
> >>>           dma-ranges = <0 0 10000 0>;
> >>>
> >>>           dev_48bit { ... };
> >>>
> >>>           periph_bus {
> >>>               ranges;
> >>>               dma-ranges = <0 0 100 0>;
> >>>
> >>>               dev_40bit { ... };
> >>>           };
> >>>       };
> >>> };
> >>>
> >>> and if that fails to work as expected (except for PCI hosts where
> >>> handling dma-ranges properly still needs sorting out), please do let us
> >>> know ;)
> >>>
> >>
> >> Just to confirm, Is this [1] the change I was supposed to test?
> >
> > Not quite - dma-ranges is only valid for nodes representing a bus, so
> > putting it directly in the USB device nodes doesn't work (FWIW that's
> > why PCI is broken, because the parser doesn't expect the
> > bus-as-leaf-node case). That's teh point of that intermediate simple-bus
> > node represented by "periph_bus" in my example (sorry, I should have put
> > compatibles in to make it clearer) - often that's actually true to life
> > (i.e. "soc" is something like a CCI and "periph_bus" is something like
> > an AXI NIC gluing a bunch of lower-bandwidth DMA masters to one of the
> > CCI ports) but at worst it's just a necessary evil to make the binding
> > happy (if it literally only represents the point-to-point link between
> > the device master port and interconnect slave port).
> >
>
> Quick update: so I adjusted to device tree according to your example and
> it works so now I can get rid of that nasty kernel arg based workaround,
> yey! :-)

Great that we have a generic solution like I hoped for!  So you will
submit a new revision of the series to include these dts updates,
right?

Regards,
Leo

^ permalink raw reply

* Re: [PATCH net-next 4/5] ipv6: do not drop vrf udp multicast packets
From: Paolo Abeni @ 2018-09-20 13:02 UTC (permalink / raw)
  To: Mike Manning, netdev; +Cc: Dewi Morgan
In-Reply-To: <20180920085848.17721-5-mmanning@vyatta.att-mail.com>

Hi,

On Thu, 2018-09-20 at 09:58 +0100, Mike Manning wrote:
> diff --git a/net/ipv6/ip6_input.c b/net/ipv6/ip6_input.c
> index 108f5f88ec98..fc60f297d95b 100644
> --- a/net/ipv6/ip6_input.c
> +++ b/net/ipv6/ip6_input.c
> @@ -325,9 +325,12 @@ static int ip6_input_finish(struct net *net, struct sock *sk, struct sk_buff *sk
>  {
>  	const struct inet6_protocol *ipprot;
>  	struct inet6_dev *idev;
> +	struct net_device *dev;
>  	unsigned int nhoff;
> +	int sdif = inet6_sdif(skb);
>  	int nexthdr;
>  	bool raw;
> +	bool deliver;
>  	bool have_final = false;

Please, try instead to sort the variable in reverse x-mas tree order.
>  
>  	/*
> @@ -371,9 +374,27 @@ static int ip6_input_finish(struct net *net, struct sock *sk, struct sk_buff *sk
>  			skb_postpull_rcsum(skb, skb_network_header(skb),
>  					   skb_network_header_len(skb));
>  			hdr = ipv6_hdr(skb);
> -			if (ipv6_addr_is_multicast(&hdr->daddr) &&
> -			    !ipv6_chk_mcast_addr(skb->dev, &hdr->daddr,
> -			    &hdr->saddr) &&
> +
> +			/* skb->dev passed may be master dev for vrfs. */
> +			if (sdif) {
> +				rcu_read_lock();

AFAICS, the rcu lock is already acquired at the beginning of
ip6_input_finish(), not need to acquire it here again.
+				dev = dev_get_by_index_rcu(dev_net(skb->dev),
> +							   sdif);
> +				if (!dev) {
> +					rcu_read_unlock();
> +					kfree_skb(skb);
> +					return -ENODEV;
> +				}
> +			} else {
> +				dev = skb->dev;

The above fragment of code is a recurring pattern in this series,
perhaps adding an helper for it would reduce code duplication ?

Cheers,

Paolo

^ permalink raw reply

* Re: [PATCH net-next] vhost_net: add a missing error return
From: Michael S. Tsirkin @ 2018-09-20 12:51 UTC (permalink / raw)
  To: Dan Carpenter; +Cc: Jason Wang, kvm, virtualization, netdev, kernel-janitors
In-Reply-To: <20180920100158.GA9551@mwanda>

On Thu, Sep 20, 2018 at 01:01:59PM +0300, Dan Carpenter wrote:
> We accidentally left out this error return so it leads to some use after
> free bugs later on.
> 
> Fixes: 0a0be13b8fe2 ("vhost_net: batch submitting XDP buffers to underlayer sockets")
> Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com>

Ouch.

Acked-by: Michael S. Tsirkin <mst@redhat.com>

> 
> diff --git a/drivers/vhost/net.c b/drivers/vhost/net.c
> index dd4e0a301635..1bff6bc8161a 100644
> --- a/drivers/vhost/net.c
> +++ b/drivers/vhost/net.c
> @@ -1244,6 +1244,7 @@ static int vhost_net_open(struct inode *inode, struct file *f)
>  		kfree(vqs);
>  		kvfree(n);
>  		kfree(queue);
> +		return -ENOMEM;
>  	}
>  	n->vqs[VHOST_NET_VQ_TX].xdp = xdp;
>  

^ permalink raw reply

* Re: [PATCH v3 net-next 07/12] net: ethernet: Add helper to remove a supported link mode
From: Andrew Lunn @ 2018-09-20 12:51 UTC (permalink / raw)
  To: Simon Horman
  Cc: David Miller, netdev, Florian Fainelli, Sergei Shtylyov,
	linux-renesas-soc
In-Reply-To: <20180920080506.qxiy2zeg6xd3xxfz@verge.net.au>

> eth0: no link
>   registers for MII PHY 0: 
>     1140 7949 0022 1622 0981 c1e1 000d 0000

Hi Simon

The ID registers 0022 1622 indicate this is a Micrel KSZ9031.
Are you using the micrel PHY driver?

> I note a difference in the 3rd line of hex output: 7002 vs 6002
> but I am unsure if that is relevant.

Register 20, or 0x14. The datasheet says "Reserved" and there is no
description given :-(

I will decode the other registers and see if i can find anything.

    Andrew

^ permalink raw reply

* [PATCH net-next 19/22] net: plip: fix return type of ndo_start_xmit function
From: YueHaibing @ 2018-09-20 12:33 UTC (permalink / raw)
  To: davem, dmitry.tarnyagin, wg, mkl, michal.simek, hsweeten,
	madalin.bucur, pantelis.antoniou, claudiu.manoil, leoyang.li,
	linux, sammy, ralf, nico, steve.glendinning, f.fainelli,
	grygorii.strashko, w-kwok2, m-karicheri2, t.sailer, jreuter, kys,
	haiyangz, wei.liu2, paul.durrant, arvid.brodin, pshelar
  Cc: linux-kernel, netdev, linux-can, linux-arm-kernel, linuxppc-dev,
	linux-mips, linux-omap, linux-hams, devel, linux-usb, xen-devel,
	dev, YueHaibing
In-Reply-To: <20180920123306.14772-1-yuehaibing@huawei.com>

The method ndo_start_xmit() is defined as returning an 'netdev_tx_t',
which is a typedef for an enum type, so make sure the implementation in
this driver has returns 'netdev_tx_t' value, and change the function
return type to netdev_tx_t.

Found by coccinelle.

Signed-off-by: YueHaibing <yuehaibing@huawei.com>
---
 drivers/net/plip/plip.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/net/plip/plip.c b/drivers/net/plip/plip.c
index feb92ec..0b354e6 100644
--- a/drivers/net/plip/plip.c
+++ b/drivers/net/plip/plip.c
@@ -146,7 +146,7 @@
 static void plip_interrupt(void *dev_id);
 
 /* Functions for DEV methods */
-static int plip_tx_packet(struct sk_buff *skb, struct net_device *dev);
+static netdev_tx_t plip_tx_packet(struct sk_buff *skb, struct net_device *dev);
 static int plip_hard_header(struct sk_buff *skb, struct net_device *dev,
                             unsigned short type, const void *daddr,
 			    const void *saddr, unsigned len);
@@ -962,7 +962,7 @@ static __be16 plip_type_trans(struct sk_buff *skb, struct net_device *dev)
 	spin_unlock_irqrestore(&nl->lock, flags);
 }
 
-static int
+static netdev_tx_t
 plip_tx_packet(struct sk_buff *skb, struct net_device *dev)
 {
 	struct net_local *nl = netdev_priv(dev);
-- 
1.8.3.1

^ permalink raw reply related

* [PATCH net-next 16/22] usbnet: ipheth: fix return type of ndo_start_xmit function
From: YueHaibing @ 2018-09-20 12:33 UTC (permalink / raw)
  To: davem, dmitry.tarnyagin, wg, mkl, michal.simek, hsweeten,
	madalin.bucur, pantelis.antoniou, claudiu.manoil, leoyang.li,
	linux, sammy, ralf, nico, steve.glendinning, f.fainelli,
	grygorii.strashko, w-kwok2, m-karicheri2, t.sailer, jreuter, kys,
	haiyangz, wei.liu2, paul.durrant, arvid.brodin, pshelar
  Cc: linux-kernel, netdev, linux-can, linux-arm-kernel, linuxppc-dev,
	linux-mips, linux-omap, linux-hams, devel, linux-usb, xen-devel,
	dev, YueHaibing
In-Reply-To: <20180920123306.14772-1-yuehaibing@huawei.com>

The method ndo_start_xmit() is defined as returning an 'netdev_tx_t',
which is a typedef for an enum type, so make sure the implementation in
this driver has returns 'netdev_tx_t' value, and change the function
return type to netdev_tx_t.

Found by coccinelle.

Signed-off-by: YueHaibing <yuehaibing@huawei.com>
---
 drivers/net/usb/ipheth.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/usb/ipheth.c b/drivers/net/usb/ipheth.c
index 7275761..53eab6fb 100644
--- a/drivers/net/usb/ipheth.c
+++ b/drivers/net/usb/ipheth.c
@@ -413,7 +413,7 @@ static int ipheth_close(struct net_device *net)
 	return 0;
 }
 
-static int ipheth_tx(struct sk_buff *skb, struct net_device *net)
+static netdev_tx_t ipheth_tx(struct sk_buff *skb, struct net_device *net)
 {
 	struct ipheth_device *dev = netdev_priv(net);
 	struct usb_device *udev = dev->udev;
-- 
1.8.3.1

^ permalink raw reply related

* [PATCH net-next 13/22] net: xen-netback: fix return type of ndo_start_xmit function
From: YueHaibing @ 2018-09-20 12:32 UTC (permalink / raw)
  To: davem, dmitry.tarnyagin, wg, mkl, michal.simek, hsweeten,
	madalin.bucur, pantelis.antoniou, claudiu.manoil, leoyang.li,
	linux, sammy, ralf, nico, steve.glendinning, f.fainelli,
	grygorii.strashko, w-kwok2, m-karicheri2, t.sailer, jreuter, kys,
	haiyangz, wei.liu2, paul.durrant, arvid.brodin, pshelar
  Cc: linux-kernel, netdev, linux-can, linux-arm-kernel, linuxppc-dev,
	linux-mips, linux-omap, linux-hams, devel, linux-usb, xen-devel,
	dev, YueHaibing
In-Reply-To: <20180920123306.14772-1-yuehaibing@huawei.com>

The method ndo_start_xmit() is defined as returning an 'netdev_tx_t',
which is a typedef for an enum type, so make sure the implementation in
this driver has returns 'netdev_tx_t' value, and change the function
return type to netdev_tx_t.

Found by coccinelle.

Signed-off-by: YueHaibing <yuehaibing@huawei.com>
---
 drivers/net/xen-netback/interface.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/net/xen-netback/interface.c b/drivers/net/xen-netback/interface.c
index 92274c2..7e3ea39 100644
--- a/drivers/net/xen-netback/interface.c
+++ b/drivers/net/xen-netback/interface.c
@@ -165,7 +165,8 @@ static u16 xenvif_select_queue(struct net_device *dev, struct sk_buff *skb,
 	return vif->hash.mapping[skb_get_hash_raw(skb) % size];
 }
 
-static int xenvif_start_xmit(struct sk_buff *skb, struct net_device *dev)
+static netdev_tx_t
+xenvif_start_xmit(struct sk_buff *skb, struct net_device *dev)
 {
 	struct xenvif *vif = netdev_priv(dev);
 	struct xenvif_queue *queue = NULL;
-- 
1.8.3.1

^ permalink raw reply related

* [PATCH net-next 08/22] net: apple: fix return type of ndo_start_xmit function
From: YueHaibing @ 2018-09-20 12:32 UTC (permalink / raw)
  To: davem, dmitry.tarnyagin, wg, mkl, michal.simek, hsweeten,
	madalin.bucur, pantelis.antoniou, claudiu.manoil, leoyang.li,
	linux, sammy, ralf, nico, steve.glendinning, f.fainelli,
	grygorii.strashko, w-kwok2, m-karicheri2, t.sailer, jreuter, kys,
	haiyangz, wei.liu2, paul.durrant, arvid.brodin, pshelar
  Cc: linux-kernel, netdev, linux-can, linux-arm-kernel, linuxppc-dev,
	linux-mips, linux-omap, linux-hams, devel, linux-usb, xen-devel,
	dev, YueHaibing
In-Reply-To: <20180920123306.14772-1-yuehaibing@huawei.com>

The method ndo_start_xmit() is defined as returning an 'netdev_tx_t',
which is a typedef for an enum type, so make sure the implementation in
this driver has returns 'netdev_tx_t' value, and change the function
return type to netdev_tx_t.

Found by coccinelle.

Signed-off-by: YueHaibing <yuehaibing@huawei.com>
---
 drivers/net/ethernet/apple/bmac.c    | 4 ++--
 drivers/net/ethernet/apple/mace.c    | 4 ++--
 drivers/net/ethernet/apple/macmace.c | 4 ++--
 3 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/drivers/net/ethernet/apple/bmac.c b/drivers/net/ethernet/apple/bmac.c
index 024998d..6a8e256 100644
--- a/drivers/net/ethernet/apple/bmac.c
+++ b/drivers/net/ethernet/apple/bmac.c
@@ -154,7 +154,7 @@ struct bmac_data {
 static irqreturn_t bmac_rxdma_intr(int irq, void *dev_id);
 static void bmac_set_timeout(struct net_device *dev);
 static void bmac_tx_timeout(struct timer_list *t);
-static int bmac_output(struct sk_buff *skb, struct net_device *dev);
+static netdev_tx_t bmac_output(struct sk_buff *skb, struct net_device *dev);
 static void bmac_start(struct net_device *dev);
 
 #define	DBDMA_SET(x)	( ((x) | (x) << 16) )
@@ -1456,7 +1456,7 @@ static int bmac_close(struct net_device *dev)
 	spin_unlock_irqrestore(&bp->lock, flags);
 }
 
-static int
+static netdev_tx_t
 bmac_output(struct sk_buff *skb, struct net_device *dev)
 {
 	struct bmac_data *bp = netdev_priv(dev);
diff --git a/drivers/net/ethernet/apple/mace.c b/drivers/net/ethernet/apple/mace.c
index 0b5429d..68b9ee4 100644
--- a/drivers/net/ethernet/apple/mace.c
+++ b/drivers/net/ethernet/apple/mace.c
@@ -78,7 +78,7 @@ struct mace_data {
 
 static int mace_open(struct net_device *dev);
 static int mace_close(struct net_device *dev);
-static int mace_xmit_start(struct sk_buff *skb, struct net_device *dev);
+static netdev_tx_t mace_xmit_start(struct sk_buff *skb, struct net_device *dev);
 static void mace_set_multicast(struct net_device *dev);
 static void mace_reset(struct net_device *dev);
 static int mace_set_address(struct net_device *dev, void *addr);
@@ -525,7 +525,7 @@ static inline void mace_set_timeout(struct net_device *dev)
     mp->timeout_active = 1;
 }
 
-static int mace_xmit_start(struct sk_buff *skb, struct net_device *dev)
+static netdev_tx_t mace_xmit_start(struct sk_buff *skb, struct net_device *dev)
 {
     struct mace_data *mp = netdev_priv(dev);
     volatile struct dbdma_regs __iomem *td = mp->tx_dma;
diff --git a/drivers/net/ethernet/apple/macmace.c b/drivers/net/ethernet/apple/macmace.c
index 137cbb4..376f2c2 100644
--- a/drivers/net/ethernet/apple/macmace.c
+++ b/drivers/net/ethernet/apple/macmace.c
@@ -89,7 +89,7 @@ struct mace_frame {
 
 static int mace_open(struct net_device *dev);
 static int mace_close(struct net_device *dev);
-static int mace_xmit_start(struct sk_buff *skb, struct net_device *dev);
+static netdev_tx_t mace_xmit_start(struct sk_buff *skb, struct net_device *dev);
 static void mace_set_multicast(struct net_device *dev);
 static int mace_set_address(struct net_device *dev, void *addr);
 static void mace_reset(struct net_device *dev);
@@ -444,7 +444,7 @@ static int mace_close(struct net_device *dev)
  * Transmit a frame
  */
 
-static int mace_xmit_start(struct sk_buff *skb, struct net_device *dev)
+static netdev_tx_t mace_xmit_start(struct sk_buff *skb, struct net_device *dev)
 {
 	struct mace_data *mp = netdev_priv(dev);
 	unsigned long flags;
-- 
1.8.3.1

^ permalink raw reply related

* [PATCH net-next 05/22] net: sgi: fix return type of ndo_start_xmit function
From: YueHaibing @ 2018-09-20 12:32 UTC (permalink / raw)
  To: davem, dmitry.tarnyagin, wg, mkl, michal.simek, hsweeten,
	madalin.bucur, pantelis.antoniou, claudiu.manoil, leoyang.li,
	linux, sammy, ralf, nico, steve.glendinning, f.fainelli,
	grygorii.strashko, w-kwok2, m-karicheri2, t.sailer, jreuter, kys,
	haiyangz, wei.liu2, paul.durrant, arvid.brodin, pshelar
  Cc: linux-kernel, netdev, linux-can, linux-arm-kernel, linuxppc-dev,
	linux-mips, linux-omap, linux-hams, devel, linux-usb, xen-devel,
	dev, YueHaibing
In-Reply-To: <20180920123306.14772-1-yuehaibing@huawei.com>

The method ndo_start_xmit() is defined as returning an 'netdev_tx_t',
which is a typedef for an enum type, so make sure the implementation in
this driver has returns 'netdev_tx_t' value, and change the function
return type to netdev_tx_t.

Found by coccinelle.

Signed-off-by: YueHaibing <yuehaibing@huawei.com>
---
 drivers/net/ethernet/sgi/ioc3-eth.c | 4 ++--
 drivers/net/ethernet/sgi/meth.c     | 2 +-
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/net/ethernet/sgi/ioc3-eth.c b/drivers/net/ethernet/sgi/ioc3-eth.c
index 18d533f..3140999 100644
--- a/drivers/net/ethernet/sgi/ioc3-eth.c
+++ b/drivers/net/ethernet/sgi/ioc3-eth.c
@@ -99,7 +99,7 @@ struct ioc3_private {
 
 static int ioc3_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
 static void ioc3_set_multicast_list(struct net_device *dev);
-static int ioc3_start_xmit(struct sk_buff *skb, struct net_device *dev);
+static netdev_tx_t ioc3_start_xmit(struct sk_buff *skb, struct net_device *dev);
 static void ioc3_timeout(struct net_device *dev);
 static inline unsigned int ioc3_hash(const unsigned char *addr);
 static inline void ioc3_stop(struct ioc3_private *ip);
@@ -1390,7 +1390,7 @@ static void ioc3_remove_one(struct pci_dev *pdev)
 	.remove		= ioc3_remove_one,
 };
 
-static int ioc3_start_xmit(struct sk_buff *skb, struct net_device *dev)
+static netdev_tx_t ioc3_start_xmit(struct sk_buff *skb, struct net_device *dev)
 {
 	unsigned long data;
 	struct ioc3_private *ip = netdev_priv(dev);
diff --git a/drivers/net/ethernet/sgi/meth.c b/drivers/net/ethernet/sgi/meth.c
index ea55abd..703fbbe 100644
--- a/drivers/net/ethernet/sgi/meth.c
+++ b/drivers/net/ethernet/sgi/meth.c
@@ -697,7 +697,7 @@ static void meth_add_to_tx_ring(struct meth_private *priv, struct sk_buff *skb)
 /*
  * Transmit a packet (called by the kernel)
  */
-static int meth_tx(struct sk_buff *skb, struct net_device *dev)
+static netdev_tx_t meth_tx(struct sk_buff *skb, struct net_device *dev)
 {
 	struct meth_private *priv = netdev_priv(dev);
 	unsigned long flags;
-- 
1.8.3.1

^ permalink raw reply related

* [PATCH net-next 00/22] net: fix return type of ndo_start_xmit function
From: YueHaibing @ 2018-09-20 12:32 UTC (permalink / raw)
  To: davem, dmitry.tarnyagin, wg, mkl, michal.simek, hsweeten,
	madalin.bucur, pantelis.antoniou, claudiu.manoil, leoyang.li,
	linux, sammy, ralf, nico, steve.glendinning, f.fainelli,
	grygorii.strashko, w-kwok2, m-karicheri2, t.sailer, jreuter, kys,
	haiyangz, wei.liu2, paul.durrant, arvid.brodin, pshelar
  Cc: linux-kernel, netdev, linux-can, linux-arm-kernel, linuxppc-dev,
	linux-mips, linux-omap, linux-hams, devel, linux-usb, xen-devel,
	dev, YueHaibing

The method ndo_start_xmit() is defined as returning an 'netdev_tx_t',
which is a typedef for an enum type, so make sure the implementation in
this driver has returns 'netdev_tx_t' value, and change the function
return type to netdev_tx_t.

YueHaibing (22):
  net: micrel: fix return type of ndo_start_xmit function
  net: freescale: fix return type of ndo_start_xmit function
  net: seeq: fix return type of ndo_start_xmit function
  net: cirrus: fix return type of ndo_start_xmit function
  net: sgi: fix return type of ndo_start_xmit function
  net: wiznet: fix return type of ndo_start_xmit function
  net: i825xx: fix return type of ndo_start_xmit function
  net: apple: fix return type of ndo_start_xmit function
  net: smsc: fix return type of ndo_start_xmit function
  net: ti: fix return type of ndo_start_xmit function
  net: faraday: fix return type of ndo_start_xmit function
  net: ovs: fix return type of ndo_start_xmit function
  net: xen-netback: fix return type of ndo_start_xmit function
  net: caif: fix return type of ndo_start_xmit function
  net: hamradio: fix return type of ndo_start_xmit function
  usbnet: ipheth: fix return type of ndo_start_xmit function
  hv_netvsc: fix return type of ndo_start_xmit function
  can: xilinx: fix return type of ndo_start_xmit function
  net: plip: fix return type of ndo_start_xmit function
  rionet: fix return type of ndo_start_xmit function
  l2tp: fix return type of ndo_start_xmit function
  net: hsr: fix return type of ndo_start_xmit function

 drivers/net/caif/caif_hsi.c                           | 10 +++++-----
 drivers/net/caif/caif_serial.c                        |  7 +++++--
 drivers/net/caif/caif_spi.c                           |  6 +++---
 drivers/net/caif/caif_virtio.c                        |  2 +-
 drivers/net/can/xilinx_can.c                          |  2 +-
 drivers/net/ethernet/apple/bmac.c                     |  4 ++--
 drivers/net/ethernet/apple/mace.c                     |  4 ++--
 drivers/net/ethernet/apple/macmace.c                  |  4 ++--
 drivers/net/ethernet/cirrus/ep93xx_eth.c              |  2 +-
 drivers/net/ethernet/cirrus/mac89x0.c                 |  4 ++--
 drivers/net/ethernet/faraday/ftgmac100.c              |  4 ++--
 drivers/net/ethernet/faraday/ftmac100.c               |  7 ++++---
 drivers/net/ethernet/freescale/dpaa/dpaa_eth.c        |  3 ++-
 drivers/net/ethernet/freescale/fec_mpc52xx.c          |  3 ++-
 drivers/net/ethernet/freescale/fs_enet/fs_enet-main.c |  3 ++-
 drivers/net/ethernet/freescale/gianfar.c              |  4 ++--
 drivers/net/ethernet/freescale/ucc_geth.c             |  3 ++-
 drivers/net/ethernet/i825xx/ether1.c                  |  5 +++--
 drivers/net/ethernet/i825xx/lib82596.c                |  4 ++--
 drivers/net/ethernet/i825xx/sun3_82586.c              |  6 ++++--
 drivers/net/ethernet/micrel/ks8695net.c               |  2 +-
 drivers/net/ethernet/micrel/ks8851_mll.c              |  4 ++--
 drivers/net/ethernet/seeq/ether3.c                    |  5 +++--
 drivers/net/ethernet/seeq/sgiseeq.c                   |  3 ++-
 drivers/net/ethernet/sgi/ioc3-eth.c                   |  4 ++--
 drivers/net/ethernet/sgi/meth.c                       |  2 +-
 drivers/net/ethernet/smsc/smc911x.c                   |  3 ++-
 drivers/net/ethernet/smsc/smc91x.c                    |  3 ++-
 drivers/net/ethernet/smsc/smsc911x.c                  |  3 ++-
 drivers/net/ethernet/ti/cpmac.c                       |  2 +-
 drivers/net/ethernet/ti/davinci_emac.c                |  2 +-
 drivers/net/ethernet/ti/netcp_core.c                  |  8 ++++----
 drivers/net/ethernet/wiznet/w5100.c                   |  2 +-
 drivers/net/ethernet/wiznet/w5300.c                   |  2 +-
 drivers/net/hamradio/baycom_epp.c                     |  3 ++-
 drivers/net/hamradio/dmascc.c                         |  4 ++--
 drivers/net/hyperv/netvsc_drv.c                       | 10 +++++++---
 drivers/net/plip/plip.c                               |  4 ++--
 drivers/net/rionet.c                                  |  3 ++-
 drivers/net/usb/ipheth.c                              |  2 +-
 drivers/net/xen-netback/interface.c                   |  3 ++-
 net/caif/chnl_net.c                                   |  3 ++-
 net/hsr/hsr_device.c                                  |  2 +-
 net/l2tp/l2tp_eth.c                                   |  3 ++-
 net/openvswitch/vport-internal_dev.c                  |  5 +++--
 45 files changed, 100 insertions(+), 74 deletions(-)

-- 
1.8.3.1

^ permalink raw reply

* Re: [PATCH] net-next: mscc: remove unused ocelot_dev_gmii.h
From: David Miller @ 2018-09-20 18:25 UTC (permalink / raw)
  To: clabbe; +Cc: alexandre.belloni, linux-kernel, netdev
In-Reply-To: <1537384013-2353-1-git-send-email-clabbe@baylibre.com>

From: Corentin Labbe <clabbe@baylibre.com>
Date: Wed, 19 Sep 2018 19:06:53 +0000

> The header ocelot_dev_gmii.h is unused since the inclusion of the driver.
> It is unused, lets just remove it.
> 
> Signed-off-by: Corentin Labbe <clabbe@baylibre.com>

Yeah if it's unused, let's toss it.  If future code uses it we can bring it
back, if necessary.

Thanks!

^ permalink raw reply

* Re: [PATCH v7 4/4] gpiolib: Implement fast processing path in get/set array
From: Dan Carpenter @ 2018-09-20 18:05 UTC (permalink / raw)
  To: Janusz Krzysztofik
  Cc: Andrew Lunn, Ulf Hansson, linux-doc, linux-iio, Linus Walleij,
	Dominik Brodowski, Yegor Yefremov, David S. Miller, linux-i2c,
	Peter Meerwald-Stadler, Marek Szyprowski, devel, Florian Fainelli,
	Jonathan Corbet, Krzysztof Kozlowski, Kishon Vijay Abraham I,
	Tony Lindgren, Peter Korsgaard, Geert Uytterhoeven, linux-serial,
	Jiri Slaby, Michael Hennerich, Uwe Kleine-König
In-Reply-To: <9860023.SlBYqtbjDV@z50>

On Thu, Sep 20, 2018 at 05:48:22PM +0200, Janusz Krzysztofik wrote:
> diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c
> index a53d17745d21..5bc3447949c9 100644
> --- a/drivers/gpio/gpiolib.c
> +++ b/drivers/gpio/gpiolib.c
> @@ -2880,7 +2880,7 @@ int gpiod_get_array_value_complex(bool raw, bool can_sleep,
>  			__set_bit(hwgpio, mask);
>  
>  			if (array_info)
> -				find_next_zero_bit(array_info->get_mask,
> +				i = find_next_zero_bit(array_info->get_mask,
>  						   array_size, i);

We could mark find_next_zero_bit() and friends as a __must_check
functions so we avoid this bug in the future.  I have a more complicated
idea how to detect these bugs in a generic way using Smatch but it will
take longer to implement.

regards,
dan carpenter

^ permalink raw reply

* Re: [PATCH] qtnfmac: remove set but not used variable 'vif'
From: Kalle Valo @ 2018-09-20 12:12 UTC (permalink / raw)
  To: YueHaibing
  Cc: Igor Mitsyanko, Avinash Patil, Sergey Matyukevich,
	Sergei Maksimenko, Vasily Ulyanov, Andrey Shevchenko, YueHaibing,
	linux-wireless, netdev, kernel-janitors
In-Reply-To: <1536668904-13110-1-git-send-email-yuehaibing@huawei.com>

YueHaibing <yuehaibing@huawei.com> wrote:

> Fixes gcc '-Wunused-but-set-variable' warning:
> 
> drivers/net/wireless/quantenna/qtnfmac/cfg80211.c: In function 'qtnf_dump_survey':
> drivers/net/wireless/quantenna/qtnfmac/cfg80211.c:694:19: warning:
>  variable 'vif' set but not used [-Wunused-but-set-variable]
> 
> Signed-off-by: YueHaibing <yuehaibing@huawei.com>
> Reviewed-by: Sergey Matyukevich <sergey.matyukevich.os@quantenna.com>

Patch applied to wireless-drivers-next.git, thanks.

93ed990e3a6e qtnfmac: remove set but not used variable 'vif'

-- 
https://patchwork.kernel.org/patch/10595609/

https://wireless.wiki.kernel.org/en/developers/documentation/submittingpatches

^ permalink raw reply

* Re: [PATCH] brcm80211: remove redundant condition check before debugfs_remove_recursive
From: Kalle Valo @ 2018-09-20 12:10 UTC (permalink / raw)
  To: zhong jiang
  Cc: davem, arend.vanspriel, franky.lin, hante.meuleman, chi-hsien.lin,
	wright.feng, linux-wireless, brcm80211-dev-list.pdl, netdev
In-Reply-To: <1536414043-32146-1-git-send-email-zhongjiang@huawei.com>

zhong jiang <zhongjiang@huawei.com> wrote:

> debugfs_remove_recursive has taken IS_ERR_OR_NULL into account. So just
> remove the condition check before debugfs_remove_recursive.
> 
> Signed-off-by: zhong jiang <zhongjiang@huawei.com>

Patch applied to wireless-drivers-next.git, thanks.

761cb7cdef1a brcm80211: remove redundant condition check before debugfs_remove_recursive

-- 
https://patchwork.kernel.org/patch/10593061/

https://wireless.wiki.kernel.org/en/developers/documentation/submittingpatches

^ permalink raw reply

* Re: [PATCH] bpf: remove redundant null pointer check before consume_skb
From: Song Liu @ 2018-09-20 17:53 UTC (permalink / raw)
  To: zhongjiang; +Cc: Alexei Starovoitov, Daniel Borkmann, Networking, open list
In-Reply-To: <1537436772-42545-1-git-send-email-zhongjiang@huawei.com>

On Thu, Sep 20, 2018 at 3:00 AM zhong jiang <zhongjiang@huawei.com> wrote:
>
> consume_skb has taken the null pointer into account. hence it is safe
> to remove the redundant null pointer check before consume_skb.
>
> Signed-off-by: zhong jiang <zhongjiang@huawei.com>

Acked-by: Song Liu <songliubraving@fb.com>

> ---
>  kernel/bpf/sockmap.c | 6 ++----
>  1 file changed, 2 insertions(+), 4 deletions(-)
>
> diff --git a/kernel/bpf/sockmap.c b/kernel/bpf/sockmap.c
> index 488ef96..a9359cb 100644
> --- a/kernel/bpf/sockmap.c
> +++ b/kernel/bpf/sockmap.c
> @@ -590,8 +590,7 @@ static int free_sg(struct sock *sk, int start,
>                 if (i == MAX_SKB_FRAGS)
>                         i = 0;
>         }
> -       if (md->skb)
> -               consume_skb(md->skb);
> +       consume_skb(md->skb);
>
>         return free;
>  }
> @@ -973,8 +972,7 @@ static int bpf_tcp_recvmsg(struct sock *sk, struct msghdr *msg, size_t len,
>
>                 if (!sg->length && md->sg_start == md->sg_end) {
>                         list_del(&md->list);
> -                       if (md->skb)
> -                               consume_skb(md->skb);
> +                       consume_skb(md->skb);
>                         kfree(md);
>                 }
>         }
> --
> 1.7.12.4
>

^ permalink raw reply

* Re: [PATCH] docs: fix some broken documentation references
From: Jonathan Corbet @ 2018-09-20 17:10 UTC (permalink / raw)
  To: Mauro Carvalho Chehab
  Cc: linux-kernel, Linux Media Mailing List, Mauro Carvalho Chehab,
	Jan Kara, Stephen Hemminger, David S. Miller, Michael Ellerman,
	Greg Kroah-Hartman, Andrew Morton, Arnd Bergmann, linux-doc,
	linux-ext4, bridge, netdev
In-Reply-To: <6b47bf56b898c48a0dc3cd42283c9e5c7c23367a.1537210894.git.mchehab+samsung@kernel.org>

On Mon, 17 Sep 2018 15:02:34 -0400
Mauro Carvalho Chehab <mchehab+samsung@kernel.org> wrote:

> Some documentation files received recent changes and are
> pointing to wrong places.
> 
> Those references can easily fixed with the help of a
> script:
> 
> 	$ ./scripts/documentation-file-ref-check --fix
> 
> Signed-off-by: Mauro Carvalho Chehab <mchehab+samsung@kernel.org>

Applied, thanks.

jon

^ permalink raw reply

* [PATCH net-next,3/3] hv_netvsc: Update document for LRO/RSC support
From: Haiyang Zhang @ 2018-09-20 17:07 UTC (permalink / raw)
  To: davem, netdev
  Cc: haiyangz, kys, sthemmin, olaf, vkuznets, devel, linux-kernel
In-Reply-To: <20180920170701.9574-1-haiyangz@linuxonhyperv.com>

From: Haiyang Zhang <haiyangz@microsoft.com>

Update document for LRO/RSC support, and the command line info to
change the setting.

Signed-off-by: Haiyang Zhang <haiyangz@microsoft.com>
---
 Documentation/networking/netvsc.txt | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/Documentation/networking/netvsc.txt b/Documentation/networking/netvsc.txt
index 92f5b31392fa..3bfa635bbbd5 100644
--- a/Documentation/networking/netvsc.txt
+++ b/Documentation/networking/netvsc.txt
@@ -45,6 +45,15 @@ Features
   like packets and significantly reduces CPU usage under heavy Rx
   load.
 
+  Large Receive Offload (LRO), or Receive Side Coalescing (RSC)
+  -------------------------------------------------------------
+  The driver supports LRO/RSC in the vSwitch feature. It reduces the per packet
+  processing overhead by coalescing multiple TCP segments when possible. The
+  feature is enabled by default on VMs running on Windows Server 2019 and
+  later. It may be changed by ethtool command:
+	ethtool -K eth0 lro on
+	ethtool -K eth0 lro off
+
   SR-IOV support
   --------------
   Hyper-V supports SR-IOV as a hardware acceleration option. If SR-IOV
-- 
2.18.0

^ permalink raw reply related

* [PATCH net-next,2/3] hv_netvsc: Add handler for LRO setting change
From: Haiyang Zhang @ 2018-09-20 17:07 UTC (permalink / raw)
  To: davem, netdev; +Cc: olaf, sthemmin, haiyangz, linux-kernel, devel, vkuznets
In-Reply-To: <20180920170701.9574-1-haiyangz@linuxonhyperv.com>

From: Haiyang Zhang <haiyangz@microsoft.com>

This patch adds the handler for LRO setting change, so that a user
can use ethtool command to enable / disable LRO feature.

Signed-off-by: Haiyang Zhang <haiyangz@microsoft.com>
---
 drivers/net/hyperv/hyperv_net.h   |  4 ++++
 drivers/net/hyperv/netvsc_drv.c   | 30 ++++++++++++++++++++++++++++++
 drivers/net/hyperv/rndis_filter.c | 11 ++++++++---
 3 files changed, 42 insertions(+), 3 deletions(-)

diff --git a/drivers/net/hyperv/hyperv_net.h b/drivers/net/hyperv/hyperv_net.h
index 7f1603dc8128..ef6f766f6389 100644
--- a/drivers/net/hyperv/hyperv_net.h
+++ b/drivers/net/hyperv/hyperv_net.h
@@ -185,6 +185,7 @@ struct rndis_device {
 
 /* Interface */
 struct rndis_message;
+struct ndis_offload_params;
 struct netvsc_device;
 struct netvsc_channel;
 struct net_device_context;
@@ -218,6 +219,9 @@ void rndis_filter_device_remove(struct hv_device *dev,
 				struct netvsc_device *nvdev);
 int rndis_filter_set_rss_param(struct rndis_device *rdev,
 			       const u8 *key);
+int rndis_filter_set_offload_params(struct net_device *ndev,
+				    struct netvsc_device *nvdev,
+				    struct ndis_offload_params *req_offloads);
 int rndis_filter_receive(struct net_device *ndev,
 			 struct netvsc_device *net_dev,
 			 struct netvsc_channel *nvchan,
diff --git a/drivers/net/hyperv/netvsc_drv.c b/drivers/net/hyperv/netvsc_drv.c
index f8c18370d9d1..ec699741170b 100644
--- a/drivers/net/hyperv/netvsc_drv.c
+++ b/drivers/net/hyperv/netvsc_drv.c
@@ -1006,6 +1006,8 @@ static void netvsc_init_settings(struct net_device *dev)
 
 	ndc->speed = SPEED_UNKNOWN;
 	ndc->duplex = DUPLEX_FULL;
+
+	dev->features = NETIF_F_LRO;
 }
 
 static int netvsc_get_link_ksettings(struct net_device *dev,
@@ -1733,6 +1735,33 @@ static int netvsc_set_ringparam(struct net_device *ndev,
 	return ret;
 }
 
+static int netvsc_set_features(struct net_device *ndev,
+			       netdev_features_t features)
+{
+	netdev_features_t change = features ^ ndev->features;
+	struct net_device_context *ndevctx = netdev_priv(ndev);
+	struct netvsc_device *nvdev = rtnl_dereference(ndevctx->nvdev);
+	struct ndis_offload_params offloads;
+
+	if (!nvdev || nvdev->destroy)
+		return -ENODEV;
+
+	if (!(change & NETIF_F_LRO))
+		return 0;
+
+	memset(&offloads, 0, sizeof(struct ndis_offload_params));
+
+	if (features & NETIF_F_LRO) {
+		offloads.rsc_ip_v4 = NDIS_OFFLOAD_PARAMETERS_RSC_ENABLED;
+		offloads.rsc_ip_v6 = NDIS_OFFLOAD_PARAMETERS_RSC_ENABLED;
+	} else {
+		offloads.rsc_ip_v4 = NDIS_OFFLOAD_PARAMETERS_RSC_DISABLED;
+		offloads.rsc_ip_v6 = NDIS_OFFLOAD_PARAMETERS_RSC_DISABLED;
+	}
+
+	return rndis_filter_set_offload_params(ndev, nvdev, &offloads);
+}
+
 static u32 netvsc_get_msglevel(struct net_device *ndev)
 {
 	struct net_device_context *ndev_ctx = netdev_priv(ndev);
@@ -1776,6 +1805,7 @@ static const struct net_device_ops device_ops = {
 	.ndo_start_xmit =		netvsc_start_xmit,
 	.ndo_change_rx_flags =		netvsc_change_rx_flags,
 	.ndo_set_rx_mode =		netvsc_set_rx_mode,
+	.ndo_set_features =		netvsc_set_features,
 	.ndo_change_mtu =		netvsc_change_mtu,
 	.ndo_validate_addr =		eth_validate_addr,
 	.ndo_set_mac_address =		netvsc_set_mac_addr,
diff --git a/drivers/net/hyperv/rndis_filter.c b/drivers/net/hyperv/rndis_filter.c
index 7bc8ade5c2bd..f94892edaa21 100644
--- a/drivers/net/hyperv/rndis_filter.c
+++ b/drivers/net/hyperv/rndis_filter.c
@@ -716,7 +716,7 @@ int rndis_filter_set_device_mac(struct netvsc_device *nvdev,
 	return ret;
 }
 
-static int
+int
 rndis_filter_set_offload_params(struct net_device *ndev,
 				struct netvsc_device *nvdev,
 				struct ndis_offload_params *req_offloads)
@@ -1246,8 +1246,13 @@ static int rndis_netdev_set_hwcaps(struct rndis_device *rndis_device,
 	if (hwcaps.rsc.ip4 && hwcaps.rsc.ip6) {
 		net->hw_features |= NETIF_F_LRO;
 
-		offloads.rsc_ip_v4 = NDIS_OFFLOAD_PARAMETERS_RSC_ENABLED;
-		offloads.rsc_ip_v6 = NDIS_OFFLOAD_PARAMETERS_RSC_ENABLED;
+		if (net->features & NETIF_F_LRO) {
+			offloads.rsc_ip_v4 = NDIS_OFFLOAD_PARAMETERS_RSC_ENABLED;
+			offloads.rsc_ip_v6 = NDIS_OFFLOAD_PARAMETERS_RSC_ENABLED;
+		} else {
+			offloads.rsc_ip_v4 = NDIS_OFFLOAD_PARAMETERS_RSC_DISABLED;
+			offloads.rsc_ip_v6 = NDIS_OFFLOAD_PARAMETERS_RSC_DISABLED;
+		}
 	}
 
 	/* In case some hw_features disappeared we need to remove them from
-- 
2.18.0

^ permalink raw reply related

* [PATCH net-next,1/3] hv_netvsc: Add support for LRO/RSC in the vSwitch
From: Haiyang Zhang @ 2018-09-20 17:06 UTC (permalink / raw)
  To: davem, netdev
  Cc: haiyangz, kys, sthemmin, olaf, vkuznets, devel, linux-kernel
In-Reply-To: <20180920170701.9574-1-haiyangz@linuxonhyperv.com>

From: Haiyang Zhang <haiyangz@microsoft.com>

LRO/RSC in the vSwitch is a feature available in Windows Server 2019
hosts and later. It reduces the per packet processing overhead by
coalescing multiple TCP segments when possible. This patch adds netvsc
driver support for this feature.

Signed-off-by: Haiyang Zhang <haiyangz@microsoft.com>
---
 drivers/net/hyperv/hyperv_net.h   | 47 +++++++++++++---
 drivers/net/hyperv/netvsc.c       | 18 +++++--
 drivers/net/hyperv/netvsc_drv.c   | 28 +++++-----
 drivers/net/hyperv/rndis_filter.c | 90 ++++++++++++++++++++++++++-----
 4 files changed, 145 insertions(+), 38 deletions(-)

diff --git a/drivers/net/hyperv/hyperv_net.h b/drivers/net/hyperv/hyperv_net.h
index a32ded5b4f41..7f1603dc8128 100644
--- a/drivers/net/hyperv/hyperv_net.h
+++ b/drivers/net/hyperv/hyperv_net.h
@@ -186,6 +186,7 @@ struct rndis_device {
 /* Interface */
 struct rndis_message;
 struct netvsc_device;
+struct netvsc_channel;
 struct net_device_context;
 
 extern u32 netvsc_ring_bytes;
@@ -203,10 +204,7 @@ void netvsc_linkstatus_callback(struct net_device *net,
 				struct rndis_message *resp);
 int netvsc_recv_callback(struct net_device *net,
 			 struct netvsc_device *nvdev,
-			 struct vmbus_channel *channel,
-			 void  *data, u32 len,
-			 const struct ndis_tcp_ip_checksum_info *csum_info,
-			 const struct ndis_pkt_8021q_info *vlan);
+			 struct netvsc_channel *nvchan);
 void netvsc_channel_cb(void *context);
 int netvsc_poll(struct napi_struct *napi, int budget);
 
@@ -222,7 +220,7 @@ int rndis_filter_set_rss_param(struct rndis_device *rdev,
 			       const u8 *key);
 int rndis_filter_receive(struct net_device *ndev,
 			 struct netvsc_device *net_dev,
-			 struct vmbus_channel *channel,
+			 struct netvsc_channel *nvchan,
 			 void *data, u32 buflen);
 
 int rndis_filter_set_device_mac(struct netvsc_device *ndev,
@@ -524,6 +522,8 @@ struct nvsp_2_vsc_capability {
 			u64 ieee8021q:1;
 			u64 correlation_id:1;
 			u64 teaming:1;
+			u64 vsubnetid:1;
+			u64 rsc:1;
 		};
 	};
 } __packed;
@@ -826,7 +826,7 @@ struct nvsp_message {
 
 #define NETVSC_SUPPORTED_HW_FEATURES (NETIF_F_RXCSUM | NETIF_F_IP_CSUM | \
 				      NETIF_F_TSO | NETIF_F_IPV6_CSUM | \
-				      NETIF_F_TSO6)
+				      NETIF_F_TSO6 | NETIF_F_LRO)
 
 #define VRSS_SEND_TAB_SIZE 16  /* must be power of 2 */
 #define VRSS_CHANNEL_MAX 64
@@ -852,6 +852,18 @@ struct multi_recv_comp {
 	u32 next;	/* next entry for writing */
 };
 
+#define NVSP_RSC_MAX 562 /* Max #RSC frags in a vmbus xfer page pkt */
+
+struct nvsc_rsc {
+	const struct ndis_pkt_8021q_info *vlan;
+	const struct ndis_tcp_ip_checksum_info *csum_info;
+	u8 is_last; /* last RNDIS msg in a vmtransfer_page */
+	u32 cnt; /* #fragments in an RSC packet */
+	u32 pktlen; /* Full packet length */
+	void *data[NVSP_RSC_MAX];
+	u32 len[NVSP_RSC_MAX];
+};
+
 struct netvsc_stats {
 	u64 packets;
 	u64 bytes;
@@ -955,6 +967,7 @@ struct netvsc_channel {
 	struct multi_send_data msd;
 	struct multi_recv_comp mrc;
 	atomic_t queue_sends;
+	struct nvsc_rsc rsc;
 
 	struct netvsc_stats tx_stats;
 	struct netvsc_stats rx_stats;
@@ -1136,7 +1149,8 @@ struct rndis_oobd {
 /* Packet extension field contents associated with a Data message. */
 struct rndis_per_packet_info {
 	u32 size;
-	u32 type;
+	u32 type:31;
+	u32 internal:1;
 	u32 ppi_offset;
 };
 
@@ -1157,6 +1171,25 @@ enum ndis_per_pkt_info_type {
 	MAX_PER_PKT_INFO
 };
 
+enum rndis_per_pkt_info_interal_type {
+	RNDIS_PKTINFO_ID = 1,
+	/* Add more memebers here */
+
+	RNDIS_PKTINFO_MAX
+};
+
+#define RNDIS_PKTINFO_SUBALLOC BIT(0)
+#define RNDIS_PKTINFO_1ST_FRAG BIT(1)
+#define RNDIS_PKTINFO_LAST_FRAG BIT(2)
+
+#define RNDIS_PKTINFO_ID_V1 1
+
+struct rndis_pktinfo_id {
+	u8 ver;
+	u8 flag;
+	u16 pkt_id;
+};
+
 struct ndis_pkt_8021q_info {
 	union {
 		struct {
diff --git a/drivers/net/hyperv/netvsc.c b/drivers/net/hyperv/netvsc.c
index fe01e141c8f8..922054c1d544 100644
--- a/drivers/net/hyperv/netvsc.c
+++ b/drivers/net/hyperv/netvsc.c
@@ -542,6 +542,9 @@ static int negotiate_nvsp_ver(struct hv_device *device,
 		init_packet->msg.v2_msg.send_ndis_config.capability.teaming = 1;
 	}
 
+	if (nvsp_ver >= NVSP_PROTOCOL_VERSION_61)
+		init_packet->msg.v2_msg.send_ndis_config.capability.rsc = 1;
+
 	trace_nvsp_send(ndev, init_packet);
 
 	ret = vmbus_sendpacket(device->channel, init_packet,
@@ -1111,11 +1114,12 @@ static void enq_receive_complete(struct net_device *ndev,
 
 static int netvsc_receive(struct net_device *ndev,
 			  struct netvsc_device *net_device,
-			  struct vmbus_channel *channel,
+			  struct netvsc_channel *nvchan,
 			  const struct vmpacket_descriptor *desc,
 			  const struct nvsp_message *nvsp)
 {
 	struct net_device_context *net_device_ctx = netdev_priv(ndev);
+	struct vmbus_channel *channel = nvchan->channel;
 	const struct vmtransfer_page_packet_header *vmxferpage_packet
 		= container_of(desc, const struct vmtransfer_page_packet_header, d);
 	u16 q_idx = channel->offermsg.offer.sub_channel_index;
@@ -1150,6 +1154,7 @@ static int netvsc_receive(struct net_device *ndev,
 		int ret;
 
 		if (unlikely(offset + buflen > net_device->recv_buf_size)) {
+			nvchan->rsc.cnt = 0;
 			status = NVSP_STAT_FAIL;
 			netif_err(net_device_ctx, rx_err, ndev,
 				  "Packet offset:%u + len:%u too big\n",
@@ -1160,11 +1165,13 @@ static int netvsc_receive(struct net_device *ndev,
 
 		data = recv_buf + offset;
 
+		nvchan->rsc.is_last = (i == count - 1);
+
 		trace_rndis_recv(ndev, q_idx, data);
 
 		/* Pass it to the upper layer */
 		ret = rndis_filter_receive(ndev, net_device,
-					   channel, data, buflen);
+					   nvchan, data, buflen);
 
 		if (unlikely(ret != NVSP_STAT_SUCCESS))
 			status = NVSP_STAT_FAIL;
@@ -1223,12 +1230,13 @@ static  void netvsc_receive_inband(struct net_device *ndev,
 }
 
 static int netvsc_process_raw_pkt(struct hv_device *device,
-				  struct vmbus_channel *channel,
+				  struct netvsc_channel *nvchan,
 				  struct netvsc_device *net_device,
 				  struct net_device *ndev,
 				  const struct vmpacket_descriptor *desc,
 				  int budget)
 {
+	struct vmbus_channel *channel = nvchan->channel;
 	const struct nvsp_message *nvmsg = hv_pkt_data(desc);
 
 	trace_nvsp_recv(ndev, channel, nvmsg);
@@ -1240,7 +1248,7 @@ static int netvsc_process_raw_pkt(struct hv_device *device,
 		break;
 
 	case VM_PKT_DATA_USING_XFER_PAGES:
-		return netvsc_receive(ndev, net_device, channel,
+		return netvsc_receive(ndev, net_device, nvchan,
 				      desc, nvmsg);
 		break;
 
@@ -1284,7 +1292,7 @@ int netvsc_poll(struct napi_struct *napi, int budget)
 		nvchan->desc = hv_pkt_iter_first(channel);
 
 	while (nvchan->desc && work_done < budget) {
-		work_done += netvsc_process_raw_pkt(device, channel, net_device,
+		work_done += netvsc_process_raw_pkt(device, nvchan, net_device,
 						    ndev, nvchan->desc, budget);
 		nvchan->desc = hv_pkt_iter_next(channel, nvchan->desc);
 	}
diff --git a/drivers/net/hyperv/netvsc_drv.c b/drivers/net/hyperv/netvsc_drv.c
index 3af6d8d15233..f8c18370d9d1 100644
--- a/drivers/net/hyperv/netvsc_drv.c
+++ b/drivers/net/hyperv/netvsc_drv.c
@@ -744,14 +744,16 @@ void netvsc_linkstatus_callback(struct net_device *net,
 }
 
 static struct sk_buff *netvsc_alloc_recv_skb(struct net_device *net,
-					     struct napi_struct *napi,
-					     const struct ndis_tcp_ip_checksum_info *csum_info,
-					     const struct ndis_pkt_8021q_info *vlan,
-					     void *data, u32 buflen)
+					     struct netvsc_channel *nvchan)
 {
+	struct napi_struct *napi = &nvchan->napi;
+	const struct ndis_pkt_8021q_info *vlan = nvchan->rsc.vlan;
+	const struct ndis_tcp_ip_checksum_info *csum_info =
+						nvchan->rsc.csum_info;
 	struct sk_buff *skb;
+	int i;
 
-	skb = napi_alloc_skb(napi, buflen);
+	skb = napi_alloc_skb(napi, nvchan->rsc.pktlen);
 	if (!skb)
 		return skb;
 
@@ -759,7 +761,8 @@ static struct sk_buff *netvsc_alloc_recv_skb(struct net_device *net,
 	 * Copy to skb. This copy is needed here since the memory pointed by
 	 * hv_netvsc_packet cannot be deallocated
 	 */
-	skb_put_data(skb, data, buflen);
+	for (i = 0; i < nvchan->rsc.cnt; i++)
+		skb_put_data(skb, nvchan->rsc.data[i], nvchan->rsc.len[i]);
 
 	skb->protocol = eth_type_trans(skb, net);
 
@@ -792,14 +795,11 @@ static struct sk_buff *netvsc_alloc_recv_skb(struct net_device *net,
  */
 int netvsc_recv_callback(struct net_device *net,
 			 struct netvsc_device *net_device,
-			 struct vmbus_channel *channel,
-			 void  *data, u32 len,
-			 const struct ndis_tcp_ip_checksum_info *csum_info,
-			 const struct ndis_pkt_8021q_info *vlan)
+			 struct netvsc_channel *nvchan)
 {
 	struct net_device_context *net_device_ctx = netdev_priv(net);
+	struct vmbus_channel *channel = nvchan->channel;
 	u16 q_idx = channel->offermsg.offer.sub_channel_index;
-	struct netvsc_channel *nvchan = &net_device->chan_table[q_idx];
 	struct sk_buff *skb;
 	struct netvsc_stats *rx_stats;
 
@@ -807,8 +807,8 @@ int netvsc_recv_callback(struct net_device *net,
 		return NVSP_STAT_FAIL;
 
 	/* Allocate a skb - TODO direct I/O to pages? */
-	skb = netvsc_alloc_recv_skb(net, &nvchan->napi,
-				    csum_info, vlan, data, len);
+	skb = netvsc_alloc_recv_skb(net, nvchan);
+
 	if (unlikely(!skb)) {
 		++net_device_ctx->eth_stats.rx_no_memory;
 		rcu_read_unlock();
@@ -825,7 +825,7 @@ int netvsc_recv_callback(struct net_device *net,
 	rx_stats = &nvchan->rx_stats;
 	u64_stats_update_begin(&rx_stats->syncp);
 	rx_stats->packets++;
-	rx_stats->bytes += len;
+	rx_stats->bytes += nvchan->rsc.pktlen;
 
 	if (skb->pkt_type == PACKET_BROADCAST)
 		++rx_stats->broadcast;
diff --git a/drivers/net/hyperv/rndis_filter.c b/drivers/net/hyperv/rndis_filter.c
index 2a5209f23f29..7bc8ade5c2bd 100644
--- a/drivers/net/hyperv/rndis_filter.c
+++ b/drivers/net/hyperv/rndis_filter.c
@@ -342,7 +342,8 @@ static void rndis_filter_receive_response(struct net_device *ndev,
  * Get the Per-Packet-Info with the specified type
  * return NULL if not found.
  */
-static inline void *rndis_get_ppi(struct rndis_packet *rpkt, u32 type)
+static inline void *rndis_get_ppi(struct rndis_packet *rpkt,
+				  u32 type, u8 internal)
 {
 	struct rndis_per_packet_info *ppi;
 	int len;
@@ -355,7 +356,7 @@ static inline void *rndis_get_ppi(struct rndis_packet *rpkt, u32 type)
 	len = rpkt->per_pkt_info_len;
 
 	while (len > 0) {
-		if (ppi->type == type)
+		if (ppi->type == type && ppi->internal == internal)
 			return (void *)((ulong)ppi + ppi->ppi_offset);
 		len -= ppi->size;
 		ppi = (struct rndis_per_packet_info *)((ulong)ppi + ppi->size);
@@ -364,17 +365,41 @@ static inline void *rndis_get_ppi(struct rndis_packet *rpkt, u32 type)
 	return NULL;
 }
 
+static inline void rsc_add_data
+	(struct netvsc_channel *nvchan,
+	 const struct ndis_pkt_8021q_info *vlan,
+	 const struct ndis_tcp_ip_checksum_info *csum_info,
+	 void *data, u32 len)
+{
+	u32 cnt = nvchan->rsc.cnt;
+
+	if (cnt) {
+		nvchan->rsc.pktlen += len;
+	} else {
+		nvchan->rsc.vlan = vlan;
+		nvchan->rsc.csum_info = csum_info;
+		nvchan->rsc.pktlen = len;
+	}
+
+	nvchan->rsc.data[cnt] = data;
+	nvchan->rsc.len[cnt] = len;
+	nvchan->rsc.cnt++;
+}
+
 static int rndis_filter_receive_data(struct net_device *ndev,
 				     struct netvsc_device *nvdev,
-				     struct vmbus_channel *channel,
+				     struct netvsc_channel *nvchan,
 				     struct rndis_message *msg,
 				     u32 data_buflen)
 {
 	struct rndis_packet *rndis_pkt = &msg->msg.pkt;
 	const struct ndis_tcp_ip_checksum_info *csum_info;
 	const struct ndis_pkt_8021q_info *vlan;
+	const struct rndis_pktinfo_id *pktinfo_id;
 	u32 data_offset;
 	void *data;
+	bool rsc_more = false;
+	int ret;
 
 	/* Remove the rndis header and pass it back up the stack */
 	data_offset = RNDIS_HEADER_SIZE + rndis_pkt->data_offset;
@@ -393,25 +418,59 @@ static int rndis_filter_receive_data(struct net_device *ndev,
 		return NVSP_STAT_FAIL;
 	}
 
-	vlan = rndis_get_ppi(rndis_pkt, IEEE_8021Q_INFO);
+	vlan = rndis_get_ppi(rndis_pkt, IEEE_8021Q_INFO, 0);
+
+	csum_info = rndis_get_ppi(rndis_pkt, TCPIP_CHKSUM_PKTINFO, 0);
 
-	csum_info = rndis_get_ppi(rndis_pkt, TCPIP_CHKSUM_PKTINFO);
+	pktinfo_id = rndis_get_ppi(rndis_pkt, RNDIS_PKTINFO_ID, 1);
 
 	data = (void *)msg + data_offset;
 
-	/*
-	 * Remove the rndis trailer padding from rndis packet message
+	/* Identify RSC frags, drop erroneous packets */
+	if (pktinfo_id && (pktinfo_id->flag & RNDIS_PKTINFO_SUBALLOC)) {
+		if (pktinfo_id->flag & RNDIS_PKTINFO_1ST_FRAG)
+			nvchan->rsc.cnt = 0;
+		else if (nvchan->rsc.cnt == 0)
+			goto drop;
+
+		rsc_more = true;
+
+		if (pktinfo_id->flag & RNDIS_PKTINFO_LAST_FRAG)
+			rsc_more = false;
+
+		if (rsc_more && nvchan->rsc.is_last)
+			goto drop;
+	} else {
+		nvchan->rsc.cnt = 0;
+	}
+
+	if (unlikely(nvchan->rsc.cnt >= NVSP_RSC_MAX))
+		goto drop;
+
+	/* Put data into per channel structure.
+	 * Also, remove the rndis trailer padding from rndis packet message
 	 * rndis_pkt->data_len tell us the real data length, we only copy
 	 * the data packet to the stack, without the rndis trailer padding
 	 */
-	return netvsc_recv_callback(ndev, nvdev, channel,
-				    data, rndis_pkt->data_len,
-				    csum_info, vlan);
+	rsc_add_data(nvchan, vlan, csum_info, data, rndis_pkt->data_len);
+
+	if (rsc_more)
+		return NVSP_STAT_SUCCESS;
+
+	ret = netvsc_recv_callback(ndev, nvdev, nvchan);
+	nvchan->rsc.cnt = 0;
+
+	return ret;
+
+drop:
+	/* Drop incomplete packet */
+	nvchan->rsc.cnt = 0;
+	return NVSP_STAT_FAIL;
 }
 
 int rndis_filter_receive(struct net_device *ndev,
 			 struct netvsc_device *net_dev,
-			 struct vmbus_channel *channel,
+			 struct netvsc_channel *nvchan,
 			 void *data, u32 buflen)
 {
 	struct net_device_context *net_device_ctx = netdev_priv(ndev);
@@ -422,7 +481,7 @@ int rndis_filter_receive(struct net_device *ndev,
 
 	switch (rndis_msg->ndis_msg_type) {
 	case RNDIS_MSG_PACKET:
-		return rndis_filter_receive_data(ndev, net_dev, channel,
+		return rndis_filter_receive_data(ndev, net_dev, nvchan,
 						 rndis_msg, buflen);
 	case RNDIS_MSG_INIT_C:
 	case RNDIS_MSG_QUERY_C:
@@ -1184,6 +1243,13 @@ static int rndis_netdev_set_hwcaps(struct rndis_device *rndis_device,
 		}
 	}
 
+	if (hwcaps.rsc.ip4 && hwcaps.rsc.ip6) {
+		net->hw_features |= NETIF_F_LRO;
+
+		offloads.rsc_ip_v4 = NDIS_OFFLOAD_PARAMETERS_RSC_ENABLED;
+		offloads.rsc_ip_v6 = NDIS_OFFLOAD_PARAMETERS_RSC_ENABLED;
+	}
+
 	/* In case some hw_features disappeared we need to remove them from
 	 * net->features list as they're no longer supported.
 	 */
-- 
2.18.0

^ permalink raw reply related

* [PATCH net-next,0/3] hv_netvsc: Support LRO/RSC in the vSwitch
From: Haiyang Zhang @ 2018-09-20 17:06 UTC (permalink / raw)
  To: davem, netdev
  Cc: haiyangz, kys, sthemmin, olaf, vkuznets, devel, linux-kernel

From: Haiyang Zhang <haiyangz@microsoft.com>

The patch adds support for LRO/RSC in the vSwitch feature. It reduces
the per packet processing overhead by coalescing multiple TCP segments
when possible. The feature is enabled by default on VMs running on
Windows Server 2019 and later.

The patch set also adds ethtool command handler and documents.

Haiyang Zhang (3):
  hv_netvsc: Add support for LRO/RSC in the vSwitch
  hv_netvsc: Add handler for LRO setting change
  hv_netvsc: Update document for LRO/RSC support

 Documentation/networking/netvsc.txt |  9 +++
 drivers/net/hyperv/hyperv_net.h     | 51 ++++++++++++---
 drivers/net/hyperv/netvsc.c         | 18 ++++--
 drivers/net/hyperv/netvsc_drv.c     | 58 ++++++++++++-----
 drivers/net/hyperv/rndis_filter.c   | 97 +++++++++++++++++++++++++----
 5 files changed, 194 insertions(+), 39 deletions(-)

-- 
2.18.0

^ permalink raw reply

* [RFC PATCH iproute2-next 3/3] rdma: Add an option to rename IB device interface
From: Leon Romanovsky @ 2018-09-20 11:22 UTC (permalink / raw)
  To: David Ahern; +Cc: Leon Romanovsky, netdev, RDMA mailing list, Stephen Hemminger
In-Reply-To: <20180920112232.9602-1-leon@kernel.org>

From: Leon Romanovsky <leonro@mellanox.com>

Enrich rdmatool with an option to rename IB devices,
the command interface follows Iproute2 convention:
"rdma dev set [OLD-DEVNAME] name NEW-DEVNAME"

Signed-off-by: Leon Romanovsky <leonro@mellanox.com>
---
 rdma/dev.c | 35 +++++++++++++++++++++++++++++++++++
 1 file changed, 35 insertions(+)

diff --git a/rdma/dev.c b/rdma/dev.c
index e2eafe47..760b7fb3 100644
--- a/rdma/dev.c
+++ b/rdma/dev.c
@@ -14,6 +14,7 @@
 static int dev_help(struct rd *rd)
 {
 	pr_out("Usage: %s dev show [DEV]\n", rd->filename);
+	pr_out("       %s dev set [DEV] name DEVNAME\n", rd->filename);
 	return 0;
 }

@@ -240,17 +241,51 @@ static int dev_one_show(struct rd *rd)
 	return rd_exec_cmd(rd, cmds, "parameter");
 }

+static int dev_set_name(struct rd *rd)
+{
+	uint32_t seq;
+
+	if (rd_no_arg(rd)) {
+		pr_err("Please provide device new name.\n");
+		return -EINVAL;
+	}
+
+	rd_prepare_msg(rd, RDMA_NLDEV_CMD_SET,
+		       &seq, (NLM_F_REQUEST | NLM_F_ACK));
+	mnl_attr_put_u32(rd->nlh, RDMA_NLDEV_ATTR_DEV_INDEX, rd->dev_idx);
+	mnl_attr_put_strz(rd->nlh, RDMA_NLDEV_ATTR_DEV_NAME, rd_argv(rd));
+
+	return rd_send_msg(rd);
+}
+
+static int dev_one_set(struct rd *rd)
+{
+	const struct rd_cmd cmds[] = {
+		{ NULL,		dev_help},
+		{ "name",	dev_set_name},
+		{ 0 }
+	};
+
+	return rd_exec_cmd(rd, cmds, "parameter");
+}
+
 static int dev_show(struct rd *rd)
 {
 	return rd_exec_dev(rd, dev_one_show);
 }

+static int dev_set(struct rd *rd)
+{
+	return rd_exec_require_dev(rd, dev_one_set);
+}
+
 int cmd_dev(struct rd *rd)
 {
 	const struct rd_cmd cmds[] = {
 		{ NULL,		dev_show },
 		{ "show",	dev_show },
 		{ "list",	dev_show },
+		{ "set",	dev_set },
 		{ "help",	dev_help },
 		{ 0 }
 	};

^ permalink raw reply related

* [RFC PATCH iproute2-next 2/3] rdma: Introduce command execution helper with required device name
From: Leon Romanovsky @ 2018-09-20 11:22 UTC (permalink / raw)
  To: David Ahern; +Cc: Leon Romanovsky, netdev, RDMA mailing list, Stephen Hemminger
In-Reply-To: <20180920112232.9602-1-leon@kernel.org>

From: Leon Romanovsky <leonro@mellanox.com>

In contradiction to various show commands, the set command explicitly
requires to use device name as an argument. Provide new command
execution helper which enforces it.

Signed-off-by: Leon Romanovsky <leonro@mellanox.com>
---
 rdma/rdma.h  |  1 +
 rdma/utils.c | 10 ++++++++++
 2 files changed, 11 insertions(+)

diff --git a/rdma/rdma.h b/rdma/rdma.h
index d4b7ba19..dde9e128 100644
--- a/rdma/rdma.h
+++ b/rdma/rdma.h
@@ -90,6 +90,7 @@ int cmd_link(struct rd *rd);
 int cmd_res(struct rd *rd);
 int rd_exec_cmd(struct rd *rd, const struct rd_cmd *c, const char *str);
 int rd_exec_dev(struct rd *rd, int (*cb)(struct rd *rd));
+int rd_exec_require_dev(struct rd *rd, int (*cb)(struct rd *rd));
 int rd_exec_link(struct rd *rd, int (*cb)(struct rd *rd), bool strict_port);
 void rd_free(struct rd *rd);
 int rd_set_arg_to_devname(struct rd *rd);
diff --git a/rdma/utils.c b/rdma/utils.c
index 4840bf22..61f4aeb1 100644
--- a/rdma/utils.c
+++ b/rdma/utils.c
@@ -577,6 +577,16 @@ out:
 	return ret;
 }

+int rd_exec_require_dev(struct rd *rd, int (*cb)(struct rd *rd))
+{
+	if (rd_no_arg(rd)) {
+		pr_err("Please provide device name.\n");
+		return -EINVAL;
+	}
+
+	return rd_exec_dev(rd, cb);
+}
+
 int rd_exec_cmd(struct rd *rd, const struct rd_cmd *cmds, const char *str)
 {
 	const struct rd_cmd *c;

^ 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