ebpf: implement RSS load balancing in hardware mode

pull/3952/head
Eric Leblond 7 years ago committed by Victor Julien
parent 8b4c365352
commit 94bda5b7fb

@ -45,6 +45,10 @@
#define USE_PERCPU_HASH 1 #define USE_PERCPU_HASH 1
#define GOT_TX_PEER 1 #define GOT_TX_PEER 1
/* set to non 0 to load balance in hardware mode on RSS_QUEUE_NUMBERS queues
* and unset BUILD_CPUMAP */
#define RSS_QUEUE_NUMBERS 40
struct vlan_hdr { struct vlan_hdr {
__u16 h_vlan_TCI; __u16 h_vlan_TCI;
__u16 h_vlan_encapsulated_proto; __u16 h_vlan_encapsulated_proto;
@ -202,7 +206,7 @@ static __always_inline int get_dport(void *trans_data, void *data_end,
} }
} }
static int __always_inline filter_ipv4(void *data, __u64 nh_off, void *data_end, __u16 vlan0, __u16 vlan1) static int __always_inline filter_ipv4(struct xdp_md *ctx, void *data, __u64 nh_off, void *data_end, __u16 vlan0, __u16 vlan1)
{ {
struct iphdr *iph = data + nh_off; struct iphdr *iph = data + nh_off;
int dport; int dport;
@ -296,11 +300,17 @@ static int __always_inline filter_ipv4(void *data, __u64 nh_off, void *data_end,
return XDP_PASS; return XDP_PASS;
} }
#else #else
#if RSS_QUEUE_NUMBERS
/* IP-pairs + protocol (UDP/TCP/ICMP) hit same CPU */
__u32 xdp_hash = tuple.src + tuple.dst;
xdp_hash = SuperFastHash((char *)&xdp_hash, 4, INITVAL + iph->protocol);
ctx->rx_queue_index = xdp_hash % RSS_QUEUE_NUMBERS;
#endif
return XDP_PASS; return XDP_PASS;
#endif #endif
} }
static int __always_inline filter_ipv6(void *data, __u64 nh_off, void *data_end, __u16 vlan0, __u16 vlan1) static int __always_inline filter_ipv6(struct xdp_md *ctx, void *data, __u64 nh_off, void *data_end, __u16 vlan0, __u16 vlan1)
{ {
struct ipv6hdr *ip6h = data + nh_off; struct ipv6hdr *ip6h = data + nh_off;
int dport; int dport;
@ -388,6 +398,16 @@ static int __always_inline filter_ipv6(void *data, __u64 nh_off, void *data_end,
return XDP_PASS; return XDP_PASS;
} }
#else #else
#if RSS_QUEUE_NUMBERS
/* IP-pairs + protocol (UDP/TCP/ICMP) hit same CPU */
__u32 xdp_hash = tuple.src[0] + tuple.dst[0];
xdp_hash += tuple.src[1] + tuple.dst[1];
xdp_hash += tuple.src[2] + tuple.dst[2];
xdp_hash += tuple.src[3] + tuple.dst[3];
xdp_hash = SuperFastHash((char *)&xdp_hash, 4, ip6h->nexthdr);
ctx->rx_queue_index = xdp_hash % RSS_QUEUE_NUMBERS;
#endif
return XDP_PASS; return XDP_PASS;
#endif #endif
} }
@ -447,9 +467,9 @@ int SEC("xdp") xdp_hashfilter(struct xdp_md *ctx)
} }
if (h_proto == __constant_htons(ETH_P_IP)) if (h_proto == __constant_htons(ETH_P_IP))
return filter_ipv4(data, nh_off, data_end, vlan0, vlan1); return filter_ipv4(ctx, data, nh_off, data_end, vlan0, vlan1);
else if (h_proto == __constant_htons(ETH_P_IPV6)) else if (h_proto == __constant_htons(ETH_P_IPV6))
return filter_ipv6(data, nh_off, data_end, vlan0, vlan1); return filter_ipv6(ctx, data, nh_off, data_end, vlan0, vlan1);
else else
rc = XDP_PASS; rc = XDP_PASS;

Loading…
Cancel
Save