[<prev] [next>] [<thread-prev] [day] [month] [year] [list]
Message-ID: <i5ofr6nj2fmxqeaswucvhbtvgglhvurzslsismthlrr77v7bsk@aishfdtaq4vb>
Date: Fri, 14 Jun 2024 16:37:12 +0200
From: Stefano Garzarella <sgarzare@...hat.com>
To: Luigi Leonardi <luigi.leonardi@...look.com>
Cc: edumazet@...gle.com, virtualization@...ts.linux.dev,
netdev@...r.kernel.org, kuba@...nel.org, kvm@...r.kernel.org, stefanha@...hat.com,
pabeni@...hat.com, davem@...emloft.net, Marco Pinna <marco.pinn95@...il.com>
Subject: Re: [PATCH net-next 1/2] vsock/virtio: refactor
virtio_transport_send_pkt_work
On Fri, Jun 14, 2024 at 03:55:42PM GMT, Luigi Leonardi wrote:
>From: Marco Pinna <marco.pinn95@...il.com>
>
>This is a preliminary patch to introduce an optimization to
>the enqueue system.
>
>All the code used to enqueue a packet into the virtqueue
>is removed from virtio_transport_send_pkt_work()
>and moved to the new virtio_transport_send_skb() function.
>
>Co-developed-by: Luigi Leonardi <luigi.leonardi@...look.com>
>Signed-off-by: Luigi Leonardi <luigi.leonardi@...look.com>
>Signed-off-by: Marco Pinna <marco.pinn95@...il.com>
>---
> net/vmw_vsock/virtio_transport.c | 134 +++++++++++++++++--------------
> 1 file changed, 74 insertions(+), 60 deletions(-)
>
>diff --git a/net/vmw_vsock/virtio_transport.c b/net/vmw_vsock/virtio_transport.c
>index 43d405298857..c930235ecaec 100644
>--- a/net/vmw_vsock/virtio_transport.c
>+++ b/net/vmw_vsock/virtio_transport.c
>@@ -94,6 +94,78 @@ static u32 virtio_transport_get_local_cid(void)
> return ret;
> }
>
>+/* Caller need to hold vsock->tx_lock on vq */
>+static int virtio_transport_send_skb(struct sk_buff *skb, struct virtqueue *vq,
>+ struct virtio_vsock *vsock, bool *restart_rx)
>+{
>+ int ret, in_sg = 0, out_sg = 0;
>+ struct scatterlist **sgs;
>+ bool reply;
>+
>+ reply = virtio_vsock_skb_reply(skb);
>+ sgs = vsock->out_sgs;
>+ sg_init_one(sgs[out_sg], virtio_vsock_hdr(skb),
>+ sizeof(*virtio_vsock_hdr(skb)));
>+ out_sg++;
>+
>+ if (!skb_is_nonlinear(skb)) {
>+ if (skb->len > 0) {
>+ sg_init_one(sgs[out_sg], skb->data, skb->len);
>+ out_sg++;
>+ }
>+ } else {
>+ struct skb_shared_info *si;
>+ int i;
>+
>+ /* If skb is nonlinear, then its buffer must contain
>+ * only header and nothing more. Data is stored in
>+ * the fragged part.
>+ */
>+ WARN_ON_ONCE(skb_headroom(skb) != sizeof(*virtio_vsock_hdr(skb)));
>+
>+ si = skb_shinfo(skb);
>+
>+ for (i = 0; i < si->nr_frags; i++) {
>+ skb_frag_t *skb_frag = &si->frags[i];
>+ void *va;
>+
>+ /* We will use 'page_to_virt()' for the userspace page
>+ * here, because virtio or dma-mapping layers will call
>+ * 'virt_to_phys()' later to fill the buffer descriptor.
>+ * We don't touch memory at "virtual" address of
>this page.
>+ */
>+ va = page_to_virt(skb_frag_page(skb_frag));
>+ sg_init_one(sgs[out_sg],
>+ va + skb_frag_off(skb_frag),
>+ skb_frag_size(skb_frag));
>+ out_sg++;
>+ }
>+ }
>+
>+ ret = virtqueue_add_sgs(vq, sgs, out_sg, in_sg, skb, GFP_KERNEL);
>+ /* Usually this means that there is no more space available in
>+ * the vq
>+ */
>+ if (ret < 0)
>+ goto out;
We use the `out` label just here, so what about remove it since we just
return ret?
I mean:
if (ret < 0)
return ret;
...
>+
>+ virtio_transport_deliver_tap_pkt(skb);
>+
>+ if (reply) {
>+ struct virtqueue *rx_vq = vsock->vqs[VSOCK_VQ_RX];
>+ int val;
>+
>+ val = atomic_dec_return(&vsock->queued_replies);
>+
>+ /* Do we now have resources to resume rx processing? */
>+ if (val + 1 == virtqueue_get_vring_size(rx_vq))
>+ *restart_rx = true;
>+ }
>+
return 0;
}
>+out:
>+ return ret;
>+}
>+
> static void
> virtio_transport_send_pkt_work(struct work_struct *work)
> {
>@@ -111,77 +183,19 @@ virtio_transport_send_pkt_work(struct work_struct *work)
> vq = vsock->vqs[VSOCK_VQ_TX];
>
> for (;;) {
>- int ret, in_sg = 0, out_sg = 0;
>- struct scatterlist **sgs;
> struct sk_buff *skb;
>- bool reply;
>+ int ret;
>
> skb = virtio_vsock_skb_dequeue(&vsock->send_pkt_queue);
> if (!skb)
> break;
>
>- reply = virtio_vsock_skb_reply(skb);
>- sgs = vsock->out_sgs;
>- sg_init_one(sgs[out_sg], virtio_vsock_hdr(skb),
>- sizeof(*virtio_vsock_hdr(skb)));
>- out_sg++;
>-
>- if (!skb_is_nonlinear(skb)) {
>- if (skb->len > 0) {
>- sg_init_one(sgs[out_sg], skb->data, skb->len);
>- out_sg++;
>- }
>- } else {
>- struct skb_shared_info *si;
>- int i;
>+ ret = virtio_transport_send_skb(skb, vq, vsock, &restart_rx);
>
nit: I'd remove this new line here.
>- /* If skb is nonlinear, then its buffer must contain
>- * only header and nothing more. Data is stored in
>- * the fragged part.
>- */
>- WARN_ON_ONCE(skb_headroom(skb) != sizeof(*virtio_vsock_hdr(skb)));
>-
>- si = skb_shinfo(skb);
>-
>- for (i = 0; i < si->nr_frags; i++) {
>- skb_frag_t *skb_frag = &si->frags[i];
>- void *va;
>-
>- /* We will use 'page_to_virt()' for the userspace page
>- * here, because virtio or dma-mapping layers will call
>- * 'virt_to_phys()' later to fill the buffer descriptor.
>- * We don't touch memory at "virtual" address of this page.
>- */
>- va = page_to_virt(skb_frag_page(skb_frag));
>- sg_init_one(sgs[out_sg],
>- va + skb_frag_off(skb_frag),
>- skb_frag_size(skb_frag));
>- out_sg++;
>- }
>- }
>-
>- ret = virtqueue_add_sgs(vq, sgs, out_sg, in_sg, skb,
>GFP_KERNEL);
>- /* Usually this means that there is no more space
>available in
>- * the vq
>- */
> if (ret < 0) {
> virtio_vsock_skb_queue_head(&vsock->send_pkt_queue, skb);
> break;
> }
>-
>- virtio_transport_deliver_tap_pkt(skb);
>-
>- if (reply) {
>- struct virtqueue *rx_vq = vsock->vqs[VSOCK_VQ_RX];
>- int val;
>-
>- val = atomic_dec_return(&vsock->queued_replies);
>-
>- /* Do we now have resources to resume rx processing? */
>- if (val + 1 == virtqueue_get_vring_size(rx_vq))
>- restart_rx = true;
>- }
>-
nit: maybe I'd move the empty line here.
Our usual style is:
ret = foo();
if (ret < 0) {
//error handling
}
next_stuff...
Thanks,
Stefano
> added = true;
> }
>
>--
>2.45.2
>
Powered by blists - more mailing lists