Мое приложение использует DPDK-stable-20.11.10. Сегодня утром произошла ошибка сегментации, когда я пытался запустить приложение как обычно. Затем я использовал GDB, чтобы отследить проблему, и обнаружил, что ошибка сегментации возникла из-за несанкционированного доступа к памяти в DPDK. Проблема возникла в функции rxq_cq_decompress_v, определенной в драйверах\net\mlx5\mlx5_rxtx_vec_neon.h (эта функция реализована по-разному в разных архитектурах, мой сервер — aarch64). Вот код проблемы:
Код: Выделить всё
static inline uint16_t
rxq_cq_decompress_v(struct mlx5_rxq_data *rxq, volatile struct mlx5_cqe *cq,
struct rte_mbuf **elts)
{
......
/*
* A. load mCQEs into a 128bit register.
* B. store rearm data to mbuf.
* C. combine data from mCQEs with rx_descriptor_fields1.
* D. store rx_descriptor_fields1.
* E. store flow tag (rte_flow mark).
*/
for (pos = 0; pos < mcqe_n; ) {
uint8_t *p = (void *)&mcq[pos % 8];
uint8_t *e0 = (void *)&elts[pos]->rearm_data;
uint8_t *e1 = (void *)&elts[pos + 1]->rearm_data;
uint8_t *e2 = (void *)&elts[pos + 2]->rearm_data;
uint8_t *e3 = (void *)&elts[pos + 3]->rearm_data;
uint16x4_t byte_cnt;
#ifdef MLX5_PMD_SOFT_COUNTERS
uint16x4_t invalid_mask =
vcreate_u16(mcqe_n - pos < MLX5_VPMD_DESCS_PER_LOOP ?
-1UL rearm_data;, когда DPDK попытался посетить elts[pos + 3] .
При последующих попытках воспроизвести ошибку я обнаружил, что она может возникнуть в[code]elts[pos + 3]
обратиться за помощью
Я прочитал соответствующий код и обнаружил, что это похоже на кольцевой буфер. В функции rxq_burst_v, которая вызывает rxq_cq_decompress_v, для доступа к этому массиву использовалась маска e_mask:
Код: Выделить всё
static inline uint16_t
rxq_burst_v(struct mlx5_rxq_data *rxq, struct rte_mbuf **pkts,
uint16_t pkts_n, uint64_t *err, bool *no_cq)
{
......
const uint16_t e_n = 1 elts_n;
const uint16_t e_mask = e_n - 1;
......
if (rcvd_pkt > 0) {
......
rxq_copy_mbuf_v(&(*rxq->elts)[rxq->rq_pi & e_mask],
pkts, rcvd_pkt);
......
}
elts_idx = rxq->rq_pi & e_mask;
elts = &(*rxq->elts)[elts_idx];
- Что на самом деле означает код DPDK, указанный выше? Учитывая, что elts представляет собой кольцевой буфер, почему не выполняется проверка границ массива или почему код не использует какую-либо маску, например e_mask?
- Какие шаги можно Что можно предпринять, чтобы избежать этой проблемы?

Подробнее здесь: https://stackoverflow.com/questions/791 ... -receiving