Skip to content
/ linux Public
forked from torvalds/linux

Commit

Permalink
Merge branch 'tunnel-offload-future-proof'
Browse files Browse the repository at this point in the history
Alexander Duyck says:

====================
Future-proof tunnel offload handlers

These patches are meant to address two things.  First we are currently
using the ndo_add/del_vxlan_port calls with VXLAN-GPE tunnels and we
cannot really support that as it is likely to cause more harm than
good since VXLAN-GPE can support tunnels without a MAC address on the
inner header.

As such we need to add a new offload to advertise this, but in doing so it
would mean introducing 3 new functions for the driver to request the ports,
and then for the tunnel to push the changes to add and delete the ports to
the device.  However instead of taking that approach I think it would be
much better if we just made one common function for fetching the ports, and
provided a generic means to push the tunnels to the device.  So in order to
make this work this patch set does several things.

First it merges the existing VXLAN and GENEVE functionality into one set of
functions and passes an enum in order to specify the type of tunnel we want
to offload.  By doing this we only have to extend this enum in the future
if we want to add additional types.

Second it goes through the drivers replacing all of the tunnel specific
offload calls with implementations that support the generic calls so that
we can drop the VXLAN and GENEVE specific calls entirely.

Finally I go through in the last patch and replace the VXLAN specific
offload request that was being used for VXLAN-GPE with one that specifies
if we want to offload VXLAN or VXLAN-GPE so that the hardware can decide if
it can actually support it or not.

I also ended up with some minor clean-up built into the driver patches for
this.  Most of it is to either fix misuse of build flags, specifying a type
to ignore instead of the type that should be used, or in the case of ixgbe
I actually moved a rtnl_lock/unlock in order to avoid taking it unless it
was actually needed.

v2:
I did my best to remove the word "offload" from any of the calls or
notifiers as this isn't really an offload.  It
 is a workaround for the fact that the drivers don't provide basic features
like CHECKSUM_COMPLETE.  I also added a disclaimer to the section defining
the function prototypes explaining that these are essentially workarounds.

I ended up going through and stripping all of the VXLAN and GENEVE build
flags from the drivers.  There isn't much point in carrying them.  In
addition I dropped the use of the vxlan.h or geneve.h header files in favor
of udp_tunnel.h in the cases where a driver didn't need anything from
either of those headers.

I updated the tunnel add/del functions so that they pass a udp_tunnel_info
structure instead of a list of arguments.  This way we should be able to
add additional information in the future with little impact on the other
drivers.

I updated bnxt so that it doesn't use a hard-coded port number for GENEVE.

I have been able to test mlx4e, mlx5e, and i40e and verified functionality
on these drivers.  Though there are patches for the net tree I submitted
due to unrelated bugs I found in the mlx4e and i40e/i40evf drivers.

v3:
Fixed a typo that caused us to add geneve port when we should have been
deleting it.

Ended up dropping geneve and vxlan wrappers for
udp_tunnel_notify_rx_add/del_port and instead just called them directly.

Updated comments for functions to call out RTNL instead of port lock.

Updated patch description to remove changes that were moved into a second
patch.

Rebased on latest net-next to fix merge conflict on bnxt driver.
====================

Signed-off-by: David S. Miller <[email protected]>
  • Loading branch information
davem330 committed Jun 18, 2016
2 parents 9f6ed03 + b9adcd6 commit 832dfd1
Show file tree
Hide file tree
Showing 27 changed files with 477 additions and 709 deletions.
21 changes: 0 additions & 21 deletions drivers/net/ethernet/broadcom/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -139,26 +139,6 @@ config BNX2X_SRIOV
Virtualization support in the 578xx and 57712 products. This
allows for virtual function acceleration in virtual environments.

config BNX2X_VXLAN
bool "Virtual eXtensible Local Area Network support"
default n
depends on BNX2X && VXLAN && !(BNX2X=y && VXLAN=m)
---help---
This enables hardward offload support for VXLAN protocol over the
NetXtremeII series adapters.
Say Y here if you want to enable hardware offload support for
Virtual eXtensible Local Area Network (VXLAN) in the driver.

config BNX2X_GENEVE
bool "Generic Network Virtualization Encapsulation (GENEVE) support"
depends on BNX2X && GENEVE && !(BNX2X=y && GENEVE=m)
---help---
This allows one to create GENEVE virtual interfaces that provide
Layer 2 Networks over Layer 3 Networks. GENEVE is often used
to tunnel virtual network infrastructure in virtualized environments.
Say Y here if you want to enable hardware offload support for
Generic Network Virtualization Encapsulation (GENEVE) in the driver.

config BGMAC
tristate "BCMA bus GBit core support"
depends on BCMA && BCMA_HOST_SOC
Expand Down Expand Up @@ -186,7 +166,6 @@ config SYSTEMPORT
config BNXT
tristate "Broadcom NetXtreme-C/E support"
depends on PCI
depends on VXLAN || VXLAN=n
select FW_LOADER
select LIBCRC32C
---help---
Expand Down
94 changes: 33 additions & 61 deletions drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -59,9 +59,6 @@
#include <linux/semaphore.h>
#include <linux/stringify.h>
#include <linux/vmalloc.h>
#if IS_ENABLED(CONFIG_BNX2X_GENEVE)
#include <net/geneve.h>
#endif
#include "bnx2x.h"
#include "bnx2x_init.h"
#include "bnx2x_init_ops.h"
Expand Down Expand Up @@ -10076,7 +10073,6 @@ static void bnx2x_parity_recover(struct bnx2x *bp)
}
}

#if defined(CONFIG_BNX2X_VXLAN) || IS_ENABLED(CONFIG_BNX2X_GENEVE)
static int bnx2x_udp_port_update(struct bnx2x *bp)
{
struct bnx2x_func_switch_update_params *switch_update_params;
Expand Down Expand Up @@ -10177,47 +10173,42 @@ static void __bnx2x_del_udp_port(struct bnx2x *bp, u16 port,
DP(BNX2X_MSG_SP, "Deleted UDP tunnel [%d] port %d\n",
type, port);
}
#endif

#ifdef CONFIG_BNX2X_VXLAN
static void bnx2x_add_vxlan_port(struct net_device *netdev,
sa_family_t sa_family, __be16 port)
{
struct bnx2x *bp = netdev_priv(netdev);
u16 t_port = ntohs(port);

__bnx2x_add_udp_port(bp, t_port, BNX2X_UDP_PORT_VXLAN);
}

static void bnx2x_del_vxlan_port(struct net_device *netdev,
sa_family_t sa_family, __be16 port)
{
struct bnx2x *bp = netdev_priv(netdev);
u16 t_port = ntohs(port);

__bnx2x_del_udp_port(bp, t_port, BNX2X_UDP_PORT_VXLAN);
}
#endif

#if IS_ENABLED(CONFIG_BNX2X_GENEVE)
static void bnx2x_add_geneve_port(struct net_device *netdev,
sa_family_t sa_family, __be16 port)
static void bnx2x_udp_tunnel_add(struct net_device *netdev,
struct udp_tunnel_info *ti)
{
struct bnx2x *bp = netdev_priv(netdev);
u16 t_port = ntohs(port);
u16 t_port = ntohs(ti->port);

__bnx2x_add_udp_port(bp, t_port, BNX2X_UDP_PORT_GENEVE);
switch (ti->type) {
case UDP_TUNNEL_TYPE_VXLAN:
__bnx2x_add_udp_port(bp, t_port, BNX2X_UDP_PORT_VXLAN);
break;
case UDP_TUNNEL_TYPE_GENEVE:
__bnx2x_add_udp_port(bp, t_port, BNX2X_UDP_PORT_GENEVE);
break;
default:
break;
}
}

static void bnx2x_del_geneve_port(struct net_device *netdev,
sa_family_t sa_family, __be16 port)
static void bnx2x_udp_tunnel_del(struct net_device *netdev,
struct udp_tunnel_info *ti)
{
struct bnx2x *bp = netdev_priv(netdev);
u16 t_port = ntohs(port);
u16 t_port = ntohs(ti->port);

__bnx2x_del_udp_port(bp, t_port, BNX2X_UDP_PORT_GENEVE);
switch (ti->type) {
case UDP_TUNNEL_TYPE_VXLAN:
__bnx2x_del_udp_port(bp, t_port, BNX2X_UDP_PORT_VXLAN);
break;
case UDP_TUNNEL_TYPE_GENEVE:
__bnx2x_del_udp_port(bp, t_port, BNX2X_UDP_PORT_GENEVE);
break;
default:
break;
}
}
#endif

static int bnx2x_close(struct net_device *dev);

Expand Down Expand Up @@ -10325,7 +10316,6 @@ static void bnx2x_sp_rtnl_task(struct work_struct *work)
&bp->sp_rtnl_state))
bnx2x_update_mng_version(bp);

#if defined(CONFIG_BNX2X_VXLAN) || IS_ENABLED(CONFIG_BNX2X_GENEVE)
if (test_and_clear_bit(BNX2X_SP_RTNL_CHANGE_UDP_PORT,
&bp->sp_rtnl_state)) {
if (bnx2x_udp_port_update(bp)) {
Expand All @@ -10335,20 +10325,14 @@ static void bnx2x_sp_rtnl_task(struct work_struct *work)
BNX2X_UDP_PORT_MAX);
} else {
/* Since we don't store additional port information,
* if no port is configured for any feature ask for
* if no ports are configured for any feature ask for
* information about currently configured ports.
*/
#ifdef CONFIG_BNX2X_VXLAN
if (!bp->udp_tunnel_ports[BNX2X_UDP_PORT_VXLAN].count)
vxlan_get_rx_port(bp->dev);
#endif
#if IS_ENABLED(CONFIG_BNX2X_GENEVE)
if (!bp->udp_tunnel_ports[BNX2X_UDP_PORT_GENEVE].count)
geneve_get_rx_port(bp->dev);
#endif
if (!bp->udp_tunnel_ports[BNX2X_UDP_PORT_VXLAN].count &&
!bp->udp_tunnel_ports[BNX2X_UDP_PORT_GENEVE].count)
udp_tunnel_get_rx_info(bp->dev);
}
}
#endif

/* work which needs rtnl lock not-taken (as it takes the lock itself and
* can be called from other contexts as well)
Expand Down Expand Up @@ -12551,14 +12535,8 @@ static int bnx2x_open(struct net_device *dev)
if (rc)
return rc;

#ifdef CONFIG_BNX2X_VXLAN
if (IS_PF(bp))
vxlan_get_rx_port(dev);
#endif
#if IS_ENABLED(CONFIG_BNX2X_GENEVE)
if (IS_PF(bp))
geneve_get_rx_port(dev);
#endif
udp_tunnel_get_rx_info(dev);

return 0;
}
Expand Down Expand Up @@ -13045,14 +13023,8 @@ static const struct net_device_ops bnx2x_netdev_ops = {
.ndo_get_phys_port_id = bnx2x_get_phys_port_id,
.ndo_set_vf_link_state = bnx2x_set_vf_link_state,
.ndo_features_check = bnx2x_features_check,
#ifdef CONFIG_BNX2X_VXLAN
.ndo_add_vxlan_port = bnx2x_add_vxlan_port,
.ndo_del_vxlan_port = bnx2x_del_vxlan_port,
#endif
#if IS_ENABLED(CONFIG_BNX2X_GENEVE)
.ndo_add_geneve_port = bnx2x_add_geneve_port,
.ndo_del_geneve_port = bnx2x_del_geneve_port,
#endif
.ndo_udp_tunnel_add = bnx2x_udp_tunnel_add,
.ndo_udp_tunnel_del = bnx2x_udp_tunnel_del,
};

static int bnx2x_set_coherency_mask(struct bnx2x *bp)
Expand Down
104 changes: 70 additions & 34 deletions drivers/net/ethernet/broadcom/bnxt/bnxt.c
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,7 @@
#include <net/udp.h>
#include <net/checksum.h>
#include <net/ip6_checksum.h>
#if defined(CONFIG_VXLAN) || defined(CONFIG_VXLAN_MODULE)
#include <net/vxlan.h>
#endif
#include <net/udp_tunnel.h>
#ifdef CONFIG_NET_RX_BUSY_POLL
#include <net/busy_poll.h>
#endif
Expand Down Expand Up @@ -5255,15 +5253,8 @@ static int __bnxt_open_nic(struct bnxt *bp, bool irq_re_init, bool link_re_init)
netdev_warn(bp->dev, "failed to update phy settings\n");
}

if (irq_re_init) {
#if defined(CONFIG_VXLAN) || defined(CONFIG_VXLAN_MODULE)
vxlan_get_rx_port(bp->dev);
#endif
if (!bnxt_hwrm_tunnel_dst_port_alloc(
bp, htons(0x17c1),
TUNNEL_DST_PORT_FREE_REQ_TUNNEL_TYPE_GENEVE))
bp->nge_port_cnt = 1;
}
if (irq_re_init)
udp_tunnel_get_rx_info(bp->dev);

set_bit(BNXT_STATE_OPEN, &bp->state);
bnxt_enable_int(bp);
Expand Down Expand Up @@ -5881,6 +5872,15 @@ static void bnxt_sp_task(struct work_struct *work)
bnxt_hwrm_tunnel_dst_port_free(
bp, TUNNEL_DST_PORT_FREE_REQ_TUNNEL_TYPE_VXLAN);
}
if (test_and_clear_bit(BNXT_GENEVE_ADD_PORT_SP_EVENT, &bp->sp_event)) {
bnxt_hwrm_tunnel_dst_port_alloc(
bp, bp->nge_port,
TUNNEL_DST_PORT_FREE_REQ_TUNNEL_TYPE_GENEVE);
}
if (test_and_clear_bit(BNXT_GENEVE_DEL_PORT_SP_EVENT, &bp->sp_event)) {
bnxt_hwrm_tunnel_dst_port_free(
bp, TUNNEL_DST_PORT_FREE_REQ_TUNNEL_TYPE_GENEVE);
}
if (test_and_clear_bit(BNXT_RESET_TASK_SP_EVENT, &bp->sp_event))
bnxt_reset(bp, false);

Expand Down Expand Up @@ -6250,47 +6250,83 @@ static void bnxt_cfg_ntp_filters(struct bnxt *bp)

#endif /* CONFIG_RFS_ACCEL */

static void bnxt_add_vxlan_port(struct net_device *dev, sa_family_t sa_family,
__be16 port)
static void bnxt_udp_tunnel_add(struct net_device *dev,
struct udp_tunnel_info *ti)
{
struct bnxt *bp = netdev_priv(dev);

if (!netif_running(dev))
if (ti->sa_family != AF_INET6 && ti->sa_family != AF_INET)
return;

if (sa_family != AF_INET6 && sa_family != AF_INET)
if (!netif_running(dev))
return;

if (bp->vxlan_port_cnt && bp->vxlan_port != port)
return;
switch (ti->type) {
case UDP_TUNNEL_TYPE_VXLAN:
if (bp->vxlan_port_cnt && bp->vxlan_port != ti->port)
return;

bp->vxlan_port_cnt++;
if (bp->vxlan_port_cnt == 1) {
bp->vxlan_port = port;
set_bit(BNXT_VXLAN_ADD_PORT_SP_EVENT, &bp->sp_event);
schedule_work(&bp->sp_task);
bp->vxlan_port_cnt++;
if (bp->vxlan_port_cnt == 1) {
bp->vxlan_port = ti->port;
set_bit(BNXT_VXLAN_ADD_PORT_SP_EVENT, &bp->sp_event);
schedule_work(&bp->sp_task);
}
break;
case UDP_TUNNEL_TYPE_GENEVE:
if (bp->nge_port_cnt && bp->nge_port != ti->port)
return;

bp->nge_port_cnt++;
if (bp->nge_port_cnt == 1) {
bp->nge_port = ti->port;
set_bit(BNXT_GENEVE_ADD_PORT_SP_EVENT, &bp->sp_event);
}
break;
default:
return;
}

schedule_work(&bp->sp_task);
}

static void bnxt_del_vxlan_port(struct net_device *dev, sa_family_t sa_family,
__be16 port)
static void bnxt_udp_tunnel_del(struct net_device *dev,
struct udp_tunnel_info *ti)
{
struct bnxt *bp = netdev_priv(dev);

if (!netif_running(dev))
if (ti->sa_family != AF_INET6 && ti->sa_family != AF_INET)
return;

if (sa_family != AF_INET6 && sa_family != AF_INET)
if (!netif_running(dev))
return;

if (bp->vxlan_port_cnt && bp->vxlan_port == port) {
switch (ti->type) {
case UDP_TUNNEL_TYPE_VXLAN:
if (!bp->vxlan_port_cnt || bp->vxlan_port != ti->port)
return;
bp->vxlan_port_cnt--;

if (bp->vxlan_port_cnt == 0) {
set_bit(BNXT_VXLAN_DEL_PORT_SP_EVENT, &bp->sp_event);
schedule_work(&bp->sp_task);
}
if (bp->vxlan_port_cnt != 0)
return;

set_bit(BNXT_VXLAN_DEL_PORT_SP_EVENT, &bp->sp_event);
break;
case UDP_TUNNEL_TYPE_GENEVE:
if (!bp->nge_port_cnt || bp->nge_port != ti->port)
return;
bp->nge_port_cnt--;

if (bp->nge_port_cnt != 0)
return;

set_bit(BNXT_GENEVE_DEL_PORT_SP_EVENT, &bp->sp_event);
break;
default:
return;
}

schedule_work(&bp->sp_task);
}

static const struct net_device_ops bnxt_netdev_ops = {
Expand Down Expand Up @@ -6321,8 +6357,8 @@ static const struct net_device_ops bnxt_netdev_ops = {
#ifdef CONFIG_RFS_ACCEL
.ndo_rx_flow_steer = bnxt_rx_flow_steer,
#endif
.ndo_add_vxlan_port = bnxt_add_vxlan_port,
.ndo_del_vxlan_port = bnxt_del_vxlan_port,
.ndo_udp_tunnel_add = bnxt_udp_tunnel_add,
.ndo_udp_tunnel_del = bnxt_udp_tunnel_del,
#ifdef CONFIG_NET_RX_BUSY_POLL
.ndo_busy_poll = bnxt_busy_poll,
#endif
Expand Down
3 changes: 3 additions & 0 deletions drivers/net/ethernet/broadcom/bnxt/bnxt.h
Original file line number Diff line number Diff line change
Expand Up @@ -1049,6 +1049,7 @@ struct bnxt {
__be16 vxlan_port;
u8 vxlan_port_cnt;
__le16 vxlan_fw_dst_port_id;
__be16 nge_port;
u8 nge_port_cnt;
__le16 nge_fw_dst_port_id;
u8 port_partition_type;
Expand Down Expand Up @@ -1078,6 +1079,8 @@ struct bnxt {
#define BNXT_PERIODIC_STATS_SP_EVENT 9
#define BNXT_HWRM_PORT_MODULE_SP_EVENT 10
#define BNXT_RESET_TASK_SILENT_SP_EVENT 11
#define BNXT_GENEVE_ADD_PORT_SP_EVENT 12
#define BNXT_GENEVE_DEL_PORT_SP_EVENT 13

struct bnxt_pf_info pf;
#ifdef CONFIG_BNXT_SRIOV
Expand Down
8 changes: 0 additions & 8 deletions drivers/net/ethernet/emulex/benet/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,3 @@ config BE2NET_HWMON
---help---
Say Y here if you want to expose thermal sensor data on
be2net network adapter.

config BE2NET_VXLAN
bool "VXLAN offload support on be2net driver"
default y
depends on BE2NET && VXLAN && !(BE2NET=y && VXLAN=m)
---help---
Say Y here if you want to enable VXLAN offload support on
be2net driver.
Loading

0 comments on commit 832dfd1

Please sign in to comment.