From: Willem de Bruijn <will...@google.com> Allow the tun device to intercept zerocopy completions to increment its counters.
Pass an array of two struct ubuf_info to the device. The first is initialized as usual and used to notify vhost_net. The second is granted to the tun device for its callback. Use the existing per-device ubuf_info pool, but take out two elements at a time, so double the size. Signed-off-by: Willem de Bruijn <will...@google.com> --- drivers/vhost/net.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/drivers/vhost/net.c b/drivers/vhost/net.c index 58585ec8699e..22988a7df656 100644 --- a/drivers/vhost/net.c +++ b/drivers/vhost/net.c @@ -47,6 +47,7 @@ MODULE_PARM_DESC(experimental_zcopytx, "Enable Zero Copy TX;" /* MAX number of TX used buffers for outstanding zerocopy */ #define VHOST_MAX_PEND 128 #define VHOST_GOODCOPY_LEN 256 +#define UBUFLEN 2 /* Number of consecutive ubuf_info passed to tun */ /* * For transmit, used buffer len is unused; we override it to track buffer @@ -254,7 +255,7 @@ static int vhost_net_set_ubuf_info(struct vhost_net *n) if (!zcopy) continue; n->vqs[i].ubuf_info = kmalloc(sizeof(*n->vqs[i].ubuf_info) * - UIO_MAXIOV, GFP_KERNEL); + UIO_MAXIOV * UBUFLEN, GFP_KERNEL); if (!n->vqs[i].ubuf_info) goto err; } @@ -526,7 +527,7 @@ static void handle_tx(struct vhost_net *net) /* use msg_control to pass vhost zerocopy ubuf info to skb */ if (zcopy_used) { struct ubuf_info *ubuf; - ubuf = nvq->ubuf_info + nvq->upend_idx; + ubuf = nvq->ubuf_info + (nvq->upend_idx * UBUFLEN); vq->heads[nvq->upend_idx].id = cpu_to_vhost32(vq, head); vq->heads[nvq->upend_idx].len = VHOST_DMA_IN_PROGRESS; @@ -535,7 +536,7 @@ static void handle_tx(struct vhost_net *net) ubuf->desc = nvq->upend_idx; refcount_set(&ubuf->refcnt, 1); msg.msg_control = ubuf; - msg.msg_controllen = sizeof(ubuf); + msg.msg_controllen = sizeof(*ubuf) * UBUFLEN; ubufs = nvq->ubufs; atomic_inc(&ubufs->refcount); nvq->upend_idx = (nvq->upend_idx + 1) % UIO_MAXIOV; -- 2.14.2.920.gcf0c67979c-goog