在同一个 DPDK lcore 上运行多个线程

时间:2021-07-16 13:26:24

标签: c dpdk

我正在开发一个 dpdk 转发应用程序来接收和转发数据包。我有两个函数来接收和转发来自两个端口的数据包。我调用了函数, rte_eal_remote_launch 在两个不同的 lcore 上启动转发和接收功能。这消耗了 lcore 掩码的两个 lcore。因此,我使用服务核心在同一个 lcore 中启动两者。我可以让这两个函数接收和转发注册为服务。但是当我启动这些服务时,只有一个服务在运行。

服务已成功注册并映射到同一个lcore。但只有一个在运行时运行。感谢您对此问题的任何澄清。

服务注册和启动的代码如下。

 for (i = 0; i < 4; i++){
        uint32_t id;
        ret = rte_service_component_register(&services[i], &id);
        printf("service id : %d\n", id);
        if (ret)
                rte_exit(-1, "service register() failed");

        rte_service_component_runstate_set(id, 1);
        rte_service_set_stats_enable(id, 1);
        ret = rte_service_runstate_set(id, 1);
        if (ret)
                return -ENOEXEC;
}
printf("Service Components Registrations Done!\n");
ret = rte_service_lcore_add(core);
if(ret == 0)
    printf("Service core added\n");
if (ret && ret != -EALREADY)
    printf("core %d added ret %d\n", core, ret);

ret = rte_service_lcore_start(core);
if(ret == 0)
    printf("Service core started\n");
if (ret && ret != -EALREADY)
    printf("core %d start ret %d\n", core, ret);

for (int s = 0; s < 4; s=s+2) {
    if (rte_service_map_lcore_set(s, core, 1))
        printf("failed to map lcore %d\n", core);
    else{
        printf("Service %d started on core\n", s);
    }
    

以下是使用rte_service_dump延迟系统后rte_delay_us_sleep(5 * US_PER_S);的结果

    Services Summary
  service_channel_in: stats 1   calls 0 cycles 0    avg: 0
  service_channel_out: stats 1  calls 0 cycles 0    avg: 0
  service_channel_in: stats 1   calls 0 cycles 0    avg: 0
  service_channel_out: stats 1  calls 0 cycles 0    avg: 0
Service Cores Summary
05  0   0   0   0

1 个答案:

答案 0 :(得分:1)

DPDK API rte_eal_remote_launch 可以在不同的 CPU 内核以及相同的 CPU 内核上工作。

  1. 在不同的 CPU 逻辑内核上-l 2-3
  2. 在相同的 CPU 逻辑核心上运行 --lcore (0-1)@2

注意第二个选项将运行 create 2 DPDK 线程 '0-1' 以在 CPU 逻辑内核上运行 2

根据 rte_service_dump 的结果,有 2 个函数在运行,分别是 service_channel_in 和 service_channel_out

因此,关于 rte_remote_launch 和 rte_service 不在同一 CPU 物理核心上运行的观察是不正确的。

示例代码

#include <stdint.h>
#include <inttypes.h>
#include <signal.h>

#include <rte_eal.h>
#include <rte_cycles.h>
#include <rte_lcore.h>

volatile bool run = true;

int helloWaitTest(void *arg)
{
        uint16_t val = *(uint16_t *)arg;

        while(run)
        {
                printf(" val %u dpdk logical core %u logical core index %u\n", val, rte_lcore_id(), rte_lcore_index(rte_lcore_id()));
                rte_delay_ms(1000 + 1000 * val);
        }

        return 0;
}

static void
signal_handler(int signum)
{
        if (signum == SIGINT) {
                run = false;
        }
}


int main(int argc, char *argv[])
{
        signal(SIGINT, signal_handler);

        /* Initialize the Environment Abstraction Layer (EAL). */
        int ret = rte_eal_init(argc, argv);
        if (ret < 0)
                rte_exit(EXIT_FAILURE, "Error with EAL initialization\n");

        argc -= ret;
        argv += ret;

        uint16_t lcore_id = 0;
        RTE_LCORE_FOREACH_WORKER(lcore_id)
        {
                uint16_t temp = lcore_id;
                rte_eal_remote_launch(helloWaitTest, &temp, temp);
        }
        uint16_t temp = rte_lcore_id();
        helloWaitTest(&temp);

        rte_eal_mp_wait_lcore();
        /* clean up the EAL */
        rte_eal_cleanup();

        return 0;
}

如何运行:sudo ./a.out --lcores '(1-2)@3'