Netdev List
 help / color / mirror / Atom feed
* Re: [PATCH net] vxlan: eliminate cached dst leak
From: Paolo Abeni @ 2017-05-30  8:34 UTC (permalink / raw)
  To: Lance Richardson, netdev
In-Reply-To: <20170529172557.7065-1-lrichard@redhat.com>

On Mon, 2017-05-29 at 13:25 -0400, Lance Richardson wrote:
> After commit 0c1d70af924b ("net: use dst_cache for vxlan device"),
> cached dst entries could be leaked when more than one remote was
> present for a given vxlan_fdb entry, causing subsequent netns
> operations to block indefinitely and "unregister_netdevice: waiting
> for lo to become free." messages to appear in the kernel log.
> 
> Fix by properly releasing cached dst and freeing resources in this
> case.
> 
> Fixes: commit 0c1d70af924b ("net: use dst_cache for vxlan device")
> Signed-off-by: Lance Richardson <lrichard@redhat.com>
> ---
>  drivers/net/vxlan.c | 20 +++++++++++++++++---
>  1 file changed, 17 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/net/vxlan.c b/drivers/net/vxlan.c
> index 328b471..5c1d69e 100644
> --- a/drivers/net/vxlan.c
> +++ b/drivers/net/vxlan.c
> @@ -740,6 +740,22 @@ static void vxlan_fdb_destroy(struct vxlan_dev *vxlan, struct vxlan_fdb *f)
>  	call_rcu(&f->rcu, vxlan_fdb_free);
>  }
>  
> +static void vxlan_dst_free(struct rcu_head *head)
> +{
> +	struct vxlan_rdst *rd = container_of(head, struct vxlan_rdst, rcu);
> +
> +	dst_cache_destroy(&rd->dst_cache);
> +	kfree(rd);
> +}
> +
> +static void vxlan_fdb_dst_destroy(struct vxlan_dev *vxlan, struct vxlan_fdb *f,
> +				  struct vxlan_rdst *rd)
> +{
> +	list_del_rcu(&rd->list);
> +	vxlan_fdb_notify(vxlan, f, rd, RTM_DELNEIGH);
> +	call_rcu(&rd->rcu, vxlan_dst_free);
> +}
> +
>  static int vxlan_fdb_parse(struct nlattr *tb[], struct vxlan_dev *vxlan,
>  			   union vxlan_addr *ip, __be16 *port, __be32 *src_vni,
>  			   __be32 *vni, u32 *ifindex)
> @@ -864,9 +880,7 @@ static int __vxlan_fdb_delete(struct vxlan_dev *vxlan,
>  	 * otherwise destroy the fdb entry
>  	 */
>  	if (rd && !list_is_singular(&f->remotes)) {
> -		list_del_rcu(&rd->list);
> -		vxlan_fdb_notify(vxlan, f, rd, RTM_DELNEIGH);
> -		kfree_rcu(rd, rcu);
> +		vxlan_fdb_dst_destroy(vxlan, f, rd);
>  		goto out;
>  	}
>  

LGTM, thanks Lance!

Acked-by: Paolo Abeni <pabeni@redhat.com>

^ permalink raw reply

* [PATCH net 3/3] MAINTAINERS: Move mlx5 rdma header file to IB driver charge
From: Tariq Toukan @ 2017-05-30  8:44 UTC (permalink / raw)
  To: David S. Miller
  Cc: netdev, Eran Ben Elisha, Majd Dibbiny, Saeed Mahameed,
	Yishai Hadas, Tariq Toukan
In-Reply-To: <1496133846-18343-1-git-send-email-tariqt@mellanox.com>

It belongs there, should not be under mlx5 Core driver.

Signed-off-by: Tariq Toukan <tariqt@mellanox.com>
---
 MAINTAINERS | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/MAINTAINERS b/MAINTAINERS
index 0dbc20c963c4..0f92a2ff4b12 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -8538,7 +8538,6 @@ Q:	http://patchwork.ozlabs.org/project/netdev/list/
 S:	Supported
 F:	drivers/net/ethernet/mellanox/mlx5/core/
 F:	include/linux/mlx5/
-F:	include/uapi/rdma/mlx5-abi.h
 
 MELLANOX MLX5 IB driver
 M:	Matan Barak <matanb@mellanox.com>
@@ -8549,6 +8548,7 @@ Q:	http://patchwork.kernel.org/project/linux-rdma/list/
 S:	Supported
 F:	drivers/infiniband/hw/mlx5/
 F:	include/linux/mlx5/
+F:	include/uapi/rdma/mlx5-abi.h
 
 MELEXIS MLX90614 DRIVER
 M:	Crt Mori <cmo@melexis.com>
-- 
1.8.3.1

^ permalink raw reply related

* [PATCH net 2/3] MAINTAINERS: Move mlx4 rdma header file to IB driver charge
From: Tariq Toukan @ 2017-05-30  8:44 UTC (permalink / raw)
  To: David S. Miller
  Cc: netdev, Eran Ben Elisha, Majd Dibbiny, Saeed Mahameed,
	Yishai Hadas, Tariq Toukan
In-Reply-To: <1496133846-18343-1-git-send-email-tariqt@mellanox.com>

It belongs there, should not be under mlx4 Core driver.

Signed-off-by: Tariq Toukan <tariqt@mellanox.com>
---
 MAINTAINERS | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/MAINTAINERS b/MAINTAINERS
index d9d5398d0a49..0dbc20c963c4 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -8516,7 +8516,6 @@ Q:	http://patchwork.ozlabs.org/project/netdev/list/
 S:	Supported
 F:	drivers/net/ethernet/mellanox/mlx4/
 F:	include/linux/mlx4/
-F:	include/uapi/rdma/mlx4-abi.h
 
 MELLANOX MLX4 IB driver
 M:	Yishai Hadas <yishaih@mellanox.com>
@@ -8526,6 +8525,7 @@ Q:	http://patchwork.kernel.org/project/linux-rdma/list/
 S:	Supported
 F:	drivers/infiniband/hw/mlx4/
 F:	include/linux/mlx4/
+F:	include/uapi/rdma/mlx4-abi.h
 
 MELLANOX MLX5 core VPI driver
 M:	Saeed Mahameed <saeedm@mellanox.com>
-- 
1.8.3.1

^ permalink raw reply related

* [PATCH net 0/3] MAINTAINERS updates
From: Tariq Toukan @ 2017-05-30  8:44 UTC (permalink / raw)
  To: David S. Miller
  Cc: netdev, Eran Ben Elisha, Majd Dibbiny, Saeed Mahameed,
	Yishai Hadas, Tariq Toukan

Hi Dave,

This patchset contains updates to the MAINTAINERS file.
In the first patch, I replace Yishai as the maintainer of
the mlx4_core driver.

In the other two patches we move an RDMA header file from
the list of the mlx4/mlx5 core driver into the respective
IB driver, where it belongs.

Series generated against net commit:
468b0df61a51 Merge git://git.kernel.org/pub/scm/linux/kernel/git/pablo/nf

Thanks,
Tariq.

Tariq Toukan (3):
  MAINTAINERS: Update MELLANOX MLX4 core VPI driver maintainer
  MAINTAINERS: Move mlx4 rdma header file to IB driver charge
  MAINTAINERS: Move mlx5 rdma header file to IB driver charge

 MAINTAINERS | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

-- 
1.8.3.1

^ permalink raw reply

* [PATCH net 1/3] MAINTAINERS: Update MELLANOX MLX4 core VPI driver maintainer
From: Tariq Toukan @ 2017-05-30  8:44 UTC (permalink / raw)
  To: David S. Miller
  Cc: netdev, Eran Ben Elisha, Majd Dibbiny, Saeed Mahameed,
	Yishai Hadas, Tariq Toukan
In-Reply-To: <1496133846-18343-1-git-send-email-tariqt@mellanox.com>

Add myself as a maintainer for mlx4 core driver,
replacing Yishai Hadas.

Signed-off-by: Tariq Toukan <tariqt@mellanox.com>
---
 MAINTAINERS | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/MAINTAINERS b/MAINTAINERS
index 9e984645c4b0..d9d5398d0a49 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -8508,7 +8508,7 @@ S:	Odd Fixes
 F:	drivers/media/radio/radio-miropcm20*
 
 MELLANOX MLX4 core VPI driver
-M:	Yishai Hadas <yishaih@mellanox.com>
+M:	Tariq Toukan <tariqt@mellanox.com>
 L:	netdev@vger.kernel.org
 L:	linux-rdma@vger.kernel.org
 W:	http://www.mellanox.com
-- 
1.8.3.1

^ permalink raw reply related

* ravb WoL interrupt flood
From: Geert Uytterhoeven @ 2017-05-30  9:23 UTC (permalink / raw)
  To: Niklas Söderlund
  Cc: Sergei Shtylyov, Linux-Renesas, netdev@vger.kernel.org

Hi Niklas,

I just got a flood of messages after WoL from s2idle on r8a7795/salvator-x:

[  802.341060] ravb e6800000.ethernet eth0: ignoring interrupt, rx
status 0x00000001, rx mask 0x00000001,
[  802.350369] ravb e6800000.ethernet eth0:                     tx
status 0x00000000, tx mask 0x00000001.
[  802.359684] ravb e6800000.ethernet eth0: ignoring interrupt, rx
status 0x00000001, rx mask 0x00000001,
[  802.368993] ravb e6800000.ethernet eth0:                     tx
status 0x00000000, tx mask 0x00000001.
[  802.378308] ravb e6800000.ethernet eth0: ignoring interrupt, rx
status 0x00000001, rx mask 0x00000001,
[  802.387616] ravb e6800000.ethernet eth0:                     tx
status 0x00000000, tx mask 0x00000001.
[  802.396931] ravb e6800000.ethernet eth0: ignoring interrupt, rx
status 0x00000001, rx mask 0x00000001,
[  802.406240] ravb e6800000.ethernet eth0:                     tx
status 0x00000000, tx mask 0x00000001.
...

Unfortunately I cannot reproduce it.

Gr{oetje,eeting}s,

                        Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds

^ permalink raw reply

* [PATCH net-next] net/mlxfw: select CONFIG_XZ_DEC
From: Arnd Bergmann @ 2017-05-30  9:26 UTC (permalink / raw)
  To: Yotam Gigi
  Cc: Arnd Bergmann, David S. Miller, Ido Schimmel, Jiri Pirko, netdev,
	linux-kernel

The new mlxfw code fails to build without the xz library:

drivers/net/ethernet/mellanox/mlxfw/mlxfw_mfa2.o: In function `mlxfw_mfa2_xz_dec_run':
:(.text.mlxfw_mfa2_xz_dec_run+0x8): undefined reference to `xz_dec_run'
drivers/net/ethernet/mellanox/mlxfw/mlxfw_mfa2.o: In function `mlxfw_mfa2_file_component_get':
:(.text.mlxfw_mfa2_file_component_get+0x218): undefined reference to `xz_dec_init'
:(.text.mlxfw_mfa2_file_component_get+0x2c0): undefined reference to `xz_dec_end'

This adds a Kconfig 'select' statement for it, which is also what
the other user of that library has.

Fixes: 410ed13cae39 ("Add the mlxfw module for Mellanox firmware flash process")
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
---
 drivers/net/ethernet/mellanox/mlxfw/Kconfig | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/net/ethernet/mellanox/mlxfw/Kconfig b/drivers/net/ethernet/mellanox/mlxfw/Kconfig
index 56b60ac7bc34..2b21af8a2b1d 100644
--- a/drivers/net/ethernet/mellanox/mlxfw/Kconfig
+++ b/drivers/net/ethernet/mellanox/mlxfw/Kconfig
@@ -4,3 +4,4 @@
 
 config MLXFW
         tristate "mlxfw" if COMPILE_TEST
+	select XZ_DEC
-- 
2.9.0

^ permalink raw reply related

* Re: [PATCH net-next] net/mlxfw: select CONFIG_XZ_DEC
From: Yotam Gigi @ 2017-05-30  9:28 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: David S. Miller, Ido Schimmel, Jiri Pirko, netdev, linux-kernel
In-Reply-To: <20170530092628.1306028-1-arnd@arndb.de>

On 05/30/2017 12:26 PM, Arnd Bergmann wrote:
> The new mlxfw code fails to build without the xz library:
>
> drivers/net/ethernet/mellanox/mlxfw/mlxfw_mfa2.o: In function `mlxfw_mfa2_xz_dec_run':
> :(.text.mlxfw_mfa2_xz_dec_run+0x8): undefined reference to `xz_dec_run'
> drivers/net/ethernet/mellanox/mlxfw/mlxfw_mfa2.o: In function `mlxfw_mfa2_file_component_get':
> :(.text.mlxfw_mfa2_file_component_get+0x218): undefined reference to `xz_dec_init'
> :(.text.mlxfw_mfa2_file_component_get+0x2c0): undefined reference to `xz_dec_end'
>
> This adds a Kconfig 'select' statement for it, which is also what
> the other user of that library has.
>
> Fixes: 410ed13cae39 ("Add the mlxfw module for Mellanox firmware flash process")
> Signed-off-by: Arnd Bergmann <arnd@arndb.de>
> ---
>  drivers/net/ethernet/mellanox/mlxfw/Kconfig | 1 +
>  1 file changed, 1 insertion(+)
>
> diff --git a/drivers/net/ethernet/mellanox/mlxfw/Kconfig b/drivers/net/ethernet/mellanox/mlxfw/Kconfig
> index 56b60ac7bc34..2b21af8a2b1d 100644
> --- a/drivers/net/ethernet/mellanox/mlxfw/Kconfig
> +++ b/drivers/net/ethernet/mellanox/mlxfw/Kconfig
> @@ -4,3 +4,4 @@
>  
>  config MLXFW
>          tristate "mlxfw" if COMPILE_TEST
> +	select XZ_DEC

Thanks!

Acked-by: Yotam Gigi <yotamg@mellanox.com>

^ permalink raw reply

* [PATCH nf-next] netns: add and use net_ns_barrier
From: Florian Westphal @ 2017-05-30  9:38 UTC (permalink / raw)
  To: netfilter-devel; +Cc: netdev, Florian Westphal, Eric W. Biederman

Quoting Joe Stringer:
  If a user loads nf_conntrack_ftp, sends FTP traffic through a network
  namespace, destroys that namespace then unloads the FTP helper module,
  then the kernel will crash.

Events that lead to the crash:
1. conntrack is created with ftp helper in netns x
2. This netns is destroyed
3. netns destruction is scheduled
4. netns destruction wq starts, removes netns from global list
5. ftp helper is unloaded, which resets all helpers of the conntracks
via for_each_net()

but because netns is already gone from list the for_each_net() loop
doesn't include it, therefore all of these conntracks are unaffected.

6. helper module unload finishes
7. netns wq invokes destructor for rmmod'ed helper

CC: "Eric W. Biederman" <ebiederm@xmission.com>
Reported-by: Joe Stringer <joe@ovn.org>
Signed-off-by: Florian Westphal <fw@strlen.de>
---
 Eric, I'd like an explicit (n)ack from you for this one.

 include/net/net_namespace.h       |  3 +++
 net/core/net_namespace.c          | 17 +++++++++++++++++
 net/netfilter/nf_conntrack_core.c |  9 +++++++++
 3 files changed, 29 insertions(+)

diff --git a/include/net/net_namespace.h b/include/net/net_namespace.h
index fe80bb48ab1f..a24a57593202 100644
--- a/include/net/net_namespace.h
+++ b/include/net/net_namespace.h
@@ -158,6 +158,7 @@ extern struct net init_net;
 struct net *copy_net_ns(unsigned long flags, struct user_namespace *user_ns,
 			struct net *old_net);
 
+void net_ns_barrier(void);
 #else /* CONFIG_NET_NS */
 #include <linux/sched.h>
 #include <linux/nsproxy.h>
@@ -168,6 +169,8 @@ static inline struct net *copy_net_ns(unsigned long flags,
 		return ERR_PTR(-EINVAL);
 	return old_net;
 }
+
+static inline void net_ns_barrier(void) {}
 #endif /* CONFIG_NET_NS */
 
 
diff --git a/net/core/net_namespace.c b/net/core/net_namespace.c
index 1934efd4a9d4..1f15abb1d733 100644
--- a/net/core/net_namespace.c
+++ b/net/core/net_namespace.c
@@ -482,6 +482,23 @@ static void cleanup_net(struct work_struct *work)
 		net_drop_ns(net);
 	}
 }
+
+/**
+ * net_ns_barrier - wait until concurrent net_cleanup_work is done
+ *
+ * cleanup_net runs from work queue and will first remove namespaces
+ * from the global list, then run net exit functions.
+ *
+ * Call this in module exit path to make sure that all netns
+ * ->exit ops have been invoked before the function is removed.
+ */
+void net_ns_barrier(void)
+{
+	mutex_lock(&net_mutex);
+	mutex_unlock(&net_mutex);
+}
+EXPORT_SYMBOL(net_ns_barrier);
+
 static DECLARE_WORK(net_cleanup_work, cleanup_net);
 
 void __put_net(struct net *net)
diff --git a/net/netfilter/nf_conntrack_core.c b/net/netfilter/nf_conntrack_core.c
index c3bd9b086dcc..ee972ee7bf81 100644
--- a/net/netfilter/nf_conntrack_core.c
+++ b/net/netfilter/nf_conntrack_core.c
@@ -1720,6 +1720,8 @@ EXPORT_SYMBOL_GPL(nf_ct_iterate_cleanup_net);
  * Like nf_ct_iterate_cleanup, but first marks conntracks on the
  * unconfirmed list as dying (so they will not be inserted into
  * main table).
+ *
+ * Can only be called in module exit path.
  */
 void
 nf_ct_iterate_destroy(int (*iter)(struct nf_conn *i, void *data), void *data)
@@ -1734,6 +1736,13 @@ nf_ct_iterate_destroy(int (*iter)(struct nf_conn *i, void *data), void *data)
 	}
 	rtnl_unlock();
 
+	/* Need to wait for netns cleanup worker to finish, if its
+	 * running -- it might have deleted a net namespace from
+	 * the global list, so our __nf_ct_unconfirmed_destroy() might
+	 * not have affected all namespaces.
+	 */
+	net_ns_barrier();
+
 	/* a conntrack could have been unlinked from unconfirmed list
 	 * before we grabbed pcpu lock in __nf_ct_unconfirmed_destroy().
 	 * This makes sure its inserted into conntrack table.
-- 
2.13.0


^ permalink raw reply related

* Re: [PATCH net-next] cxgb4: FW upgrade fixes
From: Sergei Shtylyov @ 2017-05-30  9:39 UTC (permalink / raw)
  To: Ganesh Goudar, netdev, davem; +Cc: nirranjan, Arjun Vynipadath, Casey Leedom
In-Reply-To: <1496128525-7881-1-git-send-email-ganeshgr@chelsio.com>

Hello!

On 5/30/2017 10:15 AM, Ganesh Goudar wrote:

> From: Arjun Vynipadath <arjun@chelsio.com>
>
> Disable FW_OK flags while flashing Firmware. This will help to fix any
> potential mailbox timeouts during Firmware flash.
>
> Grab new devlog parameters after Firmware restart. When we FLASH new
> Firmware onto an adapter, the new Firmware may have the Firmware Device Log
> located at a different memory address or have a different size for it.
>
> Signed-off-by: Arjun Vynipadath <arjun@chelsio.com>
> Signed-off-by: Casey Leedom <leedom@chelsio.com>
> Signed-off-by: Ganesh Goudar <ganeshgr@chelsio.com>
> ---
>  drivers/net/ethernet/chelsio/cxgb4/t4_hw.c | 21 ++++++++++++++++++---
>  1 file changed, 18 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c b/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c
> index b97ce4a..325f98c 100644
> --- a/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c
> +++ b/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c
> @@ -6288,13 +6288,18 @@ int t4_fw_upgrade(struct adapter *adap, unsigned int mbox,
>  	if (!t4_fw_matches_chip(adap, fw_hdr))
>  		return -EINVAL;
>
> +	/* Disable FW_OK flags so that mbox commands with FW_OK flags check
> +	 * wont be send when we are flashing FW.

    Sent.

[...]

MBR, Sergei

^ permalink raw reply

* Re: [RFC net-next PATCH 3/5] net: introduce XDP driver features interface
From: Jesper Dangaard Brouer @ 2017-05-30  9:58 UTC (permalink / raw)
  To: Daniel Borkmann; +Cc: Daniel Borkmann, Alexei Starovoitov, netdev, brouer
In-Reply-To: <59231AE0.8080409@iogearbox.net>


On Mon, 22 May 2017 19:07:44 +0200 Daniel Borkmann <daniel@iogearbox.net> wrote:

> On 05/22/2017 04:49 PM, Jesper Dangaard Brouer wrote:
> >
> > How do we move forward from here?  
> 
> If we introduce such feature bits one day, one possibility I see
> that more or less could work is to propagate this into tail call
> maps in a similar way like we do today with bpf_prog_array_compatible().
> Latter checks the prog type and whether a prog was jited, as both
> really cannot be mixed among each other.

I went down this path, of extending bpf_prog_array_compatible() and
traversing the tail call maps when the bpf_prog gets attached in the
XDP driver.  It is first at the XDP driver attachment point-in-time, the
features can be checked and locked down.

See patch below (on top of this RFC patchset).
Tested with:
 https://github.com/netoptimizer/prototype-kernel/tree/master/kernel/samples/bpf
 bpf_tail_calls01_{kern,user}.c

> So, once you load the program, either we somehow need to tell the
> verifier upfront about our requirements, or the verifier detects
> them based on the programs that are loaded (not sure about this
> one though), 

IMHO "optional" features are *detected* by bpf verifier and filter.c
rewriter.  And "required" features are defined/detect/verified at NIC
driver level.  The user (XDP bpf programmer) do NOT supply "features".

> and besides prog, it needs to mark the tail call map
> with the same mask, such that any programs added later on to this
> tail call map are guaranteed to use the same set of features or
> just a subset of them. This also means that later updates cannot
> use features outside of this set anymore (even if the driver could
> support it). Then, the 'root' program which is to be attached to
> the device can check against the driver's capabilities eventually,
> since any program reachable from the root program would be guaranteed
> to not use features outside of this set.

I've also solved this one by storing the max supported features by the
driver, after validating that the "used" features passed the driver
check.  Thus, later runtime progs can still use all features supported
by the driver, even-though they were not "used" at XDO init/attach time.
 
> Still big question-mark wrt exposing these feature bits, and how
> the set would be determined eventually, e.g. the loader would somehow
> need to transparently calc the superset of features based on all
> progs residing in the object file, and then pass them into the kernel
> on prog load, where verifier checks them against the prog and if the
> prog makes use of the same set or a subset, then we mark it and related
> maps with the superset.

I've managed to keep the bpf side of the feature bits completely
flexible and not-exposed.  It is only the NIC drivers XDP_DRV_F_*
defines that gets exposed, which is what we want to easily "see" and
enforce what drivers (must) support.  For the bpf side, the bits can be
removed and recycled once a XDP_DRV_F_XXX feature moved to the required
set XDP_DRV_FEATURES_REQUIRED.

I've also managed to keep feature validation to "setup-time", thus no
additional runtime overhead is added for tail calls.


[PATCH RFC] bpf: handle XDP features for bpf tail calls

From: Jesper Dangaard Brouer <brouer@redhat.com>

XDP is challenging the bpf infrastructure assumption, that a
bpf_helper imply that a features is available to the bpf program.
This is no-longer true for XDP NIC drivers as the feature behind the
bpf_helper need to be implemented on a per driver basis.

Disregarding handling bpf tail calls, it is fairly easily to implement
and detect feature mismatch, via leveraging the bpf verifier and
ins-rewriter, who knows what helpers and direct access a given
bpf_prog are activating, as demonstrated in previous patches.

This patch handle tail calls (BPF_MAP_TYPE_PROG_ARRAY) by traversing
the tail call prog array, and collecting the features.

When attaching the XDP bpf_prog to a given XDP driver, the prog arrays
are traversed, and used features are verified against what the XDP
driver supports.  On success the supported NIC XDP features are locked
down (for the traversed bpf prog_array maps).  Later when runtime
adding bpf_prog's to the map, then features are checked.

The supported feature set is locked down to the maximum supported
features by the driver, to allow runtime adding tail calls that need
more features, but within drivers capabilities.

When adding a tail call, that itself have tail calls, the same
traversal verification is performed.  On success, these prog_array's
are also feature locked based on inheriting the supported features of
the array being inserted into.

At XDP driver attachment time, the bpf_prog have already been made
read-only.  Thus, the needed info are stored in struct bpf_array.

Signed-off-by: Jesper Dangaard Brouer <brouer@redhat.com>
---
 include/linux/bpf.h    |   26 ++++++
 include/linux/filter.h |    5 +
 kernel/bpf/core.c      |  226 +++++++++++++++++++++++++++++++++++++++++++++++-
 kernel/bpf/verifier.c  |    1 
 net/core/dev.c         |   18 ++--
 5 files changed, 262 insertions(+), 14 deletions(-)

diff --git a/include/linux/bpf.h b/include/linux/bpf.h
index 6bb38d76faf4..842409105925 100644
--- a/include/linux/bpf.h
+++ b/include/linux/bpf.h
@@ -167,6 +167,23 @@ struct bpf_verifier_ops {
 			union bpf_attr __user *uattr);
 };
 
+/* These bpf_feature bits are 100% internal to the bpf infrastructure
+ * They mirror some of the bpf_prog bits, related to features.  Over
+ * time these features bits will get removed when the subsystem using
+ * them, like XDP, will support the feature from all call points
+ * (e.g. XDP drivers).
+ */
+struct bpf_features {
+	union {
+		struct {
+			u32	cb_access:1,
+				xdp_rxhash_needed:1;
+		};
+		u32	flags;
+	};
+};
+typedef u32	bpf_features_t;
+
 struct bpf_prog_aux {
 	atomic_t refcnt;
 	u32 used_map_cnt;
@@ -193,6 +210,15 @@ struct bpf_array {
 	 */
 	enum bpf_prog_type owner_prog_type;
 	bool owner_jited;
+
+	/* Restrict features allowed */
+	bpf_features_t features_supported;
+	bool features_locked;
+
+	/* Members needed when traversing prog_array tail calls */
+	struct list_head traversed_node;
+	bool is_traversed;
+
 	union {
 		char value[0] __aligned(8);
 		void *ptrs[0] __aligned(8);
diff --git a/include/linux/filter.h b/include/linux/filter.h
index 33a254ccd47d..113914b7ac28 100644
--- a/include/linux/filter.h
+++ b/include/linux/filter.h
@@ -641,6 +641,11 @@ static inline int sk_filter(struct sock *sk, struct sk_buff *skb)
 	return sk_filter_trim_cap(sk, skb, 1);
 }
 
+netdev_features_t bpf_get_xdp_features(struct bpf_prog *xdp_prog);
+bool bpf_lock_xdp_features(struct bpf_prog *prog,
+			   netdev_features_t xdp_approved_f,
+			   netdev_features_t xdp_dev_support_f);
+
 struct bpf_prog *bpf_prog_select_runtime(struct bpf_prog *fp, int *err);
 void bpf_prog_free(struct bpf_prog *fp);
 
diff --git a/kernel/bpf/core.c b/kernel/bpf/core.c
index 6f81e0f5a0fa..d3dbce365993 100644
--- a/kernel/bpf/core.c
+++ b/kernel/bpf/core.c
@@ -1224,21 +1224,241 @@ static unsigned int __bpf_prog_run(void *ctx, const struct bpf_insn *insn)
 }
 STACK_FRAME_NON_STANDARD(__bpf_prog_run); /* jump table */
 
+/* convert bpf_prog bits into bpf_features bits */
+static bpf_features_t __bpf_prog_to_features(const struct bpf_prog *prog)
+{
+	struct bpf_features f = { 0 };
+
+	if (prog->cb_access)
+		f.cb_access = 1;
+
+	if (prog->xdp_rxhash_needed)
+		f.xdp_rxhash_needed = 1;
+
+	return f.flags;
+}
+
+/* convert bpf_features bits into net_device xdp_features */
+static netdev_features_t __bpf_features_to_xdp_features(bpf_features_t f)
+{
+	netdev_features_t features = XDP_DRV_FEATURES_REQUIRED;
+	struct bpf_features bf;
+
+	bf.flags = f;
+	if (bf.xdp_rxhash_needed)
+		features |= XDP_DRV_F_RXHASH;
+
+	return features;
+}
+
+/* Extend bpf_features with extra features based on xdp_features input */
+bpf_features_t __bpf_features_extend_from_xdp_features(bpf_features_t bpf_f,
+						       netdev_features_t xdp_f)
+{
+	struct bpf_features bf;
+
+	bf.flags = bpf_f;
+	if (xdp_f & XDP_DRV_F_RXHASH)
+		bf.xdp_rxhash_needed = 1;
+
+	return bf.flags;
+}
+
+static DEFINE_MUTEX(prog_array_traversal_mutex);
+static LIST_HEAD(prog_array_traversal_q);
+
+static bpf_features_t
+__bpf_features_via_prog_array(const struct bpf_prog *top_prog,
+			      bpf_features_t features)
+{
+	struct bpf_prog_aux *aux = top_prog->aux;
+	int i;
+
+	/* First extract features from bpf_prog's in known prog_array's */
+	for (i = 0; i < aux->used_map_cnt; i++) {
+		struct bpf_map *map = aux->used_maps[i];
+		struct bpf_array *array;
+		int j;
+
+		/* Walk all prog_array's */
+		if (map->map_type != BPF_MAP_TYPE_PROG_ARRAY)
+			continue;
+		array = container_of(map, struct bpf_array, map);
+
+		/* Look at features in each active bpf_prog in prog_array */
+		for (j = 0; j < array->map.max_entries; j++) {
+			const struct bpf_prog *prog;
+
+			prog = array->ptrs[j];
+			if (!prog)
+				continue;
+
+			features |= __bpf_prog_to_features(prog);
+		}
+	}
+
+	/* Now recursive visit bpf_prog's for containing prog_array's */
+	for (i = 0; i < aux->used_map_cnt; i++) {
+		struct bpf_map *map = aux->used_maps[i];
+		struct bpf_array *array;
+		int j;
+
+		/* Walk all prog_array's again */
+		if (map->map_type != BPF_MAP_TYPE_PROG_ARRAY)
+			continue;
+		array = container_of(map, struct bpf_array, map);
+
+		/* Avoid traversal loops and record prog_array's */
+		if (array->is_traversed)
+			continue;
+		array->is_traversed = true;
+		list_add_tail(&array->traversed_node, &prog_array_traversal_q);
+
+		/* Recurse into bpf_prog in prog_array */
+		for (j = 0; j < array->map.max_entries; j++) {
+			const struct bpf_prog *p;
+
+			p = array->ptrs[j];
+			if (!p)
+				continue;
+
+			features |= __bpf_features_via_prog_array(p, features);
+		}
+	}
+
+	return features;
+}
+
+/* Find superset of features traversing tail call maps */
+static bpf_features_t bpf_features_via_prog_array(const struct bpf_prog *prog,
+						  bpf_features_t features)
+{
+	struct bpf_array *prog_array, *tmp;
+
+	features |= __bpf_features_via_prog_array(prog, features);
+	list_for_each_entry_safe(prog_array, tmp, &prog_array_traversal_q,
+				 traversed_node)
+	{
+		list_del(&prog_array->traversed_node);
+		prog_array->is_traversed = false;
+	}
+
+	return features;
+}
+
+netdev_features_t bpf_get_xdp_features(struct bpf_prog *prog)
+{
+	bpf_features_t bpf_features;
+
+	mutex_lock(&prog_array_traversal_mutex);
+	bpf_features = __bpf_prog_to_features(prog);
+	bpf_features = bpf_features_via_prog_array(prog, bpf_features);
+	mutex_unlock(&prog_array_traversal_mutex);
+
+	return __bpf_features_to_xdp_features(bpf_features);
+}
+
+/* Caller have checked xdp features are approved */
+bool bpf_lock_xdp_features(struct bpf_prog *prog,
+			   netdev_features_t xdp_approved_f,
+			   netdev_features_t xdp_dev_support_f)
+{
+	struct bpf_array *prog_array, *tmp;
+	netdev_features_t xdp_f_in_use;
+	bpf_features_t bpf_f_in_use;
+	bool lock_features = true;
+	bpf_features_t max;
+
+	mutex_lock(&prog_array_traversal_mutex);
+
+	/* Get and detect if bpf_features changed */
+	bpf_f_in_use  = __bpf_prog_to_features(prog);
+	bpf_f_in_use |= __bpf_features_via_prog_array(prog, bpf_f_in_use);
+	xdp_f_in_use  = __bpf_features_to_xdp_features(bpf_f_in_use);
+	if (xdp_f_in_use != xdp_approved_f)
+		lock_features = false;
+
+	/* XDP driver might support more features than in-use, allow
+	 * later added bpf_prog's to still use-these extra features
+	 */
+	max = __bpf_features_extend_from_xdp_features(bpf_f_in_use,
+						      xdp_dev_support_f);
+	list_for_each_entry_safe(prog_array, tmp, &prog_array_traversal_q,
+				 traversed_node)
+	{
+		list_del(&prog_array->traversed_node);
+		prog_array->is_traversed = false;
+		if (lock_features) {
+			/* Handle when already locked by another driver.
+			 * Find smallest common feature set (via simple AND)
+			 */
+			if (prog_array->features_locked)
+				prog_array->features_supported &= max;
+			else
+				prog_array->features_supported = max;
+			prog_array->features_locked = true;
+		}
+	}
+	mutex_unlock(&prog_array_traversal_mutex);
+	return lock_features;
+}
+
 bool bpf_prog_array_compatible(struct bpf_array *array,
 			       const struct bpf_prog *fp)
 {
+	bool compat = false;
+
+	mutex_lock(&prog_array_traversal_mutex);
+
 	if (!array->owner_prog_type) {
 		/* There's no owner yet where we could check for
 		 * compatibility.
 		 */
 		array->owner_prog_type = fp->type;
 		array->owner_jited = fp->jited;
+		array->features_locked = false;
+		array->is_traversed = false;
+		compat = true;
+		goto out;
+	}
+
+	/* Features can be locked, e.g. when XDP prog is attach to net_device */
+	if (array->features_locked)
+	{
+		bpf_features_t f = __bpf_prog_to_features(fp);
+		struct bpf_array *pa, *tmp;
+		bpf_features_t max;
 
-		return true;
+		f |= __bpf_features_via_prog_array(fp, f);
+
+		/* Detect any feature bit set, which is not supported */
+		if (f & ~(array->features_supported)) {
+			compat = false;
+			goto out;
+		}
+		/* If fp contained tail call's itself, they need to be
+		 * locked down, to this array->features_supported.
+		 */
+		max = array->features_supported;
+		list_for_each_entry_safe(pa, tmp, &prog_array_traversal_q,
+					 traversed_node)
+		{
+			list_del(&pa->traversed_node);
+			pa->is_traversed = false;
+			/* Handle when already locked by another driver */
+			if (pa->features_locked)
+				pa->features_supported &= max;
+			else
+				pa->features_supported = max;
+			pa->features_locked = true;
+		}
 	}
 
-	return array->owner_prog_type == fp->type &&
-	       array->owner_jited == fp->jited;
+	compat = (array->owner_prog_type == fp->type &&
+		  array->owner_jited == fp->jited);
+out:
+	mutex_unlock(&prog_array_traversal_mutex);
+	return compat;
 }
 
 static int bpf_check_tail_call(const struct bpf_prog *fp)
diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
index 248bc113ad18..df9d08a79ac6 100644
--- a/kernel/bpf/verifier.c
+++ b/kernel/bpf/verifier.c
@@ -3355,7 +3355,6 @@ static int fixup_bpf_calls(struct bpf_verifier_env *env)
 			 * the program array.
 			 */
 			prog->cb_access = 1;
-			prog->xdp_rxhash_needed = 1;
 
 			/* mark bpf_tail_call as different opcode to avoid
 			 * conditional branch in the interpeter for every normal
diff --git a/net/core/dev.c b/net/core/dev.c
index 28082067ac00..b45e8114b84c 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -6855,16 +6855,6 @@ int dev_change_proto_down(struct net_device *dev, bool proto_down)
 }
 EXPORT_SYMBOL(dev_change_proto_down);
 
-netdev_features_t bpf_get_xdp_features(struct bpf_prog *prog)
-{
-	netdev_features_t features = XDP_DRV_FEATURES_REQUIRED;
-
-	if (prog->xdp_rxhash_needed)
-		features |= XDP_DRV_F_RXHASH;
-
-	return features;
-}
-
 bool xdp_features_check(struct net_device *dev, struct bpf_prog *xdp_prog,
 			struct netlink_ext_ack *extack, u32 flags)
 {
@@ -6881,6 +6871,14 @@ bool xdp_features_check(struct net_device *dev, struct bpf_prog *xdp_prog,
 			       "Required XDP feature not supported by device");
 		return false;
 	}
+	/* Ask BPF infra to limit runtime added bpf_prog's (tail calls)
+	 * to features supported by XDP driver.
+	 */
+	if (!bpf_lock_xdp_features(xdp_prog, req_features, dev_xdp_features)) {
+		NL_SET_ERR_MSG(extack,
+			"Couldn't lock XDP features supported by device");
+		return false;
+	}
 	return true;
 }
 


-- 
Best regards,
  Jesper Dangaard Brouer
  MSc.CS, Principal Kernel Engineer at Red Hat
  LinkedIn: http://www.linkedin.com/in/brouer

^ permalink raw reply related

* Re: ravb WoL interrupt flood
From: Niklas Söderlund @ 2017-05-30 10:29 UTC (permalink / raw)
  To: Geert Uytterhoeven; +Cc: Sergei Shtylyov, Linux-Renesas, netdev@vger.kernel.org
In-Reply-To: <CAMuHMdWmt7oB4B4OYkO59+HvEbpVLVeqB_AV2c5OnYJEUJRxRg@mail.gmail.com>

Hi Geert,

Thanks for the report. I did run a 200+ loop suspend/resume without 
issues so this error is probably hard to reproduce or something changed 
since v4.11-rc1 which if IIRC was the base I used to do the tests.

All I can think of is that if the interface was down at the time the 
system was suspend. There is a bug in  the driver which is in 
renesas-drivers related to that. But given that you woken up by WoL that 
is probably not the case :-)

I will do more tests and see if I can reproduce this once I'm back in 
Stockholm.


On 2017-05-30 11:23:23 +0200, Geert Uytterhoeven wrote:
> Hi Niklas,
> 
> I just got a flood of messages after WoL from s2idle on r8a7795/salvator-x:
> 
> [  802.341060] ravb e6800000.ethernet eth0: ignoring interrupt, rx
> status 0x00000001, rx mask 0x00000001,
> [  802.350369] ravb e6800000.ethernet eth0:                     tx
> status 0x00000000, tx mask 0x00000001.
> [  802.359684] ravb e6800000.ethernet eth0: ignoring interrupt, rx
> status 0x00000001, rx mask 0x00000001,
> [  802.368993] ravb e6800000.ethernet eth0:                     tx
> status 0x00000000, tx mask 0x00000001.
> [  802.378308] ravb e6800000.ethernet eth0: ignoring interrupt, rx
> status 0x00000001, rx mask 0x00000001,
> [  802.387616] ravb e6800000.ethernet eth0:                     tx
> status 0x00000000, tx mask 0x00000001.
> [  802.396931] ravb e6800000.ethernet eth0: ignoring interrupt, rx
> status 0x00000001, rx mask 0x00000001,
> [  802.406240] ravb e6800000.ethernet eth0:                     tx
> status 0x00000000, tx mask 0x00000001.
> ...
> 
> Unfortunately I cannot reproduce it.
> 
> Gr{oetje,eeting}s,
> 
>                         Geert
> 
> --
> Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org
> 
> In personal conversations with technical people, I call myself a hacker. But
> when I'm talking to journalists I just say "programmer" or something like that.
>                                 -- Linus Torvalds

-- 
Regards,
Niklas Söderlund

^ permalink raw reply

* [PATCH V2 1/3] Documentation: devicetree: add multiple cpu port DSA binding
From: John Crispin @ 2017-05-30 10:44 UTC (permalink / raw)
  To: Andrew Lunn, Vivien Didelot, Florian Fainelli, David S . Miller,
	Sean Wang
  Cc: netdev, linux-kernel, John Crispin, Rob Herring, devicetree

Extend the DSA binding documentation, adding the new property required
when there is more than one CPU port attached to the switch.

Cc: Rob Herring <robh+dt@kernel.org>
Cc: devicetree@vger.kernel.org
Signed-off-by: John Crispin <john@phrozen.org>
---
 Documentation/devicetree/bindings/net/dsa/dsa.txt | 61 ++++++++++++++++++++++-
 1 file changed, 60 insertions(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/net/dsa/dsa.txt b/Documentation/devicetree/bindings/net/dsa/dsa.txt
index cfe8f64eca4f..c164eb38ccc5 100644
--- a/Documentation/devicetree/bindings/net/dsa/dsa.txt
+++ b/Documentation/devicetree/bindings/net/dsa/dsa.txt
@@ -55,6 +55,11 @@ A user port has the following optional property:
 - label			: Describes the label associated with this port, which
                           will become the netdev name.
 
+- cpu			: Option for non "cpu"/"dsa" ports. A phandle to a
+			  "cpu" port, which will be used for passing packets
+			  from this port to the host. If not present, the first
+			  "cpu" port will be used.
+
 Port child nodes may also contain the following optional standardised
 properties, described in binding documents:
 
@@ -71,7 +76,7 @@ properties, described in binding documents:
 			  Documentation/devicetree/bindings/net/fixed-link.txt
 			  for details.
 
-Example
+Examples
 
 The following example shows three switches on three MDIO busses,
 linked into one DSA cluster.
@@ -264,6 +269,60 @@ linked into one DSA cluster.
 	};
 };
 
+The following example shows a switch that has two cpu ports each connecting
+to a different MAC.
+
+&mdio0 {
+	switch@0 {
+		compatible = "mediatek,mt7530";
+		#address-cells = <1>;
+		#size-cells = <0>;
+		reg = <0>;
+
+		ports {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			port@0 {
+				reg = <0>;
+				label = "lan0";
+				cpu = <&cpu_port1>;
+			};
+
+			port@1 {
+				reg = <1>;
+				label = "lan1";
+				cpu = <&cpu_port1>;
+			};
+
+			port@2 {
+				reg = <2>;
+				label = "lan2";
+				cpu = <&cpu_port1>;
+			};
+
+			port@3 {
+				reg = <3>;
+				label = "wan";
+				cpu = <&cpu_port2>;
+			};
+
+			cpu_port2: port@5 {
+				reg = <5>;
+				label = "cpu";
+				ethernet = <&gmac2>;
+				phy-mode = "trgmii";
+			};
+
+			cpu_port1: port@6 {
+				reg = <6>;
+				label = "cpu";
+				ethernet = <&gmac1>;
+				phy-mode = "trgmii";
+			};
+		};
+	};
+};
+
 Deprecated Binding
 ------------------
 
-- 
2.11.0

^ permalink raw reply related

* [PATCH V2 2/3] net-next: dsa: add multi cpu port support
From: John Crispin @ 2017-05-30 10:44 UTC (permalink / raw)
  To: Andrew Lunn, Vivien Didelot, Florian Fainelli, David S . Miller,
	Sean Wang
  Cc: netdev, linux-kernel, John Crispin
In-Reply-To: <20170530104419.6052-1-john@phrozen.org>

Some boards have two CPU interfaces connected to the switch, e.g. WiFi
access points, with 1 port labeled WAN, 4 ports labeled lan1-lan4, and
two port connected to the SoC.

This patch extends DSA to allows both CPU ports to be used. The "cpu"
node in the DSA tree can now have a phandle to the host interface it
connects to. Each user port can have a phandle to a cpu port which
should be used for traffic between the port and the CPU. Thus simple
load sharing over the two CPU ports can be achieved.

Signed-off-by: John Crispin <john@phrozen.org>
---
 include/net/dsa.h  | 21 ++++++++++++++++++++-
 net/dsa/dsa2.c     | 35 +++++++++++++++++++++++++++++++----
 net/dsa/dsa_priv.h |  1 +
 net/dsa/slave.c    | 26 ++++++++++++++++----------
 4 files changed, 68 insertions(+), 15 deletions(-)

diff --git a/include/net/dsa.h b/include/net/dsa.h
index c0e567c0c824..d2994bd2c507 100644
--- a/include/net/dsa.h
+++ b/include/net/dsa.h
@@ -186,6 +186,8 @@ struct dsa_port {
 	u8			stp_state;
 	struct net_device	*bridge_dev;
 	struct devlink_port	devlink_port;
+	struct net_device	*ethernet;
+	int			upstream;
 };
 
 struct dsa_switch {
@@ -251,7 +253,7 @@ struct dsa_switch {
 
 static inline bool dsa_is_cpu_port(struct dsa_switch *ds, int p)
 {
-	return ds->dst->cpu_dp == &ds->ports[p];
+	return !!(ds->cpu_port_mask & (1 << p));
 }
 
 static inline bool dsa_is_dsa_port(struct dsa_switch *ds, int p)
@@ -269,6 +271,11 @@ static inline bool dsa_is_port_initialized(struct dsa_switch *ds, int p)
 	return ds->enabled_port_mask & (1 << p) && ds->ports[p].netdev;
 }
 
+static inline bool dsa_is_upstream_port(struct dsa_switch *ds, int p)
+{
+	return dsa_is_cpu_port(ds, p) || dsa_is_dsa_port(ds, p);
+}
+
 static inline u8 dsa_upstream_port(struct dsa_switch *ds)
 {
 	struct dsa_switch_tree *dst = ds->dst;
@@ -285,6 +292,18 @@ static inline u8 dsa_upstream_port(struct dsa_switch *ds)
 		return ds->rtable[dst->cpu_dp->ds->index];
 }
 
+static inline u8 dsa_port_upstream_port(struct dsa_switch *ds, int port)
+{
+	/*
+	 * If this port has a specific upstream cpu port, use it,
+	 * otherwise use the switch default.
+	 */
+	if (ds->ports[port].upstream)
+		return ds->ports[port].upstream;
+	else
+		return dsa_upstream_port(ds);
+}
+
 struct dsa_switch_ops {
 	/*
 	 * Legacy probing.
diff --git a/net/dsa/dsa2.c b/net/dsa/dsa2.c
index 4301f52e4f5a..8b13aa735c40 100644
--- a/net/dsa/dsa2.c
+++ b/net/dsa/dsa2.c
@@ -253,8 +253,6 @@ static int dsa_cpu_port_apply(struct dsa_port *port, u32 index,
 		return err;
 	}
 
-	ds->cpu_port_mask |= BIT(index);
-
 	memset(&ds->ports[index].devlink_port, 0,
 	       sizeof(ds->ports[index].devlink_port));
 	err = devlink_port_register(ds->devlink, &ds->ports[index].devlink_port,
@@ -269,6 +267,10 @@ static void dsa_cpu_port_unapply(struct dsa_port *port, u32 index,
 	dsa_cpu_dsa_destroy(port);
 	ds->cpu_port_mask &= ~BIT(index);
 
+	if (ds->ports[index].ethernet) {
+		dev_put(ds->ports[index].ethernet);
+		ds->ports[index].ethernet = NULL;
+	}
 }
 
 static int dsa_user_port_apply(struct dsa_port *port, u32 index,
@@ -530,6 +532,29 @@ static int dsa_cpu_parse(struct dsa_port *port, u32 index,
 
 	dst->rcv = dst->tag_ops->rcv;
 
+	dev_hold(ethernet_dev);
+	ds->ports[index].ethernet = ethernet_dev;
+	ds->cpu_port_mask |= BIT(index);
+
+	return 0;
+}
+
+static int dsa_user_parse(struct device_node *port, u32 index,
+			  struct dsa_switch *ds)
+{
+	struct device_node *cpu_port;
+	const unsigned int *cpu_port_reg;
+	int cpu_port_index;
+
+	cpu_port = of_parse_phandle(port, "cpu", 0);
+	if (cpu_port) {
+		cpu_port_reg = of_get_property(cpu_port, "reg", NULL);
+		if (!cpu_port_reg)
+			return -EINVAL;
+		cpu_port_index = be32_to_cpup(cpu_port_reg);
+		ds->ports[index].upstream = cpu_port_index;
+	}
+
 	return 0;
 }
 
@@ -544,11 +569,13 @@ static int dsa_ds_parse(struct dsa_switch_tree *dst, struct dsa_switch *ds)
 		if (!dsa_port_is_valid(port))
 			continue;
 
-		if (dsa_port_is_cpu(port)) {
+		if (dsa_port_is_cpu(port))
 			err = dsa_cpu_parse(port, index, dst, ds);
+		else if (dsa_is_normal_port(port))
+			err = dsa_user_parse(port->dn, index,  ds);
+
 			if (err)
 				return err;
-		}
 	}
 
 	pr_info("DSA: switch %d %d parsed\n", dst->tree, ds->index);
diff --git a/net/dsa/dsa_priv.h b/net/dsa/dsa_priv.h
index c1d4180651af..91fdc16befb2 100644
--- a/net/dsa/dsa_priv.h
+++ b/net/dsa/dsa_priv.h
@@ -78,6 +78,7 @@ struct dsa_slave_priv {
 
 	/* DSA port data, such as switch, port index, etc. */
 	struct dsa_port		*dp;
+	struct net_device	*master;
 
 	/*
 	 * The phylib phy_device pointer for the PHY connected
diff --git a/net/dsa/slave.c b/net/dsa/slave.c
index 887e26695519..45f17f35ced1 100644
--- a/net/dsa/slave.c
+++ b/net/dsa/slave.c
@@ -66,7 +66,7 @@ static int dsa_slave_get_iflink(const struct net_device *dev)
 {
 	struct dsa_slave_priv *p = netdev_priv(dev);
 
-	return p->dp->ds->dst->master_netdev->ifindex;
+	return p->master->ifindex;
 }
 
 static inline bool dsa_port_is_bridged(struct dsa_port *dp)
@@ -77,7 +77,7 @@ static inline bool dsa_port_is_bridged(struct dsa_port *dp)
 static int dsa_slave_open(struct net_device *dev)
 {
 	struct dsa_slave_priv *p = netdev_priv(dev);
-	struct net_device *master = p->dp->ds->dst->master_netdev;
+	struct net_device *master = p->master;
 	struct dsa_switch *ds = p->dp->ds;
 	u8 stp_state = dsa_port_is_bridged(p->dp) ?
 			BR_STATE_BLOCKING : BR_STATE_FORWARDING;
@@ -132,7 +132,7 @@ static int dsa_slave_open(struct net_device *dev)
 static int dsa_slave_close(struct net_device *dev)
 {
 	struct dsa_slave_priv *p = netdev_priv(dev);
-	struct net_device *master = p->dp->ds->dst->master_netdev;
+	struct net_device *master = p->master;
 	struct dsa_switch *ds = p->dp->ds;
 
 	if (p->phy)
@@ -159,7 +159,7 @@ static int dsa_slave_close(struct net_device *dev)
 static void dsa_slave_change_rx_flags(struct net_device *dev, int change)
 {
 	struct dsa_slave_priv *p = netdev_priv(dev);
-	struct net_device *master = p->dp->ds->dst->master_netdev;
+	struct net_device *master = p->master;
 
 	if (change & IFF_ALLMULTI)
 		dev_set_allmulti(master, dev->flags & IFF_ALLMULTI ? 1 : -1);
@@ -170,7 +170,7 @@ static void dsa_slave_change_rx_flags(struct net_device *dev, int change)
 static void dsa_slave_set_rx_mode(struct net_device *dev)
 {
 	struct dsa_slave_priv *p = netdev_priv(dev);
-	struct net_device *master = p->dp->ds->dst->master_netdev;
+	struct net_device *master = p->master;
 
 	dev_mc_sync(master, dev);
 	dev_uc_sync(master, dev);
@@ -179,7 +179,7 @@ static void dsa_slave_set_rx_mode(struct net_device *dev)
 static int dsa_slave_set_mac_address(struct net_device *dev, void *a)
 {
 	struct dsa_slave_priv *p = netdev_priv(dev);
-	struct net_device *master = p->dp->ds->dst->master_netdev;
+	struct net_device *master = p->master;
 	struct sockaddr *addr = a;
 	int err;
 
@@ -376,7 +376,7 @@ static netdev_tx_t dsa_slave_xmit(struct sk_buff *skb, struct net_device *dev)
 	/* Queue the SKB for transmission on the parent interface, but
 	 * do not modify its EtherType
 	 */
-	nskb->dev = p->dp->ds->dst->master_netdev;
+	nskb->dev = p->master;
 	dev_queue_xmit(nskb);
 
 	return NETDEV_TX_OK;
@@ -685,7 +685,7 @@ static int dsa_slave_netpoll_setup(struct net_device *dev,
 {
 	struct dsa_slave_priv *p = netdev_priv(dev);
 	struct dsa_switch *ds = p->dp->ds;
-	struct net_device *master = ds->dst->master_netdev;
+	struct net_device *master = p->master;
 	struct netpoll *netpoll;
 	int err = 0;
 
@@ -1140,11 +1140,16 @@ int dsa_slave_create(struct dsa_switch *ds, struct device *parent,
 	struct net_device *master;
 	struct net_device *slave_dev;
 	struct dsa_slave_priv *p;
+	int port_cpu = ds->ports[port].upstream;
 	int ret;
 
-	master = ds->dst->master_netdev;
-	if (ds->master_netdev)
+	if (port_cpu && ds->ports[port_cpu].ethernet)
+		master = ds->ports[port_cpu].ethernet;
+	else if (ds->master_netdev)
 		master = ds->master_netdev;
+	else
+		master = ds->dst->master_netdev;
+	master->dsa_ptr = (void *)ds->dst;
 
 	slave_dev = alloc_netdev(sizeof(struct dsa_slave_priv), name,
 				 NET_NAME_UNKNOWN, ether_setup);
@@ -1173,6 +1178,7 @@ int dsa_slave_create(struct dsa_switch *ds, struct device *parent,
 	p->dp = &ds->ports[port];
 	INIT_LIST_HEAD(&p->mall_tc_list);
 	p->xmit = dst->tag_ops->xmit;
+	p->master = master;
 
 	p->old_pause = -1;
 	p->old_link = -1;
-- 
2.11.0

^ permalink raw reply related

* [PATCH V2 3/3] net-next: dsa: mt7530: add multi cpu port support
From: John Crispin @ 2017-05-30 10:44 UTC (permalink / raw)
  To: Andrew Lunn, Vivien Didelot, Florian Fainelli, David S . Miller,
	Sean Wang
  Cc: netdev, linux-kernel, John Crispin
In-Reply-To: <20170530104419.6052-1-john@phrozen.org>

MT7530 switches have 2 CPU ports. Inside an MT7623a these are connected
to GMAC1 and GMAC2. The code currently has the CPU hard coded to 6. Change
this to using the new dsa_port_upstream_port() api. In case port 5 is not
setup as a cpu port, we configure the RGMII passthrough mode allowing GMAC2
to connect to an external PHY.

Signed-off-by: John Crispin <john@phrozen.org>
---
 drivers/net/dsa/mt7530.c | 45 +++++++++++++++++++++++++++++----------------
 drivers/net/dsa/mt7530.h |  1 -
 2 files changed, 29 insertions(+), 17 deletions(-)

diff --git a/drivers/net/dsa/mt7530.c b/drivers/net/dsa/mt7530.c
index 4d2f45153ede..370e0833474b 100644
--- a/drivers/net/dsa/mt7530.c
+++ b/drivers/net/dsa/mt7530.c
@@ -632,6 +632,9 @@ static int
 mt7530_cpu_port_enable(struct mt7530_priv *priv,
 		       int port)
 {
+	u8 port_mask = 0;
+	int i;
+
 	/* Enable Mediatek header mode on the cpu port */
 	mt7530_write(priv, MT7530_PVC_P(port),
 		     PORT_SPEC_TAG);
@@ -648,8 +651,12 @@ mt7530_cpu_port_enable(struct mt7530_priv *priv,
 	/* CPU port gets connected to all user ports of
 	 * the switch
 	 */
+	for (i = 0; i < MT7530_NUM_PORTS; i++)
+		if ((priv->ds->enabled_port_mask & BIT(i)) &&
+		    (dsa_port_upstream_port(priv->ds, i) == port))
+			port_mask |= BIT(i);
 	mt7530_write(priv, MT7530_PCR_P(port),
-		     PCR_MATRIX(priv->ds->enabled_port_mask));
+		     PCR_MATRIX(port_mask));
 
 	return 0;
 }
@@ -659,6 +666,7 @@ mt7530_port_enable(struct dsa_switch *ds, int port,
 		   struct phy_device *phy)
 {
 	struct mt7530_priv *priv = ds->priv;
+	u8 upstream = dsa_port_upstream_port(ds, port);
 
 	mutex_lock(&priv->reg_mutex);
 
@@ -669,7 +677,7 @@ mt7530_port_enable(struct dsa_switch *ds, int port,
 	 * restore the port matrix if the port is the member of a certain
 	 * bridge.
 	 */
-	priv->ports[port].pm |= PCR_MATRIX(BIT(MT7530_CPU_PORT));
+	priv->ports[port].pm |= PCR_MATRIX(BIT(upstream));
 	priv->ports[port].enable = true;
 	mt7530_rmw(priv, MT7530_PCR_P(port), PCR_MATRIX_MASK,
 		   priv->ports[port].pm);
@@ -732,7 +740,8 @@ mt7530_port_bridge_join(struct dsa_switch *ds, int port,
 			struct net_device *bridge)
 {
 	struct mt7530_priv *priv = ds->priv;
-	u32 port_bitmap = BIT(MT7530_CPU_PORT);
+	u8 upstream = dsa_port_upstream_port(ds, port);
+	u32 port_bitmap = BIT(upstream);
 	int i;
 
 	mutex_lock(&priv->reg_mutex);
@@ -770,6 +779,7 @@ mt7530_port_bridge_leave(struct dsa_switch *ds, int port,
 			 struct net_device *bridge)
 {
 	struct mt7530_priv *priv = ds->priv;
+	u8 upstream = dsa_port_upstream_port(ds, port);
 	int i;
 
 	mutex_lock(&priv->reg_mutex);
@@ -794,8 +804,8 @@ mt7530_port_bridge_leave(struct dsa_switch *ds, int port,
 	 */
 	if (priv->ports[port].enable)
 		mt7530_rmw(priv, MT7530_PCR_P(port), PCR_MATRIX_MASK,
-			   PCR_MATRIX(BIT(MT7530_CPU_PORT)));
-	priv->ports[port].pm = PCR_MATRIX(BIT(MT7530_CPU_PORT));
+			   PCR_MATRIX(BIT(upstream)));
+	priv->ports[port].pm = PCR_MATRIX(BIT(upstream));
 
 	mutex_unlock(&priv->reg_mutex);
 }
@@ -892,15 +902,7 @@ mt7530_port_fdb_dump(struct dsa_switch *ds, int port,
 static enum dsa_tag_protocol
 mtk_get_tag_protocol(struct dsa_switch *ds)
 {
-	struct mt7530_priv *priv = ds->priv;
-
-	if (!dsa_is_cpu_port(ds, MT7530_CPU_PORT)) {
-		dev_warn(priv->dev,
-			 "port not matched with tagging CPU port\n");
-		return DSA_TAG_PROTO_NONE;
-	} else {
-		return DSA_TAG_PROTO_MTK;
-	}
+	return DSA_TAG_PROTO_MTK;
 }
 
 static int
@@ -971,10 +973,21 @@ mt7530_setup(struct dsa_switch *ds)
 		     SYS_CTRL_PHY_RST | SYS_CTRL_SW_RST |
 		     SYS_CTRL_REG_RST);
 
-	/* Enable Port 6 only; P5 as GMAC5 which currently is not supported */
+	/* Enable Port 6. Port 5 is setup in passthrough mode if it is not a CPU
+	 * port
+	 */
 	val = mt7530_read(priv, MT7530_MHWTRAP);
-	val &= ~MHWTRAP_P6_DIS & ~MHWTRAP_PHY_ACCESS;
+	val &= ~MHWTRAP_P5_DIS & ~MHWTRAP_P6_DIS & ~MHWTRAP_PHY_ACCESS;
 	val |= MHWTRAP_MANUAL;
+	if (!dsa_is_cpu_port(ds, 5)) {
+		val |= MHWTRAP_P5_DIS;
+		val |= MHWTRAP_P5_MAC_SEL;
+		val |= MHWTRAP_P5_RGMII_MODE;
+	} else if (0) {
+		val &= ~MHWTRAP_P5_DIS;
+		val &= ~MHWTRAP_P5_MAC_SEL;
+		val &= ~MHWTRAP_P5_RGMII_MODE;
+	}
 	mt7530_write(priv, MT7530_MHWTRAP, val);
 
 	/* Enable and reset MIB counters */
diff --git a/drivers/net/dsa/mt7530.h b/drivers/net/dsa/mt7530.h
index b83d76b99802..728e0c3a8883 100644
--- a/drivers/net/dsa/mt7530.h
+++ b/drivers/net/dsa/mt7530.h
@@ -15,7 +15,6 @@
 #define __MT7530_H
 
 #define MT7530_NUM_PORTS		7
-#define MT7530_CPU_PORT			6
 #define MT7530_NUM_FDB_RECORDS		2048
 
 #define	NUM_TRGMII_CTRL			5
-- 
2.11.0

^ permalink raw reply related

* Re: vxlan: use after free error
From: Jiri Benc @ 2017-05-30 11:47 UTC (permalink / raw)
  To: Roopa Prabhu
  Cc: Mark Bloch, davem@davemloft.net, pravin shelar, Alexander Duyck,
	Nicolas Dichtel, netdev@vger.kernel.org, Balki Raman
In-Reply-To: <CAJieiUgwRT8NbNdZ37HXJn9OYc78bpj=Zb9N5pQQQ_SLZhD1kg@mail.gmail.com>

On Mon, 29 May 2017 11:37:22 -0700, Roopa Prabhu wrote:
> This code is also hit via the OVS path, and i don't see a problem with
> your changes and analysis but i am not too familiar with the ovs call
> path. I see that the relevant developers are CC'ed.

I don't see a problem with ovs and this patch. Ovs calls
rtnl_delete_link.

I'd prefer to have the code in a vxlan_vs_del_dev function to be
symmetrical with vxlan_vs_add_dev similarly to what Roopa suggested. If
you keep me in CC while resending I'll be happy to add my ack to the
patch.

Thanks!

 Jiri

^ permalink raw reply

* Re: vxlan: use after free error
From: Jiri Benc @ 2017-05-30 11:53 UTC (permalink / raw)
  To: Roopa Prabhu
  Cc: Mark Bloch, davem@davemloft.net, pravin shelar, Alexander Duyck,
	Nicolas Dichtel, netdev@vger.kernel.org, Balki Raman
In-Reply-To: <CAJieiUgwRT8NbNdZ37HXJn9OYc78bpj=Zb9N5pQQQ_SLZhD1kg@mail.gmail.com>

On Mon, 29 May 2017 11:37:22 -0700, Roopa Prabhu wrote:
> What you say looks correct..., but does not hurt to leave this check in there..
> given rest of the changes you are proposing below.

I agree with Mark that the check is superfluous and should not be there.

> Looking at git blame, this check was added for OVS in dellink...but it
> could have been because
>  it was being called before stop in dellink.

The code at that time did not use rtnl ops to create/delete the tunnel
and was refactored meanwhile. The conditions from that time do not hold
anymore.

> That seems right. It does look redundant if we hit the same code via
> vxlan_stop during dellink.
> 
> This code is also hit via the OVS path, and i don't see a problem with
> your changes and analysis but i am not too familiar with the ovs call
> path. I see that the relevant developers are CC'ed.

I think it's okay.

Thanks!

 Jiri

^ permalink raw reply

* Re: [PATCH net-next] cxgb4: fix incorrect cim_la output for T6
From: Ganesh Goudar @ 2017-05-30 11:53 UTC (permalink / raw)
  To: David Laight
  Cc: netdev@vger.kernel.org, davem@davemloft.net,
	nirranjan@chelsio.com, indranil@chelsio.com
In-Reply-To: <063D6719AE5E284EB5DD2968C1650D6DCFFFABCB@AcuExch.aculab.com>

On Friday, May 05/19/17, 2017 at 14:17:11 +0000, David Laight wrote:
> From: Ganesh Goudar
> > Sent: 19 May 2017 11:12
> T6
> > 
> > take care of UpDbgLaRdPtr[0-3] restriction for T6
> > 
> > Signed-off-by: Ganesh Goudar <ganeshgr@chelsio.com>
> > ---
> >  drivers/net/ethernet/chelsio/cxgb4/t4_hw.c | 7 +++++++
> >  1 file changed, 7 insertions(+)
> > 
> > diff --git a/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c b/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c
> > index aded42b96..917b46b 100644
> > --- a/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c
> > +++ b/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c
> > @@ -8268,6 +8268,13 @@ int t4_cim_read_la(struct adapter *adap, u32 *la_buf, unsigned int *wrptr)
> >  		if (ret)
> >  			break;
> >  		idx = (idx + 1) & UPDBGLARDPTR_M;
> > +
> > +		/* Bits 0-3 of UpDbgLaRdPtr can be between 0000 to 1001 to
> > +		 * identify the 32-bit portion of the full 312-bit data
> > +		 */
> > +		if (is_t6(adap->params.chip))
> > +			while ((idx & 0xf) > 9)
> > +				idx = (idx + 1) % UPDBGLARDPTR_M;
> 
> Why the loop, maybe:
> 		if (is_t6(adap->params.chip) && (idx & 0xf) >= 9)
> 			idx = (idx & 0xf0) + 0x10;
> 		else
> 			idx++;
> 		idx &= UPDBGLARDPTR_M;
> 
> 	David
>
Yes, it is sensible I will send a v2, thanks David.

Thanks 

^ permalink raw reply

* Re: vxlan: use after free error
From: Jiri Benc @ 2017-05-30 11:54 UTC (permalink / raw)
  To: Roopa Prabhu
  Cc: Mark Bloch, davem@davemloft.net, pravin shelar, Alexander Duyck,
	Nicolas Dichtel, netdev@vger.kernel.org, Balki Raman
In-Reply-To: <20170530134755.6675023c@griffin>

On Tue, 30 May 2017 13:47:55 +0200, Jiri Benc wrote:
> On Mon, 29 May 2017 11:37:22 -0700, Roopa Prabhu wrote:
> > This code is also hit via the OVS path, and i don't see a problem with
> > your changes and analysis but i am not too familiar with the ovs call
> > path. I see that the relevant developers are CC'ed.
> 
> I don't see a problem with ovs and this patch. Ovs calls
> rtnl_delete_link.
> 
> I'd prefer to have the code in a vxlan_vs_del_dev function to be
> symmetrical with vxlan_vs_add_dev similarly to what Roopa suggested. If
> you keep me in CC while resending I'll be happy to add my ack to the
> patch.

I replied to a wrong email in the thread but I guess it's obvious what
I wanted to reply to :-)

Sorry for that,

 Jiri

^ permalink raw reply

* Re: Error with printk and bpf_trace_printk
From: Jesper Dangaard Brouer via iovisor-dev @ 2017-05-30 12:24 UTC (permalink / raw)
  To: Adel Fuchs
  Cc: xdp-newbies-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
	netdev-u79uwXL29TY76Z2rM5mHXA,
	iovisor-dev-9jONkmmOlFHEE9lA1F8Ukti2O/JbrIOy@public.gmane.org
In-Reply-To: <CAErYV9EJtbgaWn4KAeoADxnHgj7S+vFdHgu78Y2PxNuhpWrANw-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>


Notice, there are two mailing lists (Cc'ed) that you should likely ask
these kind of questions on (instead of netdev), depending on if this is
mostly related to bpf (iovisor-dev-9jONkmmOlFHEE9lA1F8Ukti2O/JbrIOy@public.gmane.org) or somehow
related to XDP (xdp-newbies-u79uwXL29TY76Z2rM5mHXA@public.gmane.org).

See my answer inlined below:

On Sun, 28 May 2017 17:48:20 +0300 Adel Fuchs <adelfuchs-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:

> I have a working eBPF program, and I'm trying to add outputs to it.
> I'm not able to use both printk and bpf_trace_printk functions. I get
> this error:
> 
> ELF contains non-map related relo data in entry 0 pointing to section
> 8! Compiler bug?!
> 
> Prog section 'ingress' rejected: Invalid argument (22)!
>  - Type:         3
>  - Instructions: 16 (0 over limit)
>  - License:      GPL
> 
> Verifier analysis:
> 
> 0: (bf) r6 = r1
> 1: (18) r1 = 0x0
> 3: (85) call bpf_unspec#0
> unknown func bpf_unspec#0
> 
> Error fetching program/map!
> Failed to retrieve (e)BPF data!
> 
> Are there certain "includes" that I need to add?
> In addition, I'm not sure I'm using the function correctly. I just
> wrote: printk("hi")

You obviously cannot call printk directly from and eBPF program.
I wonder how you got this compiling...

As you hinted yourself, you should be using: bpf_trace_printk().
But it is actually tricky to use... and not much help is around to
figure this out.

First of all the output end-up in this file: /sys/kernel/debug/tracing/trace_pipe
Remember to read the output use 'cat' like:

 sudo cat /sys/kernel/debug/tracing/trace_pipe

And only the first process to read the output gets the output...


I deduct you are using the TC/iproute2 examples:
 https://git.kernel.org/pub/scm/linux/kernel/git/shemminger/iproute2.git/tree/examples/bpf

Next gotcha is that, you need to provide the char* string in a very
special way to make this compile correctly.  The iproute2 provide a
helper define called "printt()" in include/bpf_api.h for this:

#ifndef printt
# define printt(fmt, ...)                                               \
        ({                                                              \
                char ____fmt[] = fmt;                                   \
                trace_printk(____fmt, sizeof(____fmt), ##__VA_ARGS__);  \
        })
#endif

Or see my solution here:
[1] https://github.com/netoptimizer/prototype-kernel/blob/master/kernel/samples/bpf/xdp_ddos01_blacklist_kern.c#L86:L99


Another gotcha I've experienced is that if you format the string
incorrectly, or use a modifier like %X, which bpf_trace_printk() does
not seem to understand, then you "hear-nothing"...  Also experienced if
using more than 3 arguments, then it fails or also go silent. Be
careful when using this somewhat "flaky" debug facility.

Do remember these bpf_trace_printk() should only be used for debugging,
as it is very slow...
-- 
Best regards,
  Jesper Dangaard Brouer
  MSc.CS, Principal Kernel Engineer at Red Hat
  LinkedIn: http://www.linkedin.com/in/brouer

^ permalink raw reply

* [PATCH net-next] cxgb4: FW upgrade fixes
From: Ganesh Goudar @ 2017-05-30 12:36 UTC (permalink / raw)
  To: netdev, davem
  Cc: nirranjan, indranil, Arjun Vynipadath, Casey Leedom,
	Ganesh Goudar

From: Arjun Vynipadath <arjun@chelsio.com>

Disable FW_OK flag while flashing Firmware. This will help to fix any
potential mailbox timeouts during Firmware flash.

Grab new devlog parameters after Firmware restart. When we FLASH new
Firmware onto an adapter, the new Firmware may have the Firmware Device Log
located at a different memory address or have a different size for it.

Signed-off-by: Arjun Vynipadath <arjun@chelsio.com>
Signed-off-by: Casey Leedom <leedom@chelsio.com>
Signed-off-by: Ganesh Goudar <ganeshgr@chelsio.com>
---
v2:
-Fix spelling mistake, "send" -> "sent"

 drivers/net/ethernet/chelsio/cxgb4/t4_hw.c | 21 ++++++++++++++++++---
 1 file changed, 18 insertions(+), 3 deletions(-)

diff --git a/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c b/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c
index b97ce4a..9160c88 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c
+++ b/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c
@@ -6288,13 +6288,18 @@ int t4_fw_upgrade(struct adapter *adap, unsigned int mbox,
 	if (!t4_fw_matches_chip(adap, fw_hdr))
 		return -EINVAL;
 
+	/* Disable FW_OK flag so that mbox commands with FW_OK flag set
+	 * wont be sent when we are flashing FW.
+	 */
+	adap->flags &= ~FW_OK;
+
 	ret = t4_fw_halt(adap, mbox, force);
 	if (ret < 0 && !force)
-		return ret;
+		goto out;
 
 	ret = t4_load_fw(adap, fw_data, size);
 	if (ret < 0)
-		return ret;
+		goto out;
 
 	/*
 	 * Older versions of the firmware don't understand the new
@@ -6305,7 +6310,17 @@ int t4_fw_upgrade(struct adapter *adap, unsigned int mbox,
 	 * its header flags to see if it advertises the capability.
 	 */
 	reset = ((be32_to_cpu(fw_hdr->flags) & FW_HDR_FLAGS_RESET_HALT) == 0);
-	return t4_fw_restart(adap, mbox, reset);
+	ret = t4_fw_restart(adap, mbox, reset);
+
+	/* Grab potentially new Firmware Device Log parameters so we can see
+	 * how healthy the new Firmware is.  It's okay to contact the new
+	 * Firmware for these parameters even though, as far as it's
+	 * concerned, we've never said "HELLO" to it ...
+	 */
+	(void)t4_init_devlog_params(adap);
+out:
+	adap->flags |= FW_OK;
+	return ret;
 }
 
 /**
-- 
2.1.0

^ permalink raw reply related

* [PATCH net] samples/bpf: bpf_load.c order of prog_fd[] should correspond with ELF order
From: Jesper Dangaard Brouer @ 2017-05-30 12:37 UTC (permalink / raw)
  To: Alexei Starovoitov; +Cc: netdev, Jesper Dangaard Brouer

An eBPF ELF file generated with LLVM can contain several program
section, which can be used for bpf tail calls.  The bpf prog file
descriptors are accessible via array prog_fd[].

At-least XDP samples assume ordering, and uses prog_fd[0] is the main
XDP program to attach.  The actual order of array prog_fd[] depend on
whether or not a bpf program section is referencing any maps or not.
Not using a map result in being loaded/processed after all other
prog section.  Thus, this can lead to some very strange and hard to
debug situation, as the user can only see a FD and cannot correlated
that with the ELF section name.

The fix is rather simple, and even removes duplicate memcmp code.
Simply load program sections as the last step, instead of
load_and_attach while processing the relocation section.

When working with tail calls, it become even more essential that the
order of prog_fd[] is consistant, like the current dependency of the
map_fd[] order.

Signed-off-by: Jesper Dangaard Brouer <brouer@redhat.com>
---
 samples/bpf/bpf_load.c |   19 +++++--------------
 1 file changed, 5 insertions(+), 14 deletions(-)

diff --git a/samples/bpf/bpf_load.c b/samples/bpf/bpf_load.c
index 74456b3eb89a..a91c57dd8571 100644
--- a/samples/bpf/bpf_load.c
+++ b/samples/bpf/bpf_load.c
@@ -516,16 +516,18 @@ static int do_load_bpf_file(const char *path, fixup_map_cb fixup_map)
 		processed_sec[maps_shndx] = true;
 	}
 
-	/* load programs that need map fixup (relocations) */
+	/* process all relo sections, and rewrite bpf insns for maps */
 	for (i = 1; i < ehdr.e_shnum; i++) {
 		if (processed_sec[i])
 			continue;
 
 		if (get_sec(elf, i, &ehdr, &shname, &shdr, &data))
 			continue;
+
 		if (shdr.sh_type == SHT_REL) {
 			struct bpf_insn *insns;
 
+			/* locate prog sec that need map fixup (relocations) */
 			if (get_sec(elf, shdr.sh_info, &ehdr, &shname_prog,
 				    &shdr_prog, &data_prog))
 				continue;
@@ -535,26 +537,15 @@ static int do_load_bpf_file(const char *path, fixup_map_cb fixup_map)
 				continue;
 
 			insns = (struct bpf_insn *) data_prog->d_buf;
-
-			processed_sec[shdr.sh_info] = true;
-			processed_sec[i] = true;
+			processed_sec[i] = true; /* relo section */
 
 			if (parse_relo_and_apply(data, symbols, &shdr, insns,
 						 map_data, nr_maps))
 				continue;
-
-			if (memcmp(shname_prog, "kprobe/", 7) == 0 ||
-			    memcmp(shname_prog, "kretprobe/", 10) == 0 ||
-			    memcmp(shname_prog, "tracepoint/", 11) == 0 ||
-			    memcmp(shname_prog, "xdp", 3) == 0 ||
-			    memcmp(shname_prog, "perf_event", 10) == 0 ||
-			    memcmp(shname_prog, "socket", 6) == 0 ||
-			    memcmp(shname_prog, "cgroup/", 7) == 0)
-				load_and_attach(shname_prog, insns, data_prog->d_size);
 		}
 	}
 
-	/* load programs that don't use maps */
+	/* load programs */
 	for (i = 1; i < ehdr.e_shnum; i++) {
 
 		if (processed_sec[i])

^ permalink raw reply related

* Re: [PATCH net-next 1/4] net/flow_dissector: add support for dissection of misc ip header fields
From: Jiri Pirko @ 2017-05-30 13:10 UTC (permalink / raw)
  To: Tom Herbert
  Cc: Or Gerlitz, Or Gerlitz, David S. Miller,
	Linux Kernel Network Developers, Saeed Mahameed, Roi Dayan,
	Paul Blakey
In-Reply-To: <CALx6S35LoybyU-NN8RTk4YMOmuOZTkJeZ6GVBnWbX6rtd2uM6Q@mail.gmail.com>

Sat, May 27, 2017 at 07:18:45PM CEST, tom@herbertland.com wrote:
>On Sat, May 27, 2017 at 9:31 AM, Or Gerlitz <gerlitz.or@gmail.com> wrote:
>> On Thu, May 25, 2017 at 7:22 PM, Tom Herbert <tom@herbertland.com> wrote:
>>> On Thu, May 25, 2017 at 6:24 AM, Or Gerlitz <ogerlitz@mellanox.com> wrote:
>>>> Add support for dissection of ip tos and ttl and ipv6 traffic-class
>>>> and hoplimit. Both are dissected into the same struct.
>>
>>>> Uses similar call to ip dissection function as with tcp, arp and others.
>>
>>
>>>> +/**
>>>> + * struct flow_dissector_key_ip:
>>>> + * @tos: tos
>>>> + * @ttl: ttl
>>>> + */
>>>> +struct flow_dissector_key_ip {
>>>> +       __u8    tos;
>>>> +       __u8    ttl;
>>>> +};
>>>> --- a/net/core/flow_dissector.c
>>>> +++ b/net/core/flow_dissector.c
>>
>>>> +static void
>>>> +__skb_flow_dissect_ipv4(const struct sk_buff *skb,
>>>> +                       struct flow_dissector *flow_dissector,
>>>> +                       void *target_container, void *data, const struct iphdr *iph)
>>>> +{
>>>> +       struct flow_dissector_key_ip *key_ip;
>>>> +
>>>> +       if (!dissector_uses_key(flow_dissector, FLOW_DISSECTOR_KEY_IP))
>>>> +               return;
>>>> +
>>>> +       key_ip = skb_flow_dissector_target(flow_dissector,
>>>> +                                          FLOW_DISSECTOR_KEY_IP,
>>>> +                                          target_container);
>>>> +       key_ip->tos = iph->tos;
>>>> +       key_ip->ttl = iph->ttl;
>>>
>>> In an encapsulation this returns the tos and ttl of the encapsulated
>>> packet. Is that really useful to the caller? Seems more likely that
>>> they need the outer tos and ttl for forwarding.
>>
>> In what we are dealing with, classification is carried after the
>> packet is decapsulated by the shared tunnel device. So even today,e.g
>> for the src/dst IP, the dissection is carried on what were the inner
>> fields before decap.
>>
>Or,
>
>I think the problem is I don't know what you're dealing with. The only
>thing I can derive from the commit log is that tos and ttl are being
>extracted, but I don't know why they are needed. I do know this is
>adding complexity to an already overly complex function, and this
>introduces new conditionals and code into the primary use case of
>flow_dissector which is to create a key for deriving skb->hash. I
>don't see that the cost of this patch has been justified.

Tom, we have been over this multiple times. The decision DaveM made at
the time I was pushing cls_flower was to have one shared dissection code
(I originally had a separate dissector inside cls_flower). And I
agree with that decision. It was a bit painful to work out the
flow_dissector in a generic way, but it was worth the efford.

So when we need to dissect something new for cls_flower, we put it here.
flow_dissector is now miles away from being just a plain
"creator of the key to derive skb->hash".

Jiří

^ permalink raw reply

* Re: 'iw events' stops receiving events after a while on 4.9 + hacks
From: Johannes Berg @ 2017-05-30 13:18 UTC (permalink / raw)
  To: Ben Greear, Bastian Bittorf; +Cc: netdev, linux-wireless@vger.kernel.org
In-Reply-To: <fa96dfad-8d1b-c48f-df3b-3df0d548a5c6@candelatech.com>

On Wed, 2017-05-17 at 08:22 -0700, Ben Greear wrote:
> 
> I saw it exactly once so far, and it happened overnight,
> but we have not been doing a lot of work with the 4.9 kernel until
> recently.
> 
> I don't think there were many messages on this system, and certainly
> others have run much longer on systems that should be generating many
> more events without trouble.

Ok.

> Is there any way to dump out the socket information if we reproduce
> the problem?

I have no idea, sorry.

If you or Bastian can tell me how to reproduce the problem, I can try
to investigate it.

johannes

^ permalink raw reply

* [i40e] regression on TCP stream and TCP maerts, kernel-4.12.0-0.rc2
From: Adam Okuliar @ 2017-05-30 13:43 UTC (permalink / raw)
  To: netdev, Adrian Tomasov, jeffrey.t.kirsher; +Cc: Otto Sabart, jhladky

Hello,

we found regression on intel card(XL710) with i40e driver. Regression is 
about ~45%
on TCP_STREAM and TCP_MAERTS test for IPv4 and IPv6. Regression was first
visible in kernel-4.12.0-0.rc1.

More details about results you can see in uploaded images in bugzilla. [0]


[0] https://bugzilla.kernel.org/show_bug.cgi?id=195923


Best regards, / S pozdravom,

Adrián Tomašov
Kernel Performance QE
atomasov@redhat.com

^ permalink raw reply


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