diff options
author | Jesper Dangaard Brouer <brouer@redhat.com> | 2018-01-03 05:25:23 -0500 |
---|---|---|
committer | Alexei Starovoitov <ast@kernel.org> | 2018-01-05 18:21:21 -0500 |
commit | 871288248de23d5c87433dcd94910ff813495588 (patch) | |
tree | 7a223dd7e7120d99875039d96d50b19a939af834 | |
parent | 0ddf543226acacfb9f521dafc6c817d5b04c7b1f (diff) |
i40e: setup xdp_rxq_info
The i40e driver has a special "FDIR" RX-ring (I40E_VSI_FDIR) which is
a sideband channel for configuring/updating the flow director tables.
This (i40e_vsi_)type does not invoke XDP-ebpf code.
As suggested by Björn (V2): Instead of marking this I40E_VSI_FDIR RX-ring
a special case, reverse the logic and only select RX-rings of type
I40E_VSI_MAIN to register xdp_rxq_info's for.
Driver hook points for xdp_rxq_info:
* reg : i40e_setup_rx_descriptors (via i40e_vsi_setup_rx_resources)
* unreg: i40e_free_rx_resources (via i40e_vsi_free_rx_resources)
Tested on actual hardware with samples/bpf program.
V2: Fixed bug in i40e_set_ringparam (memset zero) + match on I40E_VSI_MAIN.
V4: Update patch desc that got out-of-sync with code.
Cc: intel-wired-lan@lists.osuosl.org
Cc: Björn Töpel <bjorn.topel@intel.com>
Cc: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
Cc: Paul Menzel <pmenzel@molgen.mpg.de>
Signed-off-by: Jesper Dangaard Brouer <brouer@redhat.com>
Reviewed-by: Paul Menzel <pmenzel@molgen.mpg.de>
Acked-by: John Fastabend <john.fastabend@gmail.com>
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
-rw-r--r-- | drivers/net/ethernet/intel/i40e/i40e_ethtool.c | 2 | ||||
-rw-r--r-- | drivers/net/ethernet/intel/i40e/i40e_txrx.c | 18 | ||||
-rw-r--r-- | drivers/net/ethernet/intel/i40e/i40e_txrx.h | 3 |
3 files changed, 21 insertions, 2 deletions
diff --git a/drivers/net/ethernet/intel/i40e/i40e_ethtool.c b/drivers/net/ethernet/intel/i40e/i40e_ethtool.c index 5f6cf7212d4f..cfd788b4fd7a 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_ethtool.c +++ b/drivers/net/ethernet/intel/i40e/i40e_ethtool.c | |||
@@ -1585,6 +1585,8 @@ static int i40e_set_ringparam(struct net_device *netdev, | |||
1585 | */ | 1585 | */ |
1586 | rx_rings[i].desc = NULL; | 1586 | rx_rings[i].desc = NULL; |
1587 | rx_rings[i].rx_bi = NULL; | 1587 | rx_rings[i].rx_bi = NULL; |
1588 | /* Clear cloned XDP RX-queue info before setup call */ | ||
1589 | memset(&rx_rings[i].xdp_rxq, 0, sizeof(rx_rings[i].xdp_rxq)); | ||
1588 | /* this is to allow wr32 to have something to write to | 1590 | /* this is to allow wr32 to have something to write to |
1589 | * during early allocation of Rx buffers | 1591 | * during early allocation of Rx buffers |
1590 | */ | 1592 | */ |
diff --git a/drivers/net/ethernet/intel/i40e/i40e_txrx.c b/drivers/net/ethernet/intel/i40e/i40e_txrx.c index 4566d66ffc7c..2a8a85e3ae8f 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_txrx.c +++ b/drivers/net/ethernet/intel/i40e/i40e_txrx.c | |||
@@ -27,6 +27,7 @@ | |||
27 | #include <linux/prefetch.h> | 27 | #include <linux/prefetch.h> |
28 | #include <net/busy_poll.h> | 28 | #include <net/busy_poll.h> |
29 | #include <linux/bpf_trace.h> | 29 | #include <linux/bpf_trace.h> |
30 | #include <net/xdp.h> | ||
30 | #include "i40e.h" | 31 | #include "i40e.h" |
31 | #include "i40e_trace.h" | 32 | #include "i40e_trace.h" |
32 | #include "i40e_prototype.h" | 33 | #include "i40e_prototype.h" |
@@ -1236,6 +1237,8 @@ void i40e_clean_rx_ring(struct i40e_ring *rx_ring) | |||
1236 | void i40e_free_rx_resources(struct i40e_ring *rx_ring) | 1237 | void i40e_free_rx_resources(struct i40e_ring *rx_ring) |
1237 | { | 1238 | { |
1238 | i40e_clean_rx_ring(rx_ring); | 1239 | i40e_clean_rx_ring(rx_ring); |
1240 | if (rx_ring->vsi->type == I40E_VSI_MAIN) | ||
1241 | xdp_rxq_info_unreg(&rx_ring->xdp_rxq); | ||
1239 | rx_ring->xdp_prog = NULL; | 1242 | rx_ring->xdp_prog = NULL; |
1240 | kfree(rx_ring->rx_bi); | 1243 | kfree(rx_ring->rx_bi); |
1241 | rx_ring->rx_bi = NULL; | 1244 | rx_ring->rx_bi = NULL; |
@@ -1256,6 +1259,7 @@ void i40e_free_rx_resources(struct i40e_ring *rx_ring) | |||
1256 | int i40e_setup_rx_descriptors(struct i40e_ring *rx_ring) | 1259 | int i40e_setup_rx_descriptors(struct i40e_ring *rx_ring) |
1257 | { | 1260 | { |
1258 | struct device *dev = rx_ring->dev; | 1261 | struct device *dev = rx_ring->dev; |
1262 | int err = -ENOMEM; | ||
1259 | int bi_size; | 1263 | int bi_size; |
1260 | 1264 | ||
1261 | /* warn if we are about to overwrite the pointer */ | 1265 | /* warn if we are about to overwrite the pointer */ |
@@ -1283,13 +1287,21 @@ int i40e_setup_rx_descriptors(struct i40e_ring *rx_ring) | |||
1283 | rx_ring->next_to_clean = 0; | 1287 | rx_ring->next_to_clean = 0; |
1284 | rx_ring->next_to_use = 0; | 1288 | rx_ring->next_to_use = 0; |
1285 | 1289 | ||
1290 | /* XDP RX-queue info only needed for RX rings exposed to XDP */ | ||
1291 | if (rx_ring->vsi->type == I40E_VSI_MAIN) { | ||
1292 | err = xdp_rxq_info_reg(&rx_ring->xdp_rxq, rx_ring->netdev, | ||
1293 | rx_ring->queue_index); | ||
1294 | if (err < 0) | ||
1295 | goto err; | ||
1296 | } | ||
1297 | |||
1286 | rx_ring->xdp_prog = rx_ring->vsi->xdp_prog; | 1298 | rx_ring->xdp_prog = rx_ring->vsi->xdp_prog; |
1287 | 1299 | ||
1288 | return 0; | 1300 | return 0; |
1289 | err: | 1301 | err: |
1290 | kfree(rx_ring->rx_bi); | 1302 | kfree(rx_ring->rx_bi); |
1291 | rx_ring->rx_bi = NULL; | 1303 | rx_ring->rx_bi = NULL; |
1292 | return -ENOMEM; | 1304 | return err; |
1293 | } | 1305 | } |
1294 | 1306 | ||
1295 | /** | 1307 | /** |
@@ -2068,11 +2080,13 @@ static int i40e_clean_rx_irq(struct i40e_ring *rx_ring, int budget) | |||
2068 | struct sk_buff *skb = rx_ring->skb; | 2080 | struct sk_buff *skb = rx_ring->skb; |
2069 | u16 cleaned_count = I40E_DESC_UNUSED(rx_ring); | 2081 | u16 cleaned_count = I40E_DESC_UNUSED(rx_ring); |
2070 | bool failure = false, xdp_xmit = false; | 2082 | bool failure = false, xdp_xmit = false; |
2083 | struct xdp_buff xdp; | ||
2084 | |||
2085 | xdp.rxq = &rx_ring->xdp_rxq; | ||
2071 | 2086 | ||
2072 | while (likely(total_rx_packets < (unsigned int)budget)) { | 2087 | while (likely(total_rx_packets < (unsigned int)budget)) { |
2073 | struct i40e_rx_buffer *rx_buffer; | 2088 | struct i40e_rx_buffer *rx_buffer; |
2074 | union i40e_rx_desc *rx_desc; | 2089 | union i40e_rx_desc *rx_desc; |
2075 | struct xdp_buff xdp; | ||
2076 | unsigned int size; | 2090 | unsigned int size; |
2077 | u16 vlan_tag; | 2091 | u16 vlan_tag; |
2078 | u8 rx_ptype; | 2092 | u8 rx_ptype; |
diff --git a/drivers/net/ethernet/intel/i40e/i40e_txrx.h b/drivers/net/ethernet/intel/i40e/i40e_txrx.h index fbae1182e2ea..2d08760fc4ce 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_txrx.h +++ b/drivers/net/ethernet/intel/i40e/i40e_txrx.h | |||
@@ -27,6 +27,8 @@ | |||
27 | #ifndef _I40E_TXRX_H_ | 27 | #ifndef _I40E_TXRX_H_ |
28 | #define _I40E_TXRX_H_ | 28 | #define _I40E_TXRX_H_ |
29 | 29 | ||
30 | #include <net/xdp.h> | ||
31 | |||
30 | /* Interrupt Throttling and Rate Limiting Goodies */ | 32 | /* Interrupt Throttling and Rate Limiting Goodies */ |
31 | 33 | ||
32 | #define I40E_MAX_ITR 0x0FF0 /* reg uses 2 usec resolution */ | 34 | #define I40E_MAX_ITR 0x0FF0 /* reg uses 2 usec resolution */ |
@@ -428,6 +430,7 @@ struct i40e_ring { | |||
428 | */ | 430 | */ |
429 | 431 | ||
430 | struct i40e_channel *ch; | 432 | struct i40e_channel *ch; |
433 | struct xdp_rxq_info xdp_rxq; | ||
431 | } ____cacheline_internodealigned_in_smp; | 434 | } ____cacheline_internodealigned_in_smp; |
432 | 435 | ||
433 | static inline bool ring_uses_build_skb(struct i40e_ring *ring) | 436 | static inline bool ring_uses_build_skb(struct i40e_ring *ring) |