Intel DPDK包部署试验

http://blog.csdn.net/fjssharpsword/article/details/50946110


1、系统环境要求

1)intel网卡

$lspci |grep Ethernet    //查看网卡,配置2张网卡

2)CPU核数

$cat /proc/cpuinfo     //查看系统有多少个cpu,支持多少硬件线程,配置2个

3)系统内存

$cat /proc/meminfo   //系统内存支持hugepage技术

4)查看hpet

$grep hpet/proc/timer_list   //需支持hpet

如无显示,需设置BIOS:Advanced -> PCH-IO Configuration -> High Precision Timer ->(Change from Disabled to Enabled if necessary)

Virtualbox上虚拟机Ubuntu如何设置BIOS?

5)系统内核

$uname –a   //虚拟机 Ubunut(主机名c) GNU/Linux x86_64

//4.2.0-16.generic(要求Kernelversion >= 2.6.34,支持hugepage)

// Kernel需支持UIO、HUGETLBFS、PROC_PAGE_MONITOR

6)组件库

$gcc –verison   //要求gcc4.5.x以上,本机gcc5.2.1;

$sudo apt-get installglibc++

$ldd –version  //要求glibc >= 2.7 ,本机2.2.1

如何编译安装glibc(下载地址:http://ftp.gnu.org/gnu/glibc/)升级?

$sudo apt-get install libpcap-dev   //安装pcap

若要使用libpcap驱动分析,修改配置文件:$sudo gedit config/common_linuxapp

       CONFIG_RTE_LIBRTE_PMD_PCAP=n 修改为:CONFIG_RTE_LIBRTE_PMD_PCAP=y

$sudo apt-get installpython  //安装Python

$sudo apt-get installpython-dev

2、DPDK编译安装

1)Git下载

 $sudo apt-get install git  //安装git下载

 $git clone git://dpdk.org/dpdk  //git到/home/c/dpdk目录

配置环境变量:$sudo gedit/etc/profile

export  RTE_SDK=/home/c/dpdk

export  RTE_TARGET= x86_64-native-linuxapp-gcc

2)脚本安装:

$cd dpdk

$./tools/setup.sh   

//step1:14  x86_64-native-linuxapp-gcc

  RTE_SDK=/home/c/dpdk

  RTE_TARGET= x86_64-native-linuxapp-gcc

//step2:17Insert IGB UIO module

//step3:20Setup hugepage mappings for non-NUMA systems 输入64或128

//step4:23Bind Ethernet device to IGB UIO module

提前关闭网卡:$ifconfig enp0s8 down //enp0s8网卡接口名,地址00.08.0

查看PCI地址;$lspci   //找网卡地址

输入PCI地址:00.08.0

//step5:22Display current Ethernet device settings

//step6:26Run test application($RTE_TARGET/app/test)

输入bitmask:0x3 

设置CPU的掩码,根据CPU的个数来设置,比如如果只有2个cpu,按照16进制掩码就选择 0x3

提示HPET不可用,需要BIOS设置。

3)手动安装:

——编译

$makeinstall T=x86_64-native-linuxapp-gcc

——配置大页内存(非NUMA)

$echo 128> /sys/kernel/mm/hugepages/hugepages-2048kB/nr_hugepages

$mkdir/mnt/huge

$mount -thugetlbfs nodev /mnt/huge

$cat/proc/meminfo | grep Huge   //查看大页内存状态

——安装igb_uio驱动

$modprobeuio

$insmodx86_64-native-linuxapp-gcc/kmod/igb_uio.ko

——绑定网卡

$./tools/dpdk_nic_bind.py--status

$ ./tools/dpdk_nic_bind.py -b igb_uio 00.03.0  //网卡1的PCI地址,可用eth1接口名

$./tools/dpdk_nic_bind.py-b igb_uio 00.08.0   //网卡2的PCI地址,可用eth2接口名

——运行testpmd测试程序

$ ./x86_64-native-linuxapp-gcc/app/testpmd -c 0x3 -n 2 -- -i

4)运行示例

$cdexamples/helloworld

$make

$./build/helloworld-c 0xf -n 2

参数解释:c代表用几个core, 采用bit位设置,如 f 代码 二进制 1111 相当于 从0到3这4个core都采用;n 表示设置内存的通道数。


3、DPDK示例代码

[cpp]  view plain  copy
 
  1. #include   
  2. #include   
  3. #include   
  4. #include   
  5. #include   
  6. #include   
  7. #include   
  8. #include   
  9. #include   
  10. #include   
  11. #include   
  12. #include   
  13. #include   
  14. #include   
  15.    
  16. #include   
  17. #include   
  18. #include   
  19. #include   
  20. #include   
  21. #include   
  22. #include   
  23. #include   
  24. #include   
  25. #include   
  26. #include   
  27. #include   
  28. #include   
  29. #include   
  30. #include   
  31. #include   
  32. #include   
  33. #include   
  34. #include   
  35. #include   
  36. #include   
  37. #include   
  38. #include   
  39.    
  40. #define RTE_LOGTYPE_L2FWD RTE_LOGTYPE_USER1  
  41.    
  42. #define MBUF_SIZE (2048 + sizeof(struct rte_mbuf) + RTE_PKTMBUF_HEADROOM)  
  43. #define NB_MBUF   8192  
  44.    
  45. #define MAX_PKT_BURST 32  
  46. #define BURST_TX_DRAIN_US 100 /* TX drain every ~100us */  
  47.    
  48.  /* 
  49.   * Configurable number of RX/TX ring descriptors 
  50.   */  
  51. #define RTE_TEST_RX_DESC_DEFAULT 128  
  52. #define RTE_TEST_TX_DESC_DEFAULT 512  
  53.  static uint16_t nb_rxd = RTE_TEST_RX_DESC_DEFAULT;  
  54.  static uint16_t nb_txd = RTE_TEST_TX_DESC_DEFAULT;  
  55.    
  56.  /* ethernet addresses of ports */  
  57.  static struct ether_addr l2fwd_ports_eth_addr[RTE_MAX_ETHPORTS];  
  58.    
  59.  /* mask of enabled ports */  
  60.  static uint32_t l2fwd_enabled_port_mask = 0;  
  61.    
  62.  /* list of enabled ports */  
  63.  static uint32_t iweb_dst_ports[RTE_MAX_ETHPORTS];  
  64.    
  65.  static unsigned int l2fwd_rx_queue_per_lcore = 1;  
  66.    
  67.  struct mbuf_table {  
  68.      unsigned len;  
  69.      struct rte_mbuf *m_table[MAX_PKT_BURST];  
  70.  };  
  71.    
  72. #define MAX_RX_QUEUE_PER_LCORE 16  
  73. #define MAX_TX_QUEUE_PER_PORT 16  
  74.  struct lcore_queue_conf {  
  75.      unsigned n_rx_port;  
  76.      unsigned rx_port_list[MAX_RX_QUEUE_PER_LCORE];  
  77.      struct mbuf_table tx_mbufs[RTE_MAX_ETHPORTS];  
  78.    
  79.  } __rte_cache_aligned;  
  80.  struct lcore_queue_conf lcore_queue_conf[RTE_MAX_LCORE];  
  81.    
  82.  static const struct rte_eth_conf port_conf = {  
  83.      .rxmode = {  
  84.          .split_hdr_size = 0,  
  85.          .header_split   = 0, /**< Header Split disabled */  
  86.          .hw_ip_checksum = 0, /**< IP checksum offload disabled */  
  87.          .hw_vlan_filter = 0, /**< VLAN filtering disabled */  
  88.          .jumbo_frame    = 0, /**< Jumbo Frame Support disabled */  
  89.          .hw_strip_crc   = 0, /**< CRC stripped by hardware */  
  90.      },  
  91.      .txmode = {  
  92.          .mq_mode = ETH_MQ_TX_NONE,  
  93.      },  
  94.  };  
  95.    
  96.  struct rte_mempool * l2fwd_pktmbuf_pool = NULL;  
  97.    
  98.  /* Per-port statistics struct */  
  99.  struct l2fwd_port_statistics {  
  100.      uint64_t tx;  
  101.      uint64_t rx;  
  102.      uint64_t dropped;  
  103.  } __rte_cache_aligned;  
  104.  struct l2fwd_port_statistics port_statistics[RTE_MAX_ETHPORTS];  
  105.    
  106.  /* A tsc-based timer responsible for triggering statistics printout */  
  107. #define TIMER_MILLISECOND 2000000ULL /* around 1ms at 2 Ghz */  
  108. #define MAX_TIMER_PERIOD 86400 /* 1 day max */  
  109. static int64_t timer_period = 10 * TIMER_MILLISECOND * 1000; /* default period is 10 seconds */  
  110.    
  111.  /* main processing loop */  
  112.  static void  
  113.  l2fwd_main_loop(void)  
  114.  {  
  115.      struct rte_mbuf *pkts_burst[MAX_PKT_BURST];  
  116.      struct rte_mbuf *m;  
  117.      unsigned lcore_id;  
  118.      uint64_t prev_tsc, diff_tsc, cur_tsc, timer_tsc;  
  119.      unsigned i, j, portid, nb_rx;  
  120.      struct lcore_queue_conf *qconf;  
  121.      const uint64_t drain_tsc = (rte_get_tsc_hz() + US_PER_S - 1) / US_PER_S * BURST_TX_DRAIN_US;  
  122.    
  123.      prev_tsc = 0;  
  124.      timer_tsc = 0;  
  125.    
  126.      lcore_id = rte_lcore_id();  
  127.      qconf = &lcore_queue_conf[lcore_id];  
  128.    
  129.      if (qconf->n_rx_port == 0) {  
  130.          RTE_LOG(INFO, L2FWD, "lcore %u has nothing to do\n", lcore_id);  
  131.          return;  
  132.      }  
  133.    
  134.      //RTE_LOG(INFO, L2FWD, "entering main loop on lcore %u\n", lcore_id);  
  135.    
  136.      for (i = 0; i < qconf->n_rx_port; i++) {  
  137.    
  138.          portid = qconf->rx_port_list[i];  
  139.          RTE_LOG(INFO, L2FWD, " -- lcoreid=%u portid=%u\n", lcore_id, portid);  
  140.      }  
  141.    
  142.      while (1) {  
  143.    
  144.          cur_tsc = rte_rdtsc();  
  145. #if 0  
  146.          /* 
  147.           * TX burst queue drain 
  148.           */  
  149.          diff_tsc = cur_tsc - prev_tsc;  
  150.          if (unlikely(diff_tsc > drain_tsc)) {  
  151.              for (portid = 0; portid < RTE_MAX_ETHPORTS; portid++) {  
  152.                  if (qconf->tx_mbufs[portid].len == 0)  
  153.                      continue;  
  154.                  l2fwd_send_burst(&lcore_queue_conf[lcore_id],  
  155.                           qconf->tx_mbufs[portid].len,  
  156.                           (uint8_t) portid);  
  157.                  qconf->tx_mbufs[portid].len = 0;  
  158.              }  
  159.              /* if timer is enabled */  
  160.              if (timer_period > 0) {  
  161.                  /* advance the timer */  
  162.                  timer_tsc += diff_tsc;  
  163.                  /* if timer has reached its timeout */  
  164.                  if (unlikely(timer_tsc >= (uint64_t) timer_period)) {  
  165.   
  166.                      /* do this only on master core */  
  167.                      if (lcore_id == rte_get_master_lcore()) {  
  168.                          print_stats();  
  169.                          /* reset the timer */  
  170.                          timer_tsc = 0;  
  171.                      }  
  172.                  }  
  173.              }  
  174.              prev_tsc = cur_tsc;  
  175.          }  
  176. #endif  
  177.          /* 
  178.           * Read packet from RX queues 
  179.           */  
  180.           usleep(1);  
  181.          for (i = 0; i < qconf->n_rx_port; i++) {  
  182.    
  183.              portid = qconf->rx_port_list[i];  
  184.              nb_rx = rte_eth_rx_burst((uint8_t) portid, 0,  
  185.                           pkts_burst, MAX_PKT_BURST);  
  186.              if (nb_rx <= 0)  
  187.              {  
  188.                 //printf("xxxxxxxxxxxxxxxxxxxx\n");  
  189.                 break;  
  190.              }  
  191.              port_statistics[portid].rx += nb_rx;  
  192.              printf("rcv packets %d\n", port_statistics[portid].rx);  
  193.              printf("this timer packets is %d\n", nb_rx);  
  194.              for (j = 0; j < nb_rx; j++) {  
  195.                       
  196.                  m = pkts_burst[j];  
  197.                  rte_pktmbuf_free(m);  
  198.                    
  199.                  //printf("packet %d\n", j);  
  200.                  //printf("rcv packets %d\n", port_statistics[portid].rx);  
  201.              }  
  202.          }  
  203.      }  
  204.  }  
  205.    
  206.  static int l2fwd_launch_one_lcore(__attribute__((unused)) void *dummy)  
  207.  {  
  208.      l2fwd_main_loop();  
  209.      return 0;  
  210.  }  
  211.   
  212.    
  213. /* Parse the argument given in the command line of the application */  
  214. static int iweb_parse_args(int argc, char **argv)  
  215. {  
  216. }  
  217.    
  218. int  
  219. main(__attribute__((unused)) int argc, __attribute__((unused)) char **argv)  
  220. {  
  221.     struct lcore_queue_conf *qconf;  
  222.     struct rte_eth_dev_info dev_info;  
  223.     int ret;  
  224.     uint8_t nb_ports;  
  225.     uint8_t nb_ports_available;  
  226.     uint8_t portid, last_port;  
  227.     unsigned lcore_id, rx_lcore_id;  
  228.     unsigned nb_ports_in_mask = 0;  
  229.   
  230.     /* init EAL */  
  231.     ret = rte_eal_init(argc, argv);  
  232.     if (ret < 0)  
  233.     {  
  234.         rte_exit(EXIT_FAILURE, "Invalid EAL arguments\n");  
  235.     }  
  236.     argc -= ret;  
  237.     argv += ret;  
  238.   
  239.     /* parse application arguments (after the EAL ones) */  
  240.     ret = iweb_parse_args(argc, argv);  
  241.     if (ret < 0)  
  242.     {  
  243.         rte_exit(EXIT_FAILURE, "Invalid L2FWD arguments\n");  
  244.     }  
  245.       
  246.     /* create the mbuf pool */  
  247.     l2fwd_pktmbuf_pool = rte_mempool_create("mbuf_pool", NB_MBUF, MBUF_SIZE, 32,  
  248.             sizeof(struct rte_pktmbuf_pool_private), rte_pktmbuf_pool_init, NULL,  
  249.             rte_pktmbuf_init, NULL, rte_socket_id(), 0);  
  250.   
  251.     if (l2fwd_pktmbuf_pool == NULL)  
  252.     {  
  253.         rte_exit(EXIT_FAILURE, "Cannot init mbuf pool\n");  
  254.     }  
  255.       
  256.     nb_ports = rte_eth_dev_count();  
  257.     if (nb_ports != 1)  
  258.     {  
  259.         rte_exit(EXIT_FAILURE, "No Ethernet ports - bye\n");  
  260.     }  
  261.     /* reset l2fwd_dst_ports */  
  262.     iweb_dst_ports[0] = 0;  /* 这里其实只有一个port */  
  263.   
  264.     rx_lcore_id = 0;  
  265.     qconf = NULL;  
  266.     qconf = &lcore_queue_conf[rx_lcore_id];  
  267.     qconf->rx_port_list[0] = portid;  
  268.     qconf->n_rx_port = 1;  
  269.   
  270.     printf("Initializing port %u... ", (unsigned) portid);  
  271.     fflush(stdout);  
  272.     ret = rte_eth_dev_configure(portid, 1, 1, &port_conf);  
  273.     if (ret < 0)  
  274.     {  
  275.         rte_exit(EXIT_FAILURE, "Cannot configure device: err=%d, port=%u\n", ret, (unsigned)portid);  
  276.     }  
  277.   
  278.     fflush(stdout);  
  279.     ret = rte_eth_rx_queue_setup(portid, 0, nb_rxd, rte_eth_dev_socket_id(portid),NULL,l2fwd_pktmbuf_pool);  
  280.     if (ret < 0)  
  281.     {  
  282.      rte_exit(EXIT_FAILURE, "rte_eth_rx_queue_setup:err=%d, port=%u\n", ret, (unsigned)portid);  
  283.     }  
  284.       
  285.     /* init one TX queue on each port */  
  286.     fflush(stdout);  
  287.     ret = rte_eth_tx_queue_setup(portid, 0, nb_txd, rte_eth_dev_socket_id(portid), NULL);  
  288.     if (ret < 0)  
  289.     {  
  290.         rte_exit(EXIT_FAILURE, "rte_eth_tx_queue_setup:err=%d, port=%u\n", ret, (unsigned)portid);  
  291.     }  
  292.       
  293.     /* Start device */  
  294.     ret = rte_eth_dev_start(portid);  
  295.     if (ret < 0)  
  296.     {  
  297.         rte_exit(EXIT_FAILURE, "rte_eth_dev_start:err=%d, port=%u\n", ret, (unsigned)portid);  
  298.     }  
  299.     printf("done: \n");  
  300.       
  301.     /* 打开网卡的混杂模式 */  
  302.     rte_eth_promiscuous_enable(portid);  
  303.       
  304.     /* launch per-lcore init on every lcore */  
  305.     rte_eal_mp_remote_launch(l2fwd_launch_one_lcore, NULL, CALL_MASTER);  
  306.   
  307.     RTE_LCORE_FOREACH_SLAVE(lcore_id)  
  308.     {  
  309.         if (rte_eal_wait_lcore(lcore_id) < 0)  
  310.         {  
  311.             return -1;  
  312.         }  
  313.     }  
  314.   
  315.     return 0;  
  316. }  


你可能感兴趣的:(dpdk)