Netdev Archive on lore.kernel.org
help / color / mirror / Atom feed
* [PATCH net] sfc: check hash is valid before using it
@ 2020-08-14 12:26 Edward Cree
2020-08-14 21:07 ` David Miller
2020-08-18 8:35 ` Martin Habets
0 siblings, 2 replies; 3+ messages in thread
From: Edward Cree @ 2020-08-14 12:26 UTC (permalink / raw)
To: linux-net-drivers, davem; +Cc: netdev
On EF100, the RX hash field in the packet prefix may not be valid (e.g.
if the header parse failed), and this is indicated by a one-bit flag
elsewhere in the packet prefix. Only call skb_set_hash() if the
RSS_HASH_VALID bit is set.
Signed-off-by: Edward Cree <ecree@solarflare.com>
---
drivers/net/ethernet/sfc/ef100_rx.c | 5 +++++
drivers/net/ethernet/sfc/ef100_rx.h | 1 +
drivers/net/ethernet/sfc/efx.h | 8 ++++++++
drivers/net/ethernet/sfc/net_driver.h | 2 ++
drivers/net/ethernet/sfc/rx_common.c | 3 ++-
5 files changed, 18 insertions(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/sfc/ef100_rx.c b/drivers/net/ethernet/sfc/ef100_rx.c
index 13ba1a4f66fc..012925e878f4 100644
--- a/drivers/net/ethernet/sfc/ef100_rx.c
+++ b/drivers/net/ethernet/sfc/ef100_rx.c
@@ -31,6 +31,11 @@
#define ESF_GZ_RX_PREFIX_NT_OR_INNER_L3_CLASS_WIDTH \
ESF_GZ_RX_PREFIX_HCLASS_NT_OR_INNER_L3_CLASS_WIDTH
+bool ef100_rx_buf_hash_valid(const u8 *prefix)
+{
+ return PREFIX_FIELD(prefix, RSS_HASH_VALID);
+}
+
static bool check_fcs(struct efx_channel *channel, u32 *prefix)
{
u16 rxclass;
diff --git a/drivers/net/ethernet/sfc/ef100_rx.h b/drivers/net/ethernet/sfc/ef100_rx.h
index f2f266863966..fe45b36458d1 100644
--- a/drivers/net/ethernet/sfc/ef100_rx.h
+++ b/drivers/net/ethernet/sfc/ef100_rx.h
@@ -14,6 +14,7 @@
#include "net_driver.h"
+bool ef100_rx_buf_hash_valid(const u8 *prefix);
void efx_ef100_ev_rx(struct efx_channel *channel, const efx_qword_t *p_event);
void ef100_rx_write(struct efx_rx_queue *rx_queue);
void __ef100_rx_packet(struct efx_channel *channel);
diff --git a/drivers/net/ethernet/sfc/efx.h b/drivers/net/ethernet/sfc/efx.h
index a9808e86068d..daf0c00c1242 100644
--- a/drivers/net/ethernet/sfc/efx.h
+++ b/drivers/net/ethernet/sfc/efx.h
@@ -45,6 +45,14 @@ static inline void efx_rx_flush_packet(struct efx_channel *channel)
__ef100_rx_packet, __efx_rx_packet,
channel);
}
+static inline bool efx_rx_buf_hash_valid(struct efx_nic *efx, const u8 *prefix)
+{
+ if (efx->type->rx_buf_hash_valid)
+ return INDIRECT_CALL_1(efx->type->rx_buf_hash_valid,
+ ef100_rx_buf_hash_valid,
+ prefix);
+ return true;
+}
/* Maximum number of TCP segments we support for soft-TSO */
#define EFX_TSO_MAX_SEGS 100
diff --git a/drivers/net/ethernet/sfc/net_driver.h b/drivers/net/ethernet/sfc/net_driver.h
index 7bb7ecb480ae..dcb741d8bd11 100644
--- a/drivers/net/ethernet/sfc/net_driver.h
+++ b/drivers/net/ethernet/sfc/net_driver.h
@@ -1265,6 +1265,7 @@ struct efx_udp_tunnel {
* @rx_write: Write RX descriptors and doorbell
* @rx_defer_refill: Generate a refill reminder event
* @rx_packet: Receive the queued RX buffer on a channel
+ * @rx_buf_hash_valid: Determine whether the RX prefix contains a valid hash
* @ev_probe: Allocate resources for event queue
* @ev_init: Initialise event queue on the NIC
* @ev_fini: Deinitialise event queue on the NIC
@@ -1409,6 +1410,7 @@ struct efx_nic_type {
void (*rx_write)(struct efx_rx_queue *rx_queue);
void (*rx_defer_refill)(struct efx_rx_queue *rx_queue);
void (*rx_packet)(struct efx_channel *channel);
+ bool (*rx_buf_hash_valid)(const u8 *prefix);
int (*ev_probe)(struct efx_channel *channel);
int (*ev_init)(struct efx_channel *channel);
void (*ev_fini)(struct efx_channel *channel);
diff --git a/drivers/net/ethernet/sfc/rx_common.c b/drivers/net/ethernet/sfc/rx_common.c
index fb77c7bbe4af..ef9bca92b0b7 100644
--- a/drivers/net/ethernet/sfc/rx_common.c
+++ b/drivers/net/ethernet/sfc/rx_common.c
@@ -525,7 +525,8 @@ efx_rx_packet_gro(struct efx_channel *channel, struct efx_rx_buffer *rx_buf,
return;
}
- if (efx->net_dev->features & NETIF_F_RXHASH)
+ if (efx->net_dev->features & NETIF_F_RXHASH &&
+ efx_rx_buf_hash_valid(efx, eh))
skb_set_hash(skb, efx_rx_buf_hash(efx, eh),
PKT_HASH_TYPE_L3);
if (csum) {
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [PATCH net] sfc: check hash is valid before using it
2020-08-14 12:26 [PATCH net] sfc: check hash is valid before using it Edward Cree
@ 2020-08-14 21:07 ` David Miller
2020-08-18 8:35 ` Martin Habets
1 sibling, 0 replies; 3+ messages in thread
From: David Miller @ 2020-08-14 21:07 UTC (permalink / raw)
To: ecree; +Cc: linux-net-drivers, netdev
From: Edward Cree <ecree@solarflare.com>
Date: Fri, 14 Aug 2020 13:26:22 +0100
> On EF100, the RX hash field in the packet prefix may not be valid (e.g.
> if the header parse failed), and this is indicated by a one-bit flag
> elsewhere in the packet prefix. Only call skb_set_hash() if the
> RSS_HASH_VALID bit is set.
>
> Signed-off-by: Edward Cree <ecree@solarflare.com>
Applied.
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [PATCH net] sfc: check hash is valid before using it
2020-08-14 12:26 [PATCH net] sfc: check hash is valid before using it Edward Cree
2020-08-14 21:07 ` David Miller
@ 2020-08-18 8:35 ` Martin Habets
1 sibling, 0 replies; 3+ messages in thread
From: Martin Habets @ 2020-08-18 8:35 UTC (permalink / raw)
To: Edward Cree; +Cc: linux-net-drivers, davem, netdev
Hi Ed,
On Fri, Aug 14, 2020 at 01:26:22PM +0100, Edward Cree wrote:
> On EF100, the RX hash field in the packet prefix may not be valid (e.g.
> if the header parse failed), and this is indicated by a one-bit flag
> elsewhere in the packet prefix. Only call skb_set_hash() if the
> RSS_HASH_VALID bit is set.
>
> Signed-off-by: Edward Cree <ecree@solarflare.com>
> ---
> drivers/net/ethernet/sfc/ef100_rx.c | 5 +++++
> drivers/net/ethernet/sfc/ef100_rx.h | 1 +
> drivers/net/ethernet/sfc/efx.h | 8 ++++++++
> drivers/net/ethernet/sfc/net_driver.h | 2 ++
> drivers/net/ethernet/sfc/rx_common.c | 3 ++-
> 5 files changed, 18 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/net/ethernet/sfc/ef100_rx.c b/drivers/net/ethernet/sfc/ef100_rx.c
> index 13ba1a4f66fc..012925e878f4 100644
> --- a/drivers/net/ethernet/sfc/ef100_rx.c
> +++ b/drivers/net/ethernet/sfc/ef100_rx.c
> @@ -31,6 +31,11 @@
> #define ESF_GZ_RX_PREFIX_NT_OR_INNER_L3_CLASS_WIDTH \
> ESF_GZ_RX_PREFIX_HCLASS_NT_OR_INNER_L3_CLASS_WIDTH
>
> +bool ef100_rx_buf_hash_valid(const u8 *prefix)
> +{
> + return PREFIX_FIELD(prefix, RSS_HASH_VALID);
> +}
> +
> static bool check_fcs(struct efx_channel *channel, u32 *prefix)
> {
> u16 rxclass;
> diff --git a/drivers/net/ethernet/sfc/ef100_rx.h b/drivers/net/ethernet/sfc/ef100_rx.h
> index f2f266863966..fe45b36458d1 100644
> --- a/drivers/net/ethernet/sfc/ef100_rx.h
> +++ b/drivers/net/ethernet/sfc/ef100_rx.h
> @@ -14,6 +14,7 @@
>
> #include "net_driver.h"
>
> +bool ef100_rx_buf_hash_valid(const u8 *prefix);
> void efx_ef100_ev_rx(struct efx_channel *channel, const efx_qword_t *p_event);
> void ef100_rx_write(struct efx_rx_queue *rx_queue);
> void __ef100_rx_packet(struct efx_channel *channel);
> diff --git a/drivers/net/ethernet/sfc/efx.h b/drivers/net/ethernet/sfc/efx.h
> index a9808e86068d..daf0c00c1242 100644
> --- a/drivers/net/ethernet/sfc/efx.h
> +++ b/drivers/net/ethernet/sfc/efx.h
> @@ -45,6 +45,14 @@ static inline void efx_rx_flush_packet(struct efx_channel *channel)
> __ef100_rx_packet, __efx_rx_packet,
> channel);
> }
> +static inline bool efx_rx_buf_hash_valid(struct efx_nic *efx, const u8 *prefix)
> +{
> + if (efx->type->rx_buf_hash_valid)
For this to take effect you still need to hook up efx->type->rx_buf_hash_valid
in the ef100_nic.c efx_nic_type structs.
Martin
> + return INDIRECT_CALL_1(efx->type->rx_buf_hash_valid,
> + ef100_rx_buf_hash_valid,
> + prefix);
> + return true;
> +}
>
> /* Maximum number of TCP segments we support for soft-TSO */
> #define EFX_TSO_MAX_SEGS 100
> diff --git a/drivers/net/ethernet/sfc/net_driver.h b/drivers/net/ethernet/sfc/net_driver.h
> index 7bb7ecb480ae..dcb741d8bd11 100644
> --- a/drivers/net/ethernet/sfc/net_driver.h
> +++ b/drivers/net/ethernet/sfc/net_driver.h
> @@ -1265,6 +1265,7 @@ struct efx_udp_tunnel {
> * @rx_write: Write RX descriptors and doorbell
> * @rx_defer_refill: Generate a refill reminder event
> * @rx_packet: Receive the queued RX buffer on a channel
> + * @rx_buf_hash_valid: Determine whether the RX prefix contains a valid hash
> * @ev_probe: Allocate resources for event queue
> * @ev_init: Initialise event queue on the NIC
> * @ev_fini: Deinitialise event queue on the NIC
> @@ -1409,6 +1410,7 @@ struct efx_nic_type {
> void (*rx_write)(struct efx_rx_queue *rx_queue);
> void (*rx_defer_refill)(struct efx_rx_queue *rx_queue);
> void (*rx_packet)(struct efx_channel *channel);
> + bool (*rx_buf_hash_valid)(const u8 *prefix);
> int (*ev_probe)(struct efx_channel *channel);
> int (*ev_init)(struct efx_channel *channel);
> void (*ev_fini)(struct efx_channel *channel);
> diff --git a/drivers/net/ethernet/sfc/rx_common.c b/drivers/net/ethernet/sfc/rx_common.c
> index fb77c7bbe4af..ef9bca92b0b7 100644
> --- a/drivers/net/ethernet/sfc/rx_common.c
> +++ b/drivers/net/ethernet/sfc/rx_common.c
> @@ -525,7 +525,8 @@ efx_rx_packet_gro(struct efx_channel *channel, struct efx_rx_buffer *rx_buf,
> return;
> }
>
> - if (efx->net_dev->features & NETIF_F_RXHASH)
> + if (efx->net_dev->features & NETIF_F_RXHASH &&
> + efx_rx_buf_hash_valid(efx, eh))
> skb_set_hash(skb, efx_rx_buf_hash(efx, eh),
> PKT_HASH_TYPE_L3);
> if (csum) {
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2020-08-18 8:35 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-08-14 12:26 [PATCH net] sfc: check hash is valid before using it Edward Cree
2020-08-14 21:07 ` David Miller
2020-08-18 8:35 ` Martin Habets
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).