[PATCH v5 5/5] i40e: Call geneve_get_rx_port to get the existing Geneve ports
This patch adds a call to geneve_get_rx_port in i40e so that when it comes up it can learn about the existing geneve tunnels. Signed-off-by: Anjali Singhai Jain --- drivers/net/ethernet/intel/i40e/i40e_main.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c b/drivers/net/ethernet/intel/i40e/i40e_main.c index 81a6693..11059be 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_main.c +++ b/drivers/net/ethernet/intel/i40e/i40e_main.c @@ -5339,6 +5339,9 @@ int i40e_open(struct net_device *netdev) #ifdef CONFIG_I40E_VXLAN vxlan_get_rx_port(netdev); #endif +#ifdef CONFIG_I40E_GENEVE + geneve_get_rx_port(netdev); +#endif return 0; } -- 1.8.1.4 -- To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v5 2/5] i40e: geneve tunnel offload support
This patch adds driver hooks to implement ndo_ops to add/del udp port in the HW to identify GENEVE tunnels. Signed-off-by: Anjali Singhai Jain Signed-off-by: Kiran Patil --- drivers/net/ethernet/intel/i40e/i40e.h | 16 +-- drivers/net/ethernet/intel/i40e/i40e_main.c | 167 ++-- drivers/net/ethernet/intel/i40e/i40e_txrx.c | 8 +- drivers/net/ethernet/intel/i40e/i40e_txrx.h | 2 +- 4 files changed, 150 insertions(+), 43 deletions(-) diff --git a/drivers/net/ethernet/intel/i40e/i40e.h b/drivers/net/ethernet/intel/i40e/i40e.h index b7bc014..c202f9b 100644 --- a/drivers/net/ethernet/intel/i40e/i40e.h +++ b/drivers/net/ethernet/intel/i40e/i40e.h @@ -245,6 +245,11 @@ struct i40e_tc_configuration { struct i40e_tc_info tc_info[I40E_MAX_TRAFFIC_CLASS]; }; +struct i40e_udp_port_config { + __be16 index; + u8 type; +}; + /* struct that defines the Ethernet device */ struct i40e_pf { struct pci_dev *pdev; @@ -281,11 +286,9 @@ struct i40e_pf { u32 fd_atr_cnt; u32 fd_tcp_rule; -#ifdef CONFIG_I40E_VXLAN - __be16 vxlan_ports[I40E_MAX_PF_UDP_OFFLOAD_PORTS]; - u16 pending_vxlan_bitmap; + struct i40e_udp_port_config udp_ports[I40E_MAX_PF_UDP_OFFLOAD_PORTS]; + u16 pending_udp_bitmap; -#endif enum i40e_interrupt_policy int_policy; u16 rx_itr_default; u16 tx_itr_default; @@ -322,9 +325,7 @@ struct i40e_pf { #define I40E_FLAG_FD_ATR_ENABLED BIT_ULL(22) #define I40E_FLAG_PTP BIT_ULL(25) #define I40E_FLAG_MFP_ENABLED BIT_ULL(26) -#ifdef CONFIG_I40E_VXLAN -#define I40E_FLAG_VXLAN_FILTER_SYNCBIT_ULL(27) -#endif +#define I40E_FLAG_UDP_FILTER_SYNC BIT_ULL(27) #define I40E_FLAG_PORT_ID_VALIDBIT_ULL(28) #define I40E_FLAG_DCB_CAPABLE BIT_ULL(29) #define I40E_FLAG_RSS_AQ_CAPABLE BIT_ULL(31) @@ -336,6 +337,7 @@ struct i40e_pf { #define I40E_FLAG_MULTIPLE_TCP_UDP_RSS_PCTYPE BIT_ULL(38) #define I40E_FLAG_LINK_POLLING_ENABLED BIT_ULL(39) #define I40E_FLAG_VEB_MODE_ENABLED BIT_ULL(40) +#define I40E_FLAG_GENEVE_OFFLOAD_CAPABLE BIT_ULL(41) #define I40E_FLAG_NO_PCI_LINK_CHECKBIT_ULL(42) /* tracks features that get auto disabled by errors */ diff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c b/drivers/net/ethernet/intel/i40e/i40e_main.c index b118deb..81a6693 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_main.c +++ b/drivers/net/ethernet/intel/i40e/i40e_main.c @@ -27,9 +27,12 @@ /* Local includes */ #include "i40e.h" #include "i40e_diag.h" -#ifdef CONFIG_I40E_VXLAN +#if IS_ENABLED(CONFIG_VXLAN) #include #endif +#if IS_ENABLED(CONFIG_GENEVE) +#include +#endif const char i40e_driver_name[] = "i40e"; static const char i40e_driver_string[] = @@ -7036,30 +7039,30 @@ static void i40e_handle_mdd_event(struct i40e_pf *pf) i40e_flush(hw); } -#ifdef CONFIG_I40E_VXLAN /** - * i40e_sync_vxlan_filters_subtask - Sync the VSI filter list with HW + * i40e_sync_udp_filters_subtask - Sync the VSI filter list with HW * @pf: board private structure **/ -static void i40e_sync_vxlan_filters_subtask(struct i40e_pf *pf) +static void i40e_sync_udp_filters_subtask(struct i40e_pf *pf) { +#if IS_ENABLED(CONFIG_VXLAN) || IS_ENABLED(CONFIG_GENEVE) struct i40e_hw *hw = &pf->hw; i40e_status ret; __be16 port; int i; - if (!(pf->flags & I40E_FLAG_VXLAN_FILTER_SYNC)) + if (!(pf->flags & I40E_FLAG_UDP_FILTER_SYNC)) return; - pf->flags &= ~I40E_FLAG_VXLAN_FILTER_SYNC; + pf->flags &= ~I40E_FLAG_UDP_FILTER_SYNC; for (i = 0; i < I40E_MAX_PF_UDP_OFFLOAD_PORTS; i++) { - if (pf->pending_vxlan_bitmap & BIT_ULL(i)) { - pf->pending_vxlan_bitmap &= ~BIT_ULL(i); - port = pf->vxlan_ports[i]; + if (pf->pending_udp_bitmap & BIT_ULL(i)) { + pf->pending_udp_bitmap &= ~BIT_ULL(i); + port = pf->udp_ports[i].index; if (port) ret = i40e_aq_add_udp_tunnel(hw, ntohs(port), -I40E_AQC_TUNNEL_TYPE_VXLAN, +pf->udp_ports[i].type, NULL, NULL); else ret = i40e_aq_del_udp_tunnel(hw, i, NULL); @@ -7072,13 +7075,13 @@ static void i40e_sync_vxlan_filters_subtask(struct i40e_pf *pf) i40e_stat_str(&pf->hw, ret), i40e_aq_str(&pf->hw,
[PATCH v5 1/5] geneve: Add geneve udp port offload for ethernet devices
Add ndo_ops to add/del UDP ports to a device that supports geneve offload. v2: Comment fix. Signed-off-by: Anjali Singhai Jain Signed-off-by: Kiran Patil --- drivers/net/geneve.c | 23 +++ include/linux/netdevice.h | 20 +++- 2 files changed, 42 insertions(+), 1 deletion(-) diff --git a/drivers/net/geneve.c b/drivers/net/geneve.c index 0750d7a..89325e4 100644 --- a/drivers/net/geneve.c +++ b/drivers/net/geneve.c @@ -380,8 +380,11 @@ static struct socket *geneve_create_sock(struct net *net, bool ipv6, static void geneve_notify_add_rx_port(struct geneve_sock *gs) { + struct net_device *dev; struct sock *sk = gs->sock->sk; + struct net *net = sock_net(sk); sa_family_t sa_family = sk->sk_family; + __be16 port = inet_sk(sk)->inet_sport; int err; if (sa_family == AF_INET) { @@ -390,6 +393,14 @@ static void geneve_notify_add_rx_port(struct geneve_sock *gs) pr_warn("geneve: udp_add_offload failed with status %d\n", err); } + + rcu_read_lock(); + for_each_netdev_rcu(net, dev) { + if (dev->netdev_ops->ndo_add_geneve_port) + dev->netdev_ops->ndo_add_geneve_port(dev, sa_family, +port); + } + rcu_read_unlock(); } static int geneve_hlen(struct genevehdr *gh) @@ -530,8 +541,20 @@ static struct geneve_sock *geneve_socket_create(struct net *net, __be16 port, static void geneve_notify_del_rx_port(struct geneve_sock *gs) { + struct net_device *dev; struct sock *sk = gs->sock->sk; + struct net *net = sock_net(sk); sa_family_t sa_family = sk->sk_family; + __be16 port = inet_sk(sk)->inet_sport; + + rcu_read_lock(); + for_each_netdev_rcu(net, dev) { + if (dev->netdev_ops->ndo_del_geneve_port) + dev->netdev_ops->ndo_del_geneve_port(dev, sa_family, +port); + } + + rcu_read_unlock(); if (sa_family == AF_INET) udp_del_offload(&gs->udp_offloads); diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index 1bb21ff..82065a7 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h @@ -1013,6 +1013,19 @@ typedef u16 (*select_queue_fallback_t)(struct net_device *dev, * a new port starts listening. The operation is protected by the * vxlan_net->sock_lock. * + * void (*ndo_add_geneve_port)(struct net_device *dev, + * sa_family_t sa_family, __be16 port); + * Called by geneve to notify a driver about the UDP port and socket + * address family that geneve is listnening to. It is called only when + * a new port starts listening. The operation is protected by the + * geneve_net->sock_lock. + * + * void (*ndo_del_geneve_port)(struct net_device *dev, + * sa_family_t sa_family, __be16 port); + * Called by geneve to notify the driver about a UDP port and socket + * address family that geneve is not listening to anymore. The operation + * is protected by the geneve_net->sock_lock. + * * void (*ndo_del_vxlan_port)(struct net_device *dev, * sa_family_t sa_family, __be16 port); * Called by vxlan to notify the driver about a UDP port and socket @@ -1217,7 +1230,12 @@ struct net_device_ops { void(*ndo_del_vxlan_port)(struct net_device *dev, sa_family_t sa_family, __be16 port); - + void(*ndo_add_geneve_port)(struct net_device *dev, + sa_family_t sa_family, + __be16 port); + void(*ndo_del_geneve_port)(struct net_device *dev, + sa_family_t sa_family, + __be16 port); void* (*ndo_dfwd_add_station)(struct net_device *pdev, struct net_device *dev); void(*ndo_dfwd_del_station)(struct net_device *pdev, -- 1.8.1.4 -- To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v5 3/5] i40e: Kernel dependency update for i40e to support geneve offload
Update the Kconfig file with dependency for supporting GENEVE tunnel offloads. Signed-off-by: Anjali Singhai Jain Signed-off-by: Kiran Patil --- drivers/net/ethernet/intel/Kconfig | 10 ++ 1 file changed, 10 insertions(+) diff --git a/drivers/net/ethernet/intel/Kconfig b/drivers/net/ethernet/intel/Kconfig index 4163b16..fa593dd 100644 --- a/drivers/net/ethernet/intel/Kconfig +++ b/drivers/net/ethernet/intel/Kconfig @@ -280,6 +280,16 @@ config I40E_VXLAN Say Y here if you want to use Virtual eXtensible Local Area Network (VXLAN) in the driver. +config I40E_GENEVE + bool "Generic Network Virtualization Encapsulation (GENEVE) Support" + depends on I40E && GENEVE && !(I40E=y && GENEVE=m) + default n + ---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 use GENEVE in the driver. + config I40E_DCB bool "Data Center Bridging (DCB) Support" default n -- 1.8.1.4 -- To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v5 0/5] Add support for Geneve udp port offload
This patch series adds new ndo ops for Geneve add/del port, so as to help offload Geneve tunnel functionalities such as RX checksum, RSS, filters etc. i40e driver has been tested with the changes to make sure the offloads happen. We do understand that this is not the ideal solution and most likely will be redone with a more generic offload framework. But this certainly will enable us to start seeing benefits of the accelerations for Geneve tunnels. As a side note, we did find an existing issue in i40e driver where a service task can modify tunnel data structures with no locks held to help linearize access. A separate patch will be taking care of that issue. A question out to the community is regarding the driver Kconfig parameters for VxLAN and Geneve, it would be ideal to drop those if there is a way to help resolve vxlan/geneve_get_rx_port symbols while the tunnel modules are not loaded. Performance numbers: With the offloads enable on X722 devices with remote checksum enabled and no other tuning in terms of cpu governer etc on my test machine: With offload Throughput: 5527Mbits/sec with a single thread %cpu: ~43% per core with 4 threads Without offload Throughput: 2364Mbits/sec with a single thread %cpu: ~99% per core with 4 threads These numbers will get better for X722 as it is being worked. But this does bring out the delta in terms of when the stack is notified with csum_level 1 and CHECKSUM_UNNECESSARY vs not without the RX offload. --- v2: Comment fix. v3: Add Performance data. v4: Comment fix and split a patch into two. v5: Add cover letter. Anjali Singhai Jain (5): geneve: Add geneve udp port offload for ethernet devices i40e: geneve tunnel offload support i40e: Kernel dependency update for i40e to support geneve offload geneve: Add geneve_get_rx_port support i40e: Call geneve_get_rx_port to get the existing Geneve ports drivers/net/ethernet/intel/Kconfig | 10 ++ drivers/net/ethernet/intel/i40e/i40e.h | 16 +-- drivers/net/ethernet/intel/i40e/i40e_main.c | 170 +++- drivers/net/ethernet/intel/i40e/i40e_txrx.c | 8 +- drivers/net/ethernet/intel/i40e/i40e_txrx.h | 2 +- drivers/net/geneve.c| 47 include/linux/netdevice.h | 20 +++- include/net/geneve.h| 8 ++ 8 files changed, 237 insertions(+), 44 deletions(-) -- 1.8.1.4 -- To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v5 4/5] geneve: Add geneve_get_rx_port support
This patch adds an op that the drivers can call into to get existing geneve ports. Signed-off-by: Anjali Singhai Jain --- drivers/net/geneve.c | 24 include/net/geneve.h | 8 2 files changed, 32 insertions(+) diff --git a/drivers/net/geneve.c b/drivers/net/geneve.c index 89325e4..31b19fd 100644 --- a/drivers/net/geneve.c +++ b/drivers/net/geneve.c @@ -1109,6 +1109,30 @@ static struct device_type geneve_type = { .name = "geneve", }; +/* Calls the ndo_add_geneve_port of the caller in order to + * supply the listening GENEVE udp ports. Callers are expected + * to implement the ndo_add_geneve_port. + */ +void geneve_get_rx_port(struct net_device *dev) +{ + struct net *net = dev_net(dev); + struct geneve_net *gn = net_generic(net, geneve_net_id); + struct geneve_sock *gs; + sa_family_t sa_family; + struct sock *sk; + __be16 port; + + rcu_read_lock(); + list_for_each_entry_rcu(gs, &gn->sock_list, list) { + sk = gs->sock->sk; + sa_family = sk->sk_family; + port = inet_sk(sk)->inet_sport; + dev->netdev_ops->ndo_add_geneve_port(dev, sa_family, port); + } + rcu_read_unlock(); +} +EXPORT_SYMBOL_GPL(geneve_get_rx_port); + /* Initialize the device structure. */ static void geneve_setup(struct net_device *dev) { diff --git a/include/net/geneve.h b/include/net/geneve.h index 3106ed6..e6c23dc 100644 --- a/include/net/geneve.h +++ b/include/net/geneve.h @@ -62,6 +62,14 @@ struct genevehdr { struct geneve_opt options[]; }; +#if IS_ENABLED(CONFIG_GENEVE) +void geneve_get_rx_port(struct net_device *netdev); +#else +static inline void geneve_get_rx_port(struct net_device *netdev) +{ +} +#endif + #ifdef CONFIG_INET struct net_device *geneve_dev_create_fb(struct net *net, const char *name, u8 name_assign_type, u16 dst_port); -- 1.8.1.4 -- To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v4 5/5] i40e: Call geneve_get_rx_port to get the existing Geneve ports
This patch adds a call to geneve_get_rx_port in i40e so that when it comes up it can learn about the existing geneve tunnels. Signed-off-by: Anjali Singhai Jain --- drivers/net/ethernet/intel/i40e/i40e_main.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c b/drivers/net/ethernet/intel/i40e/i40e_main.c index 81a6693..11059be 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_main.c +++ b/drivers/net/ethernet/intel/i40e/i40e_main.c @@ -5339,6 +5339,9 @@ int i40e_open(struct net_device *netdev) #ifdef CONFIG_I40E_VXLAN vxlan_get_rx_port(netdev); #endif +#ifdef CONFIG_I40E_GENEVE + geneve_get_rx_port(netdev); +#endif return 0; } -- 1.8.1.4 -- To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v4 3/5] i40e: Kernel dependency update for i40e to support geneve offload
Update the Kconfig file with dependency for supporting GENEVE tunnel offloads. Signed-off-by: Anjali Singhai Jain Signed-off-by: Kiran Patil --- drivers/net/ethernet/intel/Kconfig | 10 ++ 1 file changed, 10 insertions(+) diff --git a/drivers/net/ethernet/intel/Kconfig b/drivers/net/ethernet/intel/Kconfig index 4163b16..fa593dd 100644 --- a/drivers/net/ethernet/intel/Kconfig +++ b/drivers/net/ethernet/intel/Kconfig @@ -280,6 +280,16 @@ config I40E_VXLAN Say Y here if you want to use Virtual eXtensible Local Area Network (VXLAN) in the driver. +config I40E_GENEVE + bool "Generic Network Virtualization Encapsulation (GENEVE) Support" + depends on I40E && GENEVE && !(I40E=y && GENEVE=m) + default n + ---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 use GENEVE in the driver. + config I40E_DCB bool "Data Center Bridging (DCB) Support" default n -- 1.8.1.4 -- To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v4 2/5] i40e: geneve tunnel offload support
This patch adds driver hooks to implement ndo_ops to add/del udp port in the HW to identify GENEVE tunnels. Signed-off-by: Anjali Singhai Jain Signed-off-by: Kiran Patil --- drivers/net/ethernet/intel/i40e/i40e.h | 16 +-- drivers/net/ethernet/intel/i40e/i40e_main.c | 167 ++-- drivers/net/ethernet/intel/i40e/i40e_txrx.c | 8 +- drivers/net/ethernet/intel/i40e/i40e_txrx.h | 2 +- 4 files changed, 150 insertions(+), 43 deletions(-) diff --git a/drivers/net/ethernet/intel/i40e/i40e.h b/drivers/net/ethernet/intel/i40e/i40e.h index b7bc014..c202f9b 100644 --- a/drivers/net/ethernet/intel/i40e/i40e.h +++ b/drivers/net/ethernet/intel/i40e/i40e.h @@ -245,6 +245,11 @@ struct i40e_tc_configuration { struct i40e_tc_info tc_info[I40E_MAX_TRAFFIC_CLASS]; }; +struct i40e_udp_port_config { + __be16 index; + u8 type; +}; + /* struct that defines the Ethernet device */ struct i40e_pf { struct pci_dev *pdev; @@ -281,11 +286,9 @@ struct i40e_pf { u32 fd_atr_cnt; u32 fd_tcp_rule; -#ifdef CONFIG_I40E_VXLAN - __be16 vxlan_ports[I40E_MAX_PF_UDP_OFFLOAD_PORTS]; - u16 pending_vxlan_bitmap; + struct i40e_udp_port_config udp_ports[I40E_MAX_PF_UDP_OFFLOAD_PORTS]; + u16 pending_udp_bitmap; -#endif enum i40e_interrupt_policy int_policy; u16 rx_itr_default; u16 tx_itr_default; @@ -322,9 +325,7 @@ struct i40e_pf { #define I40E_FLAG_FD_ATR_ENABLED BIT_ULL(22) #define I40E_FLAG_PTP BIT_ULL(25) #define I40E_FLAG_MFP_ENABLED BIT_ULL(26) -#ifdef CONFIG_I40E_VXLAN -#define I40E_FLAG_VXLAN_FILTER_SYNCBIT_ULL(27) -#endif +#define I40E_FLAG_UDP_FILTER_SYNC BIT_ULL(27) #define I40E_FLAG_PORT_ID_VALIDBIT_ULL(28) #define I40E_FLAG_DCB_CAPABLE BIT_ULL(29) #define I40E_FLAG_RSS_AQ_CAPABLE BIT_ULL(31) @@ -336,6 +337,7 @@ struct i40e_pf { #define I40E_FLAG_MULTIPLE_TCP_UDP_RSS_PCTYPE BIT_ULL(38) #define I40E_FLAG_LINK_POLLING_ENABLED BIT_ULL(39) #define I40E_FLAG_VEB_MODE_ENABLED BIT_ULL(40) +#define I40E_FLAG_GENEVE_OFFLOAD_CAPABLE BIT_ULL(41) #define I40E_FLAG_NO_PCI_LINK_CHECKBIT_ULL(42) /* tracks features that get auto disabled by errors */ diff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c b/drivers/net/ethernet/intel/i40e/i40e_main.c index b118deb..81a6693 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_main.c +++ b/drivers/net/ethernet/intel/i40e/i40e_main.c @@ -27,9 +27,12 @@ /* Local includes */ #include "i40e.h" #include "i40e_diag.h" -#ifdef CONFIG_I40E_VXLAN +#if IS_ENABLED(CONFIG_VXLAN) #include #endif +#if IS_ENABLED(CONFIG_GENEVE) +#include +#endif const char i40e_driver_name[] = "i40e"; static const char i40e_driver_string[] = @@ -7036,30 +7039,30 @@ static void i40e_handle_mdd_event(struct i40e_pf *pf) i40e_flush(hw); } -#ifdef CONFIG_I40E_VXLAN /** - * i40e_sync_vxlan_filters_subtask - Sync the VSI filter list with HW + * i40e_sync_udp_filters_subtask - Sync the VSI filter list with HW * @pf: board private structure **/ -static void i40e_sync_vxlan_filters_subtask(struct i40e_pf *pf) +static void i40e_sync_udp_filters_subtask(struct i40e_pf *pf) { +#if IS_ENABLED(CONFIG_VXLAN) || IS_ENABLED(CONFIG_GENEVE) struct i40e_hw *hw = &pf->hw; i40e_status ret; __be16 port; int i; - if (!(pf->flags & I40E_FLAG_VXLAN_FILTER_SYNC)) + if (!(pf->flags & I40E_FLAG_UDP_FILTER_SYNC)) return; - pf->flags &= ~I40E_FLAG_VXLAN_FILTER_SYNC; + pf->flags &= ~I40E_FLAG_UDP_FILTER_SYNC; for (i = 0; i < I40E_MAX_PF_UDP_OFFLOAD_PORTS; i++) { - if (pf->pending_vxlan_bitmap & BIT_ULL(i)) { - pf->pending_vxlan_bitmap &= ~BIT_ULL(i); - port = pf->vxlan_ports[i]; + if (pf->pending_udp_bitmap & BIT_ULL(i)) { + pf->pending_udp_bitmap &= ~BIT_ULL(i); + port = pf->udp_ports[i].index; if (port) ret = i40e_aq_add_udp_tunnel(hw, ntohs(port), -I40E_AQC_TUNNEL_TYPE_VXLAN, +pf->udp_ports[i].type, NULL, NULL); else ret = i40e_aq_del_udp_tunnel(hw, i, NULL); @@ -7072,13 +7075,13 @@ static void i40e_sync_vxlan_filters_subtask(struct i40e_pf *pf) i40e_stat_str(&pf->hw, ret), i40e_aq_str(&pf->hw,
[PATCH v4 4/5] geneve: Add geneve_get_rx_port support
This patch adds an op that the drivers can call into to get existing geneve ports. Signed-off-by: Anjali Singhai Jain --- drivers/net/geneve.c | 24 include/net/geneve.h | 8 2 files changed, 32 insertions(+) diff --git a/drivers/net/geneve.c b/drivers/net/geneve.c index 89325e4..31b19fd 100644 --- a/drivers/net/geneve.c +++ b/drivers/net/geneve.c @@ -1109,6 +1109,30 @@ static struct device_type geneve_type = { .name = "geneve", }; +/* Calls the ndo_add_geneve_port of the caller in order to + * supply the listening GENEVE udp ports. Callers are expected + * to implement the ndo_add_geneve_port. + */ +void geneve_get_rx_port(struct net_device *dev) +{ + struct net *net = dev_net(dev); + struct geneve_net *gn = net_generic(net, geneve_net_id); + struct geneve_sock *gs; + sa_family_t sa_family; + struct sock *sk; + __be16 port; + + rcu_read_lock(); + list_for_each_entry_rcu(gs, &gn->sock_list, list) { + sk = gs->sock->sk; + sa_family = sk->sk_family; + port = inet_sk(sk)->inet_sport; + dev->netdev_ops->ndo_add_geneve_port(dev, sa_family, port); + } + rcu_read_unlock(); +} +EXPORT_SYMBOL_GPL(geneve_get_rx_port); + /* Initialize the device structure. */ static void geneve_setup(struct net_device *dev) { diff --git a/include/net/geneve.h b/include/net/geneve.h index 3106ed6..e6c23dc 100644 --- a/include/net/geneve.h +++ b/include/net/geneve.h @@ -62,6 +62,14 @@ struct genevehdr { struct geneve_opt options[]; }; +#if IS_ENABLED(CONFIG_GENEVE) +void geneve_get_rx_port(struct net_device *netdev); +#else +static inline void geneve_get_rx_port(struct net_device *netdev) +{ +} +#endif + #ifdef CONFIG_INET struct net_device *geneve_dev_create_fb(struct net *net, const char *name, u8 name_assign_type, u16 dst_port); -- 1.8.1.4 -- To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v4 0/5] Add support for Geneve udp port offload
This patch series adds new ndo ops for Geneve add/del port, so as to help offload Geneve tunnel functionalities such as RX checksum, RSS, filters etc. i40e driver has been tested with the changes to make sure the offloads happen. We do understand that this is not the ideal solution and most likely will be redone with a more generic offload framework. But this certainly will enable us to start seeing benefits of the accelerations for Geneve tunnels. As a side note, we did find an existing issue in i40e driver where a service task can modify tunnel data structures with no locks held to help linearize access. A separate patch will be taking care of that issue. A question out to the community is regarding the driver Kconfig parameters for VxLAN and Geneve, it would be ideal to drop those if there is a way to help resolve vxlan/geneve_get_rx_port symbols while the tunnel modules are not loaded. Performance numbers: With the offloads enable on X722 devices with remote checksum enabled and no other tuning in terms of cpu governer etc on my test machine: With offload Throughput: 5527Mbits/sec with a single thread %cpu: ~43% per core with 4 threads Without offload Throughput: 2364Mbits/sec with a single thread %cpu: ~99% per core with 4 threads These numbers will get better for X722 as it is being worked. But this does bring out the delta in terms of when the stack is notified with csum_level 1 and CHECKSUM_UNNECESSARY vs not without the RX offload. v4: Comment fix and split a patch into two. Anjali Singhai Jain (5): geneve: Add geneve udp port offload for ethernet devices i40e: geneve tunnel offload support i40e: Kernel dependency update for i40e to support geneve offload geneve: Add geneve_get_rx_port support i40e: Call geneve_get_rx_port to get the existing Geneve ports -- To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v4 1/5] geneve: Add geneve udp port offload for ethernet devices
Add ndo_ops to add/del UDP ports to a device that supports geneve offload. v2: Comment fix. Signed-off-by: Anjali Singhai Jain Signed-off-by: Kiran Patil --- drivers/net/geneve.c | 23 +++ include/linux/netdevice.h | 20 +++- 2 files changed, 42 insertions(+), 1 deletion(-) diff --git a/drivers/net/geneve.c b/drivers/net/geneve.c index 0750d7a..89325e4 100644 --- a/drivers/net/geneve.c +++ b/drivers/net/geneve.c @@ -380,8 +380,11 @@ static struct socket *geneve_create_sock(struct net *net, bool ipv6, static void geneve_notify_add_rx_port(struct geneve_sock *gs) { + struct net_device *dev; struct sock *sk = gs->sock->sk; + struct net *net = sock_net(sk); sa_family_t sa_family = sk->sk_family; + __be16 port = inet_sk(sk)->inet_sport; int err; if (sa_family == AF_INET) { @@ -390,6 +393,14 @@ static void geneve_notify_add_rx_port(struct geneve_sock *gs) pr_warn("geneve: udp_add_offload failed with status %d\n", err); } + + rcu_read_lock(); + for_each_netdev_rcu(net, dev) { + if (dev->netdev_ops->ndo_add_geneve_port) + dev->netdev_ops->ndo_add_geneve_port(dev, sa_family, +port); + } + rcu_read_unlock(); } static int geneve_hlen(struct genevehdr *gh) @@ -530,8 +541,20 @@ static struct geneve_sock *geneve_socket_create(struct net *net, __be16 port, static void geneve_notify_del_rx_port(struct geneve_sock *gs) { + struct net_device *dev; struct sock *sk = gs->sock->sk; + struct net *net = sock_net(sk); sa_family_t sa_family = sk->sk_family; + __be16 port = inet_sk(sk)->inet_sport; + + rcu_read_lock(); + for_each_netdev_rcu(net, dev) { + if (dev->netdev_ops->ndo_del_geneve_port) + dev->netdev_ops->ndo_del_geneve_port(dev, sa_family, +port); + } + + rcu_read_unlock(); if (sa_family == AF_INET) udp_del_offload(&gs->udp_offloads); diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index 1bb21ff..82065a7 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h @@ -1013,6 +1013,19 @@ typedef u16 (*select_queue_fallback_t)(struct net_device *dev, * a new port starts listening. The operation is protected by the * vxlan_net->sock_lock. * + * void (*ndo_add_geneve_port)(struct net_device *dev, + * sa_family_t sa_family, __be16 port); + * Called by geneve to notify a driver about the UDP port and socket + * address family that geneve is listnening to. It is called only when + * a new port starts listening. The operation is protected by the + * geneve_net->sock_lock. + * + * void (*ndo_del_geneve_port)(struct net_device *dev, + * sa_family_t sa_family, __be16 port); + * Called by geneve to notify the driver about a UDP port and socket + * address family that geneve is not listening to anymore. The operation + * is protected by the geneve_net->sock_lock. + * * void (*ndo_del_vxlan_port)(struct net_device *dev, * sa_family_t sa_family, __be16 port); * Called by vxlan to notify the driver about a UDP port and socket @@ -1217,7 +1230,12 @@ struct net_device_ops { void(*ndo_del_vxlan_port)(struct net_device *dev, sa_family_t sa_family, __be16 port); - + void(*ndo_add_geneve_port)(struct net_device *dev, + sa_family_t sa_family, + __be16 port); + void(*ndo_del_geneve_port)(struct net_device *dev, + sa_family_t sa_family, + __be16 port); void* (*ndo_dfwd_add_station)(struct net_device *pdev, struct net_device *dev); void(*ndo_dfwd_del_station)(struct net_device *pdev, -- 1.8.1.4 -- To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v3 2/4] i40e: geneve tunnel offload support
This patch adds driver hooks to implement ndo_ops to add/del udp port in the HW to identify GENEVE tunnels. Signed-off-by: Anjali Singhai Jain Signed-off-by: Kiran Patil --- drivers/net/ethernet/intel/i40e/i40e.h | 16 +-- drivers/net/ethernet/intel/i40e/i40e_main.c | 167 ++-- drivers/net/ethernet/intel/i40e/i40e_txrx.c | 8 +- drivers/net/ethernet/intel/i40e/i40e_txrx.h | 2 +- 4 files changed, 150 insertions(+), 43 deletions(-) diff --git a/drivers/net/ethernet/intel/i40e/i40e.h b/drivers/net/ethernet/intel/i40e/i40e.h index 9b1dbbc..68f2204 100644 --- a/drivers/net/ethernet/intel/i40e/i40e.h +++ b/drivers/net/ethernet/intel/i40e/i40e.h @@ -245,6 +245,11 @@ struct i40e_tc_configuration { struct i40e_tc_info tc_info[I40E_MAX_TRAFFIC_CLASS]; }; +struct i40e_udp_port_config { + __be16 index; + u8 type; +}; + /* struct that defines the Ethernet device */ struct i40e_pf { struct pci_dev *pdev; @@ -281,11 +286,9 @@ struct i40e_pf { u32 fd_atr_cnt; u32 fd_tcp_rule; -#ifdef CONFIG_I40E_VXLAN - __be16 vxlan_ports[I40E_MAX_PF_UDP_OFFLOAD_PORTS]; - u16 pending_vxlan_bitmap; + struct i40e_udp_port_config udp_ports[I40E_MAX_PF_UDP_OFFLOAD_PORTS]; + u16 pending_udp_bitmap; -#endif enum i40e_interrupt_policy int_policy; u16 rx_itr_default; u16 tx_itr_default; @@ -322,9 +325,7 @@ struct i40e_pf { #define I40E_FLAG_FD_ATR_ENABLED BIT_ULL(22) #define I40E_FLAG_PTP BIT_ULL(25) #define I40E_FLAG_MFP_ENABLED BIT_ULL(26) -#ifdef CONFIG_I40E_VXLAN -#define I40E_FLAG_VXLAN_FILTER_SYNCBIT_ULL(27) -#endif +#define I40E_FLAG_UDP_FILTER_SYNC BIT_ULL(27) #define I40E_FLAG_PORT_ID_VALIDBIT_ULL(28) #define I40E_FLAG_DCB_CAPABLE BIT_ULL(29) #define I40E_FLAG_RSS_AQ_CAPABLE BIT_ULL(31) @@ -336,6 +337,7 @@ struct i40e_pf { #define I40E_FLAG_MULTIPLE_TCP_UDP_RSS_PCTYPE BIT_ULL(38) #define I40E_FLAG_LINK_POLLING_ENABLED BIT_ULL(39) #define I40E_FLAG_VEB_MODE_ENABLED BIT_ULL(40) +#define I40E_FLAG_GENEVE_OFFLOAD_CAPABLE BIT_ULL(41) #define I40E_FLAG_NO_PCI_LINK_CHECKBIT_ULL(42) #define I40E_FLAG_PF_MAC BIT_ULL(50) diff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c b/drivers/net/ethernet/intel/i40e/i40e_main.c index e2ca6e0..08dc7d6 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_main.c +++ b/drivers/net/ethernet/intel/i40e/i40e_main.c @@ -36,9 +36,12 @@ /* Local includes */ #include "i40e.h" #include "i40e_diag.h" -#ifdef CONFIG_I40E_VXLAN +#if IS_ENABLED(CONFIG_VXLAN) #include #endif +#if IS_ENABLED(CONFIG_GENEVE) +#include +#endif const char i40e_driver_name[] = "i40e"; static const char i40e_driver_string[] = @@ -7044,30 +7047,30 @@ static void i40e_handle_mdd_event(struct i40e_pf *pf) i40e_flush(hw); } -#ifdef CONFIG_I40E_VXLAN /** - * i40e_sync_vxlan_filters_subtask - Sync the VSI filter list with HW + * i40e_sync_udp_filters_subtask - Sync the VSI filter list with HW * @pf: board private structure **/ -static void i40e_sync_vxlan_filters_subtask(struct i40e_pf *pf) +static void i40e_sync_udp_filters_subtask(struct i40e_pf *pf) { +#if IS_ENABLED(CONFIG_VXLAN) || IS_ENABLED(CONFIG_GENEVE) struct i40e_hw *hw = &pf->hw; i40e_status ret; __be16 port; int i; - if (!(pf->flags & I40E_FLAG_VXLAN_FILTER_SYNC)) + if (!(pf->flags & I40E_FLAG_UDP_FILTER_SYNC)) return; - pf->flags &= ~I40E_FLAG_VXLAN_FILTER_SYNC; + pf->flags &= ~I40E_FLAG_UDP_FILTER_SYNC; for (i = 0; i < I40E_MAX_PF_UDP_OFFLOAD_PORTS; i++) { - if (pf->pending_vxlan_bitmap & BIT_ULL(i)) { - pf->pending_vxlan_bitmap &= ~BIT_ULL(i); - port = pf->vxlan_ports[i]; + if (pf->pending_udp_bitmap & BIT_ULL(i)) { + pf->pending_udp_bitmap &= ~BIT_ULL(i); + port = pf->udp_ports[i].index; if (port) ret = i40e_aq_add_udp_tunnel(hw, ntohs(port), -I40E_AQC_TUNNEL_TYPE_VXLAN, +pf->udp_ports[i].type, NULL, NULL); else ret = i40e_aq_del_udp_tunnel(hw, i, NULL); @@ -7080,13 +7083,13 @@ static void i40e_sync_vxlan_filters_subtask(struct i40e_pf *pf) i40e_stat_str(&pf->hw, ret), i40e_aq_str(&pf->hw,
[PATCH v3 1/4] geneve: Add geneve udp port offload for ethernet devices
Add ndo_ops to add/del UDP ports to a device that supports geneve offload. v3: Add some more comments about the use of the new ndo ops. Signed-off-by: Anjali Singhai Jain Signed-off-by: Kiran Patil --- drivers/net/geneve.c | 23 +++ include/linux/netdevice.h | 21 - 2 files changed, 43 insertions(+), 1 deletion(-) diff --git a/drivers/net/geneve.c b/drivers/net/geneve.c index de5c30c..b43fd56 100644 --- a/drivers/net/geneve.c +++ b/drivers/net/geneve.c @@ -371,8 +371,11 @@ static struct socket *geneve_create_sock(struct net *net, bool ipv6, static void geneve_notify_add_rx_port(struct geneve_sock *gs) { + struct net_device *dev; struct sock *sk = gs->sock->sk; + struct net *net = sock_net(sk); sa_family_t sa_family = sk->sk_family; + __be16 port = inet_sk(sk)->inet_sport; int err; if (sa_family == AF_INET) { @@ -381,6 +384,14 @@ static void geneve_notify_add_rx_port(struct geneve_sock *gs) pr_warn("geneve: udp_add_offload failed with status %d\n", err); } + + rcu_read_lock(); + for_each_netdev_rcu(net, dev) { + if (dev->netdev_ops->ndo_add_geneve_port) + dev->netdev_ops->ndo_add_geneve_port(dev, sa_family, +port); + } + rcu_read_unlock(); } static int geneve_hlen(struct genevehdr *gh) @@ -521,8 +532,20 @@ static struct geneve_sock *geneve_socket_create(struct net *net, __be16 port, static void geneve_notify_del_rx_port(struct geneve_sock *gs) { + struct net_device *dev; struct sock *sk = gs->sock->sk; + struct net *net = sock_net(sk); sa_family_t sa_family = sk->sk_family; + __be16 port = inet_sk(sk)->inet_sport; + + rcu_read_lock(); + for_each_netdev_rcu(net, dev) { + if (dev->netdev_ops->ndo_del_geneve_port) + dev->netdev_ops->ndo_del_geneve_port(dev, sa_family, +port); + } + + rcu_read_unlock(); if (sa_family == AF_INET) udp_del_offload(&gs->udp_offloads); diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index 1bb21ff..ff91007 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h @@ -1013,6 +1013,20 @@ typedef u16 (*select_queue_fallback_t)(struct net_device *dev, * a new port starts listening. The operation is protected by the * vxlan_net->sock_lock. * + * void (*ndo_add_geneve_port)(struct net_device *dev, + * sa_family_t sa_family, __be16 port); + * Called by geneve to notiy a driver about the UDP port and socket + * address family that geneve is listnening to. It is called only when + * a new port starts listening. The operation is protected by the + * geneve_net->sock_lock. This should be strictly used by the driver + * when setting up the device for RX side offloads only. + * + * void (*ndo_del_geneve_port)(struct net_device *dev, + * sa_family_t sa_family, __be16 port); + * Called by geneve to notify the driver about a UDP port and socket + * address family that geneve is not listening to anymore. The operation + * is protected by the geneve_net->sock_lock. + * * void (*ndo_del_vxlan_port)(struct net_device *dev, * sa_family_t sa_family, __be16 port); * Called by vxlan to notify the driver about a UDP port and socket @@ -1217,7 +1231,12 @@ struct net_device_ops { void(*ndo_del_vxlan_port)(struct net_device *dev, sa_family_t sa_family, __be16 port); - + void(*ndo_add_geneve_port)(struct net_device *dev, + sa_family_t sa_family, + __be16 port); + void(*ndo_del_geneve_port)(struct net_device *dev, + sa_family_t sa_family, + __be16 port); void* (*ndo_dfwd_add_station)(struct net_device *pdev, struct net_device *dev); void(*ndo_dfwd_del_station)(struct net_device *pdev, -- 1.8.1.4 -- To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v3 4/4] geneve: Add geneve_get_rx_port support
This patch adds an op that the drivers can call into to get existing geneve ports. Signed-off-by: Anjali Singhai Jain --- drivers/net/ethernet/intel/i40e/i40e_main.c | 3 +++ drivers/net/geneve.c| 24 include/net/geneve.h| 8 3 files changed, 35 insertions(+) diff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c b/drivers/net/ethernet/intel/i40e/i40e_main.c index 08dc7d6..338d5eb 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_main.c +++ b/drivers/net/ethernet/intel/i40e/i40e_main.c @@ -5347,6 +5347,9 @@ int i40e_open(struct net_device *netdev) #ifdef CONFIG_I40E_VXLAN vxlan_get_rx_port(netdev); #endif +#ifdef CONFIG_I40E_GENEVE + geneve_get_rx_port(netdev); +#endif return 0; } diff --git a/drivers/net/geneve.c b/drivers/net/geneve.c index b43fd56..bcf2be0 100644 --- a/drivers/net/geneve.c +++ b/drivers/net/geneve.c @@ -1090,6 +1090,30 @@ static struct device_type geneve_type = { .name = "geneve", }; +/* Calls the ndo_add_geneve_port of the caller in order to + * supply the listening GENEVE udp ports. Callers are expected + * to implement the ndo_add_geneve_port. + */ +void geneve_get_rx_port(struct net_device *dev) +{ + struct net *net = dev_net(dev); + struct geneve_net *gn = net_generic(net, geneve_net_id); + struct geneve_sock *gs; + sa_family_t sa_family; + struct sock *sk; + __be16 port; + + rcu_read_lock(); + list_for_each_entry_rcu(gs, &gn->sock_list, list) { + sk = gs->sock->sk; + sa_family = sk->sk_family; + port = inet_sk(sk)->inet_sport; + dev->netdev_ops->ndo_add_geneve_port(dev, sa_family, port); + } + rcu_read_unlock(); +} +EXPORT_SYMBOL_GPL(geneve_get_rx_port); + /* Initialize the device structure. */ static void geneve_setup(struct net_device *dev) { diff --git a/include/net/geneve.h b/include/net/geneve.h index 3106ed6..e6c23dc 100644 --- a/include/net/geneve.h +++ b/include/net/geneve.h @@ -62,6 +62,14 @@ struct genevehdr { struct geneve_opt options[]; }; +#if IS_ENABLED(CONFIG_GENEVE) +void geneve_get_rx_port(struct net_device *netdev); +#else +static inline void geneve_get_rx_port(struct net_device *netdev) +{ +} +#endif + #ifdef CONFIG_INET struct net_device *geneve_dev_create_fb(struct net *net, const char *name, u8 name_assign_type, u16 dst_port); -- 1.8.1.4 -- To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v3 3/4] i40e: Kernel dependency update for i40e to support geneve offload
Update the Kconfig file with dependency for supporting GENEVE tunnel offloads. Signed-off-by: Anjali Singhai Jain Signed-off-by: Kiran Patil --- drivers/net/ethernet/intel/Kconfig | 10 ++ 1 file changed, 10 insertions(+) diff --git a/drivers/net/ethernet/intel/Kconfig b/drivers/net/ethernet/intel/Kconfig index 4163b16..fa593dd 100644 --- a/drivers/net/ethernet/intel/Kconfig +++ b/drivers/net/ethernet/intel/Kconfig @@ -280,6 +280,16 @@ config I40E_VXLAN Say Y here if you want to use Virtual eXtensible Local Area Network (VXLAN) in the driver. +config I40E_GENEVE + bool "Generic Network Virtualization Encapsulation (GENEVE) Support" + depends on I40E && GENEVE && !(I40E=y && GENEVE=m) + default n + ---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 use GENEVE in the driver. + config I40E_DCB bool "Data Center Bridging (DCB) Support" default n -- 1.8.1.4 -- To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Add support for Geneve udp port offload
This patch series adds new ndo ops for Geneve add/del port, so as to help offload Geneve tunnel functionalities such as RX checksum, RSS, filters etc. i40e driver has been tested with the changes to make sure the offloads happen. We do understand that this is not the ideal solution and most likely will be redone with a more generic offload framework. But this certainly will enable us to start seeing benefits of the accelerations for Geneve tunnels. As a side note, we did find an existing issue in i40e driver where a service task can modify tunnel data structures with no locks held to help linearize access. A separate patch will be taking care of that issue. A question out to the community is regarding the driver Kconfig parameters for VxLAN and Geneve, it would be ideal to drop those if there is a way to help resolve vxlan/geneve_get_rx_port symbols while the tunnel modules are not loaded. Performance numbers With the offloads enable on X722 devices with remote checksum enabled and no other tuning in terms of cpu governer etc. With offload Throughput: 5527Mbits/sec with a single thread %cpu: ~43% per core with 4 threads Without offload Throughput: 2364Mbits/sec with a single thread %cpu: ~99% per core with 4 threads These numbers will get better for X722 as it is being worked. But this does bring out the delta in terms of when the stack is notified with csum_level 1 and CHECKSUM_UNNECESSARY vs not without the RX offload. Anjali Singhai Jain (4): [RFC PATCH v2 1/4] geneve: Add geneve udp port offload for ethernet [RFC PATCH v2 2/4] i40e: geneve tunnel offload support [RFC PATCH v2 3/4] i40e: Kernel dependency update for i40e to support [RFC PATCH v2 4/4] geneve: Add geneve_get_rx_port support -- To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Add support for Geneve udp port offload
This patch series adds new ndo ops for Geneve add/del port, so as to help offload Geneve tunnel functionalities such as checksum, TSO RSS, filters etc. i40e driver has been tested with the changes to make sure the offloads happen. We do understand that this is not the ideal solution and most likely will be redone with a more generic offload framework. But this certainly will enable us to start seeing benefits of the accelerations for Geneve tunnels. As a side note, we did find an existing issue in i40e driver where a service task can modify tunnel data structures with no locks held to help linearize access. A separate patch will be taking care of that issue. A question out to the community is regarding the driver Kconfig parameters for VxLAN and Geneve, it would be ideal to drop those if there is a way to help resolve vxlan/geneve_get_rx_port symbols while the tunnel modules are not loaded. Anjali Singhai Jain (4): [RFC PATCH v2 1/4] geneve: Add geneve udp port offload for ethernet [RFC PATCH v2 2/4] i40e: geneve tunnel offload support [RFC PATCH v2 3/4] i40e: Kernel dependency update for i40e to support [RFC PATCH v2 4/4] geneve: Add geneve_get_rx_port support -- To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[RFC PATCH v2 4/4] geneve: Add geneve_get_rx_port support
This patch adds an op that the drivers can call into to get existing geneve ports. Signed-off-by: Anjali Singhai Jain --- drivers/net/ethernet/intel/i40e/i40e_main.c | 3 +++ drivers/net/geneve.c| 24 include/net/geneve.h| 8 3 files changed, 35 insertions(+) diff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c b/drivers/net/ethernet/intel/i40e/i40e_main.c index ea7e6ac..a55493b 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_main.c +++ b/drivers/net/ethernet/intel/i40e/i40e_main.c @@ -5300,6 +5300,9 @@ int i40e_open(struct net_device *netdev) #ifdef CONFIG_I40E_VXLAN vxlan_get_rx_port(netdev); #endif +#ifdef CONFIG_I40E_GENEVE + geneve_get_rx_port(netdev); +#endif return 0; } diff --git a/drivers/net/geneve.c b/drivers/net/geneve.c index b43fd56..bcf2be0 100644 --- a/drivers/net/geneve.c +++ b/drivers/net/geneve.c @@ -1090,6 +1090,30 @@ static struct device_type geneve_type = { .name = "geneve", }; +/* Calls the ndo_add_geneve_port of the caller in order to + * supply the listening GENEVE udp ports. Callers are expected + * to implement the ndo_add_geneve_port. + */ +void geneve_get_rx_port(struct net_device *dev) +{ + struct net *net = dev_net(dev); + struct geneve_net *gn = net_generic(net, geneve_net_id); + struct geneve_sock *gs; + sa_family_t sa_family; + struct sock *sk; + __be16 port; + + rcu_read_lock(); + list_for_each_entry_rcu(gs, &gn->sock_list, list) { + sk = gs->sock->sk; + sa_family = sk->sk_family; + port = inet_sk(sk)->inet_sport; + dev->netdev_ops->ndo_add_geneve_port(dev, sa_family, port); + } + rcu_read_unlock(); +} +EXPORT_SYMBOL_GPL(geneve_get_rx_port); + /* Initialize the device structure. */ static void geneve_setup(struct net_device *dev) { diff --git a/include/net/geneve.h b/include/net/geneve.h index 3106ed6..e6c23dc 100644 --- a/include/net/geneve.h +++ b/include/net/geneve.h @@ -62,6 +62,14 @@ struct genevehdr { struct geneve_opt options[]; }; +#if IS_ENABLED(CONFIG_GENEVE) +void geneve_get_rx_port(struct net_device *netdev); +#else +static inline void geneve_get_rx_port(struct net_device *netdev) +{ +} +#endif + #ifdef CONFIG_INET struct net_device *geneve_dev_create_fb(struct net *net, const char *name, u8 name_assign_type, u16 dst_port); -- 1.8.1.4 -- To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[RFC PATCH v2 3/4] i40e: Kernel dependency update for i40e to support geneve offload
Update the Kconfig file with dependency for supporting GENEVE tunnel offloads. Signed-off-by: Anjali Singhai Jain Signed-off-by: Kiran Patil --- drivers/net/ethernet/intel/Kconfig | 10 ++ 1 file changed, 10 insertions(+) diff --git a/drivers/net/ethernet/intel/Kconfig b/drivers/net/ethernet/intel/Kconfig index 4163b16..fa593dd 100644 --- a/drivers/net/ethernet/intel/Kconfig +++ b/drivers/net/ethernet/intel/Kconfig @@ -280,6 +280,16 @@ config I40E_VXLAN Say Y here if you want to use Virtual eXtensible Local Area Network (VXLAN) in the driver. +config I40E_GENEVE + bool "Generic Network Virtualization Encapsulation (GENEVE) Support" + depends on I40E && GENEVE && !(I40E=y && GENEVE=m) + default n + ---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 use GENEVE in the driver. + config I40E_DCB bool "Data Center Bridging (DCB) Support" default n -- 1.8.1.4 -- To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[RFC PATCH v2 1/4] geneve: Add geneve udp port offload for ethernet devices
Add ndo_ops to add/del UDP ports to a device that supports geneve offload. Signed-off-by: Anjali Singhai Jain Signed-off-by: Kiran Patil --- drivers/net/geneve.c | 23 +++ include/linux/netdevice.h | 20 +++- 2 files changed, 42 insertions(+), 1 deletion(-) diff --git a/drivers/net/geneve.c b/drivers/net/geneve.c index de5c30c..b43fd56 100644 --- a/drivers/net/geneve.c +++ b/drivers/net/geneve.c @@ -371,8 +371,11 @@ static struct socket *geneve_create_sock(struct net *net, bool ipv6, static void geneve_notify_add_rx_port(struct geneve_sock *gs) { + struct net_device *dev; struct sock *sk = gs->sock->sk; + struct net *net = sock_net(sk); sa_family_t sa_family = sk->sk_family; + __be16 port = inet_sk(sk)->inet_sport; int err; if (sa_family == AF_INET) { @@ -381,6 +384,14 @@ static void geneve_notify_add_rx_port(struct geneve_sock *gs) pr_warn("geneve: udp_add_offload failed with status %d\n", err); } + + rcu_read_lock(); + for_each_netdev_rcu(net, dev) { + if (dev->netdev_ops->ndo_add_geneve_port) + dev->netdev_ops->ndo_add_geneve_port(dev, sa_family, +port); + } + rcu_read_unlock(); } static int geneve_hlen(struct genevehdr *gh) @@ -521,8 +532,20 @@ static struct geneve_sock *geneve_socket_create(struct net *net, __be16 port, static void geneve_notify_del_rx_port(struct geneve_sock *gs) { + struct net_device *dev; struct sock *sk = gs->sock->sk; + struct net *net = sock_net(sk); sa_family_t sa_family = sk->sk_family; + __be16 port = inet_sk(sk)->inet_sport; + + rcu_read_lock(); + for_each_netdev_rcu(net, dev) { + if (dev->netdev_ops->ndo_del_geneve_port) + dev->netdev_ops->ndo_del_geneve_port(dev, sa_family, +port); + } + + rcu_read_unlock(); if (sa_family == AF_INET) udp_del_offload(&gs->udp_offloads); diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index fa84b59..4b395a4 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h @@ -1013,6 +1013,19 @@ typedef u16 (*select_queue_fallback_t)(struct net_device *dev, * a new port starts listening. The operation is protected by the * vxlan_net->sock_lock. * + * void (*ndo_add_geneve_port)(struct net_device *dev, + * sa_family_t sa_family, __be16 port); + * Called by geneve to notiy a driver about the UDP port and socket + * address family that geneve is listnening to. It is called only when + * a new port starts listening. The operation is protected by the + * geneve_net->sock_lock. + * + * void (*ndo_del_geneve_port)(struct net_device *dev, + * sa_family_t sa_family, __be16 port); + * Called by geneve to notify the driver about a UDP port and socket + * address family that geneve is not listening to anymore. The operation + * is protected by the geneve_net->sock_lock. + * * void (*ndo_del_vxlan_port)(struct net_device *dev, * sa_family_t sa_family, __be16 port); * Called by vxlan to notify the driver about a UDP port and socket @@ -1217,7 +1230,12 @@ struct net_device_ops { void(*ndo_del_vxlan_port)(struct net_device *dev, sa_family_t sa_family, __be16 port); - + void(*ndo_add_geneve_port)(struct net_device *dev, + sa_family_t sa_family, + __be16 port); + void(*ndo_del_geneve_port)(struct net_device *dev, + sa_family_t sa_family, + __be16 port); void* (*ndo_dfwd_add_station)(struct net_device *pdev, struct net_device *dev); void(*ndo_dfwd_del_station)(struct net_device *pdev, -- 1.8.1.4 -- To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[RFC PATCH v2 2/4] i40e: geneve tunnel offload support
This patch adds driver hooks to implement ndo_ops to add/del udp port in the HW to identify GENEVE tunnels. Signed-off-by: Anjali Singhai Jain Signed-off-by: Kiran Patil --- drivers/net/ethernet/intel/i40e/i40e.h | 16 +-- drivers/net/ethernet/intel/i40e/i40e_main.c | 167 ++-- drivers/net/ethernet/intel/i40e/i40e_txrx.c | 8 +- drivers/net/ethernet/intel/i40e/i40e_txrx.h | 2 +- 4 files changed, 150 insertions(+), 43 deletions(-) diff --git a/drivers/net/ethernet/intel/i40e/i40e.h b/drivers/net/ethernet/intel/i40e/i40e.h index bd6d9c0..972d00c 100644 --- a/drivers/net/ethernet/intel/i40e/i40e.h +++ b/drivers/net/ethernet/intel/i40e/i40e.h @@ -245,6 +245,11 @@ struct i40e_tc_configuration { struct i40e_tc_info tc_info[I40E_MAX_TRAFFIC_CLASS]; }; +struct i40e_udp_port_config { + __be16 index; + u8 type; +}; + /* struct that defines the Ethernet device */ struct i40e_pf { struct pci_dev *pdev; @@ -281,11 +286,9 @@ struct i40e_pf { u32 fd_atr_cnt; u32 fd_tcp_rule; -#ifdef CONFIG_I40E_VXLAN - __be16 vxlan_ports[I40E_MAX_PF_UDP_OFFLOAD_PORTS]; - u16 pending_vxlan_bitmap; + struct i40e_udp_port_config udp_ports[I40E_MAX_PF_UDP_OFFLOAD_PORTS]; + u16 pending_udp_bitmap; -#endif enum i40e_interrupt_policy int_policy; u16 rx_itr_default; u16 tx_itr_default; @@ -322,9 +325,7 @@ struct i40e_pf { #define I40E_FLAG_FD_ATR_ENABLED BIT_ULL(22) #define I40E_FLAG_PTP BIT_ULL(25) #define I40E_FLAG_MFP_ENABLED BIT_ULL(26) -#ifdef CONFIG_I40E_VXLAN -#define I40E_FLAG_VXLAN_FILTER_SYNCBIT_ULL(27) -#endif +#define I40E_FLAG_UDP_FILTER_SYNC BIT_ULL(27) #define I40E_FLAG_PORT_ID_VALIDBIT_ULL(28) #define I40E_FLAG_DCB_CAPABLE BIT_ULL(29) #define I40E_FLAG_RSS_AQ_CAPABLE BIT_ULL(31) @@ -336,6 +337,7 @@ struct i40e_pf { #define I40E_FLAG_MULTIPLE_TCP_UDP_RSS_PCTYPE BIT_ULL(38) #define I40E_FLAG_LINK_POLLING_ENABLED BIT_ULL(39) #define I40E_FLAG_VEB_MODE_ENABLED BIT_ULL(40) +#define I40E_FLAG_GENEVE_OFFLOAD_CAPABLE BIT_ULL(41) #define I40E_FLAG_NO_PCI_LINK_CHECKBIT_ULL(42) /* tracks features that get auto disabled by errors */ diff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c b/drivers/net/ethernet/intel/i40e/i40e_main.c index 2b1b655..ea7e6ac 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_main.c +++ b/drivers/net/ethernet/intel/i40e/i40e_main.c @@ -27,9 +27,12 @@ /* Local includes */ #include "i40e.h" #include "i40e_diag.h" -#ifdef CONFIG_I40E_VXLAN +#if IS_ENABLED(CONFIG_VXLAN) #include #endif +#if IS_ENABLED(CONFIG_GENEVE) +#include +#endif const char i40e_driver_name[] = "i40e"; static const char i40e_driver_string[] = @@ -6990,30 +6993,30 @@ static void i40e_handle_mdd_event(struct i40e_pf *pf) i40e_flush(hw); } -#ifdef CONFIG_I40E_VXLAN /** - * i40e_sync_vxlan_filters_subtask - Sync the VSI filter list with HW + * i40e_sync_udp_filters_subtask - Sync the VSI filter list with HW * @pf: board private structure **/ -static void i40e_sync_vxlan_filters_subtask(struct i40e_pf *pf) +static void i40e_sync_udp_filters_subtask(struct i40e_pf *pf) { +#if IS_ENABLED(CONFIG_VXLAN) || IS_ENABLED(CONFIG_GENEVE) struct i40e_hw *hw = &pf->hw; i40e_status ret; __be16 port; int i; - if (!(pf->flags & I40E_FLAG_VXLAN_FILTER_SYNC)) + if (!(pf->flags & I40E_FLAG_UDP_FILTER_SYNC)) return; - pf->flags &= ~I40E_FLAG_VXLAN_FILTER_SYNC; + pf->flags &= ~I40E_FLAG_UDP_FILTER_SYNC; for (i = 0; i < I40E_MAX_PF_UDP_OFFLOAD_PORTS; i++) { - if (pf->pending_vxlan_bitmap & BIT_ULL(i)) { - pf->pending_vxlan_bitmap &= ~BIT_ULL(i); - port = pf->vxlan_ports[i]; + if (pf->pending_udp_bitmap & BIT_ULL(i)) { + pf->pending_udp_bitmap &= ~BIT_ULL(i); + port = pf->udp_ports[i].index; if (port) ret = i40e_aq_add_udp_tunnel(hw, ntohs(port), -I40E_AQC_TUNNEL_TYPE_VXLAN, +pf->udp_ports[i].type, NULL, NULL); else ret = i40e_aq_del_udp_tunnel(hw, i, NULL); @@ -7026,13 +7029,13 @@ static void i40e_sync_vxlan_filters_subtask(struct i40e_pf *pf) i40e_stat_str(&pf->hw, ret), i40e_aq_str(&pf->hw,
[PATCH v2] Revert "i40e: remove CONFIG_I40E_VXLAN"
This reverts commit 8fe269991aece394a7ed274f525d96c73f94109a. The case where VXLAN is a module and i40e driver is inbuilt will not be handled properly with this change since i40e will have an undefined symbol vxlan_get_rx_port in it. v2: Add a signed-off-by. Signed-off-by: Anjali Singhai Jain --- drivers/net/ethernet/intel/Kconfig | 11 +++ drivers/net/ethernet/intel/i40e/i40e.h | 4 +++- drivers/net/ethernet/intel/i40e/i40e_main.c | 12 ++-- 3 files changed, 20 insertions(+), 7 deletions(-) diff --git a/drivers/net/ethernet/intel/Kconfig b/drivers/net/ethernet/intel/Kconfig index 061e4e0..4163b16 100644 --- a/drivers/net/ethernet/intel/Kconfig +++ b/drivers/net/ethernet/intel/Kconfig @@ -269,6 +269,17 @@ config I40E To compile this driver as a module, choose M here. The module will be called i40e. +config I40E_VXLAN + bool "Virtual eXtensible Local Area Network Support" + default n + depends on I40E && VXLAN && !(I40E=y && VXLAN=m) + ---help--- + This allows one to create VXLAN virtual interfaces that provide + Layer 2 Networks over Layer 3 Networks. VXLAN is often used + to tunnel virtual network infrastructure in virtualized environments. + Say Y here if you want to use Virtual eXtensible Local Area Network + (VXLAN) in the driver. + config I40E_DCB bool "Data Center Bridging (DCB) Support" default n diff --git a/drivers/net/ethernet/intel/i40e/i40e.h b/drivers/net/ethernet/intel/i40e/i40e.h index 23b4580..bd6d9c0 100644 --- a/drivers/net/ethernet/intel/i40e/i40e.h +++ b/drivers/net/ethernet/intel/i40e/i40e.h @@ -281,7 +281,7 @@ struct i40e_pf { u32 fd_atr_cnt; u32 fd_tcp_rule; -#if IS_ENABLED(CONFIG_VXLAN) +#ifdef CONFIG_I40E_VXLAN __be16 vxlan_ports[I40E_MAX_PF_UDP_OFFLOAD_PORTS]; u16 pending_vxlan_bitmap; @@ -322,7 +322,9 @@ struct i40e_pf { #define I40E_FLAG_FD_ATR_ENABLED BIT_ULL(22) #define I40E_FLAG_PTP BIT_ULL(25) #define I40E_FLAG_MFP_ENABLED BIT_ULL(26) +#ifdef CONFIG_I40E_VXLAN #define I40E_FLAG_VXLAN_FILTER_SYNCBIT_ULL(27) +#endif #define I40E_FLAG_PORT_ID_VALIDBIT_ULL(28) #define I40E_FLAG_DCB_CAPABLE BIT_ULL(29) #define I40E_FLAG_RSS_AQ_CAPABLE BIT_ULL(31) diff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c b/drivers/net/ethernet/intel/i40e/i40e_main.c index 8cd395d..2b1b655 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_main.c +++ b/drivers/net/ethernet/intel/i40e/i40e_main.c @@ -27,7 +27,7 @@ /* Local includes */ #include "i40e.h" #include "i40e_diag.h" -#if IS_ENABLED(CONFIG_VXLAN) +#ifdef CONFIG_I40E_VXLAN #include #endif @@ -5294,7 +5294,7 @@ int i40e_open(struct net_device *netdev) TCP_FLAG_CWR) >> 16); wr32(&pf->hw, I40E_GLLAN_TSOMSK_L, be32_to_cpu(TCP_FLAG_CWR) >> 16); -#if IS_ENABLED(CONFIG_VXLAN) +#ifdef CONFIG_I40E_VXLAN vxlan_get_rx_port(netdev); #endif @@ -6990,7 +6990,7 @@ static void i40e_handle_mdd_event(struct i40e_pf *pf) i40e_flush(hw); } -#if IS_ENABLED(CONFIG_VXLAN) +#ifdef CONFIG_I40E_VXLAN /** * i40e_sync_vxlan_filters_subtask - Sync the VSI filter list with HW * @pf: board private structure @@ -7057,7 +7057,7 @@ static void i40e_service_task(struct work_struct *work) i40e_watchdog_subtask(pf); i40e_fdir_reinit_subtask(pf); i40e_sync_filters_subtask(pf); -#if IS_ENABLED(CONFIG_VXLAN) +#ifdef CONFIG_I40E_VXLAN i40e_sync_vxlan_filters_subtask(pf); #endif i40e_clean_adminq_subtask(pf); @@ -8433,7 +8433,7 @@ static int i40e_set_features(struct net_device *netdev, return 0; } -#if IS_ENABLED(CONFIG_VXLAN) +#ifdef CONFIG_I40E_VXLAN /** * i40e_get_vxlan_port_idx - Lookup a possibly offloaded for Rx UDP port * @pf: board private structure @@ -8753,7 +8753,7 @@ static const struct net_device_ops i40e_netdev_ops = { .ndo_get_vf_config = i40e_ndo_get_vf_config, .ndo_set_vf_link_state = i40e_ndo_set_vf_link_state, .ndo_set_vf_spoofchk= i40e_ndo_set_vf_spoofchk, -#if IS_ENABLED(CONFIG_VXLAN) +#ifdef CONFIG_I40E_VXLAN .ndo_add_vxlan_port = i40e_add_vxlan_port, .ndo_del_vxlan_port = i40e_del_vxlan_port, #endif -- 1.8.1.4 -- To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH] Revert "i40e: remove CONFIG_I40E_VXLAN"
This reverts commit 8fe269991aece394a7ed274f525d96c73f94109a. The case where VXLAN is a module and i40e driver is in built will not be handled properly with this change since i40e will have an undefined symbol vxlan_get_rx_port in it. --- drivers/net/ethernet/intel/Kconfig | 11 +++ drivers/net/ethernet/intel/i40e/i40e.h | 4 +++- drivers/net/ethernet/intel/i40e/i40e_main.c | 12 ++-- 3 files changed, 20 insertions(+), 7 deletions(-) diff --git a/drivers/net/ethernet/intel/Kconfig b/drivers/net/ethernet/intel/Kconfig index 061e4e0..4163b16 100644 --- a/drivers/net/ethernet/intel/Kconfig +++ b/drivers/net/ethernet/intel/Kconfig @@ -269,6 +269,17 @@ config I40E To compile this driver as a module, choose M here. The module will be called i40e. +config I40E_VXLAN + bool "Virtual eXtensible Local Area Network Support" + default n + depends on I40E && VXLAN && !(I40E=y && VXLAN=m) + ---help--- + This allows one to create VXLAN virtual interfaces that provide + Layer 2 Networks over Layer 3 Networks. VXLAN is often used + to tunnel virtual network infrastructure in virtualized environments. + Say Y here if you want to use Virtual eXtensible Local Area Network + (VXLAN) in the driver. + config I40E_DCB bool "Data Center Bridging (DCB) Support" default n diff --git a/drivers/net/ethernet/intel/i40e/i40e.h b/drivers/net/ethernet/intel/i40e/i40e.h index 23b4580..bd6d9c0 100644 --- a/drivers/net/ethernet/intel/i40e/i40e.h +++ b/drivers/net/ethernet/intel/i40e/i40e.h @@ -281,7 +281,7 @@ struct i40e_pf { u32 fd_atr_cnt; u32 fd_tcp_rule; -#if IS_ENABLED(CONFIG_VXLAN) +#ifdef CONFIG_I40E_VXLAN __be16 vxlan_ports[I40E_MAX_PF_UDP_OFFLOAD_PORTS]; u16 pending_vxlan_bitmap; @@ -322,7 +322,9 @@ struct i40e_pf { #define I40E_FLAG_FD_ATR_ENABLED BIT_ULL(22) #define I40E_FLAG_PTP BIT_ULL(25) #define I40E_FLAG_MFP_ENABLED BIT_ULL(26) +#ifdef CONFIG_I40E_VXLAN #define I40E_FLAG_VXLAN_FILTER_SYNCBIT_ULL(27) +#endif #define I40E_FLAG_PORT_ID_VALIDBIT_ULL(28) #define I40E_FLAG_DCB_CAPABLE BIT_ULL(29) #define I40E_FLAG_RSS_AQ_CAPABLE BIT_ULL(31) diff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c b/drivers/net/ethernet/intel/i40e/i40e_main.c index 8cd395d..2b1b655 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_main.c +++ b/drivers/net/ethernet/intel/i40e/i40e_main.c @@ -27,7 +27,7 @@ /* Local includes */ #include "i40e.h" #include "i40e_diag.h" -#if IS_ENABLED(CONFIG_VXLAN) +#ifdef CONFIG_I40E_VXLAN #include #endif @@ -5294,7 +5294,7 @@ int i40e_open(struct net_device *netdev) TCP_FLAG_CWR) >> 16); wr32(&pf->hw, I40E_GLLAN_TSOMSK_L, be32_to_cpu(TCP_FLAG_CWR) >> 16); -#if IS_ENABLED(CONFIG_VXLAN) +#ifdef CONFIG_I40E_VXLAN vxlan_get_rx_port(netdev); #endif @@ -6990,7 +6990,7 @@ static void i40e_handle_mdd_event(struct i40e_pf *pf) i40e_flush(hw); } -#if IS_ENABLED(CONFIG_VXLAN) +#ifdef CONFIG_I40E_VXLAN /** * i40e_sync_vxlan_filters_subtask - Sync the VSI filter list with HW * @pf: board private structure @@ -7057,7 +7057,7 @@ static void i40e_service_task(struct work_struct *work) i40e_watchdog_subtask(pf); i40e_fdir_reinit_subtask(pf); i40e_sync_filters_subtask(pf); -#if IS_ENABLED(CONFIG_VXLAN) +#ifdef CONFIG_I40E_VXLAN i40e_sync_vxlan_filters_subtask(pf); #endif i40e_clean_adminq_subtask(pf); @@ -8433,7 +8433,7 @@ static int i40e_set_features(struct net_device *netdev, return 0; } -#if IS_ENABLED(CONFIG_VXLAN) +#ifdef CONFIG_I40E_VXLAN /** * i40e_get_vxlan_port_idx - Lookup a possibly offloaded for Rx UDP port * @pf: board private structure @@ -8753,7 +8753,7 @@ static const struct net_device_ops i40e_netdev_ops = { .ndo_get_vf_config = i40e_ndo_get_vf_config, .ndo_set_vf_link_state = i40e_ndo_set_vf_link_state, .ndo_set_vf_spoofchk= i40e_ndo_set_vf_spoofchk, -#if IS_ENABLED(CONFIG_VXLAN) +#ifdef CONFIG_I40E_VXLAN .ndo_add_vxlan_port = i40e_add_vxlan_port, .ndo_del_vxlan_port = i40e_del_vxlan_port, #endif -- 1.8.1.4 -- To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v2] net: Generalize udp based tunnel offload
Replace add/del ndo ops for vxlan_port with tunnel_port so that all UDP based tunnels can use the same ndo op. Add a parameter to pass tunnel type to the ndo_op. Change all drivers to use the generalized udp tunnel offload Patch was compile tested with x86_64_defconfig. v2: fix compile for bnxt driver. Signed-off-by: Kiran Patil Signed-off-by: Anjali Singhai Jain --- drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c | 15 ++--- drivers/net/ethernet/broadcom/bnxt/bnxt.c| 14 +--- drivers/net/ethernet/emulex/benet/be_main.c | 14 +--- drivers/net/ethernet/intel/fm10k/fm10k_netdev.c | 27 drivers/net/ethernet/intel/i40e/i40e_main.c | 41 +--- drivers/net/ethernet/intel/ixgbe/ixgbe_main.c| 17 +++--- drivers/net/ethernet/mellanox/mlx4/en_netdev.c | 21 drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c | 17 +++--- drivers/net/vxlan.c | 23 +++-- include/linux/netdevice.h| 34 ++-- include/net/udp_tunnel.h | 6 11 files changed, 158 insertions(+), 71 deletions(-) diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c index 2273576..ad2782f 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c @@ -47,6 +47,7 @@ #include #include #include +#include #include #include #include @@ -10124,11 +10125,14 @@ static void __bnx2x_add_vxlan_port(struct bnx2x *bp, u16 port) } static void bnx2x_add_vxlan_port(struct net_device *netdev, -sa_family_t sa_family, __be16 port) +sa_family_t sa_family, __be16 port, +u32 type) { struct bnx2x *bp = netdev_priv(netdev); u16 t_port = ntohs(port); + if (type != UDP_TUNNEL_VXLAN) + return; __bnx2x_add_vxlan_port(bp, t_port); } @@ -10152,11 +10156,14 @@ static void __bnx2x_del_vxlan_port(struct bnx2x *bp, u16 port) } static void bnx2x_del_vxlan_port(struct net_device *netdev, -sa_family_t sa_family, __be16 port) +sa_family_t sa_family, __be16 port, +u32 type) { struct bnx2x *bp = netdev_priv(netdev); u16 t_port = ntohs(port); + if (type != UDP_TUNNEL_VXLAN) + return; __bnx2x_del_vxlan_port(bp, t_port); } #endif @@ -13008,8 +13015,8 @@ static const struct net_device_ops bnx2x_netdev_ops = { .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, + .ndo_add_udp_tunnel_port= bnx2x_add_vxlan_port, + .ndo_del_udp_tunnel_port= bnx2x_del_vxlan_port, #endif }; diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.c b/drivers/net/ethernet/broadcom/bnxt/bnxt.c index f2d0dc9..7a27931 100644 --- a/drivers/net/ethernet/broadcom/bnxt/bnxt.c +++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.c @@ -40,6 +40,7 @@ #if defined(CONFIG_VXLAN) || defined(CONFIG_VXLAN_MODULE) #include #endif +#include #ifdef CONFIG_NET_RX_BUSY_POLL #include #endif @@ -5421,7 +5422,7 @@ 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) + __be16 port, u32 type) { struct bnxt *bp = netdev_priv(dev); @@ -5431,6 +5432,9 @@ static void bnxt_add_vxlan_port(struct net_device *dev, sa_family_t sa_family, if (sa_family != AF_INET6 && sa_family != AF_INET) return; + if (type != UDP_TUNNEL_VXLAN) + return; + if (bp->vxlan_port_cnt && bp->vxlan_port != port) return; @@ -5443,7 +5447,7 @@ static void bnxt_add_vxlan_port(struct net_device *dev, sa_family_t sa_family, } static void bnxt_del_vxlan_port(struct net_device *dev, sa_family_t sa_family, - __be16 port) + __be16 port, u32 type) { struct bnxt *bp = netdev_priv(dev); @@ -5453,6 +5457,8 @@ static void bnxt_del_vxlan_port(struct net_device *dev, sa_family_t sa_family, if (sa_family != AF_INET6 && sa_family != AF_INET) return; + if (type != UDP_TUNNEL_VXLAN) + return; if (bp->vxlan_port_cnt && bp->vxlan_port == port) { bp->vxlan_port_cnt--; @@ -5491,8 +5497,8 @@ static const struct net_device_ops bnxt_netdev_ops = { #ifdef CONFIG_RFS_ACCEL .ndo_r
[PATCH v1 1/6] net: Generalize udp based tunnel offload
Replace add/del ndo ops for vxlan_port with tunnel_port so that all UDP based tunnels can use the same ndo op. Add a parameter to pass tunnel type to the ndo_op. Change all drivers to use the generalized udp tunnel offload Patch was compile tested with x86_64_defconfig. Signed-off-by: Kiran Patil Signed-off-by: Anjali Singhai Jain --- drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c | 15 ++--- drivers/net/ethernet/broadcom/bnxt/bnxt.c| 13 +--- drivers/net/ethernet/emulex/benet/be_main.c | 14 +--- drivers/net/ethernet/intel/fm10k/fm10k_netdev.c | 27 drivers/net/ethernet/intel/i40e/i40e_main.c | 41 +--- drivers/net/ethernet/intel/ixgbe/ixgbe_main.c| 17 +++--- drivers/net/ethernet/mellanox/mlx4/en_netdev.c | 21 drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c | 17 +++--- drivers/net/vxlan.c | 23 +++-- include/linux/netdevice.h| 34 ++-- include/net/udp_tunnel.h | 6 11 files changed, 157 insertions(+), 71 deletions(-) diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c index 2273576..ad2782f 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c @@ -47,6 +47,7 @@ #include #include #include +#include #include #include #include @@ -10124,11 +10125,14 @@ static void __bnx2x_add_vxlan_port(struct bnx2x *bp, u16 port) } static void bnx2x_add_vxlan_port(struct net_device *netdev, -sa_family_t sa_family, __be16 port) +sa_family_t sa_family, __be16 port, +u32 type) { struct bnx2x *bp = netdev_priv(netdev); u16 t_port = ntohs(port); + if (type != UDP_TUNNEL_VXLAN) + return; __bnx2x_add_vxlan_port(bp, t_port); } @@ -10152,11 +10156,14 @@ static void __bnx2x_del_vxlan_port(struct bnx2x *bp, u16 port) } static void bnx2x_del_vxlan_port(struct net_device *netdev, -sa_family_t sa_family, __be16 port) +sa_family_t sa_family, __be16 port, +u32 type) { struct bnx2x *bp = netdev_priv(netdev); u16 t_port = ntohs(port); + if (type != UDP_TUNNEL_VXLAN) + return; __bnx2x_del_vxlan_port(bp, t_port); } #endif @@ -13008,8 +13015,8 @@ static const struct net_device_ops bnx2x_netdev_ops = { .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, + .ndo_add_udp_tunnel_port= bnx2x_add_vxlan_port, + .ndo_del_udp_tunnel_port= bnx2x_del_vxlan_port, #endif }; diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.c b/drivers/net/ethernet/broadcom/bnxt/bnxt.c index f2d0dc9..5b96ddf 100644 --- a/drivers/net/ethernet/broadcom/bnxt/bnxt.c +++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.c @@ -5421,7 +5421,7 @@ 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) + __be16 port, u32 type) { struct bnxt *bp = netdev_priv(dev); @@ -5431,6 +5431,9 @@ static void bnxt_add_vxlan_port(struct net_device *dev, sa_family_t sa_family, if (sa_family != AF_INET6 && sa_family != AF_INET) return; + if (type != UDP_TUNNEL_VXLAN) + return; + if (bp->vxlan_port_cnt && bp->vxlan_port != port) return; @@ -5443,7 +5446,7 @@ static void bnxt_add_vxlan_port(struct net_device *dev, sa_family_t sa_family, } static void bnxt_del_vxlan_port(struct net_device *dev, sa_family_t sa_family, - __be16 port) + __be16 port, u32 type) { struct bnxt *bp = netdev_priv(dev); @@ -5453,6 +5456,8 @@ static void bnxt_del_vxlan_port(struct net_device *dev, sa_family_t sa_family, if (sa_family != AF_INET6 && sa_family != AF_INET) return; + if (type != UDP_TUNNEL_VXLAN) + return; if (bp->vxlan_port_cnt && bp->vxlan_port == port) { bp->vxlan_port_cnt--; @@ -5491,8 +5496,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_add_udp_tunnel_port= bnxt_a
[PATCH v1 4/6] i40e: Remove CONFIG_I40E_VXLAN
If the kernel flag CONFIG_VXLAN is true or CONFIG_VXLAN_MODULE is true, enable VXLAN offload in the driver. Signed-off-by: Kiran Patil Signed-off-by: Anjali Singhai Jain --- drivers/net/ethernet/intel/Kconfig | 11 --- drivers/net/ethernet/intel/i40e/i40e_main.c | 14 -- 2 files changed, 8 insertions(+), 17 deletions(-) diff --git a/drivers/net/ethernet/intel/Kconfig b/drivers/net/ethernet/intel/Kconfig index 4163b16..061e4e0 100644 --- a/drivers/net/ethernet/intel/Kconfig +++ b/drivers/net/ethernet/intel/Kconfig @@ -269,17 +269,6 @@ config I40E To compile this driver as a module, choose M here. The module will be called i40e. -config I40E_VXLAN - bool "Virtual eXtensible Local Area Network Support" - default n - depends on I40E && VXLAN && !(I40E=y && VXLAN=m) - ---help--- - This allows one to create VXLAN virtual interfaces that provide - Layer 2 Networks over Layer 3 Networks. VXLAN is often used - to tunnel virtual network infrastructure in virtualized environments. - Say Y here if you want to use Virtual eXtensible Local Area Network - (VXLAN) in the driver. - config I40E_DCB bool "Data Center Bridging (DCB) Support" default n diff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c b/drivers/net/ethernet/intel/i40e/i40e_main.c index d65c10b..f6447c7 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_main.c +++ b/drivers/net/ethernet/intel/i40e/i40e_main.c @@ -27,7 +27,7 @@ /* Local includes */ #include "i40e.h" #include "i40e_diag.h" -#ifdef CONFIG_I40E_VXLAN +#if IS_ENABLED(CONFIG_VXLAN) #include #endif #include @@ -6990,7 +6990,7 @@ static void i40e_handle_mdd_event(struct i40e_pf *pf) **/ static void i40e_sync_udp_filters_subtask(struct i40e_pf *pf) { -#ifdef CONFIG_I40E_VXLAN +#if IS_ENABLED(CONFIG_VXLAN) struct i40e_hw *hw = &pf->hw; i40e_status ret; __be16 port; @@ -8273,7 +8273,7 @@ static int i40e_set_features(struct net_device *netdev, return 0; } -#ifdef CONFIG_I40E_VXLAN +#if IS_ENABLED(CONFIG_VXLAN) /** * i40e_get_udp_port_idx - Lookup a possibly offloaded for Rx UDP port * @pf: board private structure @@ -8293,6 +8293,7 @@ static u8 i40e_get_udp_port_idx(struct i40e_pf *pf, __be16 port) return i; } +#endif /** * i40e_add_tunnel_port - Get notifications about UDP tunnel ports that come up * @netdev: This physical port's netdev @@ -8307,6 +8308,7 @@ static void i40e_add_tunnel_port(struct net_device *netdev, sa_family_t sa_family, __be16 port, u32 type) { +#if IS_ENABLED(CONFIG_VXLAN) struct i40e_netdev_priv *np = netdev_priv(netdev); struct i40e_vsi *vsi = np->vsi; struct i40e_pf *pf = vsi->back; @@ -8344,6 +8346,7 @@ static void i40e_add_tunnel_port(struct net_device *netdev, pf->pending_udp_bitmap |= BIT_ULL(next_idx); pf->flags |= I40E_FLAG_UDP_FILTER_SYNC; +#endif } /** @@ -8360,6 +8363,7 @@ static void i40e_del_tunnel_port(struct net_device *netdev, sa_family_t sa_family, __be16 port, u32 type) { +#if IS_ENABLED(CONFIG_VXLAN) struct i40e_netdev_priv *np = netdev_priv(netdev); struct i40e_vsi *vsi = np->vsi; struct i40e_pf *pf = vsi->back; @@ -8385,9 +8389,9 @@ static void i40e_del_tunnel_port(struct net_device *netdev, netdev_warn(netdev, "udp tunnel port %d was not found, not deleting\n", ntohs(port)); } +#endif } -#endif static int i40e_get_phys_port_id(struct net_device *netdev, struct netdev_phys_item_id *ppid) { @@ -8612,10 +8616,8 @@ static const struct net_device_ops i40e_netdev_ops = { .ndo_get_vf_config = i40e_ndo_get_vf_config, .ndo_set_vf_link_state = i40e_ndo_set_vf_link_state, .ndo_set_vf_spoofchk= i40e_ndo_set_vf_spoofchk, -#ifdef CONFIG_I40E_VXLAN .ndo_add_udp_tunnel_port= i40e_add_tunnel_port, .ndo_del_udp_tunnel_port= i40e_del_tunnel_port, -#endif .ndo_get_phys_port_id = i40e_get_phys_port_id, .ndo_fdb_add= i40e_ndo_fdb_add, .ndo_features_check = i40e_features_check, -- 1.8.1.4 -- To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v1 2/6] net: Add a generic udp_offload_get_port function
The new function udp_offload_get_port replaces vxlan_get_rx_port(). This is a generic function that will help replay all udp tunnel ports irrespective of tunnel type. This way when new udp tunnels get added this function need not change. Note: Drivers besides i40e are compile tested with this change. Signed-off-by: Anjali Singhai Jain Signed-off-by: Kiran Patil --- drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c | 5 ++-- drivers/net/ethernet/broadcom/bnxt/bnxt.c| 4 +++- drivers/net/ethernet/emulex/benet/be_main.c | 4 +++- drivers/net/ethernet/intel/fm10k/fm10k_netdev.c | 3 ++- drivers/net/ethernet/intel/i40e/i40e_main.c | 5 ++-- drivers/net/ethernet/intel/ixgbe/ixgbe_main.c| 5 ++-- drivers/net/ethernet/mellanox/mlx4/en_netdev.c | 3 ++- drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c | 3 ++- drivers/net/vxlan.c | 29 ++-- include/linux/netdevice.h| 2 ++ include/net/protocol.h | 2 ++ include/net/vxlan.h | 8 --- net/ipv4/udp_offload.c | 27 ++ 13 files changed, 53 insertions(+), 47 deletions(-) diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c index ad2782f..56777c8 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c @@ -60,6 +60,7 @@ #include #include #include +#include #include "bnx2x.h" #include "bnx2x_init.h" @@ -10293,7 +10294,7 @@ sp_rtnl_not_reset: netdev_info(bp->dev, "Deleted vxlan dest port %d", port); bp->vxlan_dst_port = 0; - vxlan_get_rx_port(bp->dev); + udp_offload_get_port(bp->dev); } } #endif @@ -12499,7 +12500,7 @@ static int bnx2x_open(struct net_device *dev) #ifdef CONFIG_BNX2X_VXLAN if (IS_PF(bp)) - vxlan_get_rx_port(dev); + udp_offload_get_port(dev); #endif return 0; diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.c b/drivers/net/ethernet/broadcom/bnxt/bnxt.c index 5b96ddf..f49ca38 100644 --- a/drivers/net/ethernet/broadcom/bnxt/bnxt.c +++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.c @@ -39,6 +39,7 @@ #include #if defined(CONFIG_VXLAN) || defined(CONFIG_VXLAN_MODULE) #include +#include #endif #ifdef CONFIG_NET_RX_BUSY_POLL #include @@ -4589,7 +4590,7 @@ static int __bnxt_open_nic(struct bnxt *bp, bool irq_re_init, bool link_re_init) if (irq_re_init) { #if defined(CONFIG_VXLAN) || defined(CONFIG_VXLAN_MODULE) - vxlan_get_rx_port(bp->dev); + udp_offload_get_port(bp->dev); #endif if (!bnxt_hwrm_tunnel_dst_port_alloc( bp, htons(0x17c1), @@ -5458,6 +5459,7 @@ static void bnxt_del_vxlan_port(struct net_device *dev, sa_family_t sa_family, if (type != UDP_TUNNEL_VXLAN) return; + if (bp->vxlan_port_cnt && bp->vxlan_port == port) { bp->vxlan_port_cnt--; diff --git a/drivers/net/ethernet/emulex/benet/be_main.c b/drivers/net/ethernet/emulex/benet/be_main.c index e699deca..a4da753 100644 --- a/drivers/net/ethernet/emulex/benet/be_main.c +++ b/drivers/net/ethernet/emulex/benet/be_main.c @@ -25,6 +25,7 @@ #include #include #include +#include MODULE_VERSION(DRV_VER); MODULE_DESCRIPTION(DRV_DESC " " DRV_VER); @@ -3604,7 +3605,7 @@ static int be_open(struct net_device *netdev) #ifdef CONFIG_BE2NET_VXLAN if (skyhawk_chip(adapter)) - vxlan_get_rx_port(netdev); + udp_offload_get_port(netdev); #endif return 0; @@ -5239,6 +5240,7 @@ static void be_del_vxlan_port(struct net_device *netdev, sa_family_t sa_family, if (type != UDP_TUNNEL_VXLAN) return; + if (lancer_chip(adapter) || BEx_chip(adapter) || be_is_mc(adapter)) return; diff --git a/drivers/net/ethernet/intel/fm10k/fm10k_netdev.c b/drivers/net/ethernet/intel/fm10k/fm10k_netdev.c index 447d5e6..1564a13 100644 --- a/drivers/net/ethernet/intel/fm10k/fm10k_netdev.c +++ b/drivers/net/ethernet/intel/fm10k/fm10k_netdev.c @@ -23,6 +23,7 @@ #if IS_ENABLED(CONFIG_FM10K_VXLAN) #include #include +#include #endif /* CONFIG_FM10K_VXLAN */ /** @@ -573,7 +574,7 @@ int fm10k_open(struct net_device *netdev) #if IS_ENABLED(CONFIG_FM10K_VXLAN) /* update VXLAN port configuration */ - vxlan_get_rx_port(netdev); + udp_offload_get_port(netdev); #endif fm10k_up(interface); diff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c b/drivers/net/ethernet/intel/i40e/i40e_main.c index 520e34e..4be0a26 100644 --- a/drivers/net/ethern
[PATCH 0/6] Generalize udp based tunnels and add geneve offload
This patch series generalizes the flow for udp_based tunnels for offload hooks. So that much of the frame work can remain common for any driver adding support for geneve or any other udp_based tunnel in future. This patch series also makes the driver calls to/from the stack independent of the tunnel modules. So it would be easier to remove module config parameters from the respective drivers for tunnel support. One such example is in i40e driver. This patch series also adds support for geneve offload in i40e driver. Much thanks to Jesse Gross for his valuable feedback in getting this done the right way. Anjali Singhai Jain (6): net: Generalize udp based tunnel offload net: Add a generic udp_offload_get_port function i40e: Generalize the flow for udp based tunnels i40e: Remove CONFIG_I40E_VXLAN net: Refactor udp_offload and add Geneve port offload i40e:Add geneve tunnel offload support -- To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v1 3/6] i40e: Generalize the flow for udp based tunnels
This patch generalizes the driver flow to make room for more than just VXLAN tunnel by defining a common data structure with tunnel type. Signed-off-by: Kiran Patil Signed-off-by: Anjali Singhai Jain --- drivers/net/ethernet/intel/i40e/i40e.h | 15 drivers/net/ethernet/intel/i40e/i40e_main.c | 59 +++-- drivers/net/ethernet/intel/i40e/i40e_txrx.c | 6 +-- drivers/net/ethernet/intel/i40e/i40e_txrx.h | 2 +- 4 files changed, 42 insertions(+), 40 deletions(-) diff --git a/drivers/net/ethernet/intel/i40e/i40e.h b/drivers/net/ethernet/intel/i40e/i40e.h index 4dd3e26..c701bbb 100644 --- a/drivers/net/ethernet/intel/i40e/i40e.h +++ b/drivers/net/ethernet/intel/i40e/i40e.h @@ -244,6 +244,11 @@ struct i40e_tc_configuration { struct i40e_tc_info tc_info[I40E_MAX_TRAFFIC_CLASS]; }; +struct i40e_udp_port_config { + __be16 index; + u8 type; +}; + /* struct that defines the Ethernet device */ struct i40e_pf { struct pci_dev *pdev; @@ -280,11 +285,9 @@ struct i40e_pf { u32 fd_atr_cnt; u32 fd_tcp_rule; -#ifdef CONFIG_I40E_VXLAN - __be16 vxlan_ports[I40E_MAX_PF_UDP_OFFLOAD_PORTS]; - u16 pending_vxlan_bitmap; + struct i40e_udp_port_config udp_ports[I40E_MAX_PF_UDP_OFFLOAD_PORTS]; + u16 pending_udp_bitmap; -#endif enum i40e_interrupt_policy int_policy; u16 rx_itr_default; u16 tx_itr_default; @@ -321,9 +324,7 @@ struct i40e_pf { #define I40E_FLAG_FD_ATR_ENABLED BIT_ULL(22) #define I40E_FLAG_PTP BIT_ULL(25) #define I40E_FLAG_MFP_ENABLED BIT_ULL(26) -#ifdef CONFIG_I40E_VXLAN -#define I40E_FLAG_VXLAN_FILTER_SYNCBIT_ULL(27) -#endif +#define I40E_FLAG_UDP_FILTER_SYNC BIT_ULL(27) #define I40E_FLAG_PORT_ID_VALIDBIT_ULL(28) #define I40E_FLAG_DCB_CAPABLE BIT_ULL(29) #define I40E_FLAG_RSS_AQ_CAPABLE BIT_ULL(31) diff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c b/drivers/net/ethernet/intel/i40e/i40e_main.c index 4be0a26..d65c10b 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_main.c +++ b/drivers/net/ethernet/intel/i40e/i40e_main.c @@ -6984,30 +6984,30 @@ static void i40e_handle_mdd_event(struct i40e_pf *pf) i40e_flush(hw); } -#ifdef CONFIG_I40E_VXLAN /** - * i40e_sync_vxlan_filters_subtask - Sync the VSI filter list with HW + * i40e_sync_udp_filters_subtask - Sync the VSI filter list with HW * @pf: board private structure **/ -static void i40e_sync_vxlan_filters_subtask(struct i40e_pf *pf) +static void i40e_sync_udp_filters_subtask(struct i40e_pf *pf) { +#ifdef CONFIG_I40E_VXLAN struct i40e_hw *hw = &pf->hw; i40e_status ret; __be16 port; int i; - if (!(pf->flags & I40E_FLAG_VXLAN_FILTER_SYNC)) + if (!(pf->flags & I40E_FLAG_UDP_FILTER_SYNC)) return; - pf->flags &= ~I40E_FLAG_VXLAN_FILTER_SYNC; + pf->flags &= ~I40E_FLAG_UDP_FILTER_SYNC; for (i = 0; i < I40E_MAX_PF_UDP_OFFLOAD_PORTS; i++) { - if (pf->pending_vxlan_bitmap & BIT_ULL(i)) { - pf->pending_vxlan_bitmap &= ~BIT_ULL(i); - port = pf->vxlan_ports[i]; + if (pf->pending_udp_bitmap & BIT_ULL(i)) { + pf->pending_udp_bitmap &= ~BIT_ULL(i); + port = pf->udp_ports[i].index; if (port) ret = i40e_aq_add_udp_tunnel(hw, ntohs(port), -I40E_AQC_TUNNEL_TYPE_VXLAN, +pf->udp_ports[i].type, NULL, NULL); else ret = i40e_aq_del_udp_tunnel(hw, i, NULL); @@ -7020,13 +7020,13 @@ static void i40e_sync_vxlan_filters_subtask(struct i40e_pf *pf) i40e_stat_str(&pf->hw, ret), i40e_aq_str(&pf->hw, pf->hw.aq.asq_last_status)); - pf->vxlan_ports[i] = 0; + pf->udp_ports[i].index = 0; } } } +#endif } -#endif /** * i40e_service_task - Run the driver's async subtasks * @work: pointer to work_struct containing our data @@ -7051,9 +7051,7 @@ static void i40e_service_task(struct work_struct *work) i40e_watchdog_subtask(pf); i40e_fdir_reinit_subtask(pf); i40e_sync_filters_subtask(pf); -#ifdef CONFIG_I40E_VXLAN - i40e_sync_vxlan_filters_subtask(pf); -#endif + i40e_sync_udp_filters_subtask(pf); i40e_clean_adminq_subtask(pf); i40e_service_event_
[PATCH v1 6/6] i40e:Add geneve tunnel offload support
This patch adds driver hooks to implement ndo_ops to add/del udp port in the HW to identify GENEVE tunnels. Also cleans up the features_check path now that we support multiple udp based tunnels. Signed-off-by: Anjali Singhai Jain Signed-off-by: Kiran Patil --- drivers/net/ethernet/intel/i40e/i40e.h | 1 + drivers/net/ethernet/intel/i40e/i40e_main.c | 35 + drivers/net/ethernet/intel/i40e/i40e_txrx.c | 2 +- 3 files changed, 28 insertions(+), 10 deletions(-) diff --git a/drivers/net/ethernet/intel/i40e/i40e.h b/drivers/net/ethernet/intel/i40e/i40e.h index c701bbb..69c2c88 100644 --- a/drivers/net/ethernet/intel/i40e/i40e.h +++ b/drivers/net/ethernet/intel/i40e/i40e.h @@ -336,6 +336,7 @@ struct i40e_pf { #define I40E_FLAG_MULTIPLE_TCP_UDP_RSS_PCTYPE BIT_ULL(38) #define I40E_FLAG_LINK_POLLING_ENABLED BIT_ULL(39) #define I40E_FLAG_VEB_MODE_ENABLED BIT_ULL(40) +#define I40E_FLAG_GENEVE_OFFLOAD_CAPABLE BIT_ULL(41) #define I40E_FLAG_NO_PCI_LINK_CHECKBIT_ULL(42) /* tracks features that get auto disabled by errors */ diff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c b/drivers/net/ethernet/intel/i40e/i40e_main.c index f6447c7..e0e40c3 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_main.c +++ b/drivers/net/ethernet/intel/i40e/i40e_main.c @@ -30,6 +30,9 @@ #if IS_ENABLED(CONFIG_VXLAN) #include #endif +#if IS_ENABLED(CONFIG_GENEVE) +#include +#endif #include #include @@ -6990,7 +6993,7 @@ static void i40e_handle_mdd_event(struct i40e_pf *pf) **/ static void i40e_sync_udp_filters_subtask(struct i40e_pf *pf) { -#if IS_ENABLED(CONFIG_VXLAN) +#if IS_ENABLED(CONFIG_VXLAN) || IS_ENABLED(CONFIG_GENEVE) struct i40e_hw *hw = &pf->hw; i40e_status ret; __be16 port; @@ -8174,7 +8177,8 @@ static int i40e_sw_init(struct i40e_pf *pf) I40E_FLAG_HW_ATR_EVICT_CAPABLE | I40E_FLAG_OUTER_UDP_CSUM_CAPABLE | I40E_FLAG_WB_ON_ITR_CAPABLE | -I40E_FLAG_MULTIPLE_TCP_UDP_RSS_PCTYPE; +I40E_FLAG_MULTIPLE_TCP_UDP_RSS_PCTYPE | +I40E_FLAG_GENEVE_OFFLOAD_CAPABLE; } pf->eeprom_version = 0xDEAD; pf->lan_veb = I40E_NO_VEB; @@ -8273,7 +8277,7 @@ static int i40e_set_features(struct net_device *netdev, return 0; } -#if IS_ENABLED(CONFIG_VXLAN) +#if IS_ENABLED(CONFIG_VXLAN) || IS_ENABLED(CONFIG_GENEVE) /** * i40e_get_udp_port_idx - Lookup a possibly offloaded for Rx UDP port * @pf: board private structure @@ -8308,14 +8312,18 @@ static void i40e_add_tunnel_port(struct net_device *netdev, sa_family_t sa_family, __be16 port, u32 type) { -#if IS_ENABLED(CONFIG_VXLAN) +#if IS_ENABLED(CONFIG_VXLAN) || IS_ENABLED(CONFIG_GENEVE) struct i40e_netdev_priv *np = netdev_priv(netdev); struct i40e_vsi *vsi = np->vsi; struct i40e_pf *pf = vsi->back; u8 next_idx; u8 idx; - if (type != UDP_TUNNEL_VXLAN) + if (!(type == UDP_TUNNEL_VXLAN || type == UDP_TUNNEL_GENEVE)) + return; + + if ((type == UDP_TUNNEL_GENEVE) && + (!(pf->flags & I40E_FLAG_GENEVE_OFFLOAD_CAPABLE))) return; if (sa_family == AF_INET6) @@ -8343,6 +8351,8 @@ static void i40e_add_tunnel_port(struct net_device *netdev, pf->udp_ports[next_idx].index = port; if (type == UDP_TUNNEL_VXLAN) pf->udp_ports[next_idx].type = I40E_AQC_TUNNEL_TYPE_VXLAN; + else if (type == UDP_TUNNEL_GENEVE) + pf->udp_ports[next_idx].type = I40E_AQC_TUNNEL_TYPE_NGE; pf->pending_udp_bitmap |= BIT_ULL(next_idx); pf->flags |= I40E_FLAG_UDP_FILTER_SYNC; @@ -8363,13 +8373,13 @@ static void i40e_del_tunnel_port(struct net_device *netdev, sa_family_t sa_family, __be16 port, u32 type) { -#if IS_ENABLED(CONFIG_VXLAN) +#if IS_ENABLED(CONFIG_VXLAN) || IS_ENABLED(CONFIG_GENEVE) struct i40e_netdev_priv *np = netdev_priv(netdev); struct i40e_vsi *vsi = np->vsi; struct i40e_pf *pf = vsi->back; u8 idx; - if (type != UDP_TUNNEL_VXLAN) + if (!(type == UDP_TUNNEL_VXLAN || type == UDP_TUNNEL_GENEVE)) return; if (sa_family == AF_INET6) @@ -8569,7 +8579,10 @@ static int i40e_ndo_bridge_getlink(struct sk_buff *skb, u32 pid, u32 seq, nlflags, 0, 0, filter_mask, NULL); } -#define I40E_MAX_TUNNEL_HDR_LEN 80 +/* Hardware supports L4 tunnel length of 128B (=2^7) which includes + * inner mac plus all inner ethertypes. + */ +#define I40E_MAX_TUNNEL_HDR_LEN 128 /** * i40e_features_check - Validate encapsulated packet conforms to
[PATCH v1 5/6] net: Refactor udp_offload and add Geneve port offload support
This patch moves the calls to ndo_add/del ops for vxlan tunnel into udp_add/del_offload call. This way the ndo_add/del ops get called for not only vxlan tunnels but for any udp based tunnel. Signed-off-by: Kiran Patil Signed-off-by: Anjali Singhai Jain --- drivers/net/geneve.c | 18 +++ drivers/net/vxlan.c| 35 include/net/protocol.h | 4 ++-- net/ipv4/fou.c | 15 ++-- net/ipv4/udp_offload.c | 63 +- 5 files changed, 64 insertions(+), 71 deletions(-) diff --git a/drivers/net/geneve.c b/drivers/net/geneve.c index de5c30c..9dc513a 100644 --- a/drivers/net/geneve.c +++ b/drivers/net/geneve.c @@ -372,15 +372,12 @@ static struct socket *geneve_create_sock(struct net *net, bool ipv6, static void geneve_notify_add_rx_port(struct geneve_sock *gs) { struct sock *sk = gs->sock->sk; - sa_family_t sa_family = sk->sk_family; + struct net *net = sock_net(sk); int err; - if (sa_family == AF_INET) { - err = udp_add_offload(&gs->udp_offloads); - if (err) - pr_warn("geneve: udp_add_offload failed with status %d\n", - err); - } + err = udp_add_offload(&gs->udp_offloads, net); + if (err) + pr_warn("geneve: udp_add_offload failed with status %d\n", err); } static int geneve_hlen(struct genevehdr *gh) @@ -505,6 +502,8 @@ static struct geneve_sock *geneve_socket_create(struct net *net, __be16 port, /* Initialize the geneve udp offloads structure */ gs->udp_offloads.port = port; + gs->udp_offloads.tunnel_type = UDP_TUNNEL_GENEVE; + gs->udp_offloads.family = ipv6 ? AF_INET6 : AF_INET; gs->udp_offloads.callbacks.gro_receive = geneve_gro_receive; gs->udp_offloads.callbacks.gro_complete = geneve_gro_complete; geneve_notify_add_rx_port(gs); @@ -522,10 +521,9 @@ static struct geneve_sock *geneve_socket_create(struct net *net, __be16 port, static void geneve_notify_del_rx_port(struct geneve_sock *gs) { struct sock *sk = gs->sock->sk; - sa_family_t sa_family = sk->sk_family; + struct net *net = sock_net(sk); - if (sa_family == AF_INET) - udp_del_offload(&gs->udp_offloads); + udp_del_offload(&gs->udp_offloads, net); } static void __geneve_sock_release(struct geneve_sock *gs) diff --git a/drivers/net/vxlan.c b/drivers/net/vxlan.c index 702f9be..231c17e 100644 --- a/drivers/net/vxlan.c +++ b/drivers/net/vxlan.c @@ -613,49 +613,22 @@ static int vxlan_gro_complete(struct sk_buff *skb, int nhoff, /* Notify netdevs that UDP port started listening */ static void vxlan_notify_add_rx_port(struct vxlan_sock *vs) { - struct net_device *dev; struct sock *sk = vs->sock->sk; struct net *net = sock_net(sk); - sa_family_t sa_family = vxlan_get_sk_family(vs); - __be16 port = inet_sk(sk)->inet_sport; int err; - if (sa_family == AF_INET) { - err = udp_add_offload(&vs->udp_offloads); - if (err) - pr_warn("vxlan: udp_add_offload failed with status %d\n", err); - } - - rcu_read_lock(); - for_each_netdev_rcu(net, dev) { - if (dev->netdev_ops->ndo_add_udp_tunnel_port) - dev->netdev_ops->ndo_add_udp_tunnel_port(dev, sa_family, - port, - UDP_TUNNEL_VXLAN); - } - rcu_read_unlock(); + err = udp_add_offload(&vs->udp_offloads, net); + if (err) + pr_warn("vxlan: udp_add_offload failed with status %d\n", err); } /* Notify netdevs that UDP port is no more listening */ static void vxlan_notify_del_rx_port(struct vxlan_sock *vs) { - struct net_device *dev; struct sock *sk = vs->sock->sk; struct net *net = sock_net(sk); - sa_family_t sa_family = vxlan_get_sk_family(vs); - __be16 port = inet_sk(sk)->inet_sport; - - rcu_read_lock(); - for_each_netdev_rcu(net, dev) { - if (dev->netdev_ops->ndo_del_udp_tunnel_port) - dev->netdev_ops->ndo_del_udp_tunnel_port(dev, sa_family, - port, - UDP_TUNNEL_VXLAN); - } - rcu_read_unlock(); - if (sa_family == AF_INET) - udp_del_offload(&vs->udp_offloads); + udp_del_offload(&vs->udp_offloads, net); } /* Add new entry to forwarding table -- assumes lock held */ diff --git a/include/net/protocol.h b/include/net/protocol.h index 738bfc6..1