Re: AF_XDP only releasing from FQ in batches

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 




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!



[Index of Archives]     [Linux Networking Development]     [Fedora Linux Users]     [Linux SCTP]     [DCCP]     [Gimp]     [Yosemite Campsites]

  Powered by Linux