-
Notifications
You must be signed in to change notification settings - Fork 115
Description
I have a couple of questions regarding the implementation of port_rx_burst
and port_tx_burst
functions in the AF_XDP-forwarding/xsk_fwd.c
file.
-
poll
Call Position inport_rx_burst
:In the
port_rx_burst
function, I am wondering why thepoll
call is placed afterstatus = xsk_ring_prod__reserve(&p->umem_fq, n_pkts, &pos);
instead of afterxsk_ring_prod__submit(&p->umem_fq, n_pkts);
. Here is the full function for reference:static inline u32 port_rx_burst(struct port *p, struct burst_rx *b) { u32 n_pkts, pos, i; /* Free buffers for FQ replenish. */ n_pkts = ARRAY_SIZE(b->addr); n_pkts = bcache_cons_check(p->bc, n_pkts); if (!n_pkts) return 0; /* RXQ. */ n_pkts = xsk_ring_cons__peek(&p->rxq, n_pkts, &pos); if (!n_pkts) { if (xsk_ring_prod__needs_wakeup(&p->umem_fq)) { struct pollfd pollfd = { .fd = xsk_socket__fd(p->xsk), .events = POLLIN, }; poll(&pollfd, 1, 0); } return 0; } for (i = 0; i < n_pkts; i++) { b->addr[i] = xsk_ring_cons__rx_desc(&p->rxq, pos + i)->addr; b->len[i] = xsk_ring_cons__rx_desc(&p->rxq, pos + i)->len; } xsk_ring_cons__release(&p->rxq, n_pkts); p->n_pkts_rx += n_pkts; /* UMEM FQ. */ for ( ; ; ) { int status; status = xsk_ring_prod__reserve(&p->umem_fq, n_pkts, &pos); if (status == n_pkts) break; if (xsk_ring_prod__needs_wakeup(&p->umem_fq)) { struct pollfd pollfd = { .fd = xsk_socket__fd(p->xsk), .events = POLLIN, }; poll(&pollfd, 1, 0); } } for (i = 0; i < n_pkts; i++) *xsk_ring_prod__fill_addr(&p->umem_fq, pos + i) = bcache_cons(p->bc); xsk_ring_prod__submit(&p->umem_fq, n_pkts); return n_pkts; }
In my understanding,
poll
is typically used to notify the kernel that the fill queue has been filled and is ready for packet reception. Is this understanding correct? -
Using
poll
Instead ofsendto
inport_tx_burst
:In the
port_tx_burst
function, canpoll
be used instead ofsendto
to send a message to the kernel? If so, what would be the correct format? Here is the function for reference:static inline void port_tx_burst(struct port *p, struct burst_tx *b) { u32 n_pkts, pos, i; int status; /* UMEM CQ. */ n_pkts = p->params.bp->umem_cfg.comp_size; n_pkts = xsk_ring_cons__peek(&p->umem_cq, n_pkts, &pos); for (i = 0; i < n_pkts; i++) { u64 addr = *xsk_ring_cons__comp_addr(&p->umem_cq, pos + i); bcache_prod(p->bc, addr); } xsk_ring_cons__release(&p->umem_cq, n_pkts); /* TXQ. */ n_pkts = b->n_pkts; for ( ; ; ) { status = xsk_ring_prod__reserve(&p->txq, n_pkts, &pos); if (status == n_pkts) break; if (xsk_ring_prod__needs_wakeup(&p->txq)) sendto(xsk_socket__fd(p->xsk), NULL, 0, MSG_DONTWAIT, NULL, 0); } for (i = 0; i < n_pkts; i++) { xsk_ring_prod__tx_desc(&p->txq, pos + i)->addr = b->addr[i]; xsk_ring_prod__tx_desc(&p->txq, pos + i)->len = b->len[i]; } xsk_ring_prod__submit(&p->txq, n_pkts); if (xsk_ring_prod__needs_wakeup(&p->txq)) sendto(xsk_socket__fd(p->xsk), NULL, 0, MSG_DONTWAIT, NULL, 0); p->n_pkts_tx += n_pkts; }