* [PATCH 1/2] net: socket: fix potential spectre v1 gadget in socketcall
From: Jeremy Cline @ 2018-07-27 22:43 UTC (permalink / raw)
To: David S . Miller
Cc: netdev, linux-kernel, Josh Poimboeuf, Jeremy Cline, stable
In-Reply-To: <20180727224302.5503-1-jcline@redhat.com>
'call' is a user-controlled value, so sanitize the array index after the
bounds check to avoid speculating past the bounds of the 'nargs' array.
Found with the help of Smatch:
net/socket.c:2508 __do_sys_socketcall() warn: potential spectre issue
'nargs' [r] (local cap)
Cc: Josh Poimboeuf <jpoimboe@redhat.com>
Cc: stable@vger.kernel.org
Signed-off-by: Jeremy Cline <jcline@redhat.com>
---
net/socket.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/net/socket.c b/net/socket.c
index 3015ddace71e..f15d5cbb3ba4 100644
--- a/net/socket.c
+++ b/net/socket.c
@@ -89,6 +89,7 @@
#include <linux/magic.h>
#include <linux/slab.h>
#include <linux/xattr.h>
+#include <linux/nospec.h>
#include <linux/uaccess.h>
#include <asm/unistd.h>
@@ -2504,6 +2505,7 @@ SYSCALL_DEFINE2(socketcall, int, call, unsigned long __user *, args)
if (call < 1 || call > SYS_SENDMMSG)
return -EINVAL;
+ call = array_index_nospec(call, SYS_SENDMMSG + 1);
len = nargs[call];
if (len > sizeof(a))
--
2.17.1
^ permalink raw reply related
* [PATCH 0/2] net: socket: Fix potential spectre v1 gadgets
From: Jeremy Cline @ 2018-07-27 22:43 UTC (permalink / raw)
To: David S . Miller; +Cc: netdev, linux-kernel, Josh Poimboeuf, Jeremy Cline
Hi folks,
This fixes a pair of potential spectre v1 gadgets.
Note that because the speculation window is large, the policy is to stop
the speculative out-of-bounds load and not worry if the attack can be
completed with a dependent load or store[0].
[0] https://marc.info/?l=linux-kernel&m=152449131114778
Jeremy Cline (2):
net: socket: fix potential spectre v1 gadget in socketcall
net: socket: Fix potential spectre v1 gadget in sock_is_registered
net/socket.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
--
2.17.1
^ permalink raw reply
* [PATCH net] tcp_bbr: fix bw probing to raise in-flight data for very small BDPs
From: Neal Cardwell @ 2018-07-27 21:19 UTC (permalink / raw)
To: David Miller; +Cc: netdev, Neal Cardwell
For some very small BDPs (with just a few packets) there was a
quantization effect where the target number of packets in flight
during the super-unity-gain (1.25x) phase of gain cycling was
implicitly truncated to a number of packets no larger than the normal
unity-gain (1.0x) phase of gain cycling. This meant that in multi-flow
scenarios some flows could get stuck with a lower bandwidth, because
they did not push enough packets inflight to discover that there was
more bandwidth available. This was really only an issue in multi-flow
LAN scenarios, where RTTs and BDPs are low enough for this to be an
issue.
This fix ensures that gain cycling can raise inflight for small BDPs
by ensuring that in PROBE_BW mode target inflight values with a
super-unity gain are always greater than inflight values with a gain
<= 1. Importantly, this applies whether the inflight value is
calculated for use as a cwnd value, or as a target inflight value for
the end of the super-unity phase in bbr_is_next_cycle_phase() (both
need to be bigger to ensure we can probe with more packets in flight
reliably).
This is a candidate fix for stable releases.
Fixes: 0f8782ea1497 ("tcp_bbr: add BBR congestion control")
Signed-off-by: Neal Cardwell <ncardwell@google.com>
Acked-by: Yuchung Cheng <ycheng@google.com>
Acked-by: Soheil Hassas Yeganeh <soheil@google.com>
Acked-by: Priyaranjan Jha <priyarjha@google.com>
Reviewed-by: Eric Dumazet <edumazet@google.com>
---
net/ipv4/tcp_bbr.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/net/ipv4/tcp_bbr.c b/net/ipv4/tcp_bbr.c
index 3b5f45b9e81eb..13d34427ca3dd 100644
--- a/net/ipv4/tcp_bbr.c
+++ b/net/ipv4/tcp_bbr.c
@@ -358,6 +358,10 @@ static u32 bbr_target_cwnd(struct sock *sk, u32 bw, int gain)
/* Reduce delayed ACKs by rounding up cwnd to the next even number. */
cwnd = (cwnd + 1) & ~1U;
+ /* Ensure gain cycling gets inflight above BDP even for small BDPs. */
+ if (bbr->mode == BBR_PROBE_BW && gain > BBR_UNIT)
+ cwnd += 2;
+
return cwnd;
}
--
2.18.0.345.g5c9ce644c3-goog
^ permalink raw reply related
* Re: [PATCH net] net/mlx5e: Move mlx5e_priv_flags into en_ethtool.c
From: Saeed Mahameed @ 2018-07-27 21:17 UTC (permalink / raw)
To: Kamal Heib; +Cc: David S . Miller, Saeed Mahameed, Linux Netdev List
In-Reply-To: <20180727155940.GA12305@kheib-laptop>
On Fri, Jul 27, 2018 at 8:59 AM, Kamal Heib <kamalheib1@gmail.com> wrote:
> On Thu, Jul 26, 2018 at 11:51:49AM -0700, Saeed Mahameed wrote:
>> On Sun, Jul 15, 2018 at 12:06 PM, Kamal Heib <kamalheib1@gmail.com> wrote:
>> > Move the definition of mlx5e_priv_flags into en_ethtool.c because it's
>> > only used there.
>> >
>> > Fixes: 4e59e2888139 ("net/mlx5e: Introduce net device priv flags infrastructure")
>> > Signed-off-by: Kamal Heib <kamalheib1@gmail.com>
>> > ---
>> > drivers/net/ethernet/mellanox/mlx5/core/en.h | 7 -------
>> > drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c | 7 +++++++
>> > 2 files changed, 7 insertions(+), 7 deletions(-)
>> >
>> > diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en.h b/drivers/net/ethernet/mellanox/mlx5/core/en.h
>> > index eb9eb7aa953a..84e6a5b42286 100644
>> > --- a/drivers/net/ethernet/mellanox/mlx5/core/en.h
>> > +++ b/drivers/net/ethernet/mellanox/mlx5/core/en.h
>> > @@ -208,13 +208,6 @@ struct mlx5e_umr_wqe {
>> >
>> > extern const char mlx5e_self_tests[][ETH_GSTRING_LEN];
>> >
>> > -static const char mlx5e_priv_flags[][ETH_GSTRING_LEN] = {
>> > - "rx_cqe_moder",
>> > - "tx_cqe_moder",
>> > - "rx_cqe_compress",
>> > - "rx_striding_rq",
>> > -};
>> > -
>>
>> Hi Kamal, on a second thought, i would like to drop this change and
>> keep mlx5e_priv_flags close/local to the below mlx5e_priv_flag.
>>
>> Please let me know.
>>
>
> Hi,
>
> Basically this change came to avoid the following warning when compiling
> the mlx5 driver with "W=1" flag and this error will appear for each
> file that include the "en.h".
>
> So, I suggest not drop this change.
>
> In file included from drivers/net/ethernet/mellanox/mlx5/core//en_main.c:40:0:
> drivers/net/ethernet/mellanox/mlx5/core//en.h:206:19: warning: ‘mlx5e_priv_flags’ defined but not used [-Wunused-const-variable=]
> static const char mlx5e_priv_flags[][ETH_GSTRING_LEN] = {
>
Ok Kamal,
Patch applied to net-next-mlx5.
Thank you !
^ permalink raw reply
* [net-next 12/13] net/mlx5e: Vxlan, move vxlan logic to core driver
From: Saeed Mahameed @ 2018-07-27 21:15 UTC (permalink / raw)
To: David S. Miller; +Cc: netdev, Saeed Mahameed
In-Reply-To: <20180727211518.1916-1-saeedm@mellanox.com>
Move vxlan logic and objects to mlx5 core dirver.
Since it going to be used from different mlx5 interfaces.
e.g. mlx5e PF NIC netdev and mlx5e E-Switch representors.
Signed-off-by: Saeed Mahameed <saeedm@mellanox.com>
Reviewed-by: Or Gerlitz <ogerlitz@mellanox.com>
---
.../net/ethernet/mellanox/mlx5/core/Makefile | 4 ++--
drivers/net/ethernet/mellanox/mlx5/core/en.h | 2 --
.../net/ethernet/mellanox/mlx5/core/en_main.c | 21 ++++++++-----------
.../net/ethernet/mellanox/mlx5/core/en_tc.c | 6 +++---
.../mellanox/mlx5/core/{ => lib}/vxlan.c | 0
.../mellanox/mlx5/core/{ => lib}/vxlan.h | 0
.../net/ethernet/mellanox/mlx5/core/main.c | 5 +++++
include/linux/mlx5/driver.h | 2 ++
8 files changed, 21 insertions(+), 19 deletions(-)
rename drivers/net/ethernet/mellanox/mlx5/core/{ => lib}/vxlan.c (100%)
rename drivers/net/ethernet/mellanox/mlx5/core/{ => lib}/vxlan.h (100%)
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/Makefile b/drivers/net/ethernet/mellanox/mlx5/core/Makefile
index ae2bdcb1647c..f20fda1ced4f 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/Makefile
+++ b/drivers/net/ethernet/mellanox/mlx5/core/Makefile
@@ -14,8 +14,8 @@ mlx5_core-$(CONFIG_MLX5_FPGA) += fpga/cmd.o fpga/core.o fpga/conn.o fpga/sdk.o \
fpga/ipsec.o fpga/tls.o
mlx5_core-$(CONFIG_MLX5_CORE_EN) += en_main.o en_common.o en_fs.o en_ethtool.o \
- en_tx.o en_rx.o en_dim.o en_txrx.o en/xdp.o en_stats.o vxlan.o \
- en_arfs.o en_fs_ethtool.o en_selftest.o en/port.o
+ en_tx.o en_rx.o en_dim.o en_txrx.o en/xdp.o en_stats.o \
+ en_arfs.o en_fs_ethtool.o en_selftest.o en/port.o lib/vxlan.o
mlx5_core-$(CONFIG_MLX5_MPFS) += lib/mpfs.o
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en.h b/drivers/net/ethernet/mellanox/mlx5/core/en.h
index 1bd4536b9061..c7ed3d20fd54 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en.h
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en.h
@@ -52,7 +52,6 @@
#include "wq.h"
#include "mlx5_core.h"
#include "en_stats.h"
-#include "vxlan.h"
struct page_pool;
@@ -812,7 +811,6 @@ struct mlx5e_priv {
u32 tx_rates[MLX5E_MAX_NUM_SQS];
struct mlx5e_flow_steering fs;
- struct mlx5_vxlan *vxlan;
struct workqueue_struct *wq;
struct work_struct update_carrier_work;
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
index ef4b2f0c427c..fde35021a257 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
@@ -45,7 +45,7 @@
#include "en_accel/tls.h"
#include "accel/ipsec.h"
#include "accel/tls.h"
-#include "vxlan.h"
+#include "lib/vxlan.h"
#include "en/port.h"
#include "en/xdp.h"
@@ -2974,7 +2974,7 @@ int mlx5e_open(struct net_device *netdev)
mlx5_set_port_admin_status(priv->mdev, MLX5_PORT_UP);
mutex_unlock(&priv->state_lock);
- if (mlx5_vxlan_allowed(priv->vxlan))
+ if (mlx5_vxlan_allowed(priv->mdev->vxlan))
udp_tunnel_get_rx_info(netdev);
return err;
@@ -3983,7 +3983,7 @@ static void mlx5e_vxlan_add_work(struct work_struct *work)
u16 port = vxlan_work->port;
mutex_lock(&priv->state_lock);
- mlx5_vxlan_add_port(priv->vxlan, port);
+ mlx5_vxlan_add_port(priv->mdev->vxlan, port);
mutex_unlock(&priv->state_lock);
kfree(vxlan_work);
@@ -3997,7 +3997,7 @@ static void mlx5e_vxlan_del_work(struct work_struct *work)
u16 port = vxlan_work->port;
mutex_lock(&priv->state_lock);
- mlx5_vxlan_del_port(priv->vxlan, port);
+ mlx5_vxlan_del_port(priv->mdev->vxlan, port);
mutex_unlock(&priv->state_lock);
kfree(vxlan_work);
}
@@ -4028,7 +4028,7 @@ static void mlx5e_add_vxlan_port(struct net_device *netdev,
if (ti->type != UDP_TUNNEL_TYPE_VXLAN)
return;
- if (!mlx5_vxlan_allowed(priv->vxlan))
+ if (!mlx5_vxlan_allowed(priv->mdev->vxlan))
return;
mlx5e_vxlan_queue_work(priv, be16_to_cpu(ti->port), 1);
@@ -4042,7 +4042,7 @@ static void mlx5e_del_vxlan_port(struct net_device *netdev,
if (ti->type != UDP_TUNNEL_TYPE_VXLAN)
return;
- if (!mlx5_vxlan_allowed(priv->vxlan))
+ if (!mlx5_vxlan_allowed(priv->mdev->vxlan))
return;
mlx5e_vxlan_queue_work(priv, be16_to_cpu(ti->port), 0);
@@ -4076,7 +4076,7 @@ static netdev_features_t mlx5e_tunnel_features_check(struct mlx5e_priv *priv,
port = be16_to_cpu(udph->dest);
/* Verify if UDP port is being offloaded by HW */
- if (mlx5_vxlan_lookup_port(priv->vxlan, port))
+ if (mlx5_vxlan_lookup_port(priv->mdev->vxlan, port))
return features;
}
@@ -4648,7 +4648,7 @@ static void mlx5e_build_nic_netdev(struct net_device *netdev)
netdev->hw_features |= NETIF_F_HW_VLAN_CTAG_FILTER;
netdev->hw_features |= NETIF_F_HW_VLAN_STAG_TX;
- if (mlx5_vxlan_allowed(priv->vxlan) || MLX5_CAP_ETH(mdev, tunnel_stateless_gre)) {
+ if (mlx5_vxlan_allowed(mdev->vxlan) || MLX5_CAP_ETH(mdev, tunnel_stateless_gre)) {
netdev->hw_enc_features |= NETIF_F_IP_CSUM;
netdev->hw_enc_features |= NETIF_F_IPV6_CSUM;
netdev->hw_enc_features |= NETIF_F_TSO;
@@ -4656,7 +4656,7 @@ static void mlx5e_build_nic_netdev(struct net_device *netdev)
netdev->hw_enc_features |= NETIF_F_GSO_PARTIAL;
}
- if (mlx5_vxlan_allowed(priv->vxlan)) {
+ if (mlx5_vxlan_allowed(mdev->vxlan)) {
netdev->hw_features |= NETIF_F_GSO_UDP_TUNNEL |
NETIF_F_GSO_UDP_TUNNEL_CSUM;
netdev->hw_enc_features |= NETIF_F_GSO_UDP_TUNNEL |
@@ -4758,8 +4758,6 @@ static void mlx5e_nic_init(struct mlx5_core_dev *mdev,
struct mlx5e_priv *priv = netdev_priv(netdev);
int err;
- priv->vxlan = mlx5_vxlan_create(mdev);
-
mlx5e_build_nic_netdev_priv(mdev, netdev, profile, ppriv);
err = mlx5e_ipsec_init(priv);
if (err)
@@ -4773,7 +4771,6 @@ static void mlx5e_nic_init(struct mlx5_core_dev *mdev,
static void mlx5e_nic_cleanup(struct mlx5e_priv *priv)
{
- mlx5_vxlan_destroy(priv->vxlan);
mlx5e_tls_cleanup(priv);
mlx5e_ipsec_cleanup(priv);
}
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c b/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c
index 1b4931b62094..288a57f76e84 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c
@@ -50,7 +50,7 @@
#include "en_rep.h"
#include "en_tc.h"
#include "eswitch.h"
-#include "vxlan.h"
+#include "lib/vxlan.h"
#include "fs_core.h"
#include "en/port.h"
@@ -1133,7 +1133,7 @@ static int parse_tunnel_attr(struct mlx5e_priv *priv,
if (memchr_inv(&mask->dst, 0xff, sizeof(mask->dst)))
goto vxlan_match_offload_err;
- if (mlx5_vxlan_lookup_port(up_priv->vxlan, be16_to_cpu(key->dst)) &&
+ if (mlx5_vxlan_lookup_port(up_priv->mdev->vxlan, be16_to_cpu(key->dst)) &&
MLX5_CAP_ESW(priv->mdev, vxlan_encap_decap))
parse_vxlan_attr(spec, f);
else {
@@ -2557,7 +2557,7 @@ static int mlx5e_attach_encap(struct mlx5e_priv *priv,
return -EOPNOTSUPP;
}
- if (mlx5_vxlan_lookup_port(up_priv->vxlan, be16_to_cpu(key->tp_dst)) &&
+ if (mlx5_vxlan_lookup_port(up_priv->mdev->vxlan, be16_to_cpu(key->tp_dst)) &&
MLX5_CAP_ESW(priv->mdev, vxlan_encap_decap)) {
tunnel_type = MLX5_HEADER_TYPE_VXLAN;
} else {
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/vxlan.c b/drivers/net/ethernet/mellanox/mlx5/core/lib/vxlan.c
similarity index 100%
rename from drivers/net/ethernet/mellanox/mlx5/core/vxlan.c
rename to drivers/net/ethernet/mellanox/mlx5/core/lib/vxlan.c
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/vxlan.h b/drivers/net/ethernet/mellanox/mlx5/core/lib/vxlan.h
similarity index 100%
rename from drivers/net/ethernet/mellanox/mlx5/core/vxlan.h
rename to drivers/net/ethernet/mellanox/mlx5/core/lib/vxlan.h
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/main.c b/drivers/net/ethernet/mellanox/mlx5/core/main.c
index 6ddbb70e95de..03b9c6733eed 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/main.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/main.c
@@ -62,6 +62,7 @@
#include "accel/ipsec.h"
#include "accel/tls.h"
#include "lib/clock.h"
+#include "lib/vxlan.h"
#include "diag/fw_tracer.h"
MODULE_AUTHOR("Eli Cohen <eli@mellanox.com>");
@@ -961,6 +962,8 @@ static int mlx5_init_once(struct mlx5_core_dev *dev, struct mlx5_priv *priv)
mlx5_init_clock(dev);
+ dev->vxlan = mlx5_vxlan_create(dev);
+
err = mlx5_init_rl_table(dev);
if (err) {
dev_err(&pdev->dev, "Failed to init rate limiting\n");
@@ -1004,6 +1007,7 @@ static int mlx5_init_once(struct mlx5_core_dev *dev, struct mlx5_priv *priv)
err_rl_cleanup:
mlx5_cleanup_rl_table(dev);
err_tables_cleanup:
+ mlx5_vxlan_destroy(dev->vxlan);
mlx5_cleanup_mkey_table(dev);
mlx5_cleanup_srq_table(dev);
mlx5_cleanup_qp_table(dev);
@@ -1024,6 +1028,7 @@ static void mlx5_cleanup_once(struct mlx5_core_dev *dev)
mlx5_eswitch_cleanup(dev->priv.eswitch);
mlx5_mpfs_cleanup(dev);
mlx5_cleanup_rl_table(dev);
+ mlx5_vxlan_destroy(dev->vxlan);
mlx5_cleanup_clock(dev);
mlx5_cleanup_reserved_gids(dev);
mlx5_cleanup_mkey_table(dev);
diff --git a/include/linux/mlx5/driver.h b/include/linux/mlx5/driver.h
index fd0aaa5568fe..54f385cc8811 100644
--- a/include/linux/mlx5/driver.h
+++ b/include/linux/mlx5/driver.h
@@ -818,6 +818,7 @@ struct mlx5_clock {
};
struct mlx5_fw_tracer;
+struct mlx5_vxlan;
struct mlx5_core_dev {
struct pci_dev *pdev;
@@ -850,6 +851,7 @@ struct mlx5_core_dev {
atomic_t num_qps;
u32 issi;
struct mlx5e_resources mlx5e_res;
+ struct mlx5_vxlan *vxlan;
struct {
struct mlx5_rsvd_gids reserved_gids;
u32 roce_en;
--
2.17.0
^ permalink raw reply related
* [net-next 13/13] net/mlx5e: Issue direct lookup on vxlan ports by vport representors
From: Saeed Mahameed @ 2018-07-27 21:15 UTC (permalink / raw)
To: David S. Miller; +Cc: netdev, Saeed Mahameed
In-Reply-To: <20180727211518.1916-1-saeedm@mellanox.com>
Remove uplink representor netdevice private structure lookup, and use
mlx5 core handle directly from representor private structure to lookup
vxlan ports.
Signed-off-by: Saeed Mahameed <saeedm@mellanox.com>
Reviewed-by: Or Gerlitz <ogerlitz@mellanox.com>
---
drivers/net/ethernet/mellanox/mlx5/core/en_tc.c | 12 ++----------
1 file changed, 2 insertions(+), 10 deletions(-)
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c b/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c
index 288a57f76e84..c28fe469b04a 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c
@@ -1124,16 +1124,12 @@ static int parse_tunnel_attr(struct mlx5e_priv *priv,
skb_flow_dissector_target(f->dissector,
FLOW_DISSECTOR_KEY_ENC_PORTS,
f->mask);
- struct mlx5_eswitch *esw = priv->mdev->priv.eswitch;
- struct mlx5e_rep_priv *uplink_rpriv = mlx5_eswitch_get_uplink_priv(esw, REP_ETH);
- struct net_device *up_dev = uplink_rpriv->netdev;
- struct mlx5e_priv *up_priv = netdev_priv(up_dev);
/* Full udp dst port must be given */
if (memchr_inv(&mask->dst, 0xff, sizeof(mask->dst)))
goto vxlan_match_offload_err;
- if (mlx5_vxlan_lookup_port(up_priv->mdev->vxlan, be16_to_cpu(key->dst)) &&
+ if (mlx5_vxlan_lookup_port(priv->mdev->vxlan, be16_to_cpu(key->dst)) &&
MLX5_CAP_ESW(priv->mdev, vxlan_encap_decap))
parse_vxlan_attr(spec, f);
else {
@@ -2533,11 +2529,7 @@ static int mlx5e_attach_encap(struct mlx5e_priv *priv,
struct mlx5e_tc_flow *flow)
{
struct mlx5_eswitch *esw = priv->mdev->priv.eswitch;
- struct mlx5e_rep_priv *uplink_rpriv = mlx5_eswitch_get_uplink_priv(esw,
- REP_ETH);
- struct net_device *up_dev = uplink_rpriv->netdev;
unsigned short family = ip_tunnel_info_af(tun_info);
- struct mlx5e_priv *up_priv = netdev_priv(up_dev);
struct mlx5_esw_flow_attr *attr = flow->esw_attr;
struct ip_tunnel_key *key = &tun_info->key;
struct mlx5e_encap_entry *e;
@@ -2557,7 +2549,7 @@ static int mlx5e_attach_encap(struct mlx5e_priv *priv,
return -EOPNOTSUPP;
}
- if (mlx5_vxlan_lookup_port(up_priv->mdev->vxlan, be16_to_cpu(key->tp_dst)) &&
+ if (mlx5_vxlan_lookup_port(priv->mdev->vxlan, be16_to_cpu(key->tp_dst)) &&
MLX5_CAP_ESW(priv->mdev, vxlan_encap_decap)) {
tunnel_type = MLX5_HEADER_TYPE_VXLAN;
} else {
--
2.17.0
^ permalink raw reply related
* [net-next 11/13] net/mlx5e: Vxlan, add sync lock for add/del vxlan port
From: Saeed Mahameed @ 2018-07-27 21:15 UTC (permalink / raw)
To: David S. Miller; +Cc: netdev, Saeed Mahameed
In-Reply-To: <20180727211518.1916-1-saeedm@mellanox.com>
Vxlan API can and will be called from different mlx5 modules, we should
not count on mlx5e private state lock only, hence we introduce a vxlan
private mutex to sync between add/del vxlan port operations.
Signed-off-by: Saeed Mahameed <saeedm@mellanox.com>
Reviewed-by: Or Gerlitz <ogerlitz@mellanox.com>
---
.../net/ethernet/mellanox/mlx5/core/vxlan.c | 18 +++++++++++++++---
1 file changed, 15 insertions(+), 3 deletions(-)
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/vxlan.c b/drivers/net/ethernet/mellanox/mlx5/core/vxlan.c
index f5353134542d..c126a790234d 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/vxlan.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/vxlan.c
@@ -38,8 +38,9 @@
struct mlx5_vxlan {
struct mlx5_core_dev *mdev;
- rwlock_t lock; /* protect vxlan table */
int num_ports;
+ struct mutex sync_lock; /* sync add/del port HW operations */
+ rwlock_t lock; /* sync vxlan table with data path access */
/* max_num_ports is usuallly 4, 16 buckets is more than enough */
DECLARE_HASHTABLE(htable, 4);
};
@@ -115,17 +116,18 @@ int mlx5_vxlan_add_port(struct mlx5_vxlan *vxlan, u16 port)
return 0;
}
+ mutex_lock(&vxlan->sync_lock);
if (vxlan->num_ports >= mlx5_vxlan_max_udp_ports(vxlan->mdev)) {
mlx5_core_info(vxlan->mdev,
"UDP port (%d) not offloaded, max number of UDP ports (%d) are already offloaded\n",
port, mlx5_vxlan_max_udp_ports(vxlan->mdev));
ret = -ENOSPC;
- return ret;
+ goto unlock;
}
ret = mlx5_vxlan_core_add_port_cmd(vxlan->mdev, port);
if (ret)
- return ret;
+ goto unlock;
vxlanp = kzalloc(sizeof(*vxlanp), GFP_KERNEL);
if (!vxlanp) {
@@ -141,10 +143,14 @@ int mlx5_vxlan_add_port(struct mlx5_vxlan *vxlan, u16 port)
write_unlock_bh(&vxlan->lock);
vxlan->num_ports++;
+ mutex_unlock(&vxlan->sync_lock);
return 0;
err_delete_port:
mlx5_vxlan_core_del_port_cmd(vxlan->mdev, port);
+
+unlock:
+ mutex_unlock(&vxlan->sync_lock);
return ret;
}
@@ -154,6 +160,8 @@ int mlx5_vxlan_del_port(struct mlx5_vxlan *vxlan, u16 port)
bool remove = false;
int ret = 0;
+ mutex_lock(&vxlan->sync_lock);
+
write_lock_bh(&vxlan->lock);
vxlanp = mlx5_vxlan_lookup_port_locked(vxlan, port);
if (!vxlanp) {
@@ -174,6 +182,9 @@ int mlx5_vxlan_del_port(struct mlx5_vxlan *vxlan, u16 port)
kfree(vxlanp);
vxlan->num_ports--;
}
+
+ mutex_unlock(&vxlan->sync_lock);
+
return ret;
}
@@ -189,6 +200,7 @@ struct mlx5_vxlan *mlx5_vxlan_create(struct mlx5_core_dev *mdev)
return ERR_PTR(-ENOMEM);
vxlan->mdev = mdev;
+ mutex_init(&vxlan->sync_lock);
rwlock_init(&vxlan->lock);
hash_init(vxlan->htable);
--
2.17.0
^ permalink raw reply related
* [net-next 09/13] net/mlx5e: Vxlan, rename from mlx5e to mlx5
From: Saeed Mahameed @ 2018-07-27 21:15 UTC (permalink / raw)
To: David S. Miller; +Cc: netdev, Saeed Mahameed
In-Reply-To: <20180727211518.1916-1-saeedm@mellanox.com>
Rename vxlan functions from mlx5e_vxlan_* to mlx5_vxlan_*.
Rename mlx5e_vxlan_db to mlx5_vxlan and move it from en.h to vxlan.c
since it is not related to mlx5e anymore.
Allocate mlx5_vxlan structure dynamically in order to make it easier to
move later to core driver and to make it private in vxlan.c.
This is in preparation to move vxlan API to mlx5 core.
Signed-off-by: Saeed Mahameed <saeedm@mellanox.com>
Reviewed-by: Or Gerlitz <ogerlitz@mellanox.com>
---
drivers/net/ethernet/mellanox/mlx5/core/en.h | 10 +-
.../net/ethernet/mellanox/mlx5/core/en_main.c | 21 ++--
.../net/ethernet/mellanox/mlx5/core/en_tc.c | 4 +-
.../net/ethernet/mellanox/mlx5/core/vxlan.c | 118 ++++++++++--------
.../net/ethernet/mellanox/mlx5/core/vxlan.h | 30 +++--
5 files changed, 104 insertions(+), 79 deletions(-)
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en.h b/drivers/net/ethernet/mellanox/mlx5/core/en.h
index 870ac617550c..1bd4536b9061 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en.h
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en.h
@@ -52,6 +52,7 @@
#include "wq.h"
#include "mlx5_core.h"
#include "en_stats.h"
+#include "vxlan.h"
struct page_pool;
@@ -654,13 +655,6 @@ enum {
MLX5E_STATE_DESTROYING,
};
-struct mlx5e_vxlan_db {
- rwlock_t lock; /* protect vxlan table */
- /* max_num_ports is usuallly 4, 16 buckets is more than enough */
- DECLARE_HASHTABLE(htable, 4);
- int num_ports;
-};
-
struct mlx5e_l2_rule {
u8 addr[ETH_ALEN + 2];
struct mlx5_flow_handle *rule;
@@ -818,7 +812,7 @@ struct mlx5e_priv {
u32 tx_rates[MLX5E_MAX_NUM_SQS];
struct mlx5e_flow_steering fs;
- struct mlx5e_vxlan_db vxlan;
+ struct mlx5_vxlan *vxlan;
struct workqueue_struct *wq;
struct work_struct update_carrier_work;
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
index 7a6b78e3b5f7..ef4b2f0c427c 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
@@ -2974,7 +2974,7 @@ int mlx5e_open(struct net_device *netdev)
mlx5_set_port_admin_status(priv->mdev, MLX5_PORT_UP);
mutex_unlock(&priv->state_lock);
- if (mlx5e_vxlan_allowed(priv->mdev))
+ if (mlx5_vxlan_allowed(priv->vxlan))
udp_tunnel_get_rx_info(netdev);
return err;
@@ -3983,7 +3983,7 @@ static void mlx5e_vxlan_add_work(struct work_struct *work)
u16 port = vxlan_work->port;
mutex_lock(&priv->state_lock);
- mlx5e_vxlan_add_port(priv, port);
+ mlx5_vxlan_add_port(priv->vxlan, port);
mutex_unlock(&priv->state_lock);
kfree(vxlan_work);
@@ -3997,7 +3997,7 @@ static void mlx5e_vxlan_del_work(struct work_struct *work)
u16 port = vxlan_work->port;
mutex_lock(&priv->state_lock);
- mlx5e_vxlan_del_port(priv, port);
+ mlx5_vxlan_del_port(priv->vxlan, port);
mutex_unlock(&priv->state_lock);
kfree(vxlan_work);
}
@@ -4028,7 +4028,7 @@ static void mlx5e_add_vxlan_port(struct net_device *netdev,
if (ti->type != UDP_TUNNEL_TYPE_VXLAN)
return;
- if (!mlx5e_vxlan_allowed(priv->mdev))
+ if (!mlx5_vxlan_allowed(priv->vxlan))
return;
mlx5e_vxlan_queue_work(priv, be16_to_cpu(ti->port), 1);
@@ -4042,7 +4042,7 @@ static void mlx5e_del_vxlan_port(struct net_device *netdev,
if (ti->type != UDP_TUNNEL_TYPE_VXLAN)
return;
- if (!mlx5e_vxlan_allowed(priv->mdev))
+ if (!mlx5_vxlan_allowed(priv->vxlan))
return;
mlx5e_vxlan_queue_work(priv, be16_to_cpu(ti->port), 0);
@@ -4076,7 +4076,7 @@ static netdev_features_t mlx5e_tunnel_features_check(struct mlx5e_priv *priv,
port = be16_to_cpu(udph->dest);
/* Verify if UDP port is being offloaded by HW */
- if (mlx5e_vxlan_lookup_port(priv, port))
+ if (mlx5_vxlan_lookup_port(priv->vxlan, port))
return features;
}
@@ -4648,7 +4648,7 @@ static void mlx5e_build_nic_netdev(struct net_device *netdev)
netdev->hw_features |= NETIF_F_HW_VLAN_CTAG_FILTER;
netdev->hw_features |= NETIF_F_HW_VLAN_STAG_TX;
- if (mlx5e_vxlan_allowed(mdev) || MLX5_CAP_ETH(mdev, tunnel_stateless_gre)) {
+ if (mlx5_vxlan_allowed(priv->vxlan) || MLX5_CAP_ETH(mdev, tunnel_stateless_gre)) {
netdev->hw_enc_features |= NETIF_F_IP_CSUM;
netdev->hw_enc_features |= NETIF_F_IPV6_CSUM;
netdev->hw_enc_features |= NETIF_F_TSO;
@@ -4656,7 +4656,7 @@ static void mlx5e_build_nic_netdev(struct net_device *netdev)
netdev->hw_enc_features |= NETIF_F_GSO_PARTIAL;
}
- if (mlx5e_vxlan_allowed(mdev)) {
+ if (mlx5_vxlan_allowed(priv->vxlan)) {
netdev->hw_features |= NETIF_F_GSO_UDP_TUNNEL |
NETIF_F_GSO_UDP_TUNNEL_CSUM;
netdev->hw_enc_features |= NETIF_F_GSO_UDP_TUNNEL |
@@ -4758,6 +4758,8 @@ static void mlx5e_nic_init(struct mlx5_core_dev *mdev,
struct mlx5e_priv *priv = netdev_priv(netdev);
int err;
+ priv->vxlan = mlx5_vxlan_create(mdev);
+
mlx5e_build_nic_netdev_priv(mdev, netdev, profile, ppriv);
err = mlx5e_ipsec_init(priv);
if (err)
@@ -4767,14 +4769,13 @@ static void mlx5e_nic_init(struct mlx5_core_dev *mdev,
mlx5_core_err(mdev, "TLS initialization failed, %d\n", err);
mlx5e_build_nic_netdev(netdev);
mlx5e_build_tc2txq_maps(priv);
- mlx5e_vxlan_init(priv);
}
static void mlx5e_nic_cleanup(struct mlx5e_priv *priv)
{
+ mlx5_vxlan_destroy(priv->vxlan);
mlx5e_tls_cleanup(priv);
mlx5e_ipsec_cleanup(priv);
- mlx5e_vxlan_cleanup(priv);
}
static int mlx5e_init_nic_rx(struct mlx5e_priv *priv)
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c b/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c
index 1010ee983ab7..1b4931b62094 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c
@@ -1133,7 +1133,7 @@ static int parse_tunnel_attr(struct mlx5e_priv *priv,
if (memchr_inv(&mask->dst, 0xff, sizeof(mask->dst)))
goto vxlan_match_offload_err;
- if (mlx5e_vxlan_lookup_port(up_priv, be16_to_cpu(key->dst)) &&
+ if (mlx5_vxlan_lookup_port(up_priv->vxlan, be16_to_cpu(key->dst)) &&
MLX5_CAP_ESW(priv->mdev, vxlan_encap_decap))
parse_vxlan_attr(spec, f);
else {
@@ -2557,7 +2557,7 @@ static int mlx5e_attach_encap(struct mlx5e_priv *priv,
return -EOPNOTSUPP;
}
- if (mlx5e_vxlan_lookup_port(up_priv, be16_to_cpu(key->tp_dst)) &&
+ if (mlx5_vxlan_lookup_port(up_priv->vxlan, be16_to_cpu(key->tp_dst)) &&
MLX5_CAP_ESW(priv->mdev, vxlan_encap_decap)) {
tunnel_type = MLX5_HEADER_TYPE_VXLAN;
} else {
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/vxlan.c b/drivers/net/ethernet/mellanox/mlx5/core/vxlan.c
index 95e3140da65c..502af3bdf088 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/vxlan.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/vxlan.c
@@ -36,32 +36,26 @@
#include "mlx5_core.h"
#include "vxlan.h"
+struct mlx5_vxlan {
+ struct mlx5_core_dev *mdev;
+ rwlock_t lock; /* protect vxlan table */
+ int num_ports;
+ /* max_num_ports is usuallly 4, 16 buckets is more than enough */
+ DECLARE_HASHTABLE(htable, 4);
+};
+
struct mlx5_vxlan_port {
struct hlist_node hlist;
atomic_t refcount;
u16 udp_port;
};
-void mlx5e_vxlan_init(struct mlx5e_priv *priv)
-{
- struct mlx5e_vxlan_db *vxlan_db = &priv->vxlan;
-
- rwlock_init(&vxlan_db->lock);
- hash_init(vxlan_db->htable);
-
- if (mlx5e_vxlan_allowed(priv->mdev))
- /* Hardware adds 4789 by default.
- * Lockless since we are the only hash table consumers, wq and TX are disabled.
- */
- mlx5e_vxlan_add_port(priv, 4789);
-}
-
-static inline u8 mlx5e_vxlan_max_udp_ports(struct mlx5_core_dev *mdev)
+static inline u8 mlx5_vxlan_max_udp_ports(struct mlx5_core_dev *mdev)
{
return MLX5_CAP_ETH(mdev, max_vxlan_udp_ports) ?: 4;
}
-static int mlx5e_vxlan_core_add_port_cmd(struct mlx5_core_dev *mdev, u16 port)
+static int mlx5_vxlan_core_add_port_cmd(struct mlx5_core_dev *mdev, u16 port)
{
u32 in[MLX5_ST_SZ_DW(add_vxlan_udp_dport_in)] = {0};
u32 out[MLX5_ST_SZ_DW(add_vxlan_udp_dport_out)] = {0};
@@ -72,7 +66,7 @@ static int mlx5e_vxlan_core_add_port_cmd(struct mlx5_core_dev *mdev, u16 port)
return mlx5_cmd_exec(mdev, in, sizeof(in), out, sizeof(out));
}
-static int mlx5e_vxlan_core_del_port_cmd(struct mlx5_core_dev *mdev, u16 port)
+static int mlx5_vxlan_core_del_port_cmd(struct mlx5_core_dev *mdev, u16 port)
{
u32 in[MLX5_ST_SZ_DW(delete_vxlan_udp_dport_in)] = {0};
u32 out[MLX5_ST_SZ_DW(delete_vxlan_udp_dport_out)] = {0};
@@ -84,12 +78,11 @@ static int mlx5e_vxlan_core_del_port_cmd(struct mlx5_core_dev *mdev, u16 port)
}
static struct mlx5_vxlan_port*
-mlx5e_vxlan_lookup_port_locked(struct mlx5e_priv *priv, u16 port)
+mlx5_vxlan_lookup_port_locked(struct mlx5_vxlan *vxlan, u16 port)
{
- struct mlx5e_vxlan_db *vxlan_db = &priv->vxlan;
struct mlx5_vxlan_port *vxlanp;
- hash_for_each_possible(vxlan_db->htable, vxlanp, hlist, port) {
+ hash_for_each_possible(vxlan->htable, vxlanp, hlist, port) {
if (vxlanp->udp_port == port)
return vxlanp;
}
@@ -97,37 +90,38 @@ mlx5e_vxlan_lookup_port_locked(struct mlx5e_priv *priv, u16 port)
return NULL;
}
-struct mlx5_vxlan_port *mlx5e_vxlan_lookup_port(struct mlx5e_priv *priv, u16 port)
+struct mlx5_vxlan_port *mlx5_vxlan_lookup_port(struct mlx5_vxlan *vxlan, u16 port)
{
- struct mlx5e_vxlan_db *vxlan_db = &priv->vxlan;
struct mlx5_vxlan_port *vxlanp;
- read_lock_bh(&vxlan_db->lock);
- vxlanp = mlx5e_vxlan_lookup_port_locked(priv, port);
- read_unlock_bh(&vxlan_db->lock);
+ if (!mlx5_vxlan_allowed(vxlan))
+ return NULL;
+
+ read_lock_bh(&vxlan->lock);
+ vxlanp = mlx5_vxlan_lookup_port_locked(vxlan, port);
+ read_unlock_bh(&vxlan->lock);
return vxlanp;
}
-void mlx5e_vxlan_add_port(struct mlx5e_priv *priv, u16 port)
+void mlx5_vxlan_add_port(struct mlx5_vxlan *vxlan, u16 port)
{
- struct mlx5e_vxlan_db *vxlan_db = &priv->vxlan;
struct mlx5_vxlan_port *vxlanp;
- vxlanp = mlx5e_vxlan_lookup_port(priv, port);
+ vxlanp = mlx5_vxlan_lookup_port(vxlan, port);
if (vxlanp) {
atomic_inc(&vxlanp->refcount);
return;
}
- if (vxlan_db->num_ports >= mlx5e_vxlan_max_udp_ports(priv->mdev)) {
- netdev_info(priv->netdev,
- "UDP port (%d) not offloaded, max number of UDP ports (%d) are already offloaded\n",
- port, mlx5e_vxlan_max_udp_ports(priv->mdev));
+ if (vxlan->num_ports >= mlx5_vxlan_max_udp_ports(vxlan->mdev)) {
+ mlx5_core_info(vxlan->mdev,
+ "UDP port (%d) not offloaded, max number of UDP ports (%d) are already offloaded\n",
+ port, mlx5_vxlan_max_udp_ports(vxlan->mdev));
return;
}
- if (mlx5e_vxlan_core_add_port_cmd(priv->mdev, port))
+ if (mlx5_vxlan_core_add_port_cmd(vxlan->mdev, port))
return;
vxlanp = kzalloc(sizeof(*vxlanp), GFP_KERNEL);
@@ -137,25 +131,24 @@ void mlx5e_vxlan_add_port(struct mlx5e_priv *priv, u16 port)
vxlanp->udp_port = port;
atomic_set(&vxlanp->refcount, 1);
- write_lock_bh(&vxlan_db->lock);
- hash_add(vxlan_db->htable, &vxlanp->hlist, port);
- write_unlock_bh(&vxlan_db->lock);
+ write_lock_bh(&vxlan->lock);
+ hash_add(vxlan->htable, &vxlanp->hlist, port);
+ write_unlock_bh(&vxlan->lock);
- vxlan_db->num_ports++;
+ vxlan->num_ports++;
return;
err_delete_port:
- mlx5e_vxlan_core_del_port_cmd(priv->mdev, port);
+ mlx5_vxlan_core_del_port_cmd(vxlan->mdev, port);
}
-void mlx5e_vxlan_del_port(struct mlx5e_priv *priv, u16 port)
+void mlx5_vxlan_del_port(struct mlx5_vxlan *vxlan, u16 port)
{
- struct mlx5e_vxlan_db *vxlan_db = &priv->vxlan;
struct mlx5_vxlan_port *vxlanp;
bool remove = false;
- write_lock_bh(&vxlan_db->lock);
- vxlanp = mlx5e_vxlan_lookup_port_locked(priv, port);
+ write_lock_bh(&vxlan->lock);
+ vxlanp = mlx5_vxlan_lookup_port_locked(vxlan, port);
if (!vxlanp)
goto out_unlock;
@@ -165,26 +158,51 @@ void mlx5e_vxlan_del_port(struct mlx5e_priv *priv, u16 port)
}
out_unlock:
- write_unlock_bh(&vxlan_db->lock);
+ write_unlock_bh(&vxlan->lock);
if (remove) {
- mlx5e_vxlan_core_del_port_cmd(priv->mdev, port);
+ mlx5_vxlan_core_del_port_cmd(vxlan->mdev, port);
kfree(vxlanp);
- vxlan_db->num_ports--;
+ vxlan->num_ports--;
}
}
-void mlx5e_vxlan_cleanup(struct mlx5e_priv *priv)
+struct mlx5_vxlan *mlx5_vxlan_create(struct mlx5_core_dev *mdev)
+{
+ struct mlx5_vxlan *vxlan;
+
+ if (!MLX5_CAP_ETH(mdev, tunnel_stateless_vxlan) || !mlx5_core_is_pf(mdev))
+ return ERR_PTR(-ENOTSUPP);
+
+ vxlan = kzalloc(sizeof(*vxlan), GFP_KERNEL);
+ if (!vxlan)
+ return ERR_PTR(-ENOMEM);
+
+ vxlan->mdev = mdev;
+ rwlock_init(&vxlan->lock);
+ hash_init(vxlan->htable);
+
+ /* Hardware adds 4789 by default */
+ mlx5_vxlan_add_port(vxlan, 4789);
+
+ return vxlan;
+}
+
+void mlx5_vxlan_destroy(struct mlx5_vxlan *vxlan)
{
- struct mlx5e_vxlan_db *vxlan_db = &priv->vxlan;
struct mlx5_vxlan_port *vxlanp;
struct hlist_node *tmp;
int bkt;
- /* Lockless since we are the only hash table consumers, wq and TX are disabled */
- hash_for_each_safe(vxlan_db->htable, bkt, tmp, vxlanp, hlist) {
+ if (!mlx5_vxlan_allowed(vxlan))
+ return;
+
+ /* Lockless since we are the only hash table consumers*/
+ hash_for_each_safe(vxlan->htable, bkt, tmp, vxlanp, hlist) {
hash_del(&vxlanp->hlist);
- mlx5e_vxlan_core_del_port_cmd(priv->mdev, vxlanp->udp_port);
+ mlx5_vxlan_core_del_port_cmd(vxlan->mdev, vxlanp->udp_port);
kfree(vxlanp);
}
+
+ kfree(vxlan);
}
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/vxlan.h b/drivers/net/ethernet/mellanox/mlx5/core/vxlan.h
index 6b38b6fbd030..9d6327321814 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/vxlan.h
+++ b/drivers/net/ethernet/mellanox/mlx5/core/vxlan.h
@@ -33,20 +33,32 @@
#define __MLX5_VXLAN_H__
#include <linux/mlx5/driver.h>
-#include "en.h"
+struct mlx5_vxlan;
struct mlx5_vxlan_port;
-static inline bool mlx5e_vxlan_allowed(struct mlx5_core_dev *mdev)
+#ifdef CONFIG_MLX5_CORE_EN
+
+static inline bool mlx5_vxlan_allowed(struct mlx5_vxlan *vxlan)
{
- return (MLX5_CAP_ETH(mdev, tunnel_stateless_vxlan) &&
- mlx5_core_is_pf(mdev));
+ /* not allowed reason is encoded in vxlan pointer as error,
+ * on mlx5_vxlan_create
+ */
+ return !IS_ERR_OR_NULL(vxlan);
}
-void mlx5e_vxlan_init(struct mlx5e_priv *priv);
-void mlx5e_vxlan_cleanup(struct mlx5e_priv *priv);
-void mlx5e_vxlan_add_port(struct mlx5e_priv *priv, u16 port);
-void mlx5e_vxlan_del_port(struct mlx5e_priv *priv, u16 port);
-struct mlx5_vxlan_port *mlx5e_vxlan_lookup_port(struct mlx5e_priv *priv, u16 port);
+struct mlx5_vxlan *mlx5_vxlan_create(struct mlx5_core_dev *mdev);
+void mlx5_vxlan_destroy(struct mlx5_vxlan *vxlan);
+void mlx5_vxlan_add_port(struct mlx5_vxlan *vxlan, u16 port);
+void mlx5_vxlan_del_port(struct mlx5_vxlan *vxlan, u16 port);
+struct mlx5_vxlan_port *mlx5_vxlan_lookup_port(struct mlx5_vxlan *vxlan, u16 port);
+
+#else
+
+static inline struct mlx5_vxlan*
+mlx5_vxlan_create(struct mlx5_core_dev *mdev) { return ERR_PTR(-ENOTSUPP); }
+static inline void mlx5_vxlan_destroy(struct mlx5_vxlan *vxlan) { return; }
+
+#endif
#endif /* __MLX5_VXLAN_H__ */
--
2.17.0
^ permalink raw reply related
* [net-next 08/13] net/mlx5e: Vxlan, rename struct mlx5e_vxlan to mlx5_vxlan_port
From: Saeed Mahameed @ 2018-07-27 21:15 UTC (permalink / raw)
To: David S. Miller; +Cc: netdev, Saeed Mahameed
In-Reply-To: <20180727211518.1916-1-saeedm@mellanox.com>
The name mlx5e_vxlan will be used in downstream patch to describe
mlx5 vxlan structure that will replace mlx5e_vxlan_db.
Hence we rename struct mlx5e_vxlan to mlx5_vxlan_port which describes a
mlx5 vxlan port.
Signed-off-by: Saeed Mahameed <saeedm@mellanox.com>
Reviewed-by: Or Gerlitz <ogerlitz@mellanox.com>
---
.../net/ethernet/mellanox/mlx5/core/vxlan.c | 62 +++++++++----------
.../net/ethernet/mellanox/mlx5/core/vxlan.h | 4 +-
2 files changed, 33 insertions(+), 33 deletions(-)
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/vxlan.c b/drivers/net/ethernet/mellanox/mlx5/core/vxlan.c
index 2a25c2dd6e6f..95e3140da65c 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/vxlan.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/vxlan.c
@@ -36,7 +36,7 @@
#include "mlx5_core.h"
#include "vxlan.h"
-struct mlx5e_vxlan {
+struct mlx5_vxlan_port {
struct hlist_node hlist;
atomic_t refcount;
u16 udp_port;
@@ -83,40 +83,40 @@ static int mlx5e_vxlan_core_del_port_cmd(struct mlx5_core_dev *mdev, u16 port)
return mlx5_cmd_exec(mdev, in, sizeof(in), out, sizeof(out));
}
-static struct mlx5e_vxlan *mlx5e_vxlan_lookup_port_locked(struct mlx5e_priv *priv,
- u16 port)
+static struct mlx5_vxlan_port*
+mlx5e_vxlan_lookup_port_locked(struct mlx5e_priv *priv, u16 port)
{
struct mlx5e_vxlan_db *vxlan_db = &priv->vxlan;
- struct mlx5e_vxlan *vxlan;
+ struct mlx5_vxlan_port *vxlanp;
- hash_for_each_possible(vxlan_db->htable, vxlan, hlist, port) {
- if (vxlan->udp_port == port)
- return vxlan;
+ hash_for_each_possible(vxlan_db->htable, vxlanp, hlist, port) {
+ if (vxlanp->udp_port == port)
+ return vxlanp;
}
return NULL;
}
-struct mlx5e_vxlan *mlx5e_vxlan_lookup_port(struct mlx5e_priv *priv, u16 port)
+struct mlx5_vxlan_port *mlx5e_vxlan_lookup_port(struct mlx5e_priv *priv, u16 port)
{
struct mlx5e_vxlan_db *vxlan_db = &priv->vxlan;
- struct mlx5e_vxlan *vxlan;
+ struct mlx5_vxlan_port *vxlanp;
read_lock_bh(&vxlan_db->lock);
- vxlan = mlx5e_vxlan_lookup_port_locked(priv, port);
+ vxlanp = mlx5e_vxlan_lookup_port_locked(priv, port);
read_unlock_bh(&vxlan_db->lock);
- return vxlan;
+ return vxlanp;
}
void mlx5e_vxlan_add_port(struct mlx5e_priv *priv, u16 port)
{
struct mlx5e_vxlan_db *vxlan_db = &priv->vxlan;
- struct mlx5e_vxlan *vxlan;
+ struct mlx5_vxlan_port *vxlanp;
- vxlan = mlx5e_vxlan_lookup_port(priv, port);
- if (vxlan) {
- atomic_inc(&vxlan->refcount);
+ vxlanp = mlx5e_vxlan_lookup_port(priv, port);
+ if (vxlanp) {
+ atomic_inc(&vxlanp->refcount);
return;
}
@@ -130,15 +130,15 @@ void mlx5e_vxlan_add_port(struct mlx5e_priv *priv, u16 port)
if (mlx5e_vxlan_core_add_port_cmd(priv->mdev, port))
return;
- vxlan = kzalloc(sizeof(*vxlan), GFP_KERNEL);
- if (!vxlan)
+ vxlanp = kzalloc(sizeof(*vxlanp), GFP_KERNEL);
+ if (!vxlanp)
goto err_delete_port;
- vxlan->udp_port = port;
- atomic_set(&vxlan->refcount, 1);
+ vxlanp->udp_port = port;
+ atomic_set(&vxlanp->refcount, 1);
write_lock_bh(&vxlan_db->lock);
- hash_add(vxlan_db->htable, &vxlan->hlist, port);
+ hash_add(vxlan_db->htable, &vxlanp->hlist, port);
write_unlock_bh(&vxlan_db->lock);
vxlan_db->num_ports++;
@@ -151,16 +151,16 @@ void mlx5e_vxlan_add_port(struct mlx5e_priv *priv, u16 port)
void mlx5e_vxlan_del_port(struct mlx5e_priv *priv, u16 port)
{
struct mlx5e_vxlan_db *vxlan_db = &priv->vxlan;
- struct mlx5e_vxlan *vxlan;
+ struct mlx5_vxlan_port *vxlanp;
bool remove = false;
write_lock_bh(&vxlan_db->lock);
- vxlan = mlx5e_vxlan_lookup_port_locked(priv, port);
- if (!vxlan)
+ vxlanp = mlx5e_vxlan_lookup_port_locked(priv, port);
+ if (!vxlanp)
goto out_unlock;
- if (atomic_dec_and_test(&vxlan->refcount)) {
- hash_del(&vxlan->hlist);
+ if (atomic_dec_and_test(&vxlanp->refcount)) {
+ hash_del(&vxlanp->hlist);
remove = true;
}
@@ -169,7 +169,7 @@ void mlx5e_vxlan_del_port(struct mlx5e_priv *priv, u16 port)
if (remove) {
mlx5e_vxlan_core_del_port_cmd(priv->mdev, port);
- kfree(vxlan);
+ kfree(vxlanp);
vxlan_db->num_ports--;
}
}
@@ -177,14 +177,14 @@ void mlx5e_vxlan_del_port(struct mlx5e_priv *priv, u16 port)
void mlx5e_vxlan_cleanup(struct mlx5e_priv *priv)
{
struct mlx5e_vxlan_db *vxlan_db = &priv->vxlan;
- struct mlx5e_vxlan *vxlan;
+ struct mlx5_vxlan_port *vxlanp;
struct hlist_node *tmp;
int bkt;
/* Lockless since we are the only hash table consumers, wq and TX are disabled */
- hash_for_each_safe(vxlan_db->htable, bkt, tmp, vxlan, hlist) {
- hash_del(&vxlan->hlist);
- mlx5e_vxlan_core_del_port_cmd(priv->mdev, vxlan->udp_port);
- kfree(vxlan);
+ hash_for_each_safe(vxlan_db->htable, bkt, tmp, vxlanp, hlist) {
+ hash_del(&vxlanp->hlist);
+ mlx5e_vxlan_core_del_port_cmd(priv->mdev, vxlanp->udp_port);
+ kfree(vxlanp);
}
}
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/vxlan.h b/drivers/net/ethernet/mellanox/mlx5/core/vxlan.h
index 1a02f5b38009..6b38b6fbd030 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/vxlan.h
+++ b/drivers/net/ethernet/mellanox/mlx5/core/vxlan.h
@@ -35,7 +35,7 @@
#include <linux/mlx5/driver.h>
#include "en.h"
-struct mlx5e_vxlan;
+struct mlx5_vxlan_port;
static inline bool mlx5e_vxlan_allowed(struct mlx5_core_dev *mdev)
{
@@ -47,6 +47,6 @@ void mlx5e_vxlan_init(struct mlx5e_priv *priv);
void mlx5e_vxlan_cleanup(struct mlx5e_priv *priv);
void mlx5e_vxlan_add_port(struct mlx5e_priv *priv, u16 port);
void mlx5e_vxlan_del_port(struct mlx5e_priv *priv, u16 port);
-struct mlx5e_vxlan *mlx5e_vxlan_lookup_port(struct mlx5e_priv *priv, u16 port);
+struct mlx5_vxlan_port *mlx5e_vxlan_lookup_port(struct mlx5e_priv *priv, u16 port);
#endif /* __MLX5_VXLAN_H__ */
--
2.17.0
^ permalink raw reply related
* [net-next 10/13] net/mlx5e: Vxlan, return values for add/del port
From: Saeed Mahameed @ 2018-07-27 21:15 UTC (permalink / raw)
To: David S. Miller; +Cc: netdev, Saeed Mahameed
In-Reply-To: <20180727211518.1916-1-saeedm@mellanox.com>
For a better API mlx5_vxlan_{add/del}_port can fail, make them return
error values.
Signed-off-by: Saeed Mahameed <saeedm@mellanox.com>
Reviewed-by: Or Gerlitz <ogerlitz@mellanox.com>
---
.../net/ethernet/mellanox/mlx5/core/vxlan.c | 28 +++++++++++++------
.../net/ethernet/mellanox/mlx5/core/vxlan.h | 4 +--
2 files changed, 21 insertions(+), 11 deletions(-)
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/vxlan.c b/drivers/net/ethernet/mellanox/mlx5/core/vxlan.c
index 502af3bdf088..f5353134542d 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/vxlan.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/vxlan.c
@@ -104,29 +104,34 @@ struct mlx5_vxlan_port *mlx5_vxlan_lookup_port(struct mlx5_vxlan *vxlan, u16 por
return vxlanp;
}
-void mlx5_vxlan_add_port(struct mlx5_vxlan *vxlan, u16 port)
+int mlx5_vxlan_add_port(struct mlx5_vxlan *vxlan, u16 port)
{
struct mlx5_vxlan_port *vxlanp;
+ int ret = -ENOSPC;
vxlanp = mlx5_vxlan_lookup_port(vxlan, port);
if (vxlanp) {
atomic_inc(&vxlanp->refcount);
- return;
+ return 0;
}
if (vxlan->num_ports >= mlx5_vxlan_max_udp_ports(vxlan->mdev)) {
mlx5_core_info(vxlan->mdev,
"UDP port (%d) not offloaded, max number of UDP ports (%d) are already offloaded\n",
port, mlx5_vxlan_max_udp_ports(vxlan->mdev));
- return;
+ ret = -ENOSPC;
+ return ret;
}
- if (mlx5_vxlan_core_add_port_cmd(vxlan->mdev, port))
- return;
+ ret = mlx5_vxlan_core_add_port_cmd(vxlan->mdev, port);
+ if (ret)
+ return ret;
vxlanp = kzalloc(sizeof(*vxlanp), GFP_KERNEL);
- if (!vxlanp)
+ if (!vxlanp) {
+ ret = -ENOMEM;
goto err_delete_port;
+ }
vxlanp->udp_port = port;
atomic_set(&vxlanp->refcount, 1);
@@ -136,21 +141,25 @@ void mlx5_vxlan_add_port(struct mlx5_vxlan *vxlan, u16 port)
write_unlock_bh(&vxlan->lock);
vxlan->num_ports++;
- return;
+ return 0;
err_delete_port:
mlx5_vxlan_core_del_port_cmd(vxlan->mdev, port);
+ return ret;
}
-void mlx5_vxlan_del_port(struct mlx5_vxlan *vxlan, u16 port)
+int mlx5_vxlan_del_port(struct mlx5_vxlan *vxlan, u16 port)
{
struct mlx5_vxlan_port *vxlanp;
bool remove = false;
+ int ret = 0;
write_lock_bh(&vxlan->lock);
vxlanp = mlx5_vxlan_lookup_port_locked(vxlan, port);
- if (!vxlanp)
+ if (!vxlanp) {
+ ret = -ENOENT;
goto out_unlock;
+ }
if (atomic_dec_and_test(&vxlanp->refcount)) {
hash_del(&vxlanp->hlist);
@@ -165,6 +174,7 @@ void mlx5_vxlan_del_port(struct mlx5_vxlan *vxlan, u16 port)
kfree(vxlanp);
vxlan->num_ports--;
}
+ return ret;
}
struct mlx5_vxlan *mlx5_vxlan_create(struct mlx5_core_dev *mdev)
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/vxlan.h b/drivers/net/ethernet/mellanox/mlx5/core/vxlan.h
index 9d6327321814..fd874a30c4d0 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/vxlan.h
+++ b/drivers/net/ethernet/mellanox/mlx5/core/vxlan.h
@@ -49,8 +49,8 @@ static inline bool mlx5_vxlan_allowed(struct mlx5_vxlan *vxlan)
struct mlx5_vxlan *mlx5_vxlan_create(struct mlx5_core_dev *mdev);
void mlx5_vxlan_destroy(struct mlx5_vxlan *vxlan);
-void mlx5_vxlan_add_port(struct mlx5_vxlan *vxlan, u16 port);
-void mlx5_vxlan_del_port(struct mlx5_vxlan *vxlan, u16 port);
+int mlx5_vxlan_add_port(struct mlx5_vxlan *vxlan, u16 port);
+int mlx5_vxlan_del_port(struct mlx5_vxlan *vxlan, u16 port);
struct mlx5_vxlan_port *mlx5_vxlan_lookup_port(struct mlx5_vxlan *vxlan, u16 port);
#else
--
2.17.0
^ permalink raw reply related
* [net-next 07/13] net/mlx5e: Vxlan, move netdev only logic to en_main.c
From: Saeed Mahameed @ 2018-07-27 21:15 UTC (permalink / raw)
To: David S. Miller; +Cc: netdev, Saeed Mahameed
In-Reply-To: <20180727211518.1916-1-saeedm@mellanox.com>
Create a direct vxlan API to add and delete vxlan ports from HW.
+void mlx5e_vxlan_add_port(struct mlx5e_priv *priv, u16 port);
+void mlx5e_vxlan_del_port(struct mlx5e_priv *priv, u16 port);
And move vxlan_add/del_work to en_main.c since they are netdev only
logic.
Signed-off-by: Saeed Mahameed <saeedm@mellanox.com>
Reviewed-by: Or Gerlitz <ogerlitz@mellanox.com>
---
.../net/ethernet/mellanox/mlx5/core/en_main.c | 51 +++++++++++++++++
.../net/ethernet/mellanox/mlx5/core/vxlan.c | 55 +++----------------
.../net/ethernet/mellanox/mlx5/core/vxlan.h | 16 +-----
3 files changed, 61 insertions(+), 61 deletions(-)
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
index 14a201cbb0a4..7a6b78e3b5f7 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
@@ -3969,6 +3969,57 @@ static int mlx5e_get_vf_stats(struct net_device *dev,
}
#endif
+struct mlx5e_vxlan_work {
+ struct work_struct work;
+ struct mlx5e_priv *priv;
+ u16 port;
+};
+
+static void mlx5e_vxlan_add_work(struct work_struct *work)
+{
+ struct mlx5e_vxlan_work *vxlan_work =
+ container_of(work, struct mlx5e_vxlan_work, work);
+ struct mlx5e_priv *priv = vxlan_work->priv;
+ u16 port = vxlan_work->port;
+
+ mutex_lock(&priv->state_lock);
+ mlx5e_vxlan_add_port(priv, port);
+ mutex_unlock(&priv->state_lock);
+
+ kfree(vxlan_work);
+}
+
+static void mlx5e_vxlan_del_work(struct work_struct *work)
+{
+ struct mlx5e_vxlan_work *vxlan_work =
+ container_of(work, struct mlx5e_vxlan_work, work);
+ struct mlx5e_priv *priv = vxlan_work->priv;
+ u16 port = vxlan_work->port;
+
+ mutex_lock(&priv->state_lock);
+ mlx5e_vxlan_del_port(priv, port);
+ mutex_unlock(&priv->state_lock);
+ kfree(vxlan_work);
+}
+
+static void mlx5e_vxlan_queue_work(struct mlx5e_priv *priv, u16 port, int add)
+{
+ struct mlx5e_vxlan_work *vxlan_work;
+
+ vxlan_work = kmalloc(sizeof(*vxlan_work), GFP_ATOMIC);
+ if (!vxlan_work)
+ return;
+
+ if (add)
+ INIT_WORK(&vxlan_work->work, mlx5e_vxlan_add_work);
+ else
+ INIT_WORK(&vxlan_work->work, mlx5e_vxlan_del_work);
+
+ vxlan_work->priv = priv;
+ vxlan_work->port = port;
+ queue_work(priv->wq, &vxlan_work->work);
+}
+
static void mlx5e_add_vxlan_port(struct net_device *netdev,
struct udp_tunnel_info *ti)
{
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/vxlan.c b/drivers/net/ethernet/mellanox/mlx5/core/vxlan.c
index 64883ca451aa..2a25c2dd6e6f 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/vxlan.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/vxlan.c
@@ -36,7 +36,11 @@
#include "mlx5_core.h"
#include "vxlan.h"
-static void mlx5e_vxlan_add_port(struct mlx5e_priv *priv, u16 port);
+struct mlx5e_vxlan {
+ struct hlist_node hlist;
+ atomic_t refcount;
+ u16 udp_port;
+};
void mlx5e_vxlan_init(struct mlx5e_priv *priv)
{
@@ -105,7 +109,7 @@ struct mlx5e_vxlan *mlx5e_vxlan_lookup_port(struct mlx5e_priv *priv, u16 port)
return vxlan;
}
-static void mlx5e_vxlan_add_port(struct mlx5e_priv *priv, u16 port)
+void mlx5e_vxlan_add_port(struct mlx5e_priv *priv, u16 port)
{
struct mlx5e_vxlan_db *vxlan_db = &priv->vxlan;
struct mlx5e_vxlan *vxlan;
@@ -144,21 +148,7 @@ static void mlx5e_vxlan_add_port(struct mlx5e_priv *priv, u16 port)
mlx5e_vxlan_core_del_port_cmd(priv->mdev, port);
}
-static void mlx5e_vxlan_add_work(struct work_struct *work)
-{
- struct mlx5e_vxlan_work *vxlan_work =
- container_of(work, struct mlx5e_vxlan_work, work);
- struct mlx5e_priv *priv = vxlan_work->priv;
- u16 port = vxlan_work->port;
-
- mutex_lock(&priv->state_lock);
- mlx5e_vxlan_add_port(priv, port);
- mutex_unlock(&priv->state_lock);
-
- kfree(vxlan_work);
-}
-
-static void mlx5e_vxlan_del_port(struct mlx5e_priv *priv, u16 port)
+void mlx5e_vxlan_del_port(struct mlx5e_priv *priv, u16 port)
{
struct mlx5e_vxlan_db *vxlan_db = &priv->vxlan;
struct mlx5e_vxlan *vxlan;
@@ -184,37 +174,6 @@ static void mlx5e_vxlan_del_port(struct mlx5e_priv *priv, u16 port)
}
}
-static void mlx5e_vxlan_del_work(struct work_struct *work)
-{
- struct mlx5e_vxlan_work *vxlan_work =
- container_of(work, struct mlx5e_vxlan_work, work);
- struct mlx5e_priv *priv = vxlan_work->priv;
- u16 port = vxlan_work->port;
-
- mutex_lock(&priv->state_lock);
- mlx5e_vxlan_del_port(priv, port);
- mutex_unlock(&priv->state_lock);
- kfree(vxlan_work);
-}
-
-void mlx5e_vxlan_queue_work(struct mlx5e_priv *priv, u16 port, int add)
-{
- struct mlx5e_vxlan_work *vxlan_work;
-
- vxlan_work = kmalloc(sizeof(*vxlan_work), GFP_ATOMIC);
- if (!vxlan_work)
- return;
-
- if (add)
- INIT_WORK(&vxlan_work->work, mlx5e_vxlan_add_work);
- else
- INIT_WORK(&vxlan_work->work, mlx5e_vxlan_del_work);
-
- vxlan_work->priv = priv;
- vxlan_work->port = port;
- queue_work(priv->wq, &vxlan_work->work);
-}
-
void mlx5e_vxlan_cleanup(struct mlx5e_priv *priv)
{
struct mlx5e_vxlan_db *vxlan_db = &priv->vxlan;
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/vxlan.h b/drivers/net/ethernet/mellanox/mlx5/core/vxlan.h
index 51f19e3e5784..1a02f5b38009 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/vxlan.h
+++ b/drivers/net/ethernet/mellanox/mlx5/core/vxlan.h
@@ -35,17 +35,7 @@
#include <linux/mlx5/driver.h>
#include "en.h"
-struct mlx5e_vxlan {
- struct hlist_node hlist;
- atomic_t refcount;
- u16 udp_port;
-};
-
-struct mlx5e_vxlan_work {
- struct work_struct work;
- struct mlx5e_priv *priv;
- u16 port;
-};
+struct mlx5e_vxlan;
static inline bool mlx5e_vxlan_allowed(struct mlx5_core_dev *mdev)
{
@@ -55,8 +45,8 @@ static inline bool mlx5e_vxlan_allowed(struct mlx5_core_dev *mdev)
void mlx5e_vxlan_init(struct mlx5e_priv *priv);
void mlx5e_vxlan_cleanup(struct mlx5e_priv *priv);
-
-void mlx5e_vxlan_queue_work(struct mlx5e_priv *priv, u16 port, int add);
+void mlx5e_vxlan_add_port(struct mlx5e_priv *priv, u16 port);
+void mlx5e_vxlan_del_port(struct mlx5e_priv *priv, u16 port);
struct mlx5e_vxlan *mlx5e_vxlan_lookup_port(struct mlx5e_priv *priv, u16 port);
#endif /* __MLX5_VXLAN_H__ */
--
2.17.0
^ permalink raw reply related
* [net-next 04/13] net/mlx5e: Vxlan, replace spinlock with read-write lock
From: Saeed Mahameed @ 2018-07-27 21:15 UTC (permalink / raw)
To: David S. Miller; +Cc: netdev, Gal Pressman, Saeed Mahameed
In-Reply-To: <20180727211518.1916-1-saeedm@mellanox.com>
From: Gal Pressman <galp@mellanox.com>
The VXLAN database is mainly used by readers in data path, and rarely
used by control path writers.
Multiple readers (threads) should not block each other and cause an
unnecessary contention on the lock.
Replacing the spinlock with rwlock optimizes the common use case where
adding ports to the table (adding VXLAN interfaces) is quite rare, but
the table is accessed for each VXLAN TX skb.
Signed-off-by: Gal Pressman <galp@mellanox.com>
Signed-off-by: Saeed Mahameed <saeedm@mellanox.com>
---
drivers/net/ethernet/mellanox/mlx5/core/en.h | 2 +-
drivers/net/ethernet/mellanox/mlx5/core/vxlan.c | 14 +++++++-------
2 files changed, 8 insertions(+), 8 deletions(-)
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en.h b/drivers/net/ethernet/mellanox/mlx5/core/en.h
index 6878925c3abf..870ac617550c 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en.h
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en.h
@@ -655,7 +655,7 @@ enum {
};
struct mlx5e_vxlan_db {
- spinlock_t lock; /* protect vxlan table */
+ rwlock_t lock; /* protect vxlan table */
/* max_num_ports is usuallly 4, 16 buckets is more than enough */
DECLARE_HASHTABLE(htable, 4);
int num_ports;
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/vxlan.c b/drivers/net/ethernet/mellanox/mlx5/core/vxlan.c
index 3c0ea9bc20e3..2733ca63e46b 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/vxlan.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/vxlan.c
@@ -42,7 +42,7 @@ void mlx5e_vxlan_init(struct mlx5e_priv *priv)
{
struct mlx5e_vxlan_db *vxlan_db = &priv->vxlan;
- spin_lock_init(&vxlan_db->lock);
+ rwlock_init(&vxlan_db->lock);
hash_init(vxlan_db->htable);
if (mlx5e_vxlan_allowed(priv->mdev))
@@ -98,9 +98,9 @@ struct mlx5e_vxlan *mlx5e_vxlan_lookup_port(struct mlx5e_priv *priv, u16 port)
struct mlx5e_vxlan_db *vxlan_db = &priv->vxlan;
struct mlx5e_vxlan *vxlan;
- spin_lock_bh(&vxlan_db->lock);
+ read_lock_bh(&vxlan_db->lock);
vxlan = mlx5e_vxlan_lookup_port_locked(priv, port);
- spin_unlock_bh(&vxlan_db->lock);
+ read_unlock_bh(&vxlan_db->lock);
return vxlan;
}
@@ -133,9 +133,9 @@ static void mlx5e_vxlan_add_port(struct mlx5e_priv *priv, u16 port)
vxlan->udp_port = port;
atomic_set(&vxlan->refcount, 1);
- spin_lock_bh(&vxlan_db->lock);
+ write_lock_bh(&vxlan_db->lock);
hash_add(vxlan_db->htable, &vxlan->hlist, port);
- spin_unlock_bh(&vxlan_db->lock);
+ write_unlock_bh(&vxlan_db->lock);
vxlan_db->num_ports++;
return;
@@ -169,7 +169,7 @@ static void mlx5e_vxlan_del_work(struct work_struct *work)
bool remove = false;
mutex_lock(&priv->state_lock);
- spin_lock_bh(&vxlan_db->lock);
+ write_lock_bh(&vxlan_db->lock);
vxlan = mlx5e_vxlan_lookup_port_locked(priv, port);
if (!vxlan)
goto out_unlock;
@@ -180,7 +180,7 @@ static void mlx5e_vxlan_del_work(struct work_struct *work)
}
out_unlock:
- spin_unlock_bh(&vxlan_db->lock);
+ write_unlock_bh(&vxlan_db->lock);
if (remove) {
mlx5e_vxlan_core_del_port_cmd(priv->mdev, port);
--
2.17.0
^ permalink raw reply related
* [net-next 06/13] net/mlx5e: Vxlan, add direct delete function
From: Saeed Mahameed @ 2018-07-27 21:15 UTC (permalink / raw)
To: David S. Miller; +Cc: netdev, Saeed Mahameed
In-Reply-To: <20180727211518.1916-1-saeedm@mellanox.com>
Add direct vxlan delete function to be called from vxlan_delete_work.
Needed in downstream patch.
Signed-off-by: Saeed Mahameed <saeedm@mellanox.com>
Reviewed-by: Or Gerlitz <ogerlitz@mellanox.com>
---
.../net/ethernet/mellanox/mlx5/core/vxlan.c | 18 ++++++++++++------
1 file changed, 12 insertions(+), 6 deletions(-)
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/vxlan.c b/drivers/net/ethernet/mellanox/mlx5/core/vxlan.c
index 4a86d8132fc1..64883ca451aa 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/vxlan.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/vxlan.c
@@ -158,17 +158,12 @@ static void mlx5e_vxlan_add_work(struct work_struct *work)
kfree(vxlan_work);
}
-static void mlx5e_vxlan_del_work(struct work_struct *work)
+static void mlx5e_vxlan_del_port(struct mlx5e_priv *priv, u16 port)
{
- struct mlx5e_vxlan_work *vxlan_work =
- container_of(work, struct mlx5e_vxlan_work, work);
- struct mlx5e_priv *priv = vxlan_work->priv;
struct mlx5e_vxlan_db *vxlan_db = &priv->vxlan;
- u16 port = vxlan_work->port;
struct mlx5e_vxlan *vxlan;
bool remove = false;
- mutex_lock(&priv->state_lock);
write_lock_bh(&vxlan_db->lock);
vxlan = mlx5e_vxlan_lookup_port_locked(priv, port);
if (!vxlan)
@@ -187,6 +182,17 @@ static void mlx5e_vxlan_del_work(struct work_struct *work)
kfree(vxlan);
vxlan_db->num_ports--;
}
+}
+
+static void mlx5e_vxlan_del_work(struct work_struct *work)
+{
+ struct mlx5e_vxlan_work *vxlan_work =
+ container_of(work, struct mlx5e_vxlan_work, work);
+ struct mlx5e_priv *priv = vxlan_work->priv;
+ u16 port = vxlan_work->port;
+
+ mutex_lock(&priv->state_lock);
+ mlx5e_vxlan_del_port(priv, port);
mutex_unlock(&priv->state_lock);
kfree(vxlan_work);
}
--
2.17.0
^ permalink raw reply related
* [net-next 05/13] net/mlx5e: Vxlan, cleanup an unused member in vxlan work
From: Saeed Mahameed @ 2018-07-27 21:15 UTC (permalink / raw)
To: David S. Miller; +Cc: netdev, Gal Pressman, Saeed Mahameed
In-Reply-To: <20180727211518.1916-1-saeedm@mellanox.com>
From: Gal Pressman <galp@mellanox.com>
Cleanup the sa_family member of the vxlan work, it is unused/needed
anywhere in the code.
Signed-off-by: Gal Pressman <galp@mellanox.com>
Signed-off-by: Saeed Mahameed <saeedm@mellanox.com>
---
drivers/net/ethernet/mellanox/mlx5/core/en_main.c | 4 ++--
drivers/net/ethernet/mellanox/mlx5/core/vxlan.c | 4 +---
drivers/net/ethernet/mellanox/mlx5/core/vxlan.h | 4 +---
3 files changed, 4 insertions(+), 8 deletions(-)
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
index fad947079a43..14a201cbb0a4 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
@@ -3980,7 +3980,7 @@ static void mlx5e_add_vxlan_port(struct net_device *netdev,
if (!mlx5e_vxlan_allowed(priv->mdev))
return;
- mlx5e_vxlan_queue_work(priv, ti->sa_family, be16_to_cpu(ti->port), 1);
+ mlx5e_vxlan_queue_work(priv, be16_to_cpu(ti->port), 1);
}
static void mlx5e_del_vxlan_port(struct net_device *netdev,
@@ -3994,7 +3994,7 @@ static void mlx5e_del_vxlan_port(struct net_device *netdev,
if (!mlx5e_vxlan_allowed(priv->mdev))
return;
- mlx5e_vxlan_queue_work(priv, ti->sa_family, be16_to_cpu(ti->port), 0);
+ mlx5e_vxlan_queue_work(priv, be16_to_cpu(ti->port), 0);
}
static netdev_features_t mlx5e_tunnel_features_check(struct mlx5e_priv *priv,
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/vxlan.c b/drivers/net/ethernet/mellanox/mlx5/core/vxlan.c
index 2733ca63e46b..4a86d8132fc1 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/vxlan.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/vxlan.c
@@ -191,8 +191,7 @@ static void mlx5e_vxlan_del_work(struct work_struct *work)
kfree(vxlan_work);
}
-void mlx5e_vxlan_queue_work(struct mlx5e_priv *priv, sa_family_t sa_family,
- u16 port, int add)
+void mlx5e_vxlan_queue_work(struct mlx5e_priv *priv, u16 port, int add)
{
struct mlx5e_vxlan_work *vxlan_work;
@@ -207,7 +206,6 @@ void mlx5e_vxlan_queue_work(struct mlx5e_priv *priv, sa_family_t sa_family,
vxlan_work->priv = priv;
vxlan_work->port = port;
- vxlan_work->sa_family = sa_family;
queue_work(priv->wq, &vxlan_work->work);
}
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/vxlan.h b/drivers/net/ethernet/mellanox/mlx5/core/vxlan.h
index 52c41c22235d..51f19e3e5784 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/vxlan.h
+++ b/drivers/net/ethernet/mellanox/mlx5/core/vxlan.h
@@ -44,7 +44,6 @@ struct mlx5e_vxlan {
struct mlx5e_vxlan_work {
struct work_struct work;
struct mlx5e_priv *priv;
- sa_family_t sa_family;
u16 port;
};
@@ -57,8 +56,7 @@ static inline bool mlx5e_vxlan_allowed(struct mlx5_core_dev *mdev)
void mlx5e_vxlan_init(struct mlx5e_priv *priv);
void mlx5e_vxlan_cleanup(struct mlx5e_priv *priv);
-void mlx5e_vxlan_queue_work(struct mlx5e_priv *priv, sa_family_t sa_family,
- u16 port, int add);
+void mlx5e_vxlan_queue_work(struct mlx5e_priv *priv, u16 port, int add);
struct mlx5e_vxlan *mlx5e_vxlan_lookup_port(struct mlx5e_priv *priv, u16 port);
#endif /* __MLX5_VXLAN_H__ */
--
2.17.0
^ permalink raw reply related
* [net-next 01/13] net/mlx5e: Vxlan, reflect 4789 UDP port default addition to software database
From: Saeed Mahameed @ 2018-07-27 21:15 UTC (permalink / raw)
To: David S. Miller; +Cc: netdev, Gal Pressman, Saeed Mahameed
In-Reply-To: <20180727211518.1916-1-saeedm@mellanox.com>
From: Gal Pressman <galp@mellanox.com>
The hardware offloads 4789 UDP port (default VXLAN port) automatically.
Add it to the software database as well in order to reflect the hardware
state appropriately.
Signed-off-by: Gal Pressman <galp@mellanox.com>
Signed-off-by: Saeed Mahameed <saeedm@mellanox.com>
---
.../net/ethernet/mellanox/mlx5/core/vxlan.c | 40 +++++++++++++------
1 file changed, 27 insertions(+), 13 deletions(-)
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/vxlan.c b/drivers/net/ethernet/mellanox/mlx5/core/vxlan.c
index 2f74953e4561..2f699998d13e 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/vxlan.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/vxlan.c
@@ -36,12 +36,20 @@
#include "mlx5_core.h"
#include "vxlan.h"
+static void mlx5e_vxlan_add_port(struct mlx5e_priv *priv, u16 port);
+
void mlx5e_vxlan_init(struct mlx5e_priv *priv)
{
struct mlx5e_vxlan_db *vxlan_db = &priv->vxlan;
spin_lock_init(&vxlan_db->lock);
INIT_RADIX_TREE(&vxlan_db->tree, GFP_ATOMIC);
+
+ if (mlx5e_vxlan_allowed(priv->mdev))
+ /* Hardware adds 4789 by default.
+ * Lockless since we are the only hash table consumers, wq and TX are disabled.
+ */
+ mlx5e_vxlan_add_port(priv, 4789);
}
static int mlx5e_vxlan_core_add_port_cmd(struct mlx5_core_dev *mdev, u16 port)
@@ -78,25 +86,20 @@ struct mlx5e_vxlan *mlx5e_vxlan_lookup_port(struct mlx5e_priv *priv, u16 port)
return vxlan;
}
-static void mlx5e_vxlan_add_port(struct work_struct *work)
+static void mlx5e_vxlan_add_port(struct mlx5e_priv *priv, u16 port)
{
- struct mlx5e_vxlan_work *vxlan_work =
- container_of(work, struct mlx5e_vxlan_work, work);
- struct mlx5e_priv *priv = vxlan_work->priv;
struct mlx5e_vxlan_db *vxlan_db = &priv->vxlan;
- u16 port = vxlan_work->port;
struct mlx5e_vxlan *vxlan;
int err;
- mutex_lock(&priv->state_lock);
vxlan = mlx5e_vxlan_lookup_port(priv, port);
if (vxlan) {
atomic_inc(&vxlan->refcount);
- goto free_work;
+ return;
}
if (mlx5e_vxlan_core_add_port_cmd(priv->mdev, port))
- goto free_work;
+ return;
vxlan = kzalloc(sizeof(*vxlan), GFP_KERNEL);
if (!vxlan)
@@ -111,18 +114,29 @@ static void mlx5e_vxlan_add_port(struct work_struct *work)
if (err)
goto err_free;
- goto free_work;
+ return;
err_free:
kfree(vxlan);
err_delete_port:
mlx5e_vxlan_core_del_port_cmd(priv->mdev, port);
-free_work:
+}
+
+static void mlx5e_vxlan_add_work(struct work_struct *work)
+{
+ struct mlx5e_vxlan_work *vxlan_work =
+ container_of(work, struct mlx5e_vxlan_work, work);
+ struct mlx5e_priv *priv = vxlan_work->priv;
+ u16 port = vxlan_work->port;
+
+ mutex_lock(&priv->state_lock);
+ mlx5e_vxlan_add_port(priv, port);
mutex_unlock(&priv->state_lock);
+
kfree(vxlan_work);
}
-static void mlx5e_vxlan_del_port(struct work_struct *work)
+static void mlx5e_vxlan_del_work(struct work_struct *work)
{
struct mlx5e_vxlan_work *vxlan_work =
container_of(work, struct mlx5e_vxlan_work, work);
@@ -164,9 +178,9 @@ void mlx5e_vxlan_queue_work(struct mlx5e_priv *priv, sa_family_t sa_family,
return;
if (add)
- INIT_WORK(&vxlan_work->work, mlx5e_vxlan_add_port);
+ INIT_WORK(&vxlan_work->work, mlx5e_vxlan_add_work);
else
- INIT_WORK(&vxlan_work->work, mlx5e_vxlan_del_port);
+ INIT_WORK(&vxlan_work->work, mlx5e_vxlan_del_work);
vxlan_work->priv = priv;
vxlan_work->port = port;
--
2.17.0
^ permalink raw reply related
* [net-next 03/13] net/mlx5e: Vxlan, replace ports radix-tree with hash table
From: Saeed Mahameed @ 2018-07-27 21:15 UTC (permalink / raw)
To: David S. Miller; +Cc: netdev, Gal Pressman, Saeed Mahameed
In-Reply-To: <20180727211518.1916-1-saeedm@mellanox.com>
From: Gal Pressman <galp@mellanox.com>
The VXLAN database is accessed in the data path for each VXLAN TX skb in
order to check whether the UDP port is being offloaded or not.
The number of elements in the database is relatively small, we can
simplify the radix-tree to a hash table and speedup the lookup process.
Measuring mlx5e_vxlan_lookup_port execution time:
Radix Tree Hash Table
--------------- ------------ ------------
Single Stream 161 ns 79 ns (51% improvement)
Multi Stream 259 ns 136 ns (47% improvement)
Measuring UDP stream packet rate, single fully utilized TX core:
Radix Tree: 498,300 PPS
Hash Table: 555,468 PPS (11% improvement)
Signed-off-by: Gal Pressman <galp@mellanox.com>
Signed-off-by: Saeed Mahameed <saeedm@mellanox.com>
---
drivers/net/ethernet/mellanox/mlx5/core/en.h | 3 +-
.../net/ethernet/mellanox/mlx5/core/vxlan.c | 41 +++++++++++--------
.../net/ethernet/mellanox/mlx5/core/vxlan.h | 1 +
3 files changed, 28 insertions(+), 17 deletions(-)
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en.h b/drivers/net/ethernet/mellanox/mlx5/core/en.h
index c4d4db8722f5..6878925c3abf 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en.h
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en.h
@@ -656,7 +656,8 @@ enum {
struct mlx5e_vxlan_db {
spinlock_t lock; /* protect vxlan table */
- struct radix_tree_root tree;
+ /* max_num_ports is usuallly 4, 16 buckets is more than enough */
+ DECLARE_HASHTABLE(htable, 4);
int num_ports;
};
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/vxlan.c b/drivers/net/ethernet/mellanox/mlx5/core/vxlan.c
index e3af2efe18ce..3c0ea9bc20e3 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/vxlan.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/vxlan.c
@@ -43,7 +43,7 @@ void mlx5e_vxlan_init(struct mlx5e_priv *priv)
struct mlx5e_vxlan_db *vxlan_db = &priv->vxlan;
spin_lock_init(&vxlan_db->lock);
- INIT_RADIX_TREE(&vxlan_db->tree, GFP_ATOMIC);
+ hash_init(vxlan_db->htable);
if (mlx5e_vxlan_allowed(priv->mdev))
/* Hardware adds 4789 by default.
@@ -79,13 +79,27 @@ static int mlx5e_vxlan_core_del_port_cmd(struct mlx5_core_dev *mdev, u16 port)
return mlx5_cmd_exec(mdev, in, sizeof(in), out, sizeof(out));
}
+static struct mlx5e_vxlan *mlx5e_vxlan_lookup_port_locked(struct mlx5e_priv *priv,
+ u16 port)
+{
+ struct mlx5e_vxlan_db *vxlan_db = &priv->vxlan;
+ struct mlx5e_vxlan *vxlan;
+
+ hash_for_each_possible(vxlan_db->htable, vxlan, hlist, port) {
+ if (vxlan->udp_port == port)
+ return vxlan;
+ }
+
+ return NULL;
+}
+
struct mlx5e_vxlan *mlx5e_vxlan_lookup_port(struct mlx5e_priv *priv, u16 port)
{
struct mlx5e_vxlan_db *vxlan_db = &priv->vxlan;
struct mlx5e_vxlan *vxlan;
spin_lock_bh(&vxlan_db->lock);
- vxlan = radix_tree_lookup(&vxlan_db->tree, port);
+ vxlan = mlx5e_vxlan_lookup_port_locked(priv, port);
spin_unlock_bh(&vxlan_db->lock);
return vxlan;
@@ -95,7 +109,6 @@ static void mlx5e_vxlan_add_port(struct mlx5e_priv *priv, u16 port)
{
struct mlx5e_vxlan_db *vxlan_db = &priv->vxlan;
struct mlx5e_vxlan *vxlan;
- int err;
vxlan = mlx5e_vxlan_lookup_port(priv, port);
if (vxlan) {
@@ -121,16 +134,12 @@ static void mlx5e_vxlan_add_port(struct mlx5e_priv *priv, u16 port)
atomic_set(&vxlan->refcount, 1);
spin_lock_bh(&vxlan_db->lock);
- err = radix_tree_insert(&vxlan_db->tree, vxlan->udp_port, vxlan);
+ hash_add(vxlan_db->htable, &vxlan->hlist, port);
spin_unlock_bh(&vxlan_db->lock);
- if (err)
- goto err_free;
vxlan_db->num_ports++;
return;
-err_free:
- kfree(vxlan);
err_delete_port:
mlx5e_vxlan_core_del_port_cmd(priv->mdev, port);
}
@@ -161,12 +170,12 @@ static void mlx5e_vxlan_del_work(struct work_struct *work)
mutex_lock(&priv->state_lock);
spin_lock_bh(&vxlan_db->lock);
- vxlan = radix_tree_lookup(&vxlan_db->tree, port);
+ vxlan = mlx5e_vxlan_lookup_port_locked(priv, port);
if (!vxlan)
goto out_unlock;
if (atomic_dec_and_test(&vxlan->refcount)) {
- radix_tree_delete(&vxlan_db->tree, port);
+ hash_del(&vxlan->hlist);
remove = true;
}
@@ -206,13 +215,13 @@ void mlx5e_vxlan_cleanup(struct mlx5e_priv *priv)
{
struct mlx5e_vxlan_db *vxlan_db = &priv->vxlan;
struct mlx5e_vxlan *vxlan;
- unsigned int port = 0;
+ struct hlist_node *tmp;
+ int bkt;
- /* Lockless since we are the only radix-tree consumers, wq is disabled */
- while (radix_tree_gang_lookup(&vxlan_db->tree, (void **)&vxlan, port, 1)) {
- port = vxlan->udp_port;
- radix_tree_delete(&vxlan_db->tree, port);
- mlx5e_vxlan_core_del_port_cmd(priv->mdev, port);
+ /* Lockless since we are the only hash table consumers, wq and TX are disabled */
+ hash_for_each_safe(vxlan_db->htable, bkt, tmp, vxlan, hlist) {
+ hash_del(&vxlan->hlist);
+ mlx5e_vxlan_core_del_port_cmd(priv->mdev, vxlan->udp_port);
kfree(vxlan);
}
}
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/vxlan.h b/drivers/net/ethernet/mellanox/mlx5/core/vxlan.h
index 5ef6ae7d568a..52c41c22235d 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/vxlan.h
+++ b/drivers/net/ethernet/mellanox/mlx5/core/vxlan.h
@@ -36,6 +36,7 @@
#include "en.h"
struct mlx5e_vxlan {
+ struct hlist_node hlist;
atomic_t refcount;
u16 udp_port;
};
--
2.17.0
^ permalink raw reply related
* [net-next 02/13] net/mlx5e: Vxlan, check maximum number of UDP ports
From: Saeed Mahameed @ 2018-07-27 21:15 UTC (permalink / raw)
To: David S. Miller; +Cc: netdev, Gal Pressman, Saeed Mahameed
In-Reply-To: <20180727211518.1916-1-saeedm@mellanox.com>
From: Gal Pressman <galp@mellanox.com>
The NIC has a limited number of offloaded VXLAN UDP ports (usually 4).
Instead of letting the firmware fail when trying to add more ports than
it can handle, let the driver check it on its own.
Signed-off-by: Gal Pressman <galp@mellanox.com>
Signed-off-by: Saeed Mahameed <saeedm@mellanox.com>
---
drivers/net/ethernet/mellanox/mlx5/core/en.h | 1 +
drivers/net/ethernet/mellanox/mlx5/core/vxlan.c | 14 ++++++++++++++
include/linux/mlx5/mlx5_ifc.h | 4 +++-
3 files changed, 18 insertions(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en.h b/drivers/net/ethernet/mellanox/mlx5/core/en.h
index c41cfc2a4b70..c4d4db8722f5 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en.h
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en.h
@@ -657,6 +657,7 @@ enum {
struct mlx5e_vxlan_db {
spinlock_t lock; /* protect vxlan table */
struct radix_tree_root tree;
+ int num_ports;
};
struct mlx5e_l2_rule {
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/vxlan.c b/drivers/net/ethernet/mellanox/mlx5/core/vxlan.c
index 2f699998d13e..e3af2efe18ce 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/vxlan.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/vxlan.c
@@ -52,6 +52,11 @@ void mlx5e_vxlan_init(struct mlx5e_priv *priv)
mlx5e_vxlan_add_port(priv, 4789);
}
+static inline u8 mlx5e_vxlan_max_udp_ports(struct mlx5_core_dev *mdev)
+{
+ return MLX5_CAP_ETH(mdev, max_vxlan_udp_ports) ?: 4;
+}
+
static int mlx5e_vxlan_core_add_port_cmd(struct mlx5_core_dev *mdev, u16 port)
{
u32 in[MLX5_ST_SZ_DW(add_vxlan_udp_dport_in)] = {0};
@@ -98,6 +103,13 @@ static void mlx5e_vxlan_add_port(struct mlx5e_priv *priv, u16 port)
return;
}
+ if (vxlan_db->num_ports >= mlx5e_vxlan_max_udp_ports(priv->mdev)) {
+ netdev_info(priv->netdev,
+ "UDP port (%d) not offloaded, max number of UDP ports (%d) are already offloaded\n",
+ port, mlx5e_vxlan_max_udp_ports(priv->mdev));
+ return;
+ }
+
if (mlx5e_vxlan_core_add_port_cmd(priv->mdev, port))
return;
@@ -114,6 +126,7 @@ static void mlx5e_vxlan_add_port(struct mlx5e_priv *priv, u16 port)
if (err)
goto err_free;
+ vxlan_db->num_ports++;
return;
err_free:
@@ -163,6 +176,7 @@ static void mlx5e_vxlan_del_work(struct work_struct *work)
if (remove) {
mlx5e_vxlan_core_del_port_cmd(priv->mdev, port);
kfree(vxlan);
+ vxlan_db->num_ports--;
}
mutex_unlock(&priv->state_lock);
kfree(vxlan_work);
diff --git a/include/linux/mlx5/mlx5_ifc.h b/include/linux/mlx5/mlx5_ifc.h
index 22f54bedfaae..60c2308fe062 100644
--- a/include/linux/mlx5/mlx5_ifc.h
+++ b/include/linux/mlx5/mlx5_ifc.h
@@ -668,7 +668,9 @@ struct mlx5_ifc_per_protocol_networking_offload_caps_bits {
u8 swp[0x1];
u8 swp_csum[0x1];
u8 swp_lso[0x1];
- u8 reserved_at_23[0x1b];
+ u8 reserved_at_23[0xd];
+ u8 max_vxlan_udp_ports[0x8];
+ u8 reserved_at_38[0x6];
u8 max_geneve_opt_len[0x1];
u8 tunnel_stateless_geneve_rx[0x1];
--
2.17.0
^ permalink raw reply related
* [pull request][net-next 00/13] Mellanox, mlx5 updates 2018-07-27 (Vxlan updates)
From: Saeed Mahameed @ 2018-07-27 21:15 UTC (permalink / raw)
To: David S. Miller; +Cc: netdev, Saeed Mahameed
Hi Dave,
This series from Gal and Saeed provides updates to mlx5 vxlan implementation.
For more information please see tag log below.
Please pull and let me know if there's any problem.
Thanks,
Saeed.
---
The following changes since commit 1f3ed383fb9a073ae2e408cd7a0717b04c7c3a21:
net: sched: don't dump chains only held by actions (2018-07-27 09:38:46 -0700)
are available in the Git repository at:
git://git.kernel.org/pub/scm/linux/kernel/git/saeed/linux.git tags/mlx5e-updates-2018-07-27
for you to fetch changes up to 50920f3f268405af2b047ae9277efdbf4ed7510f:
net/mlx5e: Issue direct lookup on vxlan ports by vport representors (2018-07-27 13:57:55 -0700)
----------------------------------------------------------------
mlx5e-updates-2018-07-27 (Vxlan updates)
This series from Gal and Saeed provides updates to mlx5 vxlan implementation.
Gal, started with three cleanups to reflect the actual hardware vxlan state
- reflect 4789 UDP port default addition to software database
- check maximum number of vxlan UDP ports
- cleanup an unused member in vxlan work
Then Gal provides two performance optimizations by replacing the
vxlan radix tree with a hash table, and replacing the vxlan table
spin lock with a read-write lock.
Measuring mlx5e_vxlan_lookup_port execution time:
Radix Tree Hash Table
--------------- ------------ ------------
Single Stream 161 ns 79 ns (51% improvement)
Multi Stream 259 ns 136 ns (47% improvement)
Measuring UDP stream packet rate, single fully utilized TX core:
Radix Tree: 498,300 PPS
Hash Table: 555,468 PPS (11% improvement)
Next, from Saeed, vxlan refactoring to allow sharing the vxlan table
between different mlx5 netdevice instances like PF and VF representors,
this is done by making mlx5 vxlan interface more generic and decoupling
it from PF netdevice structures and logic, then moving it into mlx5 core
as a low level interface so it can be used by VF representors, which is
illustrated in the last patch of the serious.
-Saeed.
----------------------------------------------------------------
Gal Pressman (5):
net/mlx5e: Vxlan, reflect 4789 UDP port default addition to software database
net/mlx5e: Vxlan, check maximum number of UDP ports
net/mlx5e: Vxlan, replace ports radix-tree with hash table
net/mlx5e: Vxlan, replace spinlock with read-write lock
net/mlx5e: Vxlan, cleanup an unused member in vxlan work
Saeed Mahameed (8):
net/mlx5e: Vxlan, add direct delete function
net/mlx5e: Vxlan, move netdev only logic to en_main.c
net/mlx5e: Vxlan, rename struct mlx5e_vxlan to mlx5_vxlan_port
net/mlx5e: Vxlan, rename from mlx5e to mlx5
net/mlx5e: Vxlan, return values for add/del port
net/mlx5e: Vxlan, add sync lock for add/del vxlan port
net/mlx5e: Vxlan, move vxlan logic to core driver
net/mlx5e: Issue direct lookup on vxlan ports by vport representors
drivers/net/ethernet/mellanox/mlx5/core/Makefile | 4 +-
drivers/net/ethernet/mellanox/mlx5/core/en.h | 6 -
drivers/net/ethernet/mellanox/mlx5/core/en_main.c | 71 ++++++-
drivers/net/ethernet/mellanox/mlx5/core/en_tc.c | 14 +-
.../net/ethernet/mellanox/mlx5/core/lib/vxlan.c | 230 +++++++++++++++++++++
.../ethernet/mellanox/mlx5/core/{ => lib}/vxlan.h | 39 ++--
drivers/net/ethernet/mellanox/mlx5/core/main.c | 5 +
drivers/net/ethernet/mellanox/mlx5/core/vxlan.c | 190 -----------------
include/linux/mlx5/driver.h | 2 +
include/linux/mlx5/mlx5_ifc.h | 4 +-
10 files changed, 325 insertions(+), 240 deletions(-)
create mode 100644 drivers/net/ethernet/mellanox/mlx5/core/lib/vxlan.c
rename drivers/net/ethernet/mellanox/mlx5/core/{ => lib}/vxlan.h (66%)
delete mode 100644 drivers/net/ethernet/mellanox/mlx5/core/vxlan.c
^ permalink raw reply
* Re: [PATCH net-next] net: dcb: add DSCP to comment about priority selector types
From: Petr Machata @ 2018-07-27 21:14 UTC (permalink / raw)
To: Jakub Kicinski
Cc: davem, Ido Schimmel, Huy Nguyen, john.fastabend, mlxsw, jiri,
netdev, oss-drivers
In-Reply-To: <20180727201100.26891-1-jakub.kicinski@netronome.com>
Jakub Kicinski <jakub.kicinski@netronome.com> writes:
> Commit ee2059819450 ("net/dcb: Add dscp to priority selector type")
> added a define for the new DSCP selector type created by
> IEEE 802.1Qcd, but missed the comment enumerating all selector types.
> Update the comment.
>
> Signed-off-by: Jakub Kicinski <jakub.kicinski@netronome.com>
Reviewed-by: Petr Machata <petrm@mellanox.com>
^ permalink raw reply
* Re: [PATCH] net: usb: pegasus: Replace mdelay() with msleep() in setup_pegasus_II()
From: David Miller @ 2018-07-27 21:12 UTC (permalink / raw)
To: baijiaju1990; +Cc: petkan, linux-usb, netdev, linux-kernel
In-Reply-To: <20180727083629.18663-1-baijiaju1990@gmail.com>
From: Jia-Ju Bai <baijiaju1990@gmail.com>
Date: Fri, 27 Jul 2018 16:36:29 +0800
> setup_pegasus_II() is never called in atomic context.
> It calls mdelay() to busily wait, which is not necessary.
> mdelay() can be replaced with msleep().
>
> This is found by a static analysis tool named DCNS written by myself.
>
> Signed-off-by: Jia-Ju Bai <baijiaju1990@gmail.com>
Applied.
^ permalink raw reply
* Re: [PATCH PATCH net-next 15/18] sunrpc: whitespace fixes
From: Anna Schumaker @ 2018-07-27 20:39 UTC (permalink / raw)
To: Stephen Hemminger, davem, ericvh, rminnich, lucho, ralf, jreuter,
pablo, kadlec, fw, alex.aring, stefan, kuznet, yoshfuji, johannes,
jhs, xiyou.wangcong, jiri, vyasevich, nhorman, marcelo.leitner,
trond.myklebust, steffen.klassert, herbert
Cc: netdev, v9fs-developer, linux-hams, ceph-devel, linux-decnet-user,
netfilter-devel, coreteam, linux-wpan, linux-s390, linux-wireless,
linux-rdma, linux-sctp, linux-nfs, linux-x25, Stephen Hemminger
In-Reply-To: <20180724192918.31165-16-sthemmin@microsoft.com>
On 07/24/2018 03:29 PM, Stephen Hemminger wrote:
> Remove trailing whitespace and blank line at EOF
Looks good to me, I've applied it to my tree.
Thanks!
Anna
>
> Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
> ---
> net/sunrpc/auth_gss/auth_gss.c | 2 +-
> net/sunrpc/auth_gss/gss_generic_token.c | 1 -
> net/sunrpc/auth_gss/gss_krb5_crypto.c | 1 -
> net/sunrpc/auth_gss/gss_krb5_keys.c | 1 -
> net/sunrpc/auth_gss/gss_krb5_seal.c | 1 -
> net/sunrpc/auth_gss/gss_krb5_unseal.c | 1 -
> net/sunrpc/auth_gss/gss_krb5_wrap.c | 1 -
> net/sunrpc/auth_gss/svcauth_gss.c | 2 +-
> net/sunrpc/backchannel_rqst.c | 1 -
> net/sunrpc/clnt.c | 2 +-
> net/sunrpc/rpcb_clnt.c | 2 +-
> net/sunrpc/stats.c | 1 -
> net/sunrpc/sunrpc.h | 1 -
> net/sunrpc/xprt.c | 2 +-
> net/sunrpc/xprtsock.c | 1 -
> 15 files changed, 5 insertions(+), 15 deletions(-)
>
> diff --git a/net/sunrpc/auth_gss/auth_gss.c b/net/sunrpc/auth_gss/auth_gss.c
> index be8f103d22fd..b67ad98a36a6 100644
> --- a/net/sunrpc/auth_gss/auth_gss.c
> +++ b/net/sunrpc/auth_gss/auth_gss.c
> @@ -1571,7 +1571,7 @@ static int gss_cred_is_negative_entry(struct rpc_cred *cred)
> if (test_bit(RPCAUTH_CRED_NEGATIVE, &cred->cr_flags)) {
> unsigned long now = jiffies;
> unsigned long begin, expire;
> - struct gss_cred *gss_cred;
> + struct gss_cred *gss_cred;
>
> gss_cred = container_of(cred, struct gss_cred, gc_base);
> begin = gss_cred->gc_upcall_timestamp;
> diff --git a/net/sunrpc/auth_gss/gss_generic_token.c b/net/sunrpc/auth_gss/gss_generic_token.c
> index 254defe446a7..fe97f3106536 100644
> --- a/net/sunrpc/auth_gss/gss_generic_token.c
> +++ b/net/sunrpc/auth_gss/gss_generic_token.c
> @@ -231,4 +231,3 @@ g_verify_token_header(struct xdr_netobj *mech, int *body_size,
> }
>
> EXPORT_SYMBOL_GPL(g_verify_token_header);
> -
> diff --git a/net/sunrpc/auth_gss/gss_krb5_crypto.c b/net/sunrpc/auth_gss/gss_krb5_crypto.c
> index 8654494b4d0a..a1acee106faa 100644
> --- a/net/sunrpc/auth_gss/gss_krb5_crypto.c
> +++ b/net/sunrpc/auth_gss/gss_krb5_crypto.c
> @@ -1077,4 +1077,3 @@ krb5_rc4_setup_enc_key(struct krb5_ctx *kctx, struct crypto_skcipher *cipher,
> dprintk("%s: returning %d\n", __func__, err);
> return err;
> }
> -
> diff --git a/net/sunrpc/auth_gss/gss_krb5_keys.c b/net/sunrpc/auth_gss/gss_krb5_keys.c
> index 870133146026..f7fe2d2b851f 100644
> --- a/net/sunrpc/auth_gss/gss_krb5_keys.c
> +++ b/net/sunrpc/auth_gss/gss_krb5_keys.c
> @@ -324,4 +324,3 @@ u32 gss_krb5_aes_make_key(const struct gss_krb5_enctype *gk5e,
> err_out:
> return ret;
> }
> -
> diff --git a/net/sunrpc/auth_gss/gss_krb5_seal.c b/net/sunrpc/auth_gss/gss_krb5_seal.c
> index 94a2b3f082a8..eaad9bc7a0bd 100644
> --- a/net/sunrpc/auth_gss/gss_krb5_seal.c
> +++ b/net/sunrpc/auth_gss/gss_krb5_seal.c
> @@ -229,4 +229,3 @@ gss_get_mic_kerberos(struct gss_ctx *gss_ctx, struct xdr_buf *text,
> return gss_get_mic_v2(ctx, text, token);
> }
> }
> -
> diff --git a/net/sunrpc/auth_gss/gss_krb5_unseal.c b/net/sunrpc/auth_gss/gss_krb5_unseal.c
> index b601a73cc9db..ef2b25b86d2f 100644
> --- a/net/sunrpc/auth_gss/gss_krb5_unseal.c
> +++ b/net/sunrpc/auth_gss/gss_krb5_unseal.c
> @@ -225,4 +225,3 @@ gss_verify_mic_kerberos(struct gss_ctx *gss_ctx,
> return gss_verify_mic_v2(ctx, message_buffer, read_token);
> }
> }
> -
> diff --git a/net/sunrpc/auth_gss/gss_krb5_wrap.c b/net/sunrpc/auth_gss/gss_krb5_wrap.c
> index a737c2da0837..286fd22404f2 100644
> --- a/net/sunrpc/auth_gss/gss_krb5_wrap.c
> +++ b/net/sunrpc/auth_gss/gss_krb5_wrap.c
> @@ -623,4 +623,3 @@ gss_unwrap_kerberos(struct gss_ctx *gctx, int offset, struct xdr_buf *buf)
> return gss_unwrap_kerberos_v2(kctx, offset, buf);
> }
> }
> -
> diff --git a/net/sunrpc/auth_gss/svcauth_gss.c b/net/sunrpc/auth_gss/svcauth_gss.c
> index 5089dbb96d58..860f2a1bbb67 100644
> --- a/net/sunrpc/auth_gss/svcauth_gss.c
> +++ b/net/sunrpc/auth_gss/svcauth_gss.c
> @@ -1389,7 +1389,7 @@ static void destroy_use_gss_proxy_proc_entry(struct net *net)
> struct sunrpc_net *sn = net_generic(net, sunrpc_net_id);
>
> if (sn->use_gssp_proc) {
> - remove_proc_entry("use-gss-proxy", sn->proc_net_rpc);
> + remove_proc_entry("use-gss-proxy", sn->proc_net_rpc);
> clear_gssp_clnt(sn);
> }
> }
> diff --git a/net/sunrpc/backchannel_rqst.c b/net/sunrpc/backchannel_rqst.c
> index c2c68a15b59d..3c15a99b9700 100644
> --- a/net/sunrpc/backchannel_rqst.c
> +++ b/net/sunrpc/backchannel_rqst.c
> @@ -362,4 +362,3 @@ void xprt_complete_bc_request(struct rpc_rqst *req, uint32_t copied)
> wake_up(&bc_serv->sv_cb_waitq);
> spin_unlock(&bc_serv->sv_cb_lock);
> }
> -
> diff --git a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c
> index d839c33ae7d9..3818e4d55c66 100644
> --- a/net/sunrpc/clnt.c
> +++ b/net/sunrpc/clnt.c
> @@ -892,7 +892,7 @@ rpc_free_client(struct rpc_clnt *clnt)
> /*
> * Free an RPC client
> */
> -static struct rpc_clnt *
> +static struct rpc_clnt *
> rpc_free_auth(struct rpc_clnt *clnt)
> {
> if (clnt->cl_auth == NULL)
> diff --git a/net/sunrpc/rpcb_clnt.c b/net/sunrpc/rpcb_clnt.c
> index c526f8fb37c9..c7872bc13860 100644
> --- a/net/sunrpc/rpcb_clnt.c
> +++ b/net/sunrpc/rpcb_clnt.c
> @@ -213,7 +213,7 @@ static void rpcb_set_local(struct net *net, struct rpc_clnt *clnt,
> sn->rpcb_local_clnt = clnt;
> sn->rpcb_local_clnt4 = clnt4;
> sn->rpcb_is_af_local = is_af_local ? 1 : 0;
> - smp_wmb();
> + smp_wmb();
> sn->rpcb_users = 1;
> dprintk("RPC: created new rpcb local clients (rpcb_local_clnt: "
> "%p, rpcb_local_clnt4: %p) for net %x%s\n",
> diff --git a/net/sunrpc/stats.c b/net/sunrpc/stats.c
> index f68aa46c9dd7..86f316503c7c 100644
> --- a/net/sunrpc/stats.c
> +++ b/net/sunrpc/stats.c
> @@ -310,4 +310,3 @@ void rpc_proc_exit(struct net *net)
> dprintk("RPC: unregistering /proc/net/rpc\n");
> remove_proc_entry("rpc", net->proc_net);
> }
> -
> diff --git a/net/sunrpc/sunrpc.h b/net/sunrpc/sunrpc.h
> index 09a0315ea77b..c9bacb3c930f 100644
> --- a/net/sunrpc/sunrpc.h
> +++ b/net/sunrpc/sunrpc.h
> @@ -57,4 +57,3 @@ int svc_send_common(struct socket *sock, struct xdr_buf *xdr,
> int rpc_clients_notifier_register(void);
> void rpc_clients_notifier_unregister(void);
> #endif /* _NET_SUNRPC_SUNRPC_H */
> -
> diff --git a/net/sunrpc/xprt.c b/net/sunrpc/xprt.c
> index 3fabf9f6a0f9..a8db2e3f8904 100644
> --- a/net/sunrpc/xprt.c
> +++ b/net/sunrpc/xprt.c
> @@ -880,7 +880,7 @@ static void xprt_wait_on_pinned_rqst(struct rpc_rqst *req)
> __must_hold(&req->rq_xprt->recv_lock)
> {
> struct rpc_task *task = req->rq_task;
> -
> +
> if (task && test_bit(RPC_TASK_MSG_RECV, &task->tk_runstate)) {
> spin_unlock(&req->rq_xprt->recv_lock);
> set_bit(RPC_TASK_MSG_RECV_WAIT, &task->tk_runstate);
> diff --git a/net/sunrpc/xprtsock.c b/net/sunrpc/xprtsock.c
> index 9e1c5024aba9..6b7539c0466e 100644
> --- a/net/sunrpc/xprtsock.c
> +++ b/net/sunrpc/xprtsock.c
> @@ -3375,4 +3375,3 @@ module_param_named(tcp_max_slot_table_entries, xprt_max_tcp_slot_table_entries,
> max_slot_table_size, 0644);
> module_param_named(udp_slot_table_entries, xprt_udp_slot_table_entries,
> slot_table_size, 0644);
> -
>
^ permalink raw reply
* Re: [iproute PATCH] lib/namespace: avoid double-mounting a /sys
From: Stephen Hemminger @ 2018-07-27 20:45 UTC (permalink / raw)
To: Lubomir Rintel; +Cc: netdev, Phil Sutter
In-Reply-To: <20180724172638.760873-1-lkundrak@v3.sk>
On Tue, 24 Jul 2018 19:26:38 +0200
Lubomir Rintel <lkundrak@v3.sk> wrote:
> This partly reverts 8f0807023d067e2bb585a2ae8da93e59689d10f1, bringing
> back the umount(/sys) attempt.
>
> In a LXC container we're unable to umount the sysfs instance, nor mount
> a read-write one. We still are able to create a new read-only instance.
>
> Nevertheless, it still makes sense to attempt the umount() even though
> the sysfs is mounted read-only. Otherwise we may end up attempting to
> mount a sysfs with the same flags as is already mounted, resulting in
> an EBUSY error (meaning "Already mounted").
>
> Perhaps this is not a very likely scenario in real world, but we hit
> it in NetworkManager test suite and makes netns_switch() somewhat more
> robust. It also fixes the case, when /sys wasn't mounted at all.
>
> Signed-off-by: Lubomir Rintel <lkundrak@v3.sk>
Makes sens applied.
^ permalink raw reply
* [PATCHi iproute2-next] ip: show min and max mtu
From: Stephen Hemminger @ 2018-07-27 20:43 UTC (permalink / raw)
To: netdev; +Cc: Stephen Hemminger, Stephen Hemminger
From: Stephen Hemminger <sthemmin@microsoft.com>
Add min/max MTU to the link details
Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
include/uapi/linux/if_link.h | 2 ++
ip/ipaddress.c | 10 ++++++++++
2 files changed, 12 insertions(+)
diff --git a/include/uapi/linux/if_link.h b/include/uapi/linux/if_link.h
index 26e8cf8b45aa..8456ff254015 100644
--- a/include/uapi/linux/if_link.h
+++ b/include/uapi/linux/if_link.h
@@ -164,6 +164,8 @@ enum {
IFLA_CARRIER_UP_COUNT,
IFLA_CARRIER_DOWN_COUNT,
IFLA_NEW_IFINDEX,
+ IFLA_MIN_MTU,
+ IFLA_MAX_MTU,
__IFLA_MAX
};
diff --git a/ip/ipaddress.c b/ip/ipaddress.c
index bcee9ab731ce..85958e1a9cef 100644
--- a/ip/ipaddress.c
+++ b/ip/ipaddress.c
@@ -1012,6 +1012,16 @@ int print_linkinfo(const struct sockaddr_nl *who,
" promiscuity %u ",
rta_getattr_u32(tb[IFLA_PROMISCUITY]));
+ if (tb[IFLA_MIN_MTU])
+ print_uint(PRINT_ANY,
+ "min_mtu", "minmtu %u ",
+ rta_getattr_u32(tb[IFLA_MIN_MTU]));
+
+ if (tb[IFLA_MAX_MTU])
+ print_uint(PRINT_ANY,
+ "max_mtu", "maxmtu %u ",
+ rta_getattr_u32(tb[IFLA_MAX_MTU]));
+
if (tb[IFLA_LINKINFO])
print_linktype(fp, tb[IFLA_LINKINFO]);
--
2.18.0
^ permalink raw reply related
* [PATCH net-next 3/3] net: report invalid mtu value via netlink extack
From: Stephen Hemminger @ 2018-07-27 20:43 UTC (permalink / raw)
To: netdev; +Cc: Stephen Hemminger, Stephen Hemminger
In-Reply-To: <20180727204323.19408-1-sthemmin@microsoft.com>
If an invalid MTU value is set through rtnetlink return extra error
information instead of putting message in kernel log. For other cases
where there is no visible API, keep the error report in the log.
Example:
# ip li set dev enp12s0 mtu 10000
Error: mtu greater than device maximum.
# ifconfig enp12s0 mtu 10000
SIOCSIFMTU: Invalid argument
# dmesg | tail -1
[ 2047.795467] enp12s0: mtu greater than device maximum
Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
include/linux/netdevice.h | 2 ++
net/core/dev.c | 23 +++++++++++++++++------
net/core/rtnetlink.c | 2 +-
3 files changed, 20 insertions(+), 7 deletions(-)
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index c1295c7a452e..9c917467a2c7 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -3546,6 +3546,8 @@ int dev_set_alias(struct net_device *, const char *, size_t);
int dev_get_alias(const struct net_device *, char *, size_t);
int dev_change_net_namespace(struct net_device *, struct net *, const char *);
int __dev_set_mtu(struct net_device *, int);
+int dev_set_mtu_ext(struct net_device *dev, int mtu,
+ struct netlink_ext_ack *extack);
int dev_set_mtu(struct net_device *, int);
int dev_change_tx_queue_len(struct net_device *, unsigned long);
void dev_set_group(struct net_device *, int);
diff --git a/net/core/dev.c b/net/core/dev.c
index 87c42c8249ae..89031b5fef9f 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -7523,13 +7523,15 @@ int __dev_set_mtu(struct net_device *dev, int new_mtu)
EXPORT_SYMBOL(__dev_set_mtu);
/**
- * dev_set_mtu - Change maximum transfer unit
+ * dev_set_mtu_ext - Change maximum transfer unit
* @dev: device
* @new_mtu: new transfer unit
+ * @extack: netlink extended ack
*
* Change the maximum transfer size of the network device.
*/
-int dev_set_mtu(struct net_device *dev, int new_mtu)
+int dev_set_mtu_ext(struct net_device *dev, int new_mtu,
+ struct netlink_ext_ack *extack)
{
int err, orig_mtu;
@@ -7538,14 +7540,12 @@ int dev_set_mtu(struct net_device *dev, int new_mtu)
/* MTU must be positive, and in range */
if (new_mtu < 0 || new_mtu < dev->min_mtu) {
- net_err_ratelimited("%s: Invalid MTU %d requested, hw min %d\n",
- dev->name, new_mtu, dev->min_mtu);
+ NL_SET_ERR_MSG(extack, "mtu less than device minimum");
return -EINVAL;
}
if (dev->max_mtu > 0 && new_mtu > dev->max_mtu) {
- net_err_ratelimited("%s: Invalid MTU %d requested, hw max %d\n",
- dev->name, new_mtu, dev->max_mtu);
+ NL_SET_ERR_MSG(extack, "mtu greater than device maximum");
return -EINVAL;
}
@@ -7573,6 +7573,17 @@ int dev_set_mtu(struct net_device *dev, int new_mtu)
}
return err;
}
+
+int dev_set_mtu(struct net_device *dev, int new_mtu)
+{
+ struct netlink_ext_ack extack;
+ int err;
+
+ err = dev_set_mtu_ext(dev, new_mtu, &extack);
+ if (err)
+ net_err_ratelimited("%s: %s\n", dev->name, extack._msg);
+ return err;
+}
EXPORT_SYMBOL(dev_set_mtu);
/**
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c
index 510d4f765a13..24431e578310 100644
--- a/net/core/rtnetlink.c
+++ b/net/core/rtnetlink.c
@@ -2382,7 +2382,7 @@ static int do_setlink(const struct sk_buff *skb,
}
if (tb[IFLA_MTU]) {
- err = dev_set_mtu(dev, nla_get_u32(tb[IFLA_MTU]));
+ err = dev_set_mtu_ext(dev, nla_get_u32(tb[IFLA_MTU]), extack);
if (err < 0)
goto errout;
status |= DO_SETLINK_MODIFIED;
--
2.18.0
^ permalink raw reply related
* [PATCH net-next 2/3] net: report min and max mtu network device settings
From: Stephen Hemminger @ 2018-07-27 20:43 UTC (permalink / raw)
To: netdev; +Cc: Stephen Hemminger, Stephen Hemminger
In-Reply-To: <20180727204323.19408-1-sthemmin@microsoft.com>
Report the minimum and maximum MTU allowed on a device
via netlink so that it can be displayed by tools like
ip link.
Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
include/uapi/linux/if_link.h | 2 ++
net/core/rtnetlink.c | 6 ++++++
2 files changed, 8 insertions(+)
diff --git a/include/uapi/linux/if_link.h b/include/uapi/linux/if_link.h
index 01b5069a73a5..1fea3ff73bf6 100644
--- a/include/uapi/linux/if_link.h
+++ b/include/uapi/linux/if_link.h
@@ -164,6 +164,8 @@ enum {
IFLA_CARRIER_UP_COUNT,
IFLA_CARRIER_DOWN_COUNT,
IFLA_NEW_IFINDEX,
+ IFLA_MIN_MTU,
+ IFLA_MAX_MTU,
__IFLA_MAX
};
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c
index 92b6fa5d5f6e..510d4f765a13 100644
--- a/net/core/rtnetlink.c
+++ b/net/core/rtnetlink.c
@@ -1015,6 +1015,8 @@ static noinline size_t if_nlmsg_size(const struct net_device *dev,
+ nla_total_size(4) /* IFLA_IF_NETNSID */
+ nla_total_size(4) /* IFLA_CARRIER_UP_COUNT */
+ nla_total_size(4) /* IFLA_CARRIER_DOWN_COUNT */
+ + nla_total_size(4) /* IFLA_MIN_MTU */
+ + nla_total_size(4) /* IFLA_MAX_MTU */
+ 0;
}
@@ -1601,6 +1603,8 @@ static int rtnl_fill_ifinfo(struct sk_buff *skb,
netif_running(dev) ? dev->operstate : IF_OPER_DOWN) ||
nla_put_u8(skb, IFLA_LINKMODE, dev->link_mode) ||
nla_put_u32(skb, IFLA_MTU, dev->mtu) ||
+ nla_put_u32(skb, IFLA_MIN_MTU, dev->min_mtu) ||
+ nla_put_u32(skb, IFLA_MAX_MTU, dev->max_mtu) ||
nla_put_u32(skb, IFLA_GROUP, dev->group) ||
nla_put_u32(skb, IFLA_PROMISCUITY, dev->promiscuity) ||
nla_put_u32(skb, IFLA_NUM_TX_QUEUES, dev->num_tx_queues) ||
@@ -1732,6 +1736,8 @@ static const struct nla_policy ifla_policy[IFLA_MAX+1] = {
[IFLA_IF_NETNSID] = { .type = NLA_S32 },
[IFLA_CARRIER_UP_COUNT] = { .type = NLA_U32 },
[IFLA_CARRIER_DOWN_COUNT] = { .type = NLA_U32 },
+ [IFLA_MIN_MTU] = { .type = NLA_U32 },
+ [IFLA_MAX_MTU] = { .type = NLA_U32 },
};
static const struct nla_policy ifla_info_policy[IFLA_INFO_MAX+1] = {
--
2.18.0
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox