From 91603958d1d4fc3114739f9b264808940942e5c8 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Beno=C3=AEt=20Ganne?= Date: Fri, 16 Oct 2020 17:12:41 +0200 Subject: [PATCH] rdma: add RSS support for IPv6 and TCP MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Type: feature Change-Id: I8b0d918e6f13325954b29bf34e4ef224c1315c51 Signed-off-by: Benoît Ganne --- src/plugins/rdma/device.c | 81 ++++++++++++++++++++++++++++++----------------- src/plugins/rdma/rdma.h | 9 ++++-- 2 files changed, 58 insertions(+), 32 deletions(-) diff --git a/src/plugins/rdma/device.c b/src/plugins/rdma/device.c index c91567445bf..c2eb0006217 100644 --- a/src/plugins/rdma/device.c +++ b/src/plugins/rdma/device.c @@ -57,7 +57,7 @@ rdma_main_t rdma_main; static struct ibv_flow * rdma_rxq_init_flow (const rdma_device_t * rd, struct ibv_qp *qp, const mac_address_t * mac, const mac_address_t * mask, - u32 flags) + u16 ether_type, u32 flags) { struct ibv_flow *flow; struct raw_eth_flow_attr @@ -76,6 +76,12 @@ rdma_rxq_init_flow (const rdma_device_t * rd, struct ibv_qp *qp, memcpy (fa.spec_eth.val.dst_mac, mac, sizeof (fa.spec_eth.val.dst_mac)); memcpy (fa.spec_eth.mask.dst_mac, mask, sizeof (fa.spec_eth.mask.dst_mac)); + if (ether_type) + { + fa.spec_eth.val.ether_type = ether_type; + fa.spec_eth.mask.ether_type = 0xffff; + } + flow = ibv_create_flow (qp, &fa.attr); if (!flow) rdma_log (VLIB_LOG_LEVEL_ERR, rd, "ibv_create_flow() failed"); @@ -104,16 +110,17 @@ rdma_dev_set_promisc (rdma_device_t * rd) const mac_address_t all = {.bytes = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0} }; int err; - err = rdma_rxq_destroy_flow (rd, &rd->flow_mcast); - if (err) - return ~0; - - err = rdma_rxq_destroy_flow (rd, &rd->flow_ucast); + err = rdma_rxq_destroy_flow (rd, &rd->flow_mcast6); + err |= rdma_rxq_destroy_flow (rd, &rd->flow_ucast6); + err |= rdma_rxq_destroy_flow (rd, &rd->flow_mcast4); + err |= rdma_rxq_destroy_flow (rd, &rd->flow_ucast4); if (err) return ~0; - rd->flow_ucast = rdma_rxq_init_flow (rd, rd->rx_qp, &all, &all, 0); - if (!rd->flow_ucast) + rd->flow_ucast6 = + rdma_rxq_init_flow (rd, rd->rx_qp6, &all, &all, ntohs (ETH_P_IPV6), 0); + rd->flow_ucast4 = rdma_rxq_init_flow (rd, rd->rx_qp4, &all, &all, 0, 0); + if (!rd->flow_ucast6 || !rd->flow_ucast4) return ~0; rd->flags |= RDMA_DEVICE_F_PROMISC; @@ -128,25 +135,30 @@ rdma_dev_set_ucast (rdma_device_t * rd) const mac_address_t mcast = {.bytes = {0x1, 0x0, 0x0, 0x0, 0x0, 0x0} }; int err; - err = rdma_rxq_destroy_flow (rd, &rd->flow_mcast); - if (err) - return ~0; - - err = rdma_rxq_destroy_flow (rd, &rd->flow_ucast); + err = rdma_rxq_destroy_flow (rd, &rd->flow_mcast6); + err |= rdma_rxq_destroy_flow (rd, &rd->flow_ucast6); + err |= rdma_rxq_destroy_flow (rd, &rd->flow_mcast4); + err |= rdma_rxq_destroy_flow (rd, &rd->flow_ucast4); if (err) return ~0; - /* receive only packets with src = our MAC */ - rd->flow_ucast = rdma_rxq_init_flow (rd, rd->rx_qp, &rd->hwaddr, &ucast, 0); - if (!rd->flow_ucast) - return ~0; - - /* receive multicast packets */ - rd->flow_mcast = rdma_rxq_init_flow (rd, rd->rx_qp, &mcast, &mcast, - IBV_FLOW_ATTR_FLAGS_DONT_TRAP - /* let others receive mcast packet too (eg. Linux) */ + rd->flow_ucast6 = + rdma_rxq_init_flow (rd, rd->rx_qp6, &rd->hwaddr, &ucast, + ntohs (ETH_P_IPV6), 0); + rd->flow_mcast6 = + rdma_rxq_init_flow (rd, rd->rx_qp6, &mcast, &mcast, ntohs (ETH_P_IPV6), + IBV_FLOW_ATTR_FLAGS_DONT_TRAP + /* let others receive mcast packet too (eg. Linux) */ + ); + rd->flow_ucast4 = + rdma_rxq_init_flow (rd, rd->rx_qp4, &rd->hwaddr, &ucast, 0, 0); + rd->flow_mcast4 = + rdma_rxq_init_flow (rd, rd->rx_qp4, &mcast, &mcast, 0, + IBV_FLOW_ATTR_FLAGS_DONT_TRAP + /* let others receive mcast packet too (eg. Linux) */ ); - if (!rd->flow_mcast) + if (!rd->flow_ucast6 || !rd->flow_mcast6 || !rd->flow_ucast4 + || !rd->flow_mcast4) return ~0; rd->flags &= ~RDMA_DEVICE_F_PROMISC; @@ -375,8 +387,10 @@ rdma_dev_cleanup (rdma_device_t * rd) rdma_log (VLIB_LOG_LEVEL_DEBUG, rd, #fn "() failed (rv = %d)", rv); \ } - _(ibv_destroy_flow, rd->flow_mcast); - _(ibv_destroy_flow, rd->flow_ucast); + _(ibv_destroy_flow, rd->flow_mcast6); + _(ibv_destroy_flow, rd->flow_ucast6); + _(ibv_destroy_flow, rd->flow_mcast4); + _(ibv_destroy_flow, rd->flow_ucast4); _(ibv_dereg_mr, rd->mr); vec_foreach (txq, rd->txqs) { @@ -389,7 +403,8 @@ rdma_dev_cleanup (rdma_device_t * rd) _(ibv_destroy_cq, rxq->cq); } _(ibv_destroy_rwq_ind_table, rd->rx_rwq_ind_tbl); - _(ibv_destroy_qp, rd->rx_qp); + _(ibv_destroy_qp, rd->rx_qp6); + _(ibv_destroy_qp, rd->rx_qp4); _(ibv_dealloc_pd, rd->pd); _(ibv_close_device, rd->ctx); #undef _ @@ -523,10 +538,18 @@ rdma_rxq_finalize (vlib_main_t * vm, rdma_device_t * rd) qpia.rx_hash_conf.rx_hash_key_len = sizeof (rdma_rss_hash_key); qpia.rx_hash_conf.rx_hash_key = rdma_rss_hash_key; qpia.rx_hash_conf.rx_hash_function = IBV_RX_HASH_FUNC_TOEPLITZ; + qpia.rx_hash_conf.rx_hash_fields_mask = - IBV_RX_HASH_SRC_IPV4 | IBV_RX_HASH_DST_IPV4; - if ((rd->rx_qp = ibv_create_qp_ex (rd->ctx, &qpia)) == 0) - return clib_error_return_unix (0, "Queue Pair create failed"); + IBV_RX_HASH_SRC_IPV4 | IBV_RX_HASH_DST_IPV4 | IBV_RX_HASH_SRC_PORT_TCP | + IBV_RX_HASH_DST_PORT_TCP; + if ((rd->rx_qp4 = ibv_create_qp_ex (rd->ctx, &qpia)) == 0) + return clib_error_return_unix (0, "IPv4 Queue Pair create failed"); + + qpia.rx_hash_conf.rx_hash_fields_mask = + IBV_RX_HASH_SRC_IPV6 | IBV_RX_HASH_DST_IPV6 | IBV_RX_HASH_SRC_PORT_TCP | + IBV_RX_HASH_DST_PORT_TCP; + if ((rd->rx_qp6 = ibv_create_qp_ex (rd->ctx, &qpia)) == 0) + return clib_error_return_unix (0, "IPv6 Queue Pair create failed"); if (rdma_dev_set_ucast (rd)) return clib_error_return_unix (0, "Set unicast mode failed"); diff --git a/src/plugins/rdma/rdma.h b/src/plugins/rdma/rdma.h index 016956ee0f2..19bfb8b11e5 100644 --- a/src/plugins/rdma/rdma.h +++ b/src/plugins/rdma/rdma.h @@ -172,10 +172,13 @@ typedef struct struct ibv_context *ctx; struct ibv_pd *pd; struct ibv_mr *mr; - struct ibv_qp *rx_qp; + struct ibv_qp *rx_qp4; + struct ibv_qp *rx_qp6; struct ibv_rwq_ind_table *rx_rwq_ind_tbl; - struct ibv_flow *flow_ucast; - struct ibv_flow *flow_mcast; + struct ibv_flow *flow_ucast4; + struct ibv_flow *flow_mcast4; + struct ibv_flow *flow_ucast6; + struct ibv_flow *flow_mcast6; clib_error_t *error; } rdma_device_t; -- 2.16.6