BTW, the following is my backtrace when the system crashes.
Program received signal SIGSEGV, Segmentation fault.
0x00000000004883ab in rte_hash_reset (h=0x0)
at
/home/zhangwei1984/timopenNetVM/dpdk-2.2.0/lib/librte_hash/rte_cuckoo_hash.c:444
444while (rte_ring_dequeue(h->free_slots, &ptr) == 0)
(gdb) bt
#0 0x00000000004883ab in rte_hash_reset (h=0x0)
at
/home/zhangwei1984/timopenNetVM/dpdk-2.2.0/lib/librte_hash/rte_cuckoo_hash.c:444
#1 0x000000000048fdfb in rte_hash_lookup_with_hash (h=0x7fff32cce740,
key=0x7fffffffe220, sig=403183624)
at
/home/zhangwei1984/timopenNetVM/dpdk-2.2.0/lib/librte_hash/rte_cuckoo_hash.c:771
#2 0x000000000042b551 in onvm_ft_lookup_with_hash (table=0x7fff32cbe4c0,
pkt=0x7fff390ea9c0,
data=0x7fffffffe298) at
/home/zhangwei1984/openNetVM-master/openNetVM/onvm/shared/onvm_flow_table.c:104
#3 0x000000000042b8c3 in onvm_flow_dir_get_with_hash (table=0x7fff32cbe4c0,
pkt=0x7fff390ea9c0,
flow_entry=0x7fffffffe298)
at
/home/zhangwei1984/openNetVM-master/openNetVM/onvm/shared/onvm_flow_dir.c:14
#4 0x00000000004251d7 in packet_handler (pkt=0x7fff390ea9c0,
meta=0x7fff390eaa00)
at
/home/zhangwei1984/openNetVM-master/openNetVM/examples/flow_table/flow_table.c:212
#5 0x0000000000429502 in onvm_nf_run ()
#6 0x00000000004253f1 in main (argc=1, argv=0x7fffffffe648)
at
/home/zhangwei1984/openNetVM-master/openNetVM/examples/flow_table/flow_table.c:272
(gdb)
I met a problem which I used the DPDK hash table for multi processes. One
started as primary process and the other as secondary process.
I based on the client and server multiprocess example. My aim is that server
creates a hash table, then share it to the client. The client will read and
write the hash table, and the server will read the hash table. I use rte_calloc
allocate the space for hash table, use memzone tells the client the hash table
address.
But once I add an entry into the hash table, calling "lookup" function will
have the segment fault. But for the lookup function, I have exactly the same
parameters for lookup when the first time calls the lookup.
If I create the hash table inside the client, everything works correctly.
I put pieces of codes for server and client codes related to the hash table. I
have spent almost 3 days on this bug. But there is no any clue which can help
to solve this bug. If any of you can give some suggestions, I will be
appreciated. I post the question into the mail list, but have not yet got any
reply.
This problem is that in dpdk multi process - client and server example,
dpdk-2.2.0/examples/multi_process/client_server_mp
My aim is that server create a hash table, then share it to client. Client will
write the hash table, server will read the hash table. I am using dpdk hash
table. What I did is that server create a hash table (table and array
entries), return the table address. I use memzone pass the table address to
client. In client, the second lookup gets segment fault. The system gets
crashed. I will put some related code here.
create hash table function:
struct onvm_ft*
onvm_ft_create(int cnt, int entry_size) {
struct rte_hash* hash;
struct onvm_ft* ft;
struct rte_hash_parameters ipv4_hash_params = {
.name = NULL,
.entries = cnt,
.key_len = sizeof(struct onvm_ft_ipv4_5tuple),
.hash_func = NULL,
.hash_func_init_val = 0,
};
char s[64];
/* create ipv4 hash table. use core number and cycle counter to get a
unique name. */
ipv4_hash_params.name = s;
ipv4_hash_params.socket_id = rte_socket_id();
snprintf(s, sizeof(s), "onvm_ft_%d-%"PRIu64, rte_lcore_id(),
rte_get_tsc_cycles());
hash = rte_hash_create(&ipv4_hash_params);
if (hash == NULL) {
return NULL;
}
ft = (struct onvm_ft*)rte_calloc("table", 1, sizeof(struct onvm_ft), 0);
if (ft == NULL) {
rte_hash_free(hash);
return NULL;
}
ft->hash = hash;
ft->cnt = cnt;
ft->entry_size = entry_size;
/* Create data array for storing values */
ft->data = rte_calloc("entry", cnt, entry_size, 0);
if (ft->data == NULL) {
rte_hash_free(hash);
rte_free(ft);
return NULL;
}
return ft;
}
related structure:
struct onvm_ft {
struct rte_hash* hash;
char* data;
int cnt;
int entry_size;
};
in server side, I will call the create function, use memzone share it to
client. The following is what I do:
related variables:
struct onvm_ft *sdn_ft;
struct onvm_ft **sdn_ft_p;
const struct rte_memzone *mz_ftp;
sdn_ft = onvm_ft_create(1024, sizeof(struct onvm_flow_entry));
if(sdn_ft == NULL) {
rte_exit(EXIT_FAILURE, "Unable to create flow table\n");
}
mz_ftp = rte_memzone_reserve(MZ_FTP_INFO, sizeof(struct onvm_ft *),
rte_socket_id(), NO_FLAGS);
if (mz_ftp == NULL) {
rte_exit(EXIT_FAILURE, "Canot reserve memory zone for flow
table pointer\n");
}
memset(mz_ftp->addr, 0, sizeof(struct onvm_ft *));
sdn_ft_p = mz_ftp->addr;
*sdn_ft_p = sdn_ft;
In client side:
struct onvm_ft *sdn_ft;
static void
map_flow_table(void) {
const struct rte_memzone *mz_ftp;
struct onvm_ft **ftp;
mz_ftp = rte_memzone_lookup(MZ_FTP_INFO);
if (mz_ftp == NULL)
rte_exit(EXIT_FAILURE, "Cannot get flow table pointer\n");
ftp = mz_ftp->addr;
sdn_ft = *ftp;
}
The following is my debug message: I set a breakpoint in lookup table line. To
narrow down the problem, I just send one flow. So the second time and the first
time, the packets are the same.
For the first time, it works. I print out the parameters: inside the
onvm_ft_lookup function, if there is a related entry, it will return the
address by flow_entry.
Breakpoint 1, datapath_handle_read (dp=0x7ffff00008c0) at
/home/zhangwei1984/openNetVM-master/openNetVM/examples/flow_table/sdn.c:191
191 ret = onvm_ft_lookup(sdn_ft, fk,
(char**)&flow_entry);
(gdb) print *sdn_ft
$1 = {hash = 0x7fff32cce740, data = 0x7fff32cb0480 "", cnt = 1024, entry_size =
56}
(gdb) print *fk
$2 = {src_addr = 419496202, dst_addr = 453050634, src_port = 53764, dst_port =
11798, proto = 17 '\021'}
(gdb) s
onvm_ft_lookup (table=0x7fff32cbe4c0, key=0x7fff32b99d00, data=0x7ffff68d2b00)
at
/home/zhangwei1984/openNetVM-master/openNetVM/onvm/shared/onvm_flow_table.c:151
151 softrss = onvm_softrss(key);
(gdb) n
152 printf("software rss %d\n", softrss);
(gdb)
software rss 403183624
154 tbl_index = rte_hash_lookup_with_hash(table->hash, (const void
*)key, softrss);
(gdb) print table->hash
$3 = (struct rte_hash *) 0x7fff32cce740
(gdb) print *key
$4 = {src_addr = 419496202, dst_addr = 453050634, src_port = 53764, dst_port =
11798, proto = 17 '\021'}
(gdb) print softrss
$5 = 403183624
(gdb) c
After I hit c, it will do the second lookup,
Breakpoint 1, datapath_handle_read (dp=0x7ffff00008c0) at
/home/zhangwei1984/openNetVM-master/openNetVM/examples/flow_table/sdn.c:191
191 ret = onvm_ft_lookup(sdn_ft, fk,
(char**)&flow_entry);
(gdb) print *sdn_ft
$7 = {hash = 0x7fff32cce740, data = 0x7fff32cb0480 "", cnt = 1024, entry_size =
56}
(gdb) print *fk
$8 = {src_addr = 419496202, dst_addr = 453050634, src_port = 53764, dst_port =
11798, proto = 17 '\021'}
(gdb) s
onvm_ft_lookup (table=0x7fff32cbe4c0, key=0x7fff32b99c00, data=0x7ffff68d2b00)
at
/home/zhangwei1984/openNetVM-master/openNetVM/onvm/shared/onvm_flow_table.c:151
151 softrss = onvm_softrss(key);
(gdb) n
152 printf("software rss %d\n", softrss);
(gdb) n
software rss 403183624
154 tbl_index = rte_hash_lookup_with_hash(table->hash, (const void
*)key, softrss);
(gdb) print table->hash
$9 = (struct rte_hash *) 0x7fff32cce740
(gdb) print *key
$10 = {src_addr = 419496202, dst_addr = 453050634, src_port = 53764, dst_port =
11798, proto = 17 '\021'}
(gdb) print softrss
$11 = 403183624
(gdb) n
Program received signal SIGSEGV, Segmentation fault.
0x000000000045fb97 in __rte_hash_lookup_bulk ()
(gdb) bt
#0 0x000000000045fb97 in __rte_hash_lookup_bulk ()
#1 0x0000000000000000 in ?? ()