On Thu, Oct 29, 2020 at 03:02:16PM +0100, Lorenzo Bianconi wrote: > > On Tue, 27 Oct 2020 20:04:07 +0100 > > Lorenzo Bianconi <lorenzo@xxxxxxxxxx> wrote: > > > > > diff --git a/net/core/xdp.c b/net/core/xdp.c > > > index 48aba933a5a8..93eabd789246 100644 > > > --- a/net/core/xdp.c > > > +++ b/net/core/xdp.c > > > @@ -380,6 +380,57 @@ void xdp_return_frame_rx_napi(struct xdp_frame *xdpf) > > > } > > > EXPORT_SYMBOL_GPL(xdp_return_frame_rx_napi); > > > > > > +void xdp_flush_frame_bulk(struct xdp_frame_bulk *bq) > > > +{ > > > + struct xdp_mem_allocator *xa = bq->xa; > > > + int i; > > > + > > > + if (unlikely(!xa)) > > > + return; > > > + > > > + for (i = 0; i < bq->count; i++) { > > > + struct page *page = virt_to_head_page(bq->q[i]); > > > + > > > + page_pool_put_full_page(xa->page_pool, page, false); > > > + } > > > + bq->count = 0; > > > +} > > > +EXPORT_SYMBOL_GPL(xdp_flush_frame_bulk); > > > + > > > +void xdp_return_frame_bulk(struct xdp_frame *xdpf, > > > + struct xdp_frame_bulk *bq) > > > +{ > > > + struct xdp_mem_info *mem = &xdpf->mem; > > > + struct xdp_mem_allocator *xa, *nxa; > > > + > > > + if (mem->type != MEM_TYPE_PAGE_POOL) { > > > + __xdp_return(xdpf->data, &xdpf->mem, false); > > > + return; > > > + } > > > + > > > + rcu_read_lock(); > > > + > > > + xa = bq->xa; > > > + if (unlikely(!xa || mem->id != xa->mem.id)) { > > > + nxa = rhashtable_lookup(mem_id_ht, &mem->id, mem_id_rht_params); > > > + if (unlikely(!xa)) { > > > + bq->count = 0; > > > + bq->xa = nxa; > > > + xa = nxa; > > > + } > > > + } > > > + > > > + if (mem->id != xa->mem.id || bq->count == XDP_BULK_QUEUE_SIZE) > > > + xdp_flush_frame_bulk(bq); > > > + > > > + bq->q[bq->count++] = xdpf->data; > > > + if (mem->id != xa->mem.id) > > > + bq->xa = nxa; > > > + > > > + rcu_read_unlock(); > > > +} > > > +EXPORT_SYMBOL_GPL(xdp_return_frame_bulk); > > > > We (Ilias my co-maintainer and I) think above code is hard to read and > > understand (as a reader you need to keep too many cases in your head). > > > > I think we both have proposals to improve this, here is mine: > > > > /* Defers return when frame belongs to same mem.id as previous frame */ > > void xdp_return_frame_bulk(struct xdp_frame *xdpf, > > struct xdp_frame_bulk *bq) > > { > > struct xdp_mem_info *mem = &xdpf->mem; > > struct xdp_mem_allocator *xa; > > > > if (mem->type != MEM_TYPE_PAGE_POOL) { > > __xdp_return(xdpf->data, &xdpf->mem, false); > > return; > > } > > > > rcu_read_lock(); > > > > xa = bq->xa; > > if (unlikely(!xa)) { > > xa = rhashtable_lookup(mem_id_ht, &mem->id, mem_id_rht_params); > > bq->count = 0; > > bq->xa = xa; > > } > > > > if (bq->count == XDP_BULK_QUEUE_SIZE) > > xdp_flush_frame_bulk(bq); > > > > if (mem->id != xa->mem.id) { > > xdp_flush_frame_bulk(bq); > > bq->xa = rhashtable_lookup(mem_id_ht, &mem->id, mem_id_rht_params); > > } > > > > bq->q[bq->count++] = xdpf->data; > > > > rcu_read_unlock(); > > } > > > > Please review for correctness, and also for readability. > > the code seems fine to me (and even easier to read :)). > I will update v2 using this approach. Thx. +1 this is close to what we discussed this morning and it detangles 1 more 'weird' if case Thanks /Ilias > > Regards, > Lorenzo > > > > > -- > > Best regards, > > Jesper Dangaard Brouer > > MSc.CS, Principal Kernel Engineer at Red Hat > > LinkedIn: http://www.linkedin.com/in/brouer > >