]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
msg/async/dpdk: refactor set_rss_table to support DPDK 19.05 32170/head
authorf00391043 <f00391043@huawei.com>
Thu, 14 Nov 2019 07:58:34 +0000 (15:58 +0800)
committerluo rixin <luorixin@huawei.com>
Thu, 12 Dec 2019 13:11:36 +0000 (21:11 +0800)
The filter API was deprecated in DPDK 19.05, using the flow
API to set rss table.

Signed-off-by: Chunsong Feng <fengchunsong@huawei.com>
Signed-off-by: luo rixin <luorixin@huawei.com>
src/msg/async/dpdk/DPDK.cc
src/msg/async/dpdk/DPDK.h

index 79bffb074b0114a8314687750b2171fc51ba7e51..c73b6c147eb614a27e16c78898416a7474543e9f 100644 (file)
@@ -404,25 +404,8 @@ int DPDKDevice::init_port_fini()
     return -1;
   }
 
-  if (_num_queues > 1) {
-    if (!rte_eth_dev_filter_supported(_port_idx, RTE_ETH_FILTER_HASH)) {
-      ldout(cct, 5) << __func__ << " Port " << _port_idx << ": HASH FILTER configuration is supported" << dendl;
-
-      // Setup HW touse the TOEPLITZ hash function as an RSS hash function
-      struct rte_eth_hash_filter_info info = {};
-
-      info.info_type = RTE_ETH_HASH_FILTER_GLOBAL_CONFIG;
-      info.info.global_conf.hash_func = RTE_ETH_HASH_FUNCTION_TOEPLITZ;
-
-      if (rte_eth_dev_filter_ctrl(_port_idx, RTE_ETH_FILTER_HASH,
-                                  RTE_ETH_FILTER_SET, &info) < 0) {
-        lderr(cct) << __func__ << " cannot set hash function on a port " << _port_idx << dendl;
-        return -1;
-      }
-    }
-
+  if (_num_queues > 1)
     set_rss_table();
-  }
 
   // Wait for a link
   if (check_port_link_status() < 0) {
@@ -434,6 +417,50 @@ int DPDKDevice::init_port_fini()
   return 0;
 }
 
+void DPDKDevice::set_rss_table()
+{
+  struct rte_flow_attr attr;
+  struct rte_flow_item pattern[1];
+  struct rte_flow_action action[2];
+  struct rte_flow_action_rss rss_conf;
+
+  /*
+   * set the rule attribute.
+   * in this case only ingress packets will be checked.
+   */
+  memset(&attr, 0, sizeof(struct rte_flow_attr));
+  attr.ingress = 1;
+
+  /* the final level must be always type end */
+  pattern[0].type = RTE_FLOW_ITEM_TYPE_END;
+
+  /*
+   * create the action sequence.
+   * one action only,  set rss hash func to toeplitz.
+   */
+  uint16_t i = 0;
+  for (auto& r : _redir_table) {
+    r = i++ % _num_queues;
+  }
+  rss_conf.func = RTE_ETH_HASH_FUNCTION_TOEPLITZ;
+  rss_conf.types = ETH_RSS_FRAG_IPV4 | ETH_RSS_NONFRAG_IPV4_TCP;
+  rss_conf.queue_num = _num_queues;
+  rss_conf.queue = const_cast<uint16_t *>(_redir_table.data());
+  rss_conf.key_len = _dev_info.hash_key_size;
+  rss_conf.key = const_cast<uint8_t *>(_rss_key.data());
+  rss_conf.level = 0;
+  action[0].type = RTE_FLOW_ACTION_TYPE_RSS;
+  action[0].conf = &rss_conf;
+  action[1].type = RTE_FLOW_ACTION_TYPE_END;
+
+  if (rte_flow_validate(_port_idx, &attr, pattern, action, nullptr) == 0)
+    _flow = rte_flow_create(_port_idx, &attr, pattern, action, nullptr);
+  else
+    ldout(cct, 0) << __func__ << " Port " << _port_idx
+                  << ": flow rss func configuration is unsupported"
+                  << dendl;
+}
+
 void DPDKQueuePair::configure_proxies(const std::map<unsigned, float>& cpu_weights) {
   ceph_assert(!cpu_weights.empty());
   if (cpu_weights.size() == 1 && cpu_weights.begin()->first == _qid) {
@@ -1210,34 +1237,6 @@ size_t DPDKQueuePair::tx_buf::copy_one_data_buf(
   return len;
 }
 
-void DPDKDevice::set_rss_table()
-{
-  // always fill our local indirection table.
-  unsigned i = 0;
-  for (auto& r : _redir_table) {
-    r = i++ % _num_queues;
-  }
-
-  if (_dev_info.reta_size == 0)
-    return;
-
-  int reta_conf_size = std::max(1, _dev_info.reta_size / RTE_RETA_GROUP_SIZE);
-  rte_eth_rss_reta_entry64 reta_conf[reta_conf_size];
-
-  // Configure the HW indirection table
-  i = 0;
-  for (auto& x : reta_conf) {
-    x.mask = ~0ULL;
-    for (auto& r: x.reta) {
-      r = i++ % _num_queues;
-    }
-  }
-
-  if (rte_eth_dev_rss_reta_update(_port_idx, reta_conf, _dev_info.reta_size)) {
-    rte_exit(EXIT_FAILURE, "Port %d: Failed to update an RSS indirection table", _port_idx);
-  }
-}
-
 /******************************** Interface functions *************************/
 
 std::unique_ptr<DPDKDevice> create_dpdk_net_device(
index 6bb52973e095a0e0c35c3a036297d864599e82ef..78a1a0769326106763e7e0e36ba3bdf474686872 100644 (file)
@@ -748,8 +748,9 @@ class DPDKDevice {
   unsigned _home_cpu;
   bool _use_lro;
   bool _enable_fc;
-  std::vector<uint8_t> _redir_table;
+  std::vector<uint16_t> _redir_table;
   rss_key_type _rss_key;
+  struct rte_flow *_flow = nullptr;
   bool _is_i40e_device = false;
   bool _is_vmxnet3_device = false;
 
@@ -823,6 +824,8 @@ class DPDKDevice {
   }
 
   ~DPDKDevice() {
+    if (_flow)
+       rte_flow_destroy(_port_idx, _flow, nullptr);
     rte_eth_dev_stop(_port_idx);
   }