On 24 Jun 2019, at 16:30, Rafael Vargas wrote: > Em seg, 24 de jun de 2019 às 07:21, Eelco Chaudron > <echaudro@xxxxxxxxxx> escreveu: > >> /* Stuff the ring with as much frames as possible */ >> stock_frames = xsk_ring_prod__free(&xsk->umem->fq); >> stock_frames = MIN(stock_frames, xsk_umem_free_frames(xsk)); >> >> if (stock_frames > 0) { >> >> ret = xsk_ring_prod__reserve(&xsk->umem->fq, stock_frames, >> &idx_fq); >> while (ret != stock_frames) >> ret = xsk_ring_prod__reserve(&xsk->umem->fq, rcvd, >> &idx_fq); > once you've checked before the number of free entries, this while is > still needed? In theory not, just a safeguard… >> Where xsk_ring_prod__free() is as follows (sent patch upstream for >> adding it as an API): >> >> static inline __u32 xsk_ring_prod__free(struct xsk_ring_prod *r) >> { >> r->cached_cons = *r->consumer + r->size; >> return r->cached_cons - r->cached_prod; >> } > > this is basically xsk_prod_nb_free, but always triggering the cache > refresh, right? Yes, probably a xsk_prod_nb_free(, xsk_umem_free_frames(xsk)) would work >> >> And the following is an API around my UMEM frame handling: >> >> xsk_umem_free_frames() -> How many buffers do I have available on my >> stack >> >> xsk_free_umem_frame() -> return a buffer to my buffer stack >> >> xsk_alloc_umem_frame() -> Get a buffer from my buffer stack >> > > Is this API using another local ring or stack buffer or is it using > some clever trick I'm not figuring out? Just a simple array with all the UMEM addresses: struct xsk_socket_info { … uint64_t umem_frame_addr[NUM_FRAMES]; uint32_t umem_frame_free; } static uint64_t xsk_alloc_umem_frame(struct xsk_socket_info *xsk) { uint64_t frame; if (xsk->umem_frame_free == 0) return INVALID_UMEM_FRAME; frame = xsk->umem_frame_addr[--xsk->umem_frame_free]; xsk->umem_frame_addr[xsk->umem_frame_free] = INVALID_UMEM_FRAME; return frame; } static void xsk_free_umem_frame(struct xsk_socket_info *xsk, uint64_t frame) { assert(xsk->umem_frame_free < NUM_FRAMES); xsk->umem_frame_addr[xsk->umem_frame_free++] = frame; } static uint64_t xsk_umem_free_frames(struct xsk_socket_info *xsk) { return xsk->umem_frame_free; } > I'll try this approach, thanks!