Re: [PATCH v10 15/18] vhost/vsock: support SEQPACKET for transport
From: Stefano Garzarella <sgarzare@redhat.com>
Date: 2021-06-03 15:35:10
Also in:
kvm, lkml, netdev
On Thu, May 20, 2021 at 10:19:13PM +0300, Arseny Krasnov wrote: Please describe better the changes included in this patch in the first part of the commit message.
quoted hunk
As vhost places data in buffers of guest's rx queue, keep SEQ_EOR bit set only when last piece of data is copied. Otherwise we get sequence packets for one socket in guest's rx queue with SEQ_EOR bit set. Also remove ignore of non-stream type of packets, handle SEQPACKET feature bit. Signed-off-by: Arseny Krasnov <redacted> --- v9 -> v10: 1) Move 'restore_flag' handling to 'payload_len' calculation block. drivers/vhost/vsock.c | 44 +++++++++++++++++++++++++++++++++++++++---- 1 file changed, 40 insertions(+), 4 deletions(-)diff --git a/drivers/vhost/vsock.c b/drivers/vhost/vsock.c index 5e78fb719602..63d15beaad05 100644 --- a/drivers/vhost/vsock.c +++ b/drivers/vhost/vsock.c@@ -31,7 +31,8 @@enum { VHOST_VSOCK_FEATURES = VHOST_FEATURES | - (1ULL << VIRTIO_F_ACCESS_PLATFORM) + (1ULL << VIRTIO_F_ACCESS_PLATFORM) | + (1ULL << VIRTIO_VSOCK_F_SEQPACKET) }; enum {@@ -56,6 +57,7 @@ struct vhost_vsock {atomic_t queued_replies; u32 guest_cid; + bool seqpacket_allow; }; static u32 vhost_transport_get_local_cid(void)@@ -112,6 +114,7 @@ vhost_transport_do_send_pkt(struct vhost_vsock *vsock,size_t nbytes; size_t iov_len, payload_len; int head; + bool restore_flag = false; spin_lock_bh(&vsock->send_pkt_list_lock); if (list_empty(&vsock->send_pkt_list)) {@@ -168,9 +171,15 @@ vhost_transport_do_send_pkt(struct vhost_vsock *vsock,/* If the packet is greater than the space available in the * buffer, we split it using multiple buffers. */ - if (payload_len > iov_len - sizeof(pkt->hdr)) + if (payload_len > iov_len - sizeof(pkt->hdr)) { payload_len = iov_len - sizeof(pkt->hdr);
Please, add a comment here to explain why we need this.
quoted hunk
+ if (le32_to_cpu(pkt->hdr.flags) & VIRTIO_VSOCK_SEQ_EOR) { + pkt->hdr.flags &= ~cpu_to_le32(VIRTIO_VSOCK_SEQ_EOR); + restore_flag = true; + } + } + /* Set the correct length in the header */ pkt->hdr.len = cpu_to_le32(payload_len);@@ -181,6 +190,9 @@ vhost_transport_do_send_pkt(struct vhost_vsock*vsock, break; } + if (restore_flag) + pkt->hdr.flags |= cpu_to_le32(VIRTIO_VSOCK_SEQ_EOR); +
Maybe we can restore the flag only if we are queueing again the same
packet, I mean in the `if (pkt->off < pkt->len) {` branch below.
What do you think?
quoted hunk
nbytes = copy_to_iter(pkt->buf + pkt->off, payload_len, &iov_iter); if (nbytes != payload_len) {@@ -354,8 +366,7 @@ vhost_vsock_alloc_pkt(struct vhost_virtqueue *vq,return NULL; } - if (le16_to_cpu(pkt->hdr.type) == VIRTIO_VSOCK_TYPE_STREAM) - pkt->len = le32_to_cpu(pkt->hdr.len); + pkt->len = le32_to_cpu(pkt->hdr.len); /* No payload */ if (!pkt->len)@@ -398,6 +409,8 @@ static bool vhost_vsock_more_replies(structvhost_vsock *vsock) return val < vq->num; } +static bool vhost_transport_seqpacket_allow(u32 remote_cid); + static struct virtio_transport vhost_transport = { .transport = { .module = THIS_MODULE,@@ -424,6 +437,10 @@ static struct virtio_transport vhost_transport = {.stream_is_active = virtio_transport_stream_is_active, .stream_allow = virtio_transport_stream_allow, + .seqpacket_dequeue = virtio_transport_seqpacket_dequeue, + .seqpacket_enqueue = virtio_transport_seqpacket_enqueue, + .seqpacket_allow = vhost_transport_seqpacket_allow, + .notify_poll_in = virtio_transport_notify_poll_in, .notify_poll_out = virtio_transport_notify_poll_out, .notify_recv_init = virtio_transport_notify_recv_init,@@ -441,6 +458,22 @@ static struct virtio_transport vhost_transport = {.send_pkt = vhost_transport_send_pkt, }; +static bool vhost_transport_seqpacket_allow(u32 remote_cid) +{ + struct vhost_vsock *vsock; + bool seqpacket_allow = false; + + rcu_read_lock(); + vsock = vhost_vsock_get(remote_cid); + + if (vsock) + seqpacket_allow = vsock->seqpacket_allow; + + rcu_read_unlock(); + + return seqpacket_allow; +} + static void vhost_vsock_handle_tx_kick(struct vhost_work *work) { struct vhost_virtqueue *vq = container_of(work, struct vhost_virtqueue,@@ -785,6 +818,9 @@ static int vhost_vsock_set_features(struct vhost_vsock *vsock, u64 features)goto err; } + if (features & (1ULL << VIRTIO_VSOCK_F_SEQPACKET)) + vsock->seqpacket_allow = true; + for (i = 0; i < ARRAY_SIZE(vsock->vqs); i++) { vq = &vsock->vqs[i]; mutex_lock(&vq->mutex); -- 2.25.1
_______________________________________________ Virtualization mailing list Virtualization@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/virtualization