Netdev List
 help / color / mirror / Atom feed
* Re: [PATCH net-next 3/4] qed: Fix maximum number of CQs for iWARP
From: Leon Romanovsky @ 2017-09-19 17:46 UTC (permalink / raw)
  To: Michal Kalderon
  Cc: davem-fT/PcQaiUtIeIZ0/mPfg9Q, netdev-u79uwXL29TY76Z2rM5mHXA,
	linux-rdma-u79uwXL29TY76Z2rM5mHXA,
	dledford-H+wXaHxf7aLQT0dZR+AlfA, Ariel Elior
In-Reply-To: <1505841979-26365-4-git-send-email-Michal.Kalderon-YGCgFSpz5w/QT0dZR+AlfA@public.gmane.org>

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

On Tue, Sep 19, 2017 at 08:26:18PM +0300, Michal Kalderon wrote:
> The maximum number of CQs supported is bound to the number
> of connections supported, which differs between RoCE and iWARP.
>
> This fixes a crash that occurred in iWARP when running 1000 sessions
> using perftest.
>
> Signed-off-by: Michal Kalderon <Michal.Kalderon-YGCgFSpz5w/QT0dZR+AlfA@public.gmane.org>
> Signed-off-by: Ariel Elior <Ariel.Elior-YGCgFSpz5w/QT0dZR+AlfA@public.gmane.org>
> ---

It is worth to add Fixes line.

Thanks

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply

* [PATCH net] net: change skb->mac_header when Generic XDP calls adjust_head
From: Edward Cree @ 2017-09-19 17:45 UTC (permalink / raw)
  To: David Miller; +Cc: netdev

Since XDP's view of the packet includes the MAC header, moving the start-
 of-packet with bpf_xdp_adjust_head needs to also update the offset of the
 MAC header (which is relative to skb->head, not to the skb->data that was
 changed).
Without this, tcpdump sees packets starting from the old MAC header rather
 than the new one, at least in my tests on the loopback device.

Fixes: b5cdae3291f7 ("net: Generic XDP")
Signed-off-by: Edward Cree <ecree@solarflare.com>
---
 net/core/dev.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/net/core/dev.c b/net/core/dev.c
index fb766d9..9a2254f 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -3892,6 +3892,7 @@ static u32 netif_receive_generic_xdp(struct sk_buff *skb,
 		__skb_pull(skb, off);
 	else if (off < 0)
 		__skb_push(skb, -off);
+	skb->mac_header += off;
 
 	switch (act) {
 	case XDP_REDIRECT:

^ permalink raw reply related

* Re: [RFC PATCH 1/3] usbnet: Get rid of spammy usbnet "kevent X may have been dropped"
From: Bjørn Mork @ 2017-09-19 17:45 UTC (permalink / raw)
  To: Douglas Anderson
  Cc: Oliver Neukum, groeck, grundler, netdev, linux-usb, linux-kernel
In-Reply-To: <20170919161522.995-1-dianders@chromium.org>

Douglas Anderson <dianders@chromium.org> writes:

> Every once in a while when my system is under a bit of stress I see
> some spammy messages show up in my logs that say:
>
>   kevent X may have been dropped
>
> As far as I can tell these messages aren't terribly useful.

I agree, FWIW. These messages just confuse users for no purpose at all.


> +	/* If work is already started this will mark it to run again when it
> +	 * finishes; if we already had work pending and it hadn't started
> +	 * yet then that's fine too.
> +	 */
> +	schedule_work (&dev->kevent);
> +	netdev_dbg(dev->net, "kevent %d scheduled\n", work);

Or maybe

        if (schedule_work (&dev->kevent))
        	netdev_dbg(dev->net, "kevent %d scheduled\n", work);


?  Not that I think it matters much.


Bjørn

^ permalink raw reply

* Re: [PATCH net-next 2/4] qed: Add iWARP out of order support
From: Leon Romanovsky @ 2017-09-19 17:45 UTC (permalink / raw)
  To: Michal Kalderon
  Cc: davem-fT/PcQaiUtIeIZ0/mPfg9Q, netdev-u79uwXL29TY76Z2rM5mHXA,
	linux-rdma-u79uwXL29TY76Z2rM5mHXA,
	dledford-H+wXaHxf7aLQT0dZR+AlfA, Ariel Elior
In-Reply-To: <1505841979-26365-3-git-send-email-Michal.Kalderon-YGCgFSpz5w/QT0dZR+AlfA@public.gmane.org>

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

On Tue, Sep 19, 2017 at 08:26:17PM +0300, Michal Kalderon wrote:
> iWARP requires OOO support which is already provided by the ll2
> interface (until now was used only for iSCSI offload).
> The changes mostly include opening a ll2 dedicated connection for
> OOO and notifiying the FW about the handle id.
>
> Signed-off-by: Michal Kalderon <Michal.Kalderon-YGCgFSpz5w/QT0dZR+AlfA@public.gmane.org>
> Signed-off-by: Ariel Elior <Ariel.Elior-YGCgFSpz5w/QT0dZR+AlfA@public.gmane.org>
> ---
>  drivers/net/ethernet/qlogic/qed/qed_iwarp.c | 44 +++++++++++++++++++++++++++++
>  drivers/net/ethernet/qlogic/qed/qed_iwarp.h | 11 +++++++-
>  drivers/net/ethernet/qlogic/qed/qed_rdma.c  |  7 +++--
>  3 files changed, 59 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/net/ethernet/qlogic/qed/qed_iwarp.c b/drivers/net/ethernet/qlogic/qed/qed_iwarp.c
> index 9d989c9..568e985 100644
> --- a/drivers/net/ethernet/qlogic/qed/qed_iwarp.c
> +++ b/drivers/net/ethernet/qlogic/qed/qed_iwarp.c
> @@ -41,6 +41,7 @@
>  #include "qed_rdma.h"
>  #include "qed_reg_addr.h"
>  #include "qed_sp.h"
> +#include "qed_ooo.h"
>
>  #define QED_IWARP_ORD_DEFAULT		32
>  #define QED_IWARP_IRD_DEFAULT		32
> @@ -119,6 +120,13 @@ static void qed_iwarp_cid_cleaned(struct qed_hwfn *p_hwfn, u32 cid)
>  	spin_unlock_bh(&p_hwfn->p_rdma_info->lock);
>  }
>
> +void qed_iwarp_init_fw_ramrod(struct qed_hwfn *p_hwfn,
> +			      struct iwarp_init_func_params *p_ramrod)
> +{
> +	p_ramrod->ll2_ooo_q_index = RESC_START(p_hwfn, QED_LL2_QUEUE) +
> +				    p_hwfn->p_rdma_info->iwarp.ll2_ooo_handle;
> +}
> +
>  static int qed_iwarp_alloc_cid(struct qed_hwfn *p_hwfn, u32 *cid)
>  {
>  	int rc;
> @@ -1876,6 +1884,16 @@ static int qed_iwarp_ll2_stop(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt)
>  		iwarp_info->ll2_syn_handle = QED_IWARP_HANDLE_INVAL;
>  	}
>
> +	if (iwarp_info->ll2_ooo_handle != QED_IWARP_HANDLE_INVAL) {
> +		rc = qed_ll2_terminate_connection(p_hwfn,
> +						  iwarp_info->ll2_ooo_handle);
> +		if (rc)
> +			DP_INFO(p_hwfn, "Failed to terminate ooo connection\n");

What exactly will you do with this knowledge? Anyway you are not
interested in return values of qed_ll2_terminate_connection function in
this place and other places too.

Why don't you handle EAGAIN returned from the qed_ll2_terminate_connection()?

Thanks

> +
> +		qed_ll2_release_connection(p_hwfn, iwarp_info->ll2_ooo_handle);
> +		iwarp_info->ll2_ooo_handle = QED_IWARP_HANDLE_INVAL;
> +	}
> +
>  	qed_llh_remove_mac_filter(p_hwfn,
>  				  p_ptt, p_hwfn->p_rdma_info->iwarp.mac_addr);
>  	return rc;
> @@ -1927,10 +1945,12 @@ static int qed_iwarp_ll2_stop(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt)
>  	struct qed_iwarp_info *iwarp_info;
>  	struct qed_ll2_acquire_data data;
>  	struct qed_ll2_cbs cbs;
> +	u16 n_ooo_bufs;
>  	int rc = 0;
>
>  	iwarp_info = &p_hwfn->p_rdma_info->iwarp;
>  	iwarp_info->ll2_syn_handle = QED_IWARP_HANDLE_INVAL;
> +	iwarp_info->ll2_ooo_handle = QED_IWARP_HANDLE_INVAL;
>
>  	iwarp_info->max_mtu = params->max_mtu;
>
> @@ -1978,6 +1998,29 @@ static int qed_iwarp_ll2_stop(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt)
>  	if (rc)
>  		goto err;
>
> +	/* Start OOO connection */
> +	data.input.conn_type = QED_LL2_TYPE_OOO;
> +	data.input.mtu = params->max_mtu;
> +
> +	n_ooo_bufs = (QED_IWARP_MAX_OOO * QED_IWARP_RCV_WND_SIZE_DEF) /
> +		     iwarp_info->max_mtu;
> +	n_ooo_bufs = min_t(u32, n_ooo_bufs, QED_IWARP_LL2_OOO_MAX_RX_SIZE);
> +
> +	data.input.rx_num_desc = n_ooo_bufs;
> +	data.input.rx_num_ooo_buffers = n_ooo_bufs;
> +
> +	data.input.tx_max_bds_per_packet = 1;	/* will never be fragmented */
> +	data.input.tx_num_desc = QED_IWARP_LL2_OOO_DEF_TX_SIZE;
> +	data.p_connection_handle = &iwarp_info->ll2_ooo_handle;
> +
> +	rc = qed_ll2_acquire_connection(p_hwfn, &data);
> +	if (rc)
> +		goto err;
> +
> +	rc = qed_ll2_establish_connection(p_hwfn, iwarp_info->ll2_ooo_handle);
> +	if (rc)
> +		goto err;
> +
>  	return rc;
>  err:
>  	qed_iwarp_ll2_stop(p_hwfn, p_ptt);
> @@ -2014,6 +2057,7 @@ int qed_iwarp_setup(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt,
>
>  	qed_spq_register_async_cb(p_hwfn, PROTOCOLID_IWARP,
>  				  qed_iwarp_async_event);
> +	qed_ooo_setup(p_hwfn);
>
>  	return qed_iwarp_ll2_start(p_hwfn, params, p_ptt);
>  }
> diff --git a/drivers/net/ethernet/qlogic/qed/qed_iwarp.h b/drivers/net/ethernet/qlogic/qed/qed_iwarp.h
> index 148ef3c..9e2bfde 100644
> --- a/drivers/net/ethernet/qlogic/qed/qed_iwarp.h
> +++ b/drivers/net/ethernet/qlogic/qed/qed_iwarp.h
> @@ -47,7 +47,12 @@ enum qed_iwarp_qp_state {
>  #define QED_IWARP_LL2_SYN_TX_SIZE       (128)
>  #define QED_IWARP_LL2_SYN_RX_SIZE       (256)
>  #define QED_IWARP_MAX_SYN_PKT_SIZE      (128)
> -#define QED_IWARP_HANDLE_INVAL			(0xff)
> +
> +#define QED_IWARP_LL2_OOO_DEF_TX_SIZE   (256)
> +#define QED_IWARP_MAX_OOO		(16)
> +#define QED_IWARP_LL2_OOO_MAX_RX_SIZE   (16384)
> +
> +#define QED_IWARP_HANDLE_INVAL		(0xff)
>
>  struct qed_iwarp_ll2_buff {
>  	void *data;
> @@ -67,6 +72,7 @@ struct qed_iwarp_info {
>  	u8 crc_needed;
>  	u8 tcp_flags;
>  	u8 ll2_syn_handle;
> +	u8 ll2_ooo_handle;
>  	u8 peer2peer;
>  	enum mpa_negotiation_mode mpa_rev;
>  	enum mpa_rtr_type rtr_type;
> @@ -147,6 +153,9 @@ struct qed_iwarp_listener {
>  int qed_iwarp_setup(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt,
>  		    struct qed_rdma_start_in_params *params);
>
> +void qed_iwarp_init_fw_ramrod(struct qed_hwfn *p_hwfn,
> +			      struct iwarp_init_func_params *p_ramrod);
> +
>  int qed_iwarp_stop(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt);
>
>  void qed_iwarp_resc_free(struct qed_hwfn *p_hwfn);
> diff --git a/drivers/net/ethernet/qlogic/qed/qed_rdma.c b/drivers/net/ethernet/qlogic/qed/qed_rdma.c
> index 06715f7..4f46f28 100644
> --- a/drivers/net/ethernet/qlogic/qed/qed_rdma.c
> +++ b/drivers/net/ethernet/qlogic/qed/qed_rdma.c
> @@ -551,10 +551,13 @@ static int qed_rdma_start_fw(struct qed_hwfn *p_hwfn,
>  	if (rc)
>  		return rc;
>
> -	if (QED_IS_IWARP_PERSONALITY(p_hwfn))
> +	if (QED_IS_IWARP_PERSONALITY(p_hwfn)) {
> +		qed_iwarp_init_fw_ramrod(p_hwfn,
> +					 &p_ent->ramrod.iwarp_init_func.iwarp);
>  		p_ramrod = &p_ent->ramrod.iwarp_init_func.rdma;
> -	else
> +	} else {
>  		p_ramrod = &p_ent->ramrod.roce_init_func.rdma;
> +	}
>
>  	p_params_header = &p_ramrod->params_header;
>  	p_params_header->cnq_start_offset = (u8)RESC_START(p_hwfn,
> --
> 1.8.3.1
>

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply

* Re: [PATCH net-next 03/14] gtp: Call common functions to get tunnel routes and add dst_cache
From: David Miller @ 2017-09-19 17:44 UTC (permalink / raw)
  To: laforge; +Cc: tom, netdev, pablo, rohit
In-Reply-To: <20170919120942.dpy5kmkhzws7pqd5@nataraja>

From: Harald Welte <laforge@gnumonks.org>
Date: Tue, 19 Sep 2017 20:09:42 +0800

> So I guess you're asking us to document that rationale as form of a
> source code comment ?

Yes that would make ignoring the potential changing of the non-const
'saddr' argument at least be documented.

^ permalink raw reply

* Re: [PATCH net-next 07/14] gtp: Support encapsulation of IPv6 packets
From: David Miller @ 2017-09-19 17:42 UTC (permalink / raw)
  To: laforge; +Cc: tom, netdev, pablo, rohit
In-Reply-To: <20170919121245.t555dqwndhewmdyw@nataraja>

From: Harald Welte <laforge@gnumonks.org>
Date: Tue, 19 Sep 2017 20:12:45 +0800

> Hi Dave,
> 
> On Mon, Sep 18, 2017 at 09:19:08PM -0700, David Miller wrote:
> 
>> > +static inline u32 ipv6_hashfn(const struct in6_addr *a)
>> > +{
>> > +	return __ipv6_addr_jhash(a, gtp_h_initval);
>> > +}
>> 
>> I know you are just following the pattern of the existing "ipv4_hashfn()" here
>> but this kind of stuff is not very global namespace friendly.  Even simply
>> adding a "gtp_" prefix to these hash functions would be a lot better.
> 
> I would agree if this was an inline function defined in a header file or
> a non-static function.  But where is the global namespace concern in
> case of static inline functions defined and used in the same .c file?

The problem is if we create a generic ipv6_hashfn() in linux/ipv6.h or
something like that, then this driver stops building.

^ permalink raw reply

* Re: [RFC PATCH 3/3] usbnet: Fix memory leak when rx_submit() fails
From: Bjørn Mork @ 2017-09-19 17:41 UTC (permalink / raw)
  To: Douglas Anderson
  Cc: Oliver Neukum, groeck, grundler, netdev, linux-usb, linux-kernel
In-Reply-To: <20170919161522.995-3-dianders@chromium.org>

Douglas Anderson <dianders@chromium.org> writes:

> If rx_submit() returns an error code then nobody calls usb_free_urb().
> That means it's leaked.

Nope.  rx_submit() will call usb_free_urb() before returning an error:


static int rx_submit (struct usbnet *dev, struct urb *urb, gfp_t flags)
..
	if (!skb) {
		netif_dbg(dev, rx_err, dev->net, "no rx skb\n");
		usbnet_defer_kevent (dev, EVENT_RX_MEMORY);
		usb_free_urb (urb);
		return -ENOMEM;
	}
..
	if (retval) {
		dev_kfree_skb_any (skb);
		usb_free_urb (urb);
	}





Bjørn

^ permalink raw reply

* Re: [PATCH net] MAINTAINERS: Remove Yuval Mintz from maintainers list
From: David Miller @ 2017-09-19 17:39 UTC (permalink / raw)
  To: aelior; +Cc: netdev, everest-linux-l2
In-Reply-To: <20170919095434.1386-1-aelior@cavium.com>

From: <aelior@cavium.com>
Date: Tue, 19 Sep 2017 12:54:34 +0300

> From: Ariel Elior <aelior@cavium.com>
> 
> Remove Yuval from maintaining the bnx2x & qed* modules as he is no longer
> working for the company. Thanks Yuval for your huge contributions and
> tireless efforts over the many years and various companies.
> 
> Ariel
> Signed-off-by: Ariel Elior <aelior@cavium.com>

Applied, thanks.

^ permalink raw reply

* Re: [PATCH] VSOCK: fix uapi/linux/vm_sockets.h incomplete types
From: David Miller @ 2017-09-19 17:38 UTC (permalink / raw)
  To: stefanha; +Cc: netdev, jhansen
In-Reply-To: <20170918152100.GF4141@stefanha-x1.localdomain>

From: Stefan Hajnoczi <stefanha@redhat.com>
Date: Mon, 18 Sep 2017 16:21:00 +0100

> On Fri, Sep 15, 2017 at 02:14:32PM -0700, David Miller wrote:
>> > diff --git a/include/uapi/linux/vm_sockets.h b/include/uapi/linux/vm_sockets.h
>> > index b4ed5d895699..4ae5c625ac56 100644
>> > --- a/include/uapi/linux/vm_sockets.h
>> > +++ b/include/uapi/linux/vm_sockets.h
>> > @@ -18,6 +18,10 @@
>> >  
>> >  #include <linux/socket.h>
>> >  
>> > +#ifndef __KERNEL__
>> > +#include <sys/socket.h> /* struct sockaddr */
>> > +#endif
>> > +
>> 
>> There is no precedence whatsoever to include sys/socket.h in _any_ UAPI
>> header file provided by the kernel.
> 
> <linux/if.h> does it for the same reason:
> 
> include/uapi/linux/if.h:#include <sys/socket.h>                 /* for struct sockaddr.         */

You don't need it for struct sockaddr, you need it for sa_family_t,
the comment is very misleading.

Please do as I have instructed and it will fix this problem.

Thank you.

^ permalink raw reply

* Re: [PATCH net] bpf: do not disable/enable BH in bpf_map_free_id()
From: Martin KaFai Lau @ 2017-09-19 17:36 UTC (permalink / raw)
  To: Eric Dumazet; +Cc: David Miller, Alexei Starovoitov, netdev
In-Reply-To: <1505837759.29839.64.camel@edumazet-glaptop3.roam.corp.google.com>

On Tue, Sep 19, 2017 at 04:15:59PM +0000, Eric Dumazet wrote:
> From: Eric Dumazet <edumazet@google.com>
> 
> syzkaller reported following splat [1]
> 
> Since hard irq are disabled by the caller, bpf_map_free_id()
> should not try to enable/disable BH.
> 
> Another solution would be to change htab_map_delete_elem() to
> defer the free_htab_elem() call after
> raw_spin_unlock_irqrestore(&b->lock, flags), but this might be not
> enough to cover other code paths.
Thanks for fixing it.

Acked-by: Martin KaFai Lau <kafai@fb.com>

^ permalink raw reply

* Development Setup
From: sdnlabs Janakaraj @ 2017-09-19 17:35 UTC (permalink / raw)
  To: netdev-u79uwXL29TY76Z2rM5mHXA, dev-yBygre7rU0TnMu66kgdUjQ,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA

Dear all,
I am new a newbie, I am curious to know what development tools with Ubuntu
as Host OS, will best fit for people entering into linux kernel development
focusing on Netlink, Netdev and Wireless MAC.


I have read many blogs describing the basic setup and things like that. But
I felt input from the current developers in the same field will be more
useful.







Thanks,
Prabhu

^ permalink raw reply

* [PATCH] net: emac: Fix napi poll list corruption
From: Christian Lamparter @ 2017-09-19 17:35 UTC (permalink / raw)
  To: netdev; +Cc: David S . Miller

This patch is pretty much a carbon copy of
commit 3079c652141f ("caif: Fix napi poll list corruption")
with "caif" replaced by "emac".

The commit d75b1ade567f ("net: less interrupt masking in NAPI")
breaks emac.

It is now required that if the entire budget is consumed when poll
returns, the napi poll_list must remain empty.  However, like some
other drivers emac tries to do a last-ditch check and if there is
more work it will call napi_reschedule and then immediately process
some of this new work.  Should the entire budget be consumed while
processing such new work then we will violate the new caller
contract.

This patch fixes this by not touching any work when we reschedule
in emac.

Signed-off-by: Christian Lamparter <chunkeey@googlemail.com>
---
 drivers/net/ethernet/ibm/emac/mal.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/drivers/net/ethernet/ibm/emac/mal.c b/drivers/net/ethernet/ibm/emac/mal.c
index 2c74baa2398a..fff09dcf9e34 100644
--- a/drivers/net/ethernet/ibm/emac/mal.c
+++ b/drivers/net/ethernet/ibm/emac/mal.c
@@ -402,7 +402,7 @@ static int mal_poll(struct napi_struct *napi, int budget)
 	unsigned long flags;
 
 	MAL_DBG2(mal, "poll(%d)" NL, budget);
- again:
+
 	/* Process TX skbs */
 	list_for_each(l, &mal->poll_list) {
 		struct mal_commac *mc =
@@ -451,7 +451,6 @@ static int mal_poll(struct napi_struct *napi, int budget)
 			spin_lock_irqsave(&mal->lock, flags);
 			mal_disable_eob_irq(mal);
 			spin_unlock_irqrestore(&mal->lock, flags);
-			goto again;
 		}
 		mc->ops->poll_tx(mc->dev);
 	}
-- 
2.14.1

^ permalink raw reply related

* [PATCH net-next 4/4] qed: iWARP - Add check for errors on a SYN packet
From: Michal Kalderon @ 2017-09-19 17:26 UTC (permalink / raw)
  To: davem, netdev; +Cc: linux-rdma, dledford, Michal Kalderon, Ariel Elior
In-Reply-To: <1505841979-26365-1-git-send-email-Michal.Kalderon@cavium.com>

A SYN packet which arrives with errors from FW should be dropped.
This required adding an additional field to the ll2
rx completion data.

Signed-off-by: Michal Kalderon <Michal.Kalderon@cavium.com>
Signed-off-by: Ariel Elior <Ariel.Elior@cavium.com>
---
 drivers/net/ethernet/qlogic/qed/qed_iwarp.c | 8 ++++++++
 drivers/net/ethernet/qlogic/qed/qed_ll2.c   | 1 +
 include/linux/qed/qed_ll2_if.h              | 1 +
 3 files changed, 10 insertions(+)

diff --git a/drivers/net/ethernet/qlogic/qed/qed_iwarp.c b/drivers/net/ethernet/qlogic/qed/qed_iwarp.c
index 568e985..8fc9c811 100644
--- a/drivers/net/ethernet/qlogic/qed/qed_iwarp.c
+++ b/drivers/net/ethernet/qlogic/qed/qed_iwarp.c
@@ -1733,6 +1733,14 @@ int qed_iwarp_reject(void *rdma_cxt, struct qed_iwarp_reject_in *iparams)
 
 	memset(&cm_info, 0, sizeof(cm_info));
 	ll2_syn_handle = p_hwfn->p_rdma_info->iwarp.ll2_syn_handle;
+
+	/* Check if packet was received with errors... */
+	if (data->err_flags) {
+		DP_NOTICE(p_hwfn, "Error received on SYN packet: 0x%x\n",
+			  data->err_flags);
+		goto err;
+	}
+
 	if (GET_FIELD(data->parse_flags,
 		      PARSING_AND_ERR_FLAGS_L4CHKSMWASCALCULATED) &&
 	    GET_FIELD(data->parse_flags, PARSING_AND_ERR_FLAGS_L4CHKSMERROR)) {
diff --git a/drivers/net/ethernet/qlogic/qed/qed_ll2.c b/drivers/net/ethernet/qlogic/qed/qed_ll2.c
index c06ad4f..250afa5 100644
--- a/drivers/net/ethernet/qlogic/qed/qed_ll2.c
+++ b/drivers/net/ethernet/qlogic/qed/qed_ll2.c
@@ -413,6 +413,7 @@ static void qed_ll2_rxq_parse_reg(struct qed_hwfn *p_hwfn,
 				  struct qed_ll2_comp_rx_data *data)
 {
 	data->parse_flags = le16_to_cpu(p_cqe->rx_cqe_fp.parse_flags.flags);
+	data->err_flags = le16_to_cpu(p_cqe->rx_cqe_fp.err_flags.flags);
 	data->length.packet_length =
 	    le16_to_cpu(p_cqe->rx_cqe_fp.packet_length);
 	data->vlan = le16_to_cpu(p_cqe->rx_cqe_fp.vlan);
diff --git a/include/linux/qed/qed_ll2_if.h b/include/linux/qed/qed_ll2_if.h
index dd7a3b8..89fa0bb 100644
--- a/include/linux/qed/qed_ll2_if.h
+++ b/include/linux/qed/qed_ll2_if.h
@@ -101,6 +101,7 @@ struct qed_ll2_comp_rx_data {
 	void *cookie;
 	dma_addr_t rx_buf_addr;
 	u16 parse_flags;
+	u16 err_flags;
 	u16 vlan;
 	bool b_last_packet;
 	u8 connection_handle;
-- 
1.8.3.1

^ permalink raw reply related

* [PATCH net-next 3/4] qed: Fix maximum number of CQs for iWARP
From: Michal Kalderon @ 2017-09-19 17:26 UTC (permalink / raw)
  To: davem, netdev; +Cc: linux-rdma, dledford, Michal Kalderon, Ariel Elior
In-Reply-To: <1505841979-26365-1-git-send-email-Michal.Kalderon@cavium.com>

The maximum number of CQs supported is bound to the number
of connections supported, which differs between RoCE and iWARP.

This fixes a crash that occurred in iWARP when running 1000 sessions
using perftest.

Signed-off-by: Michal Kalderon <Michal.Kalderon@cavium.com>
Signed-off-by: Ariel Elior <Ariel.Elior@cavium.com>
---
 drivers/net/ethernet/qlogic/qed/qed_rdma.c | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/drivers/net/ethernet/qlogic/qed/qed_rdma.c b/drivers/net/ethernet/qlogic/qed/qed_rdma.c
index 4f46f28..c8c4b39 100644
--- a/drivers/net/ethernet/qlogic/qed/qed_rdma.c
+++ b/drivers/net/ethernet/qlogic/qed/qed_rdma.c
@@ -209,11 +209,11 @@ static int qed_rdma_alloc(struct qed_hwfn *p_hwfn,
 		goto free_pd_map;
 	}
 
-	/* Allocate bitmap for cq's. The maximum number of CQs is bounded to
-	 * twice the number of QPs.
+	/* Allocate bitmap for cq's. The maximum number of CQs is bound to
+	 * the number of connections we support. (num_qps in iWARP or
+	 * num_qps/2 in RoCE).
 	 */
-	rc = qed_rdma_bmap_alloc(p_hwfn, &p_rdma_info->cq_map,
-				 p_rdma_info->num_qps * 2, "CQ");
+	rc = qed_rdma_bmap_alloc(p_hwfn, &p_rdma_info->cq_map, num_cons, "CQ");
 	if (rc) {
 		DP_VERBOSE(p_hwfn, QED_MSG_RDMA,
 			   "Failed to allocate cq bitmap, rc = %d\n", rc);
@@ -222,10 +222,10 @@ static int qed_rdma_alloc(struct qed_hwfn *p_hwfn,
 
 	/* Allocate bitmap for toggle bit for cq icids
 	 * We toggle the bit every time we create or resize cq for a given icid.
-	 * The maximum number of CQs is bounded to  twice the number of QPs.
+	 * Size needs to equal the size of the cq bmap.
 	 */
 	rc = qed_rdma_bmap_alloc(p_hwfn, &p_rdma_info->toggle_bits,
-				 p_rdma_info->num_qps * 2, "Toggle");
+				 num_cons, "Toggle");
 	if (rc) {
 		DP_VERBOSE(p_hwfn, QED_MSG_RDMA,
 			   "Failed to allocate toogle bits, rc = %d\n", rc);
-- 
1.8.3.1

^ permalink raw reply related

* [PATCH net-next 2/4] qed: Add iWARP out of order support
From: Michal Kalderon @ 2017-09-19 17:26 UTC (permalink / raw)
  To: davem, netdev; +Cc: linux-rdma, dledford, Michal Kalderon, Ariel Elior
In-Reply-To: <1505841979-26365-1-git-send-email-Michal.Kalderon@cavium.com>

iWARP requires OOO support which is already provided by the ll2
interface (until now was used only for iSCSI offload).
The changes mostly include opening a ll2 dedicated connection for
OOO and notifiying the FW about the handle id.

Signed-off-by: Michal Kalderon <Michal.Kalderon@cavium.com>
Signed-off-by: Ariel Elior <Ariel.Elior@cavium.com>
---
 drivers/net/ethernet/qlogic/qed/qed_iwarp.c | 44 +++++++++++++++++++++++++++++
 drivers/net/ethernet/qlogic/qed/qed_iwarp.h | 11 +++++++-
 drivers/net/ethernet/qlogic/qed/qed_rdma.c  |  7 +++--
 3 files changed, 59 insertions(+), 3 deletions(-)

diff --git a/drivers/net/ethernet/qlogic/qed/qed_iwarp.c b/drivers/net/ethernet/qlogic/qed/qed_iwarp.c
index 9d989c9..568e985 100644
--- a/drivers/net/ethernet/qlogic/qed/qed_iwarp.c
+++ b/drivers/net/ethernet/qlogic/qed/qed_iwarp.c
@@ -41,6 +41,7 @@
 #include "qed_rdma.h"
 #include "qed_reg_addr.h"
 #include "qed_sp.h"
+#include "qed_ooo.h"
 
 #define QED_IWARP_ORD_DEFAULT		32
 #define QED_IWARP_IRD_DEFAULT		32
@@ -119,6 +120,13 @@ static void qed_iwarp_cid_cleaned(struct qed_hwfn *p_hwfn, u32 cid)
 	spin_unlock_bh(&p_hwfn->p_rdma_info->lock);
 }
 
+void qed_iwarp_init_fw_ramrod(struct qed_hwfn *p_hwfn,
+			      struct iwarp_init_func_params *p_ramrod)
+{
+	p_ramrod->ll2_ooo_q_index = RESC_START(p_hwfn, QED_LL2_QUEUE) +
+				    p_hwfn->p_rdma_info->iwarp.ll2_ooo_handle;
+}
+
 static int qed_iwarp_alloc_cid(struct qed_hwfn *p_hwfn, u32 *cid)
 {
 	int rc;
@@ -1876,6 +1884,16 @@ static int qed_iwarp_ll2_stop(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt)
 		iwarp_info->ll2_syn_handle = QED_IWARP_HANDLE_INVAL;
 	}
 
+	if (iwarp_info->ll2_ooo_handle != QED_IWARP_HANDLE_INVAL) {
+		rc = qed_ll2_terminate_connection(p_hwfn,
+						  iwarp_info->ll2_ooo_handle);
+		if (rc)
+			DP_INFO(p_hwfn, "Failed to terminate ooo connection\n");
+
+		qed_ll2_release_connection(p_hwfn, iwarp_info->ll2_ooo_handle);
+		iwarp_info->ll2_ooo_handle = QED_IWARP_HANDLE_INVAL;
+	}
+
 	qed_llh_remove_mac_filter(p_hwfn,
 				  p_ptt, p_hwfn->p_rdma_info->iwarp.mac_addr);
 	return rc;
@@ -1927,10 +1945,12 @@ static int qed_iwarp_ll2_stop(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt)
 	struct qed_iwarp_info *iwarp_info;
 	struct qed_ll2_acquire_data data;
 	struct qed_ll2_cbs cbs;
+	u16 n_ooo_bufs;
 	int rc = 0;
 
 	iwarp_info = &p_hwfn->p_rdma_info->iwarp;
 	iwarp_info->ll2_syn_handle = QED_IWARP_HANDLE_INVAL;
+	iwarp_info->ll2_ooo_handle = QED_IWARP_HANDLE_INVAL;
 
 	iwarp_info->max_mtu = params->max_mtu;
 
@@ -1978,6 +1998,29 @@ static int qed_iwarp_ll2_stop(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt)
 	if (rc)
 		goto err;
 
+	/* Start OOO connection */
+	data.input.conn_type = QED_LL2_TYPE_OOO;
+	data.input.mtu = params->max_mtu;
+
+	n_ooo_bufs = (QED_IWARP_MAX_OOO * QED_IWARP_RCV_WND_SIZE_DEF) /
+		     iwarp_info->max_mtu;
+	n_ooo_bufs = min_t(u32, n_ooo_bufs, QED_IWARP_LL2_OOO_MAX_RX_SIZE);
+
+	data.input.rx_num_desc = n_ooo_bufs;
+	data.input.rx_num_ooo_buffers = n_ooo_bufs;
+
+	data.input.tx_max_bds_per_packet = 1;	/* will never be fragmented */
+	data.input.tx_num_desc = QED_IWARP_LL2_OOO_DEF_TX_SIZE;
+	data.p_connection_handle = &iwarp_info->ll2_ooo_handle;
+
+	rc = qed_ll2_acquire_connection(p_hwfn, &data);
+	if (rc)
+		goto err;
+
+	rc = qed_ll2_establish_connection(p_hwfn, iwarp_info->ll2_ooo_handle);
+	if (rc)
+		goto err;
+
 	return rc;
 err:
 	qed_iwarp_ll2_stop(p_hwfn, p_ptt);
@@ -2014,6 +2057,7 @@ int qed_iwarp_setup(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt,
 
 	qed_spq_register_async_cb(p_hwfn, PROTOCOLID_IWARP,
 				  qed_iwarp_async_event);
+	qed_ooo_setup(p_hwfn);
 
 	return qed_iwarp_ll2_start(p_hwfn, params, p_ptt);
 }
diff --git a/drivers/net/ethernet/qlogic/qed/qed_iwarp.h b/drivers/net/ethernet/qlogic/qed/qed_iwarp.h
index 148ef3c..9e2bfde 100644
--- a/drivers/net/ethernet/qlogic/qed/qed_iwarp.h
+++ b/drivers/net/ethernet/qlogic/qed/qed_iwarp.h
@@ -47,7 +47,12 @@ enum qed_iwarp_qp_state {
 #define QED_IWARP_LL2_SYN_TX_SIZE       (128)
 #define QED_IWARP_LL2_SYN_RX_SIZE       (256)
 #define QED_IWARP_MAX_SYN_PKT_SIZE      (128)
-#define QED_IWARP_HANDLE_INVAL			(0xff)
+
+#define QED_IWARP_LL2_OOO_DEF_TX_SIZE   (256)
+#define QED_IWARP_MAX_OOO		(16)
+#define QED_IWARP_LL2_OOO_MAX_RX_SIZE   (16384)
+
+#define QED_IWARP_HANDLE_INVAL		(0xff)
 
 struct qed_iwarp_ll2_buff {
 	void *data;
@@ -67,6 +72,7 @@ struct qed_iwarp_info {
 	u8 crc_needed;
 	u8 tcp_flags;
 	u8 ll2_syn_handle;
+	u8 ll2_ooo_handle;
 	u8 peer2peer;
 	enum mpa_negotiation_mode mpa_rev;
 	enum mpa_rtr_type rtr_type;
@@ -147,6 +153,9 @@ struct qed_iwarp_listener {
 int qed_iwarp_setup(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt,
 		    struct qed_rdma_start_in_params *params);
 
+void qed_iwarp_init_fw_ramrod(struct qed_hwfn *p_hwfn,
+			      struct iwarp_init_func_params *p_ramrod);
+
 int qed_iwarp_stop(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt);
 
 void qed_iwarp_resc_free(struct qed_hwfn *p_hwfn);
diff --git a/drivers/net/ethernet/qlogic/qed/qed_rdma.c b/drivers/net/ethernet/qlogic/qed/qed_rdma.c
index 06715f7..4f46f28 100644
--- a/drivers/net/ethernet/qlogic/qed/qed_rdma.c
+++ b/drivers/net/ethernet/qlogic/qed/qed_rdma.c
@@ -551,10 +551,13 @@ static int qed_rdma_start_fw(struct qed_hwfn *p_hwfn,
 	if (rc)
 		return rc;
 
-	if (QED_IS_IWARP_PERSONALITY(p_hwfn))
+	if (QED_IS_IWARP_PERSONALITY(p_hwfn)) {
+		qed_iwarp_init_fw_ramrod(p_hwfn,
+					 &p_ent->ramrod.iwarp_init_func.iwarp);
 		p_ramrod = &p_ent->ramrod.iwarp_init_func.rdma;
-	else
+	} else {
 		p_ramrod = &p_ent->ramrod.roce_init_func.rdma;
+	}
 
 	p_params_header = &p_ramrod->params_header;
 	p_params_header->cnq_start_offset = (u8)RESC_START(p_hwfn,
-- 
1.8.3.1

^ permalink raw reply related

* [PATCH net-next 1/4] qed: Add iWARP enablement support
From: Michal Kalderon @ 2017-09-19 17:26 UTC (permalink / raw)
  To: davem, netdev; +Cc: linux-rdma, dledford, Michal Kalderon, Ariel Elior
In-Reply-To: <1505841979-26365-1-git-send-email-Michal.Kalderon@cavium.com>

This patch is the last of the initial iWARP patch series. It
adds the possiblity to actually detect iWARP from the device and enable
it in the critical locations which basically make iWARP available.

It wasn't submitted until now as iWARP hadn't been accepted into
the rdma tree.

Signed-off-by: Michal Kalderon <Michal.Kalderon@cavium.com>
Signed-off-by: Ariel Elior <Ariel.Elior@cavium.com>
---
 drivers/net/ethernet/qlogic/qed/qed_cxt.c         |  6 ++++++
 drivers/net/ethernet/qlogic/qed/qed_mcp.c         | 10 +++++-----
 drivers/net/ethernet/qlogic/qed/qed_rdma.c        |  5 ++++-
 drivers/net/ethernet/qlogic/qed/qed_sp_commands.c |  1 +
 4 files changed, 16 insertions(+), 6 deletions(-)

diff --git a/drivers/net/ethernet/qlogic/qed/qed_cxt.c b/drivers/net/ethernet/qlogic/qed/qed_cxt.c
index af106be..afd07ad 100644
--- a/drivers/net/ethernet/qlogic/qed/qed_cxt.c
+++ b/drivers/net/ethernet/qlogic/qed/qed_cxt.c
@@ -2069,6 +2069,12 @@ static void qed_rdma_set_pf_params(struct qed_hwfn *p_hwfn,
 
 	num_srqs = min_t(u32, 32 * 1024, p_params->num_srqs);
 
+	if (p_hwfn->mcp_info->func_info.protocol == QED_PCI_ETH_RDMA) {
+		DP_NOTICE(p_hwfn,
+			  "Current day drivers don't support RoCE & iWARP simultaneously on the same PF. Default to RoCE-only\n");
+		p_hwfn->hw_info.personality = QED_PCI_ETH_ROCE;
+	}
+
 	switch (p_hwfn->hw_info.personality) {
 	case QED_PCI_ETH_IWARP:
 		/* Each QP requires one connection */
diff --git a/drivers/net/ethernet/qlogic/qed/qed_mcp.c b/drivers/net/ethernet/qlogic/qed/qed_mcp.c
index 376485d..8b99c7d 100644
--- a/drivers/net/ethernet/qlogic/qed/qed_mcp.c
+++ b/drivers/net/ethernet/qlogic/qed/qed_mcp.c
@@ -1691,12 +1691,12 @@ int qed_mcp_get_media_type(struct qed_dev *cdev, u32 *p_media_type)
 	case FW_MB_PARAM_GET_PF_RDMA_ROCE:
 		*p_proto = QED_PCI_ETH_ROCE;
 		break;
-	case FW_MB_PARAM_GET_PF_RDMA_BOTH:
-		DP_NOTICE(p_hwfn,
-			  "Current day drivers don't support RoCE & iWARP. Default to RoCE-only\n");
-		*p_proto = QED_PCI_ETH_ROCE;
-		break;
 	case FW_MB_PARAM_GET_PF_RDMA_IWARP:
+		*p_proto = QED_PCI_ETH_IWARP;
+		break;
+	case FW_MB_PARAM_GET_PF_RDMA_BOTH:
+		*p_proto = QED_PCI_ETH_RDMA;
+		break;
 	default:
 		DP_NOTICE(p_hwfn,
 			  "MFW answers GET_PF_RDMA_PROTOCOL but param is %08x\n",
diff --git a/drivers/net/ethernet/qlogic/qed/qed_rdma.c b/drivers/net/ethernet/qlogic/qed/qed_rdma.c
index 6fb9951..06715f7 100644
--- a/drivers/net/ethernet/qlogic/qed/qed_rdma.c
+++ b/drivers/net/ethernet/qlogic/qed/qed_rdma.c
@@ -156,7 +156,10 @@ static int qed_rdma_alloc(struct qed_hwfn *p_hwfn,
 		return rc;
 
 	p_hwfn->p_rdma_info = p_rdma_info;
-	p_rdma_info->proto = PROTOCOLID_ROCE;
+	if (QED_IS_IWARP_PERSONALITY(p_hwfn))
+		p_rdma_info->proto = PROTOCOLID_IWARP;
+	else
+		p_rdma_info->proto = PROTOCOLID_ROCE;
 
 	num_cons = qed_cxt_get_proto_cid_count(p_hwfn, p_rdma_info->proto,
 					       NULL);
diff --git a/drivers/net/ethernet/qlogic/qed/qed_sp_commands.c b/drivers/net/ethernet/qlogic/qed/qed_sp_commands.c
index 46d0c3c..a1d33f3 100644
--- a/drivers/net/ethernet/qlogic/qed/qed_sp_commands.c
+++ b/drivers/net/ethernet/qlogic/qed/qed_sp_commands.c
@@ -377,6 +377,7 @@ int qed_sp_pf_start(struct qed_hwfn *p_hwfn,
 		p_ramrod->personality = PERSONALITY_ISCSI;
 		break;
 	case QED_PCI_ETH_ROCE:
+	case QED_PCI_ETH_IWARP:
 		p_ramrod->personality = PERSONALITY_RDMA_AND_ETH;
 		break;
 	default:
-- 
1.8.3.1

^ permalink raw reply related

* [PATCH net-next 0/4] qed: iWARP fixes and enhancements
From: Michal Kalderon @ 2017-09-19 17:26 UTC (permalink / raw)
  To: davem-fT/PcQaiUtIeIZ0/mPfg9Q, netdev-u79uwXL29TY76Z2rM5mHXA
  Cc: linux-rdma-u79uwXL29TY76Z2rM5mHXA,
	dledford-H+wXaHxf7aLQT0dZR+AlfA, Michal Kalderon, Ariel Elior

This patch series includes several fixes and enhancements
related to iWARP.

Patch #1 is actually the last of the initial iWARP submission.
It has been delayed until now as I wanted to make sure that qedr
supports iWARP prior to enabling iWARP device detection.

iWARP changes in RDMA tree have been accepted and targeted at
kernel 4.15, therefore, all iWARP fixes for this cycle are
submitted to net-next.

Signed-off by: Michal.Kalderon-YGCgFSpz5w/QT0dZR+AlfA@public.gmane.org
Signed-off-by: Ariel Elior <Ariel.Elior-YGCgFSpz5w/QT0dZR+AlfA@public.gmane.org>

Michal Kalderon (4):
  qed: Add iWARP enablement support
  qed: Add iWARP out of order support
  qed: Fix maximum number of CQs for iWARP
  qed: iWARP - Add check for errors on a SYN packet

 drivers/net/ethernet/qlogic/qed/qed_cxt.c         |  6 +++
 drivers/net/ethernet/qlogic/qed/qed_iwarp.c       | 52 +++++++++++++++++++++++
 drivers/net/ethernet/qlogic/qed/qed_iwarp.h       | 11 ++++-
 drivers/net/ethernet/qlogic/qed/qed_ll2.c         |  1 +
 drivers/net/ethernet/qlogic/qed/qed_mcp.c         | 10 ++---
 drivers/net/ethernet/qlogic/qed/qed_rdma.c        | 24 +++++++----
 drivers/net/ethernet/qlogic/qed/qed_sp_commands.c |  1 +
 include/linux/qed/qed_ll2_if.h                    |  1 +
 8 files changed, 91 insertions(+), 15 deletions(-)

-- 
1.8.3.1

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

^ permalink raw reply

* [PATCH] net: compat: assert the size of cmsg copied in is as expected
From: Meng Xu @ 2017-09-19 17:19 UTC (permalink / raw)
  To: davem, netdev, linux-kernel; +Cc: meng.xu, sanidhya, taesoo, Meng Xu

The actual length of cmsg fetched in during the second loop
(i.e., kcmsg - kcmsg_base) could be different from what we
get from the first loop (i.e., kcmlen).

The main reason is that the two get_user() calls in the two
loops (i.e., get_user(ucmlen, &ucmsg->cmsg_len) and
__get_user(ucmlen, &ucmsg->cmsg_len)) could cause ucmlen
to have different values even they fetch from the same userspace
address, as user can race to change the memory content in
&ucmsg->cmsg_len across fetches.

Although in the second loop, the sanity check
if ((char *)kcmsg_base + kcmlen - (char *)kcmsg < CMSG_ALIGN(tmp))
is inplace, it only ensures that the cmsg fetched in during the
second loop does not exceed the length of kcmlen, but not
necessarily equal to kcmlen. But indicated by the assignment
kmsg->msg_controllen = kcmlen, we should enforce that.

This patch adds this additional sanity check and ensures that
what is recorded in kmsg->msg_controllen is the actual cmsg length.

Signed-off-by: Meng Xu <mengxu.gatech@gmail.com>
---
 net/compat.c | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/net/compat.c b/net/compat.c
index 6ded6c8..2238171 100644
--- a/net/compat.c
+++ b/net/compat.c
@@ -185,6 +185,13 @@ int cmsghdr_from_user_compat_to_kern(struct msghdr *kmsg, struct sock *sk,
 		ucmsg = cmsg_compat_nxthdr(kmsg, ucmsg, ucmlen);
 	}
 
+	/*
+	 * check the length of messages copied in is the same as the
+	 * what we get from the first loop
+	 */
+	if ((char *)kcmsg - (char *)kcmsg_base != kcmlen)
+		goto Einval;
+
 	/* Ok, looks like we made it.  Hook it up and return success. */
 	kmsg->msg_control = kcmsg_base;
 	kmsg->msg_controllen = kcmlen;
-- 
2.7.4

^ permalink raw reply related

* [PATCH net] tcp: fastopen: fix on syn-data transmit failure
From: Eric Dumazet @ 2017-09-19 17:05 UTC (permalink / raw)
  To: David Miller; +Cc: Yuchung Cheng, Neal Cardwell, netdev

From: Eric Dumazet <edumazet@google.com>

Our recent change exposed a bug in TCP Fastopen Client that syzkaller
found right away [1]

When we prepare skb with SYN+DATA, we attempt to transmit it,
and we update socket state as if the transmit was a success.

In socket RTX queue we have two skbs, one with the SYN alone,
and a second one containing the DATA.

When (malicious) ACK comes in, we now complain that second one had no
skb_mstamp.

The proper fix is to make sure that if the transmit failed, we do not
pretend we sent the DATA skb, and make it our send_head.

When 3WHS completes, we can now send the DATA right away, without having
to wait for a timeout.

[1]
WARNING: CPU: 0 PID: 100189 at net/ipv4/tcp_input.c:3117 tcp_clean_rtx_queue+0x2057/0x2ab0 net/ipv4/tcp_input.c:3117()

 WARN_ON_ONCE(last_ackt == 0);

Modules linked in:
CPU: 0 PID: 100189 Comm: syz-executor1 Not tainted 
Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 01/01/2011
 0000000000000000 ffff8800b35cb1d8 ffffffff81cad00d 0000000000000000
 ffffffff828a4347 ffff88009f86c080 ffffffff8316eb20 0000000000000d7f
 ffff8800b35cb220 ffffffff812c33c2 ffff8800baad2440 00000009d46575c0
Call Trace:
 [<ffffffff81cad00d>] __dump_stack 
 [<ffffffff81cad00d>] dump_stack+0xc1/0x124 
 [<ffffffff812c33c2>] warn_slowpath_common+0xe2/0x150 
 [<ffffffff812c361e>] warn_slowpath_null+0x2e/0x40 
 [<ffffffff828a4347>] tcp_clean_rtx_queue+0x2057/0x2ab0 n
 [<ffffffff828ae6fd>] tcp_ack+0x151d/0x3930 
 [<ffffffff828baa09>] tcp_rcv_state_process+0x1c69/0x4fd0 
 [<ffffffff828efb7f>] tcp_v4_do_rcv+0x54f/0x7c0 
 [<ffffffff8258aacb>] sk_backlog_rcv 
 [<ffffffff8258aacb>] __release_sock+0x12b/0x3a0 
 [<ffffffff8258ad9e>] release_sock+0x5e/0x1c0 
 [<ffffffff8294a785>] inet_wait_for_connect 
 [<ffffffff8294a785>] __inet_stream_connect+0x545/0xc50 
 [<ffffffff82886f08>] tcp_sendmsg_fastopen 
 [<ffffffff82886f08>] tcp_sendmsg+0x2298/0x35a0 
 [<ffffffff82952515>] inet_sendmsg+0xe5/0x520 
 [<ffffffff8257152f>] sock_sendmsg_nosec 
 [<ffffffff8257152f>] sock_sendmsg+0xcf/0x110 

Fixes: 8c72c65b426b ("tcp: update skb->skb_mstamp more carefully")
Fixes: 783237e8daf1 ("net-tcp: Fast Open client - sending SYN-data")
Signed-off-by: Eric Dumazet <edumazet@google.com>
Reported-by: Dmitry Vyukov <dvyukov@google.com>
Cc: Neal Cardwell <ncardwell@google.com>
Cc: Yuchung Cheng <ycheng@google.com>
---
 net/ipv4/tcp_output.c |    9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c
index 517d737059d18d8821b65dcdf54d9bb3448784c2..0bc9e46a53696578eb6e911f2f75e6b34c80894f 100644
--- a/net/ipv4/tcp_output.c
+++ b/net/ipv4/tcp_output.c
@@ -3389,6 +3389,10 @@ static int tcp_send_syn_data(struct sock *sk, struct sk_buff *syn)
 		goto done;
 	}
 
+	/* data was not sent, this is our new send_head */
+	sk->sk_send_head = syn_data;
+	tp->packets_out -= tcp_skb_pcount(syn_data);
+
 fallback:
 	/* Send a regular SYN with Fast Open cookie request option */
 	if (fo->cookie.len > 0)
@@ -3441,6 +3445,11 @@ int tcp_connect(struct sock *sk)
 	 */
 	tp->snd_nxt = tp->write_seq;
 	tp->pushed_seq = tp->write_seq;
+	buff = tcp_send_head(sk);
+	if (unlikely(buff)) {
+		tp->snd_nxt	= TCP_SKB_CB(buff)->seq;
+		tp->pushed_seq	= TCP_SKB_CB(buff)->seq;
+	}
 	TCP_INC_STATS(sock_net(sk), TCP_MIB_ACTIVEOPENS);
 
 	/* Timer for repeating the SYN until an answer. */

^ permalink raw reply related

* Re: [PATCH RFC V1 net-next 0/6] Time based packet transmission
From: Richard Cochran @ 2017-09-19 16:46 UTC (permalink / raw)
  To: Miroslav Lichvar
  Cc: Richard Cochran, netdev, Andre Guedes, Henrik Austad,
	linux-kernel, Jesus Sanchez-Palencia, intel-wired-lan,
	John Stultz, Thomas Gleixner, Anna-Maria Gleixner, David Miller
In-Reply-To: <20170919144302.GB4347@localhost>

On Tue, Sep 19, 2017 at 04:43:02PM +0200, Miroslav Lichvar wrote:
> If I understand it correctly, this also allows us to make a PTP/NTP
> "one-step" clock with HW that doesn't support it directly.

Cool, yeah, I hadn't thought of that, but it would work...

Thanks,
Richard

^ permalink raw reply

* Re: [PATCH net v2] l2tp: fix race condition in l2tp_tunnel_delete
From: Guillaume Nault @ 2017-09-19 16:43 UTC (permalink / raw)
  To: Sabrina Dubroca; +Cc: netdev, Xin Long, Tom Parkin
In-Reply-To: <6bfc5aceda47773af4c75fe7e0e3c0d255a2342d.1505828155.git.sd@queasysnail.net>

On Tue, Sep 19, 2017 at 03:40:40PM +0200, Sabrina Dubroca wrote:
> If we try to delete the same tunnel twice, the first delete operation
> does a lookup (l2tp_tunnel_get), finds the tunnel, calls
> l2tp_tunnel_delete, which queues it for deletion by
> l2tp_tunnel_del_work.
> 
> The second delete operation also finds the tunnel and calls
> l2tp_tunnel_delete. If the workqueue has already fired and started
> running l2tp_tunnel_del_work, then l2tp_tunnel_delete will queue the
> same tunnel a second time, and try to free the socket again.
> 
> Add a dead flag to prevent firing the workqueue twice. Then we can
> remove the check of queue_work's result that was meant to prevent that
> race but doesn't.
> 
> Also check the flag in the tunnel lookup functions, to avoid returning a
> tunnel that is already scheduled for destruction.
> 
> Reproducer:
> 
>     ip l2tp add tunnel tunnel_id 3000 peer_tunnel_id 4000 local 192.168.0.2 remote 192.168.0.1 encap udp udp_sport 5000 udp_dport 6000
>     ip l2tp add session name l2tp1 tunnel_id 3000 session_id 1000 peer_session_id 2000
>     ip link set l2tp1 up
>     ip l2tp del tunnel tunnel_id 3000
>     ip l2tp del tunnel tunnel_id 3000
> 
> Fixes: f8ccac0e4493 ("l2tp: put tunnel socket release on a workqueue")
> Reported-by: Jianlin Shi <jishi@redhat.com>
> Signed-off-by: Sabrina Dubroca <sd@queasysnail.net>
> ---
> v2: as Tom Parkin explained, we can't remove the tunnel from the
>     per-net list from netlink. v2 uses only a dead flag, and adds
>     corresponding checks during lookups
> 
>  net/l2tp/l2tp_core.c | 18 +++++++++---------
>  net/l2tp/l2tp_core.h |  5 ++++-
>  2 files changed, 13 insertions(+), 10 deletions(-)
> 
> diff --git a/net/l2tp/l2tp_core.c b/net/l2tp/l2tp_core.c
> index ee485df73ccd..3891f0260f2b 100644
> --- a/net/l2tp/l2tp_core.c
> +++ b/net/l2tp/l2tp_core.c
> @@ -203,7 +203,8 @@ struct l2tp_tunnel *l2tp_tunnel_get(const struct net *net, u32 tunnel_id)
>  
>  	rcu_read_lock_bh();
>  	list_for_each_entry_rcu(tunnel, &pn->l2tp_tunnel_list, list) {
> -		if (tunnel->tunnel_id == tunnel_id) {
> +		if (tunnel->tunnel_id == tunnel_id &&
> +		    !test_bit(0, &tunnel->dead)) {
>  			l2tp_tunnel_inc_refcount(tunnel);
>  			rcu_read_unlock_bh();
>  
> @@ -390,7 +391,8 @@ struct l2tp_tunnel *l2tp_tunnel_find(const struct net *net, u32 tunnel_id)
>  
>  	rcu_read_lock_bh();
>  	list_for_each_entry_rcu(tunnel, &pn->l2tp_tunnel_list, list) {
> -		if (tunnel->tunnel_id == tunnel_id) {
> +		if (tunnel->tunnel_id == tunnel_id &&
> +		    !test_bit(0, &tunnel->dead)) {
>  			rcu_read_unlock_bh();
>  			return tunnel;
>  		}
> @@ -409,7 +411,7 @@ struct l2tp_tunnel *l2tp_tunnel_find_nth(const struct net *net, int nth)
>  
>  	rcu_read_lock_bh();
>  	list_for_each_entry_rcu(tunnel, &pn->l2tp_tunnel_list, list) {
> -		if (++count > nth) {
> +		if (++count > nth && !test_bit(0, &tunnel->dead)) {
>  			rcu_read_unlock_bh();
>  			return tunnel;
>  		}
> 
I don't get why you're checking the dead flag in l2tp_tunnel_{get,find}*().
Since it can be set concurrently right after test_bit(), it doesn't
protect the caller from getting a tunnel that is being removed by
l2tp_tunnel_delete().
Or have I missed something?

^ permalink raw reply

* Re: [RFC PATCH 1/3] usbnet: Get rid of spammy usbnet "kevent X may have been dropped"
From: Guenter Roeck @ 2017-09-19 16:43 UTC (permalink / raw)
  To: Douglas Anderson
  Cc: Oliver Neukum, Guenter Roeck, Grant Grundler, netdev, linux-usb,
	linux-kernel
In-Reply-To: <20170919161522.995-1-dianders@chromium.org>

On Tue, Sep 19, 2017 at 9:15 AM, Douglas Anderson <dianders@chromium.org> wrote:
> Every once in a while when my system is under a bit of stress I see
> some spammy messages show up in my logs that say:
>
>   kevent X may have been dropped
>
> As far as I can tell these messages aren't terribly useful.  The
> comments around the messages make me think that either workqueues used
> to work differently or that the original author of the code missed a
> sublety related to them.  The error message appears to predate the git
> conversion of the kernel so it's somewhat hard to tell.
>
> Specifically, workqueues should work like this:
>
> A) If a workqueue hasn't been scheduled then schedule_work() schedules
>    it and returns true.
>
> B) If a workqueue has been scheduled (but hasn't started) then
>    schedule_work() will do nothing and return false.
>
> C) If a workqueue has been scheduled (and has started) then
>    schedule_work() will put it on the queue to run again and return
>    true.
>
> Said another way: if you call schedule_work() you can guarantee that
> at least one full runthrough of the work will happen again.  That
> should mean that the work will get processed and I don't see any
> reason to think something should be dropped.
>
> Reading the comments in in usbnet_defer_kevent() made me think that B)
> and C) would be treated the same.  That is: even if we've started the
> work and are 99% of the way through then schedule_work() would return
> false and the work wouldn't be queued again.  If schedule_work()
> really did behave that way then, truly, some amount of work would be
> lost.  ...but it doesn't.
>
> NOTE: if somehow these warnings are useful to mean something then
> perhaps we should change them to make it more obvious.  If it's
> interesting to know when the work is backlogged then we should change
> the spam to say "warning: usbnet is backlogged".
>
> ALSO NOTE: If somehow some of the types of work need to be repeated if
> usbnet_defer_kevent() is called multiple times then that should be
> quite easy to accomplish without dropping any work on the floor.  We
> can just keep an atomic count for that type of work and add a loop
> into usbnet_deferred_kevent().
>
> Signed-off-by: Douglas Anderson <dianders@chromium.org>

Reviewed-by: Guenter Roeck <groeck@chromium.org>

> ---
>
>  drivers/net/usb/usbnet.c | 16 +++++++---------
>  1 file changed, 7 insertions(+), 9 deletions(-)
>
> diff --git a/drivers/net/usb/usbnet.c b/drivers/net/usb/usbnet.c
> index 6510e5cc1817..a3e8dbaadcf9 100644
> --- a/drivers/net/usb/usbnet.c
> +++ b/drivers/net/usb/usbnet.c
> @@ -450,19 +450,17 @@ static enum skb_state defer_bh(struct usbnet *dev, struct sk_buff *skb,
>  }
>
>  /* some work can't be done in tasklets, so we use keventd
> - *
> - * NOTE:  annoying asymmetry:  if it's active, schedule_work() fails,
> - * but tasklet_schedule() doesn't.  hope the failure is rare.
>   */
>  void usbnet_defer_kevent (struct usbnet *dev, int work)
>  {
>         set_bit (work, &dev->flags);
> -       if (!schedule_work (&dev->kevent)) {
> -               if (net_ratelimit())
> -                       netdev_err(dev->net, "kevent %d may have been dropped\n", work);
> -       } else {
> -               netdev_dbg(dev->net, "kevent %d scheduled\n", work);
> -       }
> +
> +       /* If work is already started this will mark it to run again when it
> +        * finishes; if we already had work pending and it hadn't started
> +        * yet then that's fine too.
> +        */
> +       schedule_work (&dev->kevent);
> +       netdev_dbg(dev->net, "kevent %d scheduled\n", work);
>  }
>  EXPORT_SYMBOL_GPL(usbnet_defer_kevent);
>
> --
> 2.14.1.690.gbb1197296e-goog
>

^ permalink raw reply

* [PATCH V2 net 7/7] net: hns3: Fixes the premature exit of loop when matching clients
From: Salil Mehta @ 2017-09-19 16:17 UTC (permalink / raw)
  To: davem
  Cc: salil.mehta, yisen.zhuang, lipeng321, mehta.salil.lnk, netdev,
	linux-kernel, linux-rdma, linuxarm
In-Reply-To: <20170919161716.92680-1-salil.mehta@huawei.com>

From: Lipeng <lipeng321@huawei.com>

When register/unregister ae_dev, ae_dev should match all client
in the client_list. Enet and roce can co-exists together so we
should continue checking for enet and roce presence together.
So break should not be there.

Above caused problems in loading and unloading of modules.

Fixes: 38eddd126772 ("net: hns3: Add support of the HNAE3 framework")
Signed-off-by: Lipeng <lipeng321@huawei.com>
Signed-off-by: Salil Mehta <salil.mehta@huawei.com>
---
 drivers/net/ethernet/hisilicon/hns3/hnae3.c | 43 ++++++-----------------------
 1 file changed, 9 insertions(+), 34 deletions(-)

diff --git a/drivers/net/ethernet/hisilicon/hns3/hnae3.c b/drivers/net/ethernet/hisilicon/hns3/hnae3.c
index 59efbd6..5bcb223 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hnae3.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hnae3.c
@@ -37,20 +37,15 @@ static bool hnae3_client_match(enum hnae3_client_type client_type,
 }
 
 static int hnae3_match_n_instantiate(struct hnae3_client *client,
-				     struct hnae3_ae_dev *ae_dev,
-				     bool is_reg, bool *matched)
+				     struct hnae3_ae_dev *ae_dev, bool is_reg)
 {
 	int ret;
 
-	*matched = false;
-
 	/* check if this client matches the type of ae_dev */
 	if (!(hnae3_client_match(client->type, ae_dev->dev_type) &&
 	      hnae_get_bit(ae_dev->flag, HNAE3_DEV_INITED_B))) {
 		return 0;
 	}
-	/* there is a match of client and dev */
-	*matched = true;
 
 	/* now, (un-)instantiate client by calling lower layer */
 	if (is_reg) {
@@ -69,7 +64,6 @@ int hnae3_register_client(struct hnae3_client *client)
 {
 	struct hnae3_client *client_tmp;
 	struct hnae3_ae_dev *ae_dev;
-	bool matched;
 	int ret = 0;
 
 	mutex_lock(&hnae3_common_lock);
@@ -86,7 +80,7 @@ int hnae3_register_client(struct hnae3_client *client)
 		/* if the client could not be initialized on current port, for
 		 * any error reasons, move on to next available port
 		 */
-		ret = hnae3_match_n_instantiate(client, ae_dev, true, &matched);
+		ret = hnae3_match_n_instantiate(client, ae_dev, true);
 		if (ret)
 			dev_err(&ae_dev->pdev->dev,
 				"match and instantiation failed for port\n");
@@ -102,12 +96,11 @@ EXPORT_SYMBOL(hnae3_register_client);
 void hnae3_unregister_client(struct hnae3_client *client)
 {
 	struct hnae3_ae_dev *ae_dev;
-	bool matched;
 
 	mutex_lock(&hnae3_common_lock);
 	/* un-initialize the client on every matched port */
 	list_for_each_entry(ae_dev, &hnae3_ae_dev_list, node) {
-		hnae3_match_n_instantiate(client, ae_dev, false, &matched);
+		hnae3_match_n_instantiate(client, ae_dev, false);
 	}
 
 	list_del(&client->node);
@@ -124,7 +117,6 @@ int hnae3_register_ae_algo(struct hnae3_ae_algo *ae_algo)
 	const struct pci_device_id *id;
 	struct hnae3_ae_dev *ae_dev;
 	struct hnae3_client *client;
-	bool matched;
 	int ret = 0;
 
 	mutex_lock(&hnae3_common_lock);
@@ -151,13 +143,10 @@ int hnae3_register_ae_algo(struct hnae3_ae_algo *ae_algo)
 		 * initialize the figure out client instance
 		 */
 		list_for_each_entry(client, &hnae3_client_list, node) {
-			ret = hnae3_match_n_instantiate(client, ae_dev, true,
-							&matched);
+			ret = hnae3_match_n_instantiate(client, ae_dev, true);
 			if (ret)
 				dev_err(&ae_dev->pdev->dev,
 					"match and instantiation failed\n");
-			if (matched)
-				break;
 		}
 	}
 
@@ -175,7 +164,6 @@ void hnae3_unregister_ae_algo(struct hnae3_ae_algo *ae_algo)
 	const struct pci_device_id *id;
 	struct hnae3_ae_dev *ae_dev;
 	struct hnae3_client *client;
-	bool matched;
 
 	mutex_lock(&hnae3_common_lock);
 	/* Check if there are matched ae_dev */
@@ -187,12 +175,8 @@ void hnae3_unregister_ae_algo(struct hnae3_ae_algo *ae_algo)
 		/* check the client list for the match with this ae_dev type and
 		 * un-initialize the figure out client instance
 		 */
-		list_for_each_entry(client, &hnae3_client_list, node) {
-			hnae3_match_n_instantiate(client, ae_dev, false,
-						  &matched);
-			if (matched)
-				break;
-		}
+		list_for_each_entry(client, &hnae3_client_list, node)
+			hnae3_match_n_instantiate(client, ae_dev, false);
 
 		ae_algo->ops->uninit_ae_dev(ae_dev);
 		hnae_set_bit(ae_dev->flag, HNAE3_DEV_INITED_B, 0);
@@ -212,7 +196,6 @@ int hnae3_register_ae_dev(struct hnae3_ae_dev *ae_dev)
 	const struct pci_device_id *id;
 	struct hnae3_ae_algo *ae_algo;
 	struct hnae3_client *client;
-	bool matched;
 	int ret = 0;
 
 	mutex_lock(&hnae3_common_lock);
@@ -246,13 +229,10 @@ int hnae3_register_ae_dev(struct hnae3_ae_dev *ae_dev)
 	 * initialize the figure out client instance
 	 */
 	list_for_each_entry(client, &hnae3_client_list, node) {
-		ret = hnae3_match_n_instantiate(client, ae_dev, true,
-						&matched);
+		ret = hnae3_match_n_instantiate(client, ae_dev, true);
 		if (ret)
 			dev_err(&ae_dev->pdev->dev,
 				"match and instantiation failed\n");
-		if (matched)
-			break;
 	}
 
 out_err:
@@ -270,7 +250,6 @@ void hnae3_unregister_ae_dev(struct hnae3_ae_dev *ae_dev)
 	const struct pci_device_id *id;
 	struct hnae3_ae_algo *ae_algo;
 	struct hnae3_client *client;
-	bool matched;
 
 	mutex_lock(&hnae3_common_lock);
 	/* Check if there are matched ae_algo */
@@ -279,12 +258,8 @@ void hnae3_unregister_ae_dev(struct hnae3_ae_dev *ae_dev)
 		if (!id)
 			continue;
 
-		list_for_each_entry(client, &hnae3_client_list, node) {
-			hnae3_match_n_instantiate(client, ae_dev, false,
-						  &matched);
-			if (matched)
-				break;
-		}
+		list_for_each_entry(client, &hnae3_client_list, node)
+			hnae3_match_n_instantiate(client, ae_dev, false);
 
 		ae_algo->ops->uninit_ae_dev(ae_dev);
 		hnae_set_bit(ae_dev->flag, HNAE3_DEV_INITED_B, 0);
-- 
2.7.4

^ permalink raw reply related

* [PATCH V2 net 6/7] net: hns3: Fixes the default VLAN-id of PF
From: Salil Mehta @ 2017-09-19 16:17 UTC (permalink / raw)
  To: davem
  Cc: salil.mehta, yisen.zhuang, lipeng321, mehta.salil.lnk, netdev,
	linux-kernel, linux-rdma, linuxarm, Mingguang Qu
In-Reply-To: <20170919161716.92680-1-salil.mehta@huawei.com>

From: Lipeng <lipeng321@huawei.com>

When there is no vlan id in the packets, hardware will treat the vlan id
as 0 and look for the mac_vlan table. This patch set the default vlan id
of PF as 0. Without this config, it will fail when look for mac_vlan
table, and hardware will drop packets.

Fixes: 6427264ef330 ("net: hns3: Add HNS3 Acceleration Engine &
Compatibility Layer Support")
Signed-off-by: Mingguang Qu <qumingguang@huawei.com>
Signed-off-by: Lipeng <lipeng321@huawei.com>
Signed-off-by: Salil Mehta <salil.mehta@huawei.com>
---
 drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
index 8e172af..74008ef 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
@@ -3673,6 +3673,7 @@ static int hclge_init_vlan_config(struct hclge_dev *hdev)
 {
 #define HCLGE_VLAN_TYPE_VF_TABLE   0
 #define HCLGE_VLAN_TYPE_PORT_TABLE 1
+	struct hnae3_handle *handle;
 	int ret;
 
 	ret = hclge_set_vlan_filter_ctrl(hdev, HCLGE_VLAN_TYPE_VF_TABLE,
@@ -3682,8 +3683,11 @@ static int hclge_init_vlan_config(struct hclge_dev *hdev)
 
 	ret = hclge_set_vlan_filter_ctrl(hdev, HCLGE_VLAN_TYPE_PORT_TABLE,
 					 true);
+	if (ret)
+		return ret;
 
-	return ret;
+	handle = &hdev->vport[0].nic;
+	return hclge_set_port_vlan_filter(handle, htons(ETH_P_8021Q), 0, false);
 }
 
 static int hclge_set_mtu(struct hnae3_handle *handle, int new_mtu)
-- 
2.7.4

^ permalink raw reply related

* [PATCH V2 net 5/7] net: hns3: Fixes the ether address copy with appropriate API
From: Salil Mehta @ 2017-09-19 16:17 UTC (permalink / raw)
  To: davem
  Cc: salil.mehta, yisen.zhuang, lipeng321, mehta.salil.lnk, netdev,
	linux-kernel, linux-rdma, linuxarm
In-Reply-To: <20170919161716.92680-1-salil.mehta@huawei.com>

This patch replaces the ethernet address copy instance with more
appropriate ether_addr_copy() function.

Fixes: 6427264ef330 ("net: hns3: Add HNS3 Acceleration Engine &
Compatibility Layer Support")
Signed-off-by: Salil Mehta <salil.mehta@huawei.com>
---
 drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
index eafd9c6..8e172af 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
@@ -1063,8 +1063,7 @@ static int hclge_configure(struct hclge_dev *hdev)
 	hdev->base_tqp_pid = 0;
 	hdev->rss_size_max = 1;
 	hdev->rx_buf_len = cfg.rx_buf_len;
-	for (i = 0; i < ETH_ALEN; i++)
-		hdev->hw.mac.mac_addr[i] = cfg.mac_addr[i];
+	ether_addr_copy(hdev->hw.mac.mac_addr, cfg.mac_addr);
 	hdev->hw.mac.media_type = cfg.media_type;
 	hdev->hw.mac.phy_addr = cfg.phy_addr;
 	hdev->num_desc = cfg.tqp_desc_num;
-- 
2.7.4

^ 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