init / exit function ordering
[vpp.git] / src / plugins / dpdk / device / init.c
index 13dc7de..22ea659 100644 (file)
@@ -36,6 +36,7 @@
 #include <sys/mount.h>
 #include <string.h>
 #include <fcntl.h>
+#include <dirent.h>
 
 #include <dpdk/device/dpdk_priv.h>
 
@@ -157,6 +158,47 @@ dpdk_port_crc_strip_enabled (dpdk_device_t * xd)
   return !(xd->port_conf.rxmode.offloads & DEV_RX_OFFLOAD_KEEP_CRC);
 }
 
+/* The funciton check_l3cache helps check if Level 3 cache exists or not on current CPUs
+  return value 1: exist.
+  return value 0: not exist.
+*/
+static int
+check_l3cache ()
+{
+
+  struct dirent *dp;
+  clib_error_t *err;
+  const char *sys_cache_dir = "/sys/devices/system/cpu/cpu0/cache";
+  DIR *dir_cache = opendir (sys_cache_dir);
+
+  if (dir_cache == NULL)
+    return -1;
+
+  while ((dp = readdir (dir_cache)) != NULL)
+    {
+      if (dp->d_type == DT_DIR)
+       {
+         u8 *p = NULL;
+         int level_cache = -1;
+
+         p = format (p, "%s/%s/%s", sys_cache_dir, dp->d_name, "level");
+         if ((err = clib_sysfs_read ((char *) p, "%d", &level_cache)))
+           clib_error_free (err);
+
+         if (level_cache == 3)
+           {
+             closedir (dir_cache);
+             return 1;
+           }
+       }
+    }
+
+  if (dir_cache != NULL)
+    closedir (dir_cache);
+
+  return 0;
+}
+
 static clib_error_t *
 dpdk_lib_init (dpdk_main_t * dm)
 {
@@ -229,6 +271,7 @@ dpdk_lib_init (dpdk_main_t * dm)
       struct rte_eth_dev_info dev_info;
       struct rte_pci_device *pci_dev;
       struct rte_eth_link l;
+      dpdk_portid_t next_port_id;
       dpdk_device_config_t *devconf = 0;
       vlib_pci_addr_t pci_addr;
       uword *p = 0;
@@ -274,13 +317,14 @@ dpdk_lib_init (dpdk_main_t * dm)
        devconf = &dm->conf->default_devconf;
 
       /* Handle interface naming for devices with multiple ports sharing same PCI ID */
-      if (pci_dev)
+      if (pci_dev &&
+         ((next_port_id = rte_eth_find_next (i + 1)) != RTE_MAX_ETHPORTS))
        {
          struct rte_eth_dev_info di = { 0 };
          struct rte_pci_device *next_pci_dev;
-         rte_eth_dev_info_get (i + 1, &di);
+         rte_eth_dev_info_get (next_port_id, &di);
          next_pci_dev = di.device ? RTE_DEV_TO_PCI (di.device) : 0;
-         if (pci_dev && next_pci_dev &&
+         if (next_pci_dev &&
              pci_addr.as_u32 != last_pci_addr.as_u32 &&
              memcmp (&pci_dev->addr, &next_pci_dev->addr,
                      sizeof (struct rte_pci_addr)) == 0)
@@ -501,10 +545,30 @@ dpdk_lib_init (dpdk_main_t * dm)
 
          if (devconf->num_rx_desc)
            xd->nb_rx_desc = devconf->num_rx_desc;
+          else {
+
+            /* If num_rx_desc is not specified by VPP user, the current CPU is working
+            with 2M page and has no L3 cache, default num_rx_desc is changed to 512
+            from original 1024 to help reduce TLB misses.
+            */
+            if ((clib_mem_get_default_hugepage_size () == 2 << 20)
+              && check_l3cache() == 0)
+              xd->nb_rx_desc = 512;
+          }
 
          if (devconf->num_tx_desc)
            xd->nb_tx_desc = devconf->num_tx_desc;
-       }
+          else {
+
+            /* If num_tx_desc is not specified by VPP user, the current CPU is working
+            with 2M page and has no L3 cache, default num_tx_desc is changed to 512
+            from original 1024 to help reduce TLB misses.
+            */
+            if ((clib_mem_get_default_hugepage_size () == 2 << 20)
+              && check_l3cache() == 0)
+              xd->nb_tx_desc = 512;
+         }
+       }
 
       if (xd->pmd == VNET_DPDK_PMD_AF_PACKET)
        {
@@ -1670,6 +1734,8 @@ dpdk_init (vlib_main_t * vm)
   STATIC_ASSERT (RTE_CACHE_LINE_SIZE == 1 << CLIB_LOG2_CACHE_LINE_BYTES,
                 "DPDK RTE CACHE LINE SIZE does not match with 1<<CLIB_LOG2_CACHE_LINE_BYTES");
 
+  dpdk_cli_reference ();
+
   dm->vlib_main = vm;
   dm->vnet_main = vnet_get_main ();
   dm->conf = &dpdk_config_main;
@@ -1687,10 +1753,6 @@ dpdk_init (vlib_main_t * vm)
   dm->stat_poll_interval = DPDK_STATS_POLL_INTERVAL;
   dm->link_state_poll_interval = DPDK_LINK_POLL_INTERVAL;
 
-  /* init CLI */
-  if ((error = vlib_call_init_function (vm, dpdk_cli_init)))
-    return error;
-
   dm->log_default = vlib_log_register_class ("dpdk", 0);
 
   return error;
@@ -1698,7 +1760,6 @@ dpdk_init (vlib_main_t * vm)
 
 VLIB_INIT_FUNCTION (dpdk_init);
 
-
 /*
  * fd.io coding-style-patch-verification: ON
  *