Search code examples
clinuxdpdk

DPDK throws EAL: eal_memalloc_alloc_seg_bulk(): couldn't find suitable memseg_list on string concatenate


I have a DPDK environment setup and the buggy part of my program concatenates a string. That string can be as long as it gets (lets say a 1,000,000 max characters). I run my program with ./program --lcores='0-4'

I'm using DPDK's rte_malloc, rte_memcpy, rte_strlcat and rte_free functions. Below is a snippet of the code


int current_length = strlen(fx->var);
int new_length = (datalen + current_length) + 1;

char *temp = (char *)rte_malloc("char *", new_length * (*fx->var), 0);

rte_memcpy(temp, fx->var, current_length);
rte_strlcat(temp, data, datalen);
temp[new_length] = '\0';


fx->var = (char *)rte_malloc("var", new_length * (*fx->var), 0);
rte_memcpy(fx->var, temp, new_length);
fx->var[new_length] = '\0';

rte_free(temp);

My program exits after sometime with EAL: eal_memalloc_alloc_seg_bulk(): couldn't find suitable memseg_list. Following is the stack trace I'm getting

(gdb) where
#0  0x0000555555564d5b in _mm256_storeu_si256 (__A=..., __P=0x0) at /usr/lib/gcc/x86_64-linux-gnu/9/include/avxintrin.h:928
#1  rte_mov32 (
    src=0x1a80b5a80 "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", dst=0x0) at /usr/local/include/rte_memcpy.h:320
#2  rte_mov64 (
    src=0x1a80b5a80 "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", dst=0x0) at /usr/local/include/rte_memcpy.h:330
#3  rte_memcpy_aligned (n=88, src=0x1a80b5a80, dst=0x0) at /usr/local/include/rte_memcpy.h:856
#4  rte_memcpy (n=88, src=0x1a80b5a80, dst=0x0) at /usr/local/include/rte_memcpy.h:872
#5  parse_something (flow=0x7ff7c83c8288, id=60806, 
    data=0x7ff82cd77cc5 "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", datalen=89, flags=4) at main.c:1187
#6  0x000055555557c2e1 in process_something (result=0x7fffed7fad88) at main.c:2147
#7  0x000055555557c467 in some_flow (worker=0x7fffed7fad70, result=0x7fffed7fad88) at main.c:2199
#8  0x000055555557e5e0 in some_loop (arg=0x5555556262f0) at main.c:2273

I need an idea of whats going wrong here, am I missing some EAL configurations. Until then I'm looking into the docs and trying to understand from DPDK programmer's guide (EAL, Mbuf, Mempool library in specific).

Machine specs

  • DPDK 20.11.0-rc1
  • Ubuntu 20 (x86_64 GNU/Linux kernel 5.8.0-44-generic)
  • CPU: 32
  • RAM: 256GB
  • 2 DPDK ports(igb_uio) 6-7 GB/s
  • 1GB Hugepages

Let me know if I've misssed something in the details above


Solution

  • As pointed out in the comments, one has to give a numerical value for multiplication. Else ASCII value of fx->var will be used. Hence the suggestion in the comment is shared to use atoi(fx->var) for the numerical string to int value.

    Note:By modifying the code snippet I am able to get it up and running, hence there is no issue in rte_malloc.

    Modified Code:

    #include <rte_eal.h>
    #include <rte_memcpy.h>
    #include <rte_string_fns.h>
    #include <rte_malloc.h>
    
    char *mystring = "test my string: ";
    char *data = "My Data.. ";
    int datalen = 10;
    
    int main(int argc, char **argv)
    {
            if (0 == rte_eal_init(argc, argv))
                    rte_exit(EXIT_FAILURE, "failed to init!");
    
            int current_length = strlen(mystring);
            int new_length = (datalen + current_length) + 1;
    
            //char *temp = (char *)rte_malloc("char *", new_length * (*mystring), 0);
            char *temp = (char *)rte_malloc("char *", new_length, 0);
            if (temp == NULL)
                    rte_exit(EXIT_FAILURE, "temp is null!");
    
            rte_strlcat(temp, mystring, current_length);
            rte_strlcat(temp + current_length - 1, data, datalen);
            temp[new_length] = '\0';
    
            mystring = (char *)rte_malloc("var", new_length * (*mystring), 0);
            if (mystring == NULL)
                    rte_exit(EXIT_FAILURE, "mystring is null!");
    
            rte_memcpy(mystring, temp, new_length);
            mystring[new_length] = '\0';
    
            printf("(%s)!\n\n", mystring);
            rte_free(temp);
    
            printf("Done!");
    

    Build command: gcc /tmp/t.c $(pkg-config --cflags --libs --static libdpdk) -g

    Execution Command: sudo ./a.out --no-pci

    [Edit-1] updated with the test strings suggest by Abid Zaidi

    Result: (test my string:My Data..)!