Привет эксперты Stackoverflow,
У меня проблемы с применением ip-фрагментации в нескольких ядрах.
Мой последний вопрос: возможно ли выделить несколько таблиц фрагментации ip для каждого отдельного прямого и косвенного пула.
Очень благодарен, если кто-то может указать на то, что я делаю здесь неправильно, или предоставить мне несколько альтернативных решений.
Назначение
Я пытаюсь применить ip-фрагментацию в нескольких ядрах и максимизировать производительность с сообщениями, превышающими MTU.
- для каждого локального и удаленного хоста (с использованием от 1 до 8 логических ядер)
- 1 ~ 4 для передачи фрагментированного сообщения
- 4 ~ 8 для получения и сборки сообщения
- Отправка 4KB сообщения с локального
- удаленный эхо-сообщение обратно на локальный.
- рассчитать общую пропускную способность
Задача
Если я пытаюсь выделить таблицу фрагментации для каждого из ядер, я получаю ошибку сегментации, и это происходит независимо от того, уменьшаю ли я размер таблицы фрагментации.
То, как я пытался распределить пулы и фраг-таблицы, приведено ниже.
for each coreid, coreid < allocated cores; coreid++
fragmentation_table[coreid] = rte_ip_frag_table_create(...);
direct_pool[coreid] = rte_pktmbuf_pool_create(...);
indirect_pool[coreid] rte_pktmbuf_pool_create(...);
Таким образом, в качестве альтернативы я выделил несколько таблиц фрагментации для каждого lcore, но позволил разделить прямой и косвенный пулы вместе.
for each coreid, coreid < allocated cores; coreid++
fragmentation_table[coreid] = rte_ip_frag_table_create(...);
direct_pool = rte_pktmbuf_pool_create(...);
indirect_pool = rte_pktmbuf_pool_create(...);
Положение
Теперь, когда я отправляю сообщения с использованием нескольких ядер с локального на удаленный хост, удаленный хост успешно получает сообщение только тогда, когда я отправляю сообщение с добавлением задержки, такой как (добавление sleep (1); для каждой отправки сообщения). Я был возможность получать сообщения с локального на удаленный. Но я не могу получить никаких данных, когда я пытаюсь отправить их без задержки.
Заключение
Лично я подозреваю, что мне следует выделить прямой и косвенный пулы для каждого логического ядра, и я думаю, что это главная проблема. Поскольку я смог успешно использовать только таблицу фрагментов, используя только одно логическое ядро, я подозреваю, что неправильно использую таблицу фрагментации в нескольких ядрах.
Я действительно хочу услышать от экспертов DPDK об этой проблеме, с которой я сталкиваюсь, и буду очень благодарен за любые советы по этому вопросу ...
static int
setup_queue_tbl(struct lcore_rx_queue *rxq, uint32_t lcore, uint32_t queue)
{
int socket;
uint32_t nb_mbuf;
uint64_t frag_cycles;
char buf[RTE_MEMPOOL_NAMESIZE];
socket = rte_lcore_to_socket_id(lcore);
if (socket == SOCKET_ID_ANY)
socket = 0;
frag_cycles = (rte_get_tsc_hz() + MS_PER_S - 1) / MS_PER_S * max_flow_ttl;
if ((rxq->frag_tbl = rte_ip_frag_table_create(max_flow_num,
IP_FRAG_TBL_BUCKET_ENTRIES, max_flow_num, frag_cycles,
socket)) == NULL) {
printf("rte_ip_frag_table_create failed!!!!\n");
return -1;
}
nb_mbuf = RTE_MAX(max_flow_num, 2UL * MAX_PKT_BURST) * MAX_FRAG_NUM;
nb_mbuf *= (port_conf.rxmode.max_rx_pkt_len + BUF_SIZE - 1) / BUF_SIZE;
nb_mbuf *= 1;
nb_mbuf += nb_rxd + nb_txd;
if (transfer_pool[lcore] == NULL) {
snprintf(buf, sizeof(buf), "pool_recieve_%d", socket);
receive_pool[lcore] = rte_pktmbuf_pool_create(buf, nb_mbuf, MEMPOOL_CACHE_SIZE, 0, RTE_MBUF_DEFAULT_BUF_SIZE, socket);
snprintf(buf, sizeof(buf), "pool_transfer_%d", socket);
transfer_pool[lcore] = rte_pktmbuf_pool_create(buf, nb_mbuf, MEMPOOL_CACHE_SIZE, 0, PKT_SIZE + 128, socket);
snprintf(buf, sizeof(buf), "pool_direct_%d", socket);
direct_pool[lcore] = rte_pktmbuf_pool_create(buf, nb_mbuf, MEMPOOL_CACHE_SIZE, 0, RTE_MBUF_DEFAULT_BUF_SIZE, socket);
snprintf(buf, sizeof(buf), "pool_indirect_%d", socket);
indirect_pool[lcore] = rte_pktmbuf_pool_create(buf, nb_mbuf, MEMPOOL_CACHE_SIZE, 0, 0, socket);
}
snprintf(buf, sizeof(buf), "mbuf_rx_ring_%d", lcore);
rx_ring[lcore] = rte_ring_create(buf, 512, socket, 0);
snprintf(buf, sizeof(buf), "mbuf_tx_ring_%d", lcore);
tx_ring[lcore] = rte_ring_create(buf, 512, socket, 0);
// for packet assemble
rxq->ar = (struct assembled_result *)malloc(sizeof(struct assembled_result));
rxq->ar->length = 0;
rxq->ar->assembled_pkt = (char *)malloc(sizeof(char)*PKT_SIZE);
return 0;
}
Вот полный исходный код, код, который я хочу убедиться, что он правильный, находится в dpdk_init.h
https://github.com/SungHoHong2/DPDK-Experiment/blob/master/dpdk-server-multi/dpdk_init.h