Message ID | 20170113025123.4535.75989.stgit@john-Precision-Tower-5810 |
---|---|
State | Changes Requested, archived |
Delegated to: | David Miller |
Headers | show |
On 2017年01月13日 10:51, John Fastabend wrote: > At this point the do_xdp_prog is mostly if/else branches handling > the different modes of virtio_net. So remove it and handle running > the program in the per mode handlers. > > Signed-off-by: John Fastabend <john.r.fastabend@intel.com> > --- > drivers/net/virtio_net.c | 76 +++++++++++++++++----------------------------- > 1 file changed, 28 insertions(+), 48 deletions(-) > > diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c > index 43cb2e0..ec54644 100644 > --- a/drivers/net/virtio_net.c > +++ b/drivers/net/virtio_net.c > @@ -388,49 +388,6 @@ static void virtnet_xdp_xmit(struct virtnet_info *vi, > virtqueue_kick(sq->vq); > } > [...] > > /* This happens when rx buffer size is underestimated */ > @@ -598,8 +570,10 @@ static struct sk_buff *receive_mergeable(struct net_device *dev, > if (unlikely(hdr->hdr.gso_type)) > goto err_xdp; > > - act = do_xdp_prog(vi, rq, xdp_prog, > - page_address(xdp_page) + offset, len); > + data = page_address(xdp_page) + offset; > + xdp.data = data + desc_room; > + xdp.data_end = xdp.data + (len - vi->hdr_len); It looks desc_room is always vi->hdr_len. > + act = bpf_prog_run_xdp(xdp_prog, &xdp); > switch (act) { > case XDP_PASS: > /* We can only create skb based on xdp_page. */ > @@ -613,13 +587,19 @@ static struct sk_buff *receive_mergeable(struct net_device *dev, > } > break; > case XDP_TX: > + qp = vi->curr_queue_pairs - > + vi->xdp_queue_pairs + > + smp_processor_id(); > + virtnet_xdp_xmit(vi, rq, &vi->sq[qp], &xdp, data); > ewma_pkt_len_add(&rq->mrg_avg_pkt_len, len); > if (unlikely(xdp_page != page)) > goto err_xdp; > rcu_read_unlock(); > goto xdp_xmit; > - case XDP_DROP: > default: > + bpf_warn_invalid_xdp_action(act); > + case XDP_ABORTED: > + case XDP_DROP: > if (unlikely(xdp_page != page)) > __free_pages(xdp_page, 0); > ewma_pkt_len_add(&rq->mrg_avg_pkt_len, len); >
On 17-01-12 11:40 PM, Jason Wang wrote: > > > On 2017年01月13日 10:51, John Fastabend wrote: >> At this point the do_xdp_prog is mostly if/else branches handling >> the different modes of virtio_net. So remove it and handle running >> the program in the per mode handlers. >> >> Signed-off-by: John Fastabend <john.r.fastabend@intel.com> >> --- >> drivers/net/virtio_net.c | 76 +++++++++++++++++----------------------------- >> 1 file changed, 28 insertions(+), 48 deletions(-) >> >> diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c >> index 43cb2e0..ec54644 100644 >> --- a/drivers/net/virtio_net.c >> +++ b/drivers/net/virtio_net.c >> @@ -388,49 +388,6 @@ static void virtnet_xdp_xmit(struct virtnet_info *vi, >> virtqueue_kick(sq->vq); >> } >> > > [...] > >> /* This happens when rx buffer size is underestimated */ >> @@ -598,8 +570,10 @@ static struct sk_buff *receive_mergeable(struct >> net_device *dev, >> if (unlikely(hdr->hdr.gso_type)) >> goto err_xdp; >> - act = do_xdp_prog(vi, rq, xdp_prog, >> - page_address(xdp_page) + offset, len); >> + data = page_address(xdp_page) + offset; >> + xdp.data = data + desc_room; >> + xdp.data_end = xdp.data + (len - vi->hdr_len); > > It looks desc_room is always vi->hdr_len. > Seems to be the case I'll just use vi->hdr_len and remove the variable. Thanks. >> + act = bpf_prog_run_xdp(xdp_prog, &xdp); >> switch (act) { >> case XDP_PASS: >> /* We can only create skb based on xdp_page. */ >> @@ -613,13 +587,19 @@ static struct sk_buff *receive_mergeable(struct >> net_device *dev, >> } >> break; >> case XDP_TX: >> + qp = vi->curr_queue_pairs - >> + vi->xdp_queue_pairs + >> + smp_processor_id(); >> + virtnet_xdp_xmit(vi, rq, &vi->sq[qp], &xdp, data); >> ewma_pkt_len_add(&rq->mrg_avg_pkt_len, len); >> if (unlikely(xdp_page != page)) >> goto err_xdp; >> rcu_read_unlock(); >> goto xdp_xmit; >> - case XDP_DROP: >> default: >> + bpf_warn_invalid_xdp_action(act); >> + case XDP_ABORTED: >> + case XDP_DROP: >> if (unlikely(xdp_page != page)) >> __free_pages(xdp_page, 0); >> ewma_pkt_len_add(&rq->mrg_avg_pkt_len, len); >> >
diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c index 43cb2e0..ec54644 100644 --- a/drivers/net/virtio_net.c +++ b/drivers/net/virtio_net.c @@ -388,49 +388,6 @@ static void virtnet_xdp_xmit(struct virtnet_info *vi, virtqueue_kick(sq->vq); } -static u32 do_xdp_prog(struct virtnet_info *vi, - struct receive_queue *rq, - struct bpf_prog *xdp_prog, - void *data, int len) -{ - int hdr_padded_len; - struct xdp_buff xdp; - void *buf; - unsigned int qp; - u32 act; - - if (vi->mergeable_rx_bufs) { - hdr_padded_len = sizeof(struct virtio_net_hdr_mrg_rxbuf); - xdp.data = data + hdr_padded_len; - xdp.data_end = xdp.data + (len - vi->hdr_len); - buf = data; - } else { /* small buffers */ - struct sk_buff *skb = data; - - xdp.data = skb->data; - xdp.data_end = xdp.data + len; - buf = skb->data; - } - - act = bpf_prog_run_xdp(xdp_prog, &xdp); - switch (act) { - case XDP_PASS: - return XDP_PASS; - case XDP_TX: - qp = vi->curr_queue_pairs - - vi->xdp_queue_pairs + - smp_processor_id(); - xdp.data = buf; - virtnet_xdp_xmit(vi, rq, &vi->sq[qp], &xdp, data); - return XDP_TX; - default: - bpf_warn_invalid_xdp_action(act); - case XDP_ABORTED: - case XDP_DROP: - return XDP_DROP; - } -} - static struct sk_buff *receive_small(struct net_device *dev, struct virtnet_info *vi, struct receive_queue *rq, @@ -446,19 +403,30 @@ static struct sk_buff *receive_small(struct net_device *dev, xdp_prog = rcu_dereference(rq->xdp_prog); if (xdp_prog) { struct virtio_net_hdr_mrg_rxbuf *hdr = buf; + struct xdp_buff xdp; + unsigned int qp; u32 act; if (unlikely(hdr->hdr.gso_type || hdr->hdr.flags)) goto err_xdp; - act = do_xdp_prog(vi, rq, xdp_prog, skb, len); + + xdp.data = skb->data; + xdp.data_end = xdp.data + len; + act = bpf_prog_run_xdp(xdp_prog, &xdp); switch (act) { case XDP_PASS: break; case XDP_TX: + qp = vi->curr_queue_pairs - + vi->xdp_queue_pairs + + smp_processor_id(); + virtnet_xdp_xmit(vi, rq, &vi->sq[qp], &xdp, skb); rcu_read_unlock(); goto xdp_xmit; - case XDP_DROP: default: + bpf_warn_invalid_xdp_action(act); + case XDP_ABORTED: + case XDP_DROP: goto err_xdp; } } @@ -575,7 +543,11 @@ static struct sk_buff *receive_mergeable(struct net_device *dev, rcu_read_lock(); xdp_prog = rcu_dereference(rq->xdp_prog); if (xdp_prog) { + int desc_room = sizeof(struct virtio_net_hdr_mrg_rxbuf); struct page *xdp_page; + struct xdp_buff xdp; + unsigned int qp; + void *data; u32 act; /* This happens when rx buffer size is underestimated */ @@ -598,8 +570,10 @@ static struct sk_buff *receive_mergeable(struct net_device *dev, if (unlikely(hdr->hdr.gso_type)) goto err_xdp; - act = do_xdp_prog(vi, rq, xdp_prog, - page_address(xdp_page) + offset, len); + data = page_address(xdp_page) + offset; + xdp.data = data + desc_room; + xdp.data_end = xdp.data + (len - vi->hdr_len); + act = bpf_prog_run_xdp(xdp_prog, &xdp); switch (act) { case XDP_PASS: /* We can only create skb based on xdp_page. */ @@ -613,13 +587,19 @@ static struct sk_buff *receive_mergeable(struct net_device *dev, } break; case XDP_TX: + qp = vi->curr_queue_pairs - + vi->xdp_queue_pairs + + smp_processor_id(); + virtnet_xdp_xmit(vi, rq, &vi->sq[qp], &xdp, data); ewma_pkt_len_add(&rq->mrg_avg_pkt_len, len); if (unlikely(xdp_page != page)) goto err_xdp; rcu_read_unlock(); goto xdp_xmit; - case XDP_DROP: default: + bpf_warn_invalid_xdp_action(act); + case XDP_ABORTED: + case XDP_DROP: if (unlikely(xdp_page != page)) __free_pages(xdp_page, 0); ewma_pkt_len_add(&rq->mrg_avg_pkt_len, len);
At this point the do_xdp_prog is mostly if/else branches handling the different modes of virtio_net. So remove it and handle running the program in the per mode handlers. Signed-off-by: John Fastabend <john.r.fastabend@intel.com> --- drivers/net/virtio_net.c | 76 +++++++++++++++++----------------------------- 1 file changed, 28 insertions(+), 48 deletions(-)