Commit 905e4a41 authored by Alexander Duyck's avatar Alexander Duyck Committed by David S. Miller

ixgbe: cleanup flow director hash computation to improve performance

This change cleans up the layout of the flow director data, and the
algorithm used to calculate the hash resulting in a 35x / 3500% performance
increase versus the old flow director hash computation.  The overall effect
is only a 1% increase in transactions per second though due to the fact
that only 1 packet in 20 are actually hashed upon.

TCP_RR before:
Socket Size   Request  Resp.   Elapsed  Trans.
Send   Recv   Size     Size    Time     Rate
bytes  Bytes  bytes    bytes   secs.    per sec

16384  87380  1        1       60.00    23059.27
16384  87380

TCP_RR after:
Socket Size   Request  Resp.   Elapsed  Trans.
Send   Recv   Size     Size    Time     Rate
bytes  Bytes  bytes    bytes   secs.    per sec

16384  87380  1        1       60.00    23239.98
16384  87380
Signed-off-by: default avatarAlexander Duyck <alexander.h.duyck@intel.com>
Tested-by: default avatarStephen Ko <stephen.s.ko@intel.com>
Signed-off-by: default avatarJeff Kirsher <jeffrey.t.kirsher@intel.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 2d39d576
...@@ -526,25 +526,25 @@ extern s32 ixgbe_reinit_fdir_tables_82599(struct ixgbe_hw *hw); ...@@ -526,25 +526,25 @@ extern s32 ixgbe_reinit_fdir_tables_82599(struct ixgbe_hw *hw);
extern s32 ixgbe_init_fdir_signature_82599(struct ixgbe_hw *hw, u32 pballoc); extern s32 ixgbe_init_fdir_signature_82599(struct ixgbe_hw *hw, u32 pballoc);
extern s32 ixgbe_init_fdir_perfect_82599(struct ixgbe_hw *hw, u32 pballoc); extern s32 ixgbe_init_fdir_perfect_82599(struct ixgbe_hw *hw, u32 pballoc);
extern s32 ixgbe_fdir_add_signature_filter_82599(struct ixgbe_hw *hw, extern s32 ixgbe_fdir_add_signature_filter_82599(struct ixgbe_hw *hw,
struct ixgbe_atr_input *input, union ixgbe_atr_input *input,
u8 queue); u8 queue);
extern s32 ixgbe_fdir_add_perfect_filter_82599(struct ixgbe_hw *hw, extern s32 ixgbe_fdir_add_perfect_filter_82599(struct ixgbe_hw *hw,
struct ixgbe_atr_input *input, union ixgbe_atr_input *input,
struct ixgbe_atr_input_masks *input_masks, struct ixgbe_atr_input_masks *input_masks,
u16 soft_id, u8 queue); u16 soft_id, u8 queue);
extern s32 ixgbe_atr_set_vlan_id_82599(struct ixgbe_atr_input *input, extern s32 ixgbe_atr_set_vlan_id_82599(union ixgbe_atr_input *input,
u16 vlan_id); u16 vlan_id);
extern s32 ixgbe_atr_set_src_ipv4_82599(struct ixgbe_atr_input *input, extern s32 ixgbe_atr_set_src_ipv4_82599(union ixgbe_atr_input *input,
u32 src_addr); u32 src_addr);
extern s32 ixgbe_atr_set_dst_ipv4_82599(struct ixgbe_atr_input *input, extern s32 ixgbe_atr_set_dst_ipv4_82599(union ixgbe_atr_input *input,
u32 dst_addr); u32 dst_addr);
extern s32 ixgbe_atr_set_src_port_82599(struct ixgbe_atr_input *input, extern s32 ixgbe_atr_set_src_port_82599(union ixgbe_atr_input *input,
u16 src_port); u16 src_port);
extern s32 ixgbe_atr_set_dst_port_82599(struct ixgbe_atr_input *input, extern s32 ixgbe_atr_set_dst_port_82599(union ixgbe_atr_input *input,
u16 dst_port); u16 dst_port);
extern s32 ixgbe_atr_set_flex_byte_82599(struct ixgbe_atr_input *input, extern s32 ixgbe_atr_set_flex_byte_82599(union ixgbe_atr_input *input,
u16 flex_byte); u16 flex_byte);
extern s32 ixgbe_atr_set_l4type_82599(struct ixgbe_atr_input *input, extern s32 ixgbe_atr_set_l4type_82599(union ixgbe_atr_input *input,
u8 l4type); u8 l4type);
extern void ixgbe_configure_rscctl(struct ixgbe_adapter *adapter, extern void ixgbe_configure_rscctl(struct ixgbe_adapter *adapter,
struct ixgbe_ring *ring); struct ixgbe_ring *ring);
......
This diff is collapsed.
...@@ -2278,7 +2278,7 @@ static int ixgbe_set_rx_ntuple(struct net_device *dev, ...@@ -2278,7 +2278,7 @@ static int ixgbe_set_rx_ntuple(struct net_device *dev,
{ {
struct ixgbe_adapter *adapter = netdev_priv(dev); struct ixgbe_adapter *adapter = netdev_priv(dev);
struct ethtool_rx_ntuple_flow_spec fs = cmd->fs; struct ethtool_rx_ntuple_flow_spec fs = cmd->fs;
struct ixgbe_atr_input input_struct; union ixgbe_atr_input input_struct;
struct ixgbe_atr_input_masks input_masks; struct ixgbe_atr_input_masks input_masks;
int target_queue; int target_queue;
...@@ -2293,7 +2293,7 @@ static int ixgbe_set_rx_ntuple(struct net_device *dev, ...@@ -2293,7 +2293,7 @@ static int ixgbe_set_rx_ntuple(struct net_device *dev,
(fs.action < ETHTOOL_RXNTUPLE_ACTION_DROP)) (fs.action < ETHTOOL_RXNTUPLE_ACTION_DROP))
return -EINVAL; return -EINVAL;
memset(&input_struct, 0, sizeof(struct ixgbe_atr_input)); memset(&input_struct, 0, sizeof(union ixgbe_atr_input));
memset(&input_masks, 0, sizeof(struct ixgbe_atr_input_masks)); memset(&input_masks, 0, sizeof(struct ixgbe_atr_input_masks));
input_masks.src_ip_mask = fs.m_u.tcp_ip4_spec.ip4src; input_masks.src_ip_mask = fs.m_u.tcp_ip4_spec.ip4src;
......
...@@ -6509,21 +6509,20 @@ static void ixgbe_tx_queue(struct ixgbe_ring *tx_ring, ...@@ -6509,21 +6509,20 @@ static void ixgbe_tx_queue(struct ixgbe_ring *tx_ring,
static void ixgbe_atr(struct ixgbe_adapter *adapter, struct sk_buff *skb, static void ixgbe_atr(struct ixgbe_adapter *adapter, struct sk_buff *skb,
u8 queue, u32 tx_flags, __be16 protocol) u8 queue, u32 tx_flags, __be16 protocol)
{ {
struct ixgbe_atr_input atr_input; union ixgbe_atr_input atr_input;
struct iphdr *iph = ip_hdr(skb); struct iphdr *iph = ip_hdr(skb);
struct ethhdr *eth = (struct ethhdr *)skb->data; struct ethhdr *eth = (struct ethhdr *)skb->data;
struct tcphdr *th; struct tcphdr *th;
u16 vlan_id; __be16 vlan_id;
/* Right now, we support IPv4 w/ TCP only */ /* Right now, we support IPv4 w/ TCP only */
if (protocol != htons(ETH_P_IP) || if (protocol != htons(ETH_P_IP) ||
iph->protocol != IPPROTO_TCP) iph->protocol != IPPROTO_TCP)
return; return;
memset(&atr_input, 0, sizeof(struct ixgbe_atr_input)); memset(&atr_input, 0, sizeof(union ixgbe_atr_input));
vlan_id = (tx_flags & IXGBE_TX_FLAGS_VLAN_MASK) >> vlan_id = htons(tx_flags >> IXGBE_TX_FLAGS_VLAN_SHIFT);
IXGBE_TX_FLAGS_VLAN_SHIFT;
th = tcp_hdr(skb); th = tcp_hdr(skb);
...@@ -6531,7 +6530,7 @@ static void ixgbe_atr(struct ixgbe_adapter *adapter, struct sk_buff *skb, ...@@ -6531,7 +6530,7 @@ static void ixgbe_atr(struct ixgbe_adapter *adapter, struct sk_buff *skb,
ixgbe_atr_set_src_port_82599(&atr_input, th->dest); ixgbe_atr_set_src_port_82599(&atr_input, th->dest);
ixgbe_atr_set_dst_port_82599(&atr_input, th->source); ixgbe_atr_set_dst_port_82599(&atr_input, th->source);
ixgbe_atr_set_flex_byte_82599(&atr_input, eth->h_proto); ixgbe_atr_set_flex_byte_82599(&atr_input, eth->h_proto);
ixgbe_atr_set_l4type_82599(&atr_input, IXGBE_ATR_L4TYPE_TCP); ixgbe_atr_set_l4type_82599(&atr_input, IXGBE_ATR_FLOW_TYPE_TCPV4);
/* src and dst are inverted, think how the receiver sees them */ /* src and dst are inverted, think how the receiver sees them */
ixgbe_atr_set_src_ipv4_82599(&atr_input, iph->daddr); ixgbe_atr_set_src_ipv4_82599(&atr_input, iph->daddr);
ixgbe_atr_set_dst_ipv4_82599(&atr_input, iph->saddr); ixgbe_atr_set_dst_ipv4_82599(&atr_input, iph->saddr);
......
...@@ -1990,6 +1990,7 @@ enum ixgbe_fdir_pballoc_type { ...@@ -1990,6 +1990,7 @@ enum ixgbe_fdir_pballoc_type {
#define IXGBE_FDIRCMD_LAST 0x00000800 #define IXGBE_FDIRCMD_LAST 0x00000800
#define IXGBE_FDIRCMD_COLLISION 0x00001000 #define IXGBE_FDIRCMD_COLLISION 0x00001000
#define IXGBE_FDIRCMD_QUEUE_EN 0x00008000 #define IXGBE_FDIRCMD_QUEUE_EN 0x00008000
#define IXGBE_FDIRCMD_FLOW_TYPE_SHIFT 5
#define IXGBE_FDIRCMD_RX_QUEUE_SHIFT 16 #define IXGBE_FDIRCMD_RX_QUEUE_SHIFT 16
#define IXGBE_FDIRCMD_VT_POOL_SHIFT 24 #define IXGBE_FDIRCMD_VT_POOL_SHIFT 24
#define IXGBE_FDIR_INIT_DONE_POLL 10 #define IXGBE_FDIR_INIT_DONE_POLL 10
...@@ -2147,51 +2148,63 @@ typedef u32 ixgbe_physical_layer; ...@@ -2147,51 +2148,63 @@ typedef u32 ixgbe_physical_layer;
#define FC_LOW_WATER(MTU) (2 * (2 * PAUSE_MTU(MTU) + PAUSE_RTT)) #define FC_LOW_WATER(MTU) (2 * (2 * PAUSE_MTU(MTU) + PAUSE_RTT))
/* Software ATR hash keys */ /* Software ATR hash keys */
#define IXGBE_ATR_BUCKET_HASH_KEY 0xE214AD3D #define IXGBE_ATR_BUCKET_HASH_KEY 0x3DAD14E2
#define IXGBE_ATR_SIGNATURE_HASH_KEY 0x14364D17 #define IXGBE_ATR_SIGNATURE_HASH_KEY 0x174D3614
/* Software ATR input stream offsets and masks */
#define IXGBE_ATR_VLAN_OFFSET 0
#define IXGBE_ATR_SRC_IPV6_OFFSET 2
#define IXGBE_ATR_SRC_IPV4_OFFSET 14
#define IXGBE_ATR_DST_IPV6_OFFSET 18
#define IXGBE_ATR_DST_IPV4_OFFSET 30
#define IXGBE_ATR_SRC_PORT_OFFSET 34
#define IXGBE_ATR_DST_PORT_OFFSET 36
#define IXGBE_ATR_FLEX_BYTE_OFFSET 38
#define IXGBE_ATR_VM_POOL_OFFSET 40
#define IXGBE_ATR_L4TYPE_OFFSET 41
/* Software ATR input stream values and masks */
#define IXGBE_ATR_HASH_MASK 0x7fff
#define IXGBE_ATR_L4TYPE_MASK 0x3 #define IXGBE_ATR_L4TYPE_MASK 0x3
#define IXGBE_ATR_L4TYPE_IPV6_MASK 0x4
#define IXGBE_ATR_L4TYPE_UDP 0x1 #define IXGBE_ATR_L4TYPE_UDP 0x1
#define IXGBE_ATR_L4TYPE_TCP 0x2 #define IXGBE_ATR_L4TYPE_TCP 0x2
#define IXGBE_ATR_L4TYPE_SCTP 0x3 #define IXGBE_ATR_L4TYPE_SCTP 0x3
#define IXGBE_ATR_HASH_MASK 0x7fff #define IXGBE_ATR_L4TYPE_IPV6_MASK 0x4
enum ixgbe_atr_flow_type {
IXGBE_ATR_FLOW_TYPE_IPV4 = 0x0,
IXGBE_ATR_FLOW_TYPE_UDPV4 = 0x1,
IXGBE_ATR_FLOW_TYPE_TCPV4 = 0x2,
IXGBE_ATR_FLOW_TYPE_SCTPV4 = 0x3,
IXGBE_ATR_FLOW_TYPE_IPV6 = 0x4,
IXGBE_ATR_FLOW_TYPE_UDPV6 = 0x5,
IXGBE_ATR_FLOW_TYPE_TCPV6 = 0x6,
IXGBE_ATR_FLOW_TYPE_SCTPV6 = 0x7,
};
/* Flow Director ATR input struct. */ /* Flow Director ATR input struct. */
struct ixgbe_atr_input { union ixgbe_atr_input {
/* Byte layout in order, all values with MSB first: /*
* Byte layout in order, all values with MSB first:
* *
* vm_pool - 1 byte
* flow_type - 1 byte
* vlan_id - 2 bytes * vlan_id - 2 bytes
* src_ip - 16 bytes * src_ip - 16 bytes
* dst_ip - 16 bytes * dst_ip - 16 bytes
* src_port - 2 bytes * src_port - 2 bytes
* dst_port - 2 bytes * dst_port - 2 bytes
* flex_bytes - 2 bytes * flex_bytes - 2 bytes
* vm_pool - 1 byte * rsvd0 - 2 bytes - space reserved must be 0.
* l4type - 1 byte
*/ */
u8 byte_stream[42]; struct {
u8 vm_pool;
u8 flow_type;
__be16 vlan_id;
__be32 dst_ip[4];
__be32 src_ip[4];
__be16 src_port;
__be16 dst_port;
__be16 flex_bytes;
__be16 rsvd0;
} formatted;
__be32 dword_stream[11];
}; };
struct ixgbe_atr_input_masks { struct ixgbe_atr_input_masks {
u32 src_ip_mask; __be32 src_ip_mask;
u32 dst_ip_mask; __be32 dst_ip_mask;
u16 src_port_mask; __be16 src_port_mask;
u16 dst_port_mask; __be16 dst_port_mask;
u16 vlan_id_mask; __be16 vlan_id_mask;
u16 data_mask; __be16 data_mask;
}; };
enum ixgbe_eeprom_type { enum ixgbe_eeprom_type {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment