+++ /dev/null
-From 00c0b1b3723f51d243538ace6661a31c4e279dc1 Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Thu, 14 Nov 2019 10:57:40 +0100
-Subject: vsock/virtio: add transport parameter to the
- virtio_transport_reset_no_sock()
-
-From: Stefano Garzarella <sgarzare@redhat.com>
-
-[ Upstream commit 4c7246dc45e2706770d5233f7ce1597a07e069ba ]
-
-We are going to add 'struct vsock_sock *' parameter to
-virtio_transport_get_ops().
-
-In some cases, like in the virtio_transport_reset_no_sock(),
-we don't have any socket assigned to the packet received,
-so we can't use the virtio_transport_get_ops().
-
-In order to allow virtio_transport_reset_no_sock() to use the
-'.send_pkt' callback from the 'vhost_transport' or 'virtio_transport',
-we add the 'struct virtio_transport *' to it and to its caller:
-virtio_transport_recv_pkt().
-
-We moved the 'vhost_transport' and 'virtio_transport' definition,
-to pass their address to the virtio_transport_recv_pkt().
-
-Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
-Signed-off-by: Stefano Garzarella <sgarzare@redhat.com>
-Signed-off-by: David S. Miller <davem@davemloft.net>
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- drivers/vhost/vsock.c | 94 ++++++++---------
- include/linux/virtio_vsock.h | 3 +-
- net/vmw_vsock/virtio_transport.c | 131 ++++++++++++++----------
- net/vmw_vsock/virtio_transport_common.c | 12 +--
- 4 files changed, 134 insertions(+), 106 deletions(-)
-
-diff --git a/drivers/vhost/vsock.c b/drivers/vhost/vsock.c
-index 2ac966400c428..554e131d17b3b 100644
---- a/drivers/vhost/vsock.c
-+++ b/drivers/vhost/vsock.c
-@@ -349,6 +349,52 @@ static bool vhost_vsock_more_replies(struct vhost_vsock *vsock)
- return val < vq->num;
- }
-
-+static struct virtio_transport vhost_transport = {
-+ .transport = {
-+ .get_local_cid = vhost_transport_get_local_cid,
-+
-+ .init = virtio_transport_do_socket_init,
-+ .destruct = virtio_transport_destruct,
-+ .release = virtio_transport_release,
-+ .connect = virtio_transport_connect,
-+ .shutdown = virtio_transport_shutdown,
-+ .cancel_pkt = vhost_transport_cancel_pkt,
-+
-+ .dgram_enqueue = virtio_transport_dgram_enqueue,
-+ .dgram_dequeue = virtio_transport_dgram_dequeue,
-+ .dgram_bind = virtio_transport_dgram_bind,
-+ .dgram_allow = virtio_transport_dgram_allow,
-+
-+ .stream_enqueue = virtio_transport_stream_enqueue,
-+ .stream_dequeue = virtio_transport_stream_dequeue,
-+ .stream_has_data = virtio_transport_stream_has_data,
-+ .stream_has_space = virtio_transport_stream_has_space,
-+ .stream_rcvhiwat = virtio_transport_stream_rcvhiwat,
-+ .stream_is_active = virtio_transport_stream_is_active,
-+ .stream_allow = virtio_transport_stream_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,
-+ .notify_recv_pre_block = virtio_transport_notify_recv_pre_block,
-+ .notify_recv_pre_dequeue = virtio_transport_notify_recv_pre_dequeue,
-+ .notify_recv_post_dequeue = virtio_transport_notify_recv_post_dequeue,
-+ .notify_send_init = virtio_transport_notify_send_init,
-+ .notify_send_pre_block = virtio_transport_notify_send_pre_block,
-+ .notify_send_pre_enqueue = virtio_transport_notify_send_pre_enqueue,
-+ .notify_send_post_enqueue = virtio_transport_notify_send_post_enqueue,
-+
-+ .set_buffer_size = virtio_transport_set_buffer_size,
-+ .set_min_buffer_size = virtio_transport_set_min_buffer_size,
-+ .set_max_buffer_size = virtio_transport_set_max_buffer_size,
-+ .get_buffer_size = virtio_transport_get_buffer_size,
-+ .get_min_buffer_size = virtio_transport_get_min_buffer_size,
-+ .get_max_buffer_size = virtio_transport_get_max_buffer_size,
-+ },
-+
-+ .send_pkt = vhost_transport_send_pkt,
-+};
-+
- static void vhost_vsock_handle_tx_kick(struct vhost_work *work)
- {
- struct vhost_virtqueue *vq = container_of(work, struct vhost_virtqueue,
-@@ -402,7 +448,7 @@ static void vhost_vsock_handle_tx_kick(struct vhost_work *work)
- if (le64_to_cpu(pkt->hdr.src_cid) == vsock->guest_cid &&
- le64_to_cpu(pkt->hdr.dst_cid) ==
- vhost_transport_get_local_cid())
-- virtio_transport_recv_pkt(pkt);
-+ virtio_transport_recv_pkt(&vhost_transport, pkt);
- else
- virtio_transport_free_pkt(pkt);
-
-@@ -745,52 +791,6 @@ static struct miscdevice vhost_vsock_misc = {
- .fops = &vhost_vsock_fops,
- };
-
--static struct virtio_transport vhost_transport = {
-- .transport = {
-- .get_local_cid = vhost_transport_get_local_cid,
--
-- .init = virtio_transport_do_socket_init,
-- .destruct = virtio_transport_destruct,
-- .release = virtio_transport_release,
-- .connect = virtio_transport_connect,
-- .shutdown = virtio_transport_shutdown,
-- .cancel_pkt = vhost_transport_cancel_pkt,
--
-- .dgram_enqueue = virtio_transport_dgram_enqueue,
-- .dgram_dequeue = virtio_transport_dgram_dequeue,
-- .dgram_bind = virtio_transport_dgram_bind,
-- .dgram_allow = virtio_transport_dgram_allow,
--
-- .stream_enqueue = virtio_transport_stream_enqueue,
-- .stream_dequeue = virtio_transport_stream_dequeue,
-- .stream_has_data = virtio_transport_stream_has_data,
-- .stream_has_space = virtio_transport_stream_has_space,
-- .stream_rcvhiwat = virtio_transport_stream_rcvhiwat,
-- .stream_is_active = virtio_transport_stream_is_active,
-- .stream_allow = virtio_transport_stream_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,
-- .notify_recv_pre_block = virtio_transport_notify_recv_pre_block,
-- .notify_recv_pre_dequeue = virtio_transport_notify_recv_pre_dequeue,
-- .notify_recv_post_dequeue = virtio_transport_notify_recv_post_dequeue,
-- .notify_send_init = virtio_transport_notify_send_init,
-- .notify_send_pre_block = virtio_transport_notify_send_pre_block,
-- .notify_send_pre_enqueue = virtio_transport_notify_send_pre_enqueue,
-- .notify_send_post_enqueue = virtio_transport_notify_send_post_enqueue,
--
-- .set_buffer_size = virtio_transport_set_buffer_size,
-- .set_min_buffer_size = virtio_transport_set_min_buffer_size,
-- .set_max_buffer_size = virtio_transport_set_max_buffer_size,
-- .get_buffer_size = virtio_transport_get_buffer_size,
-- .get_min_buffer_size = virtio_transport_get_min_buffer_size,
-- .get_max_buffer_size = virtio_transport_get_max_buffer_size,
-- },
--
-- .send_pkt = vhost_transport_send_pkt,
--};
--
- static int __init vhost_vsock_init(void)
- {
- int ret;
-diff --git a/include/linux/virtio_vsock.h b/include/linux/virtio_vsock.h
-index 584f9a647ad4a..0860cf4ae0461 100644
---- a/include/linux/virtio_vsock.h
-+++ b/include/linux/virtio_vsock.h
-@@ -148,7 +148,8 @@ virtio_transport_dgram_enqueue(struct vsock_sock *vsk,
-
- void virtio_transport_destruct(struct vsock_sock *vsk);
-
--void virtio_transport_recv_pkt(struct virtio_vsock_pkt *pkt);
-+void virtio_transport_recv_pkt(struct virtio_transport *t,
-+ struct virtio_vsock_pkt *pkt);
- void virtio_transport_free_pkt(struct virtio_vsock_pkt *pkt);
- void virtio_transport_inc_tx_pkt(struct virtio_vsock_sock *vvs, struct virtio_vsock_pkt *pkt);
- u32 virtio_transport_get_credit(struct virtio_vsock_sock *vvs, u32 wanted);
-diff --git a/net/vmw_vsock/virtio_transport.c b/net/vmw_vsock/virtio_transport.c
-index 67aba63b5c96d..43f6c4240b2a8 100644
---- a/net/vmw_vsock/virtio_transport.c
-+++ b/net/vmw_vsock/virtio_transport.c
-@@ -271,58 +271,6 @@ static bool virtio_transport_more_replies(struct virtio_vsock *vsock)
- return val < virtqueue_get_vring_size(vq);
- }
-
--static void virtio_transport_rx_work(struct work_struct *work)
--{
-- struct virtio_vsock *vsock =
-- container_of(work, struct virtio_vsock, rx_work);
-- struct virtqueue *vq;
--
-- vq = vsock->vqs[VSOCK_VQ_RX];
--
-- mutex_lock(&vsock->rx_lock);
--
-- if (!vsock->rx_run)
-- goto out;
--
-- do {
-- virtqueue_disable_cb(vq);
-- for (;;) {
-- struct virtio_vsock_pkt *pkt;
-- unsigned int len;
--
-- if (!virtio_transport_more_replies(vsock)) {
-- /* Stop rx until the device processes already
-- * pending replies. Leave rx virtqueue
-- * callbacks disabled.
-- */
-- goto out;
-- }
--
-- pkt = virtqueue_get_buf(vq, &len);
-- if (!pkt) {
-- break;
-- }
--
-- vsock->rx_buf_nr--;
--
-- /* Drop short/long packets */
-- if (unlikely(len < sizeof(pkt->hdr) ||
-- len > sizeof(pkt->hdr) + pkt->len)) {
-- virtio_transport_free_pkt(pkt);
-- continue;
-- }
--
-- pkt->len = len - sizeof(pkt->hdr);
-- virtio_transport_recv_pkt(pkt);
-- }
-- } while (!virtqueue_enable_cb(vq));
--
--out:
-- if (vsock->rx_buf_nr < vsock->rx_buf_max_nr / 2)
-- virtio_vsock_rx_fill(vsock);
-- mutex_unlock(&vsock->rx_lock);
--}
--
- /* event_lock must be held */
- static int virtio_vsock_event_fill_one(struct virtio_vsock *vsock,
- struct virtio_vsock_event *event)
-@@ -485,6 +433,85 @@ static struct virtio_transport virtio_transport = {
- .send_pkt = virtio_transport_send_pkt,
- };
-
-+static void virtio_transport_loopback_work(struct work_struct *work)
-+{
-+ struct virtio_vsock *vsock =
-+ container_of(work, struct virtio_vsock, loopback_work);
-+ LIST_HEAD(pkts);
-+
-+ spin_lock_bh(&vsock->loopback_list_lock);
-+ list_splice_init(&vsock->loopback_list, &pkts);
-+ spin_unlock_bh(&vsock->loopback_list_lock);
-+
-+ mutex_lock(&vsock->rx_lock);
-+
-+ if (!vsock->rx_run)
-+ goto out;
-+
-+ while (!list_empty(&pkts)) {
-+ struct virtio_vsock_pkt *pkt;
-+
-+ pkt = list_first_entry(&pkts, struct virtio_vsock_pkt, list);
-+ list_del_init(&pkt->list);
-+
-+ virtio_transport_recv_pkt(&virtio_transport, pkt);
-+ }
-+out:
-+ mutex_unlock(&vsock->rx_lock);
-+}
-+
-+static void virtio_transport_rx_work(struct work_struct *work)
-+{
-+ struct virtio_vsock *vsock =
-+ container_of(work, struct virtio_vsock, rx_work);
-+ struct virtqueue *vq;
-+
-+ vq = vsock->vqs[VSOCK_VQ_RX];
-+
-+ mutex_lock(&vsock->rx_lock);
-+
-+ if (!vsock->rx_run)
-+ goto out;
-+
-+ do {
-+ virtqueue_disable_cb(vq);
-+ for (;;) {
-+ struct virtio_vsock_pkt *pkt;
-+ unsigned int len;
-+
-+ if (!virtio_transport_more_replies(vsock)) {
-+ /* Stop rx until the device processes already
-+ * pending replies. Leave rx virtqueue
-+ * callbacks disabled.
-+ */
-+ goto out;
-+ }
-+
-+ pkt = virtqueue_get_buf(vq, &len);
-+ if (!pkt) {
-+ break;
-+ }
-+
-+ vsock->rx_buf_nr--;
-+
-+ /* Drop short/long packets */
-+ if (unlikely(len < sizeof(pkt->hdr) ||
-+ len > sizeof(pkt->hdr) + pkt->len)) {
-+ virtio_transport_free_pkt(pkt);
-+ continue;
-+ }
-+
-+ pkt->len = len - sizeof(pkt->hdr);
-+ virtio_transport_recv_pkt(&virtio_transport, pkt);
-+ }
-+ } while (!virtqueue_enable_cb(vq));
-+
-+out:
-+ if (vsock->rx_buf_nr < vsock->rx_buf_max_nr / 2)
-+ virtio_vsock_rx_fill(vsock);
-+ mutex_unlock(&vsock->rx_lock);
-+}
-+
- static int virtio_vsock_probe(struct virtio_device *vdev)
- {
- vq_callback_t *callbacks[] = {
-diff --git a/net/vmw_vsock/virtio_transport_common.c b/net/vmw_vsock/virtio_transport_common.c
-index aa9d1c7780c3d..d64285afe68f3 100644
---- a/net/vmw_vsock/virtio_transport_common.c
-+++ b/net/vmw_vsock/virtio_transport_common.c
-@@ -599,9 +599,9 @@ static int virtio_transport_reset(struct vsock_sock *vsk,
- /* Normally packets are associated with a socket. There may be no socket if an
- * attempt was made to connect to a socket that does not exist.
- */
--static int virtio_transport_reset_no_sock(struct virtio_vsock_pkt *pkt)
-+static int virtio_transport_reset_no_sock(const struct virtio_transport *t,
-+ struct virtio_vsock_pkt *pkt)
- {
-- const struct virtio_transport *t;
- struct virtio_vsock_pkt *reply;
- struct virtio_vsock_pkt_info info = {
- .op = VIRTIO_VSOCK_OP_RST,
-@@ -621,7 +621,6 @@ static int virtio_transport_reset_no_sock(struct virtio_vsock_pkt *pkt)
- if (!reply)
- return -ENOMEM;
-
-- t = virtio_transport_get_ops();
- if (!t) {
- virtio_transport_free_pkt(reply);
- return -ENOTCONN;
-@@ -919,7 +918,8 @@ static bool virtio_transport_space_update(struct sock *sk,
- /* We are under the virtio-vsock's vsock->rx_lock or vhost-vsock's vq->mutex
- * lock.
- */
--void virtio_transport_recv_pkt(struct virtio_vsock_pkt *pkt)
-+void virtio_transport_recv_pkt(struct virtio_transport *t,
-+ struct virtio_vsock_pkt *pkt)
- {
- struct sockaddr_vm src, dst;
- struct vsock_sock *vsk;
-@@ -941,7 +941,7 @@ void virtio_transport_recv_pkt(struct virtio_vsock_pkt *pkt)
- le32_to_cpu(pkt->hdr.fwd_cnt));
-
- if (le16_to_cpu(pkt->hdr.type) != VIRTIO_VSOCK_TYPE_STREAM) {
-- (void)virtio_transport_reset_no_sock(pkt);
-+ (void)virtio_transport_reset_no_sock(t, pkt);
- goto free_pkt;
- }
-
-@@ -952,7 +952,7 @@ void virtio_transport_recv_pkt(struct virtio_vsock_pkt *pkt)
- if (!sk) {
- sk = vsock_find_bound_socket(&dst);
- if (!sk) {
-- (void)virtio_transport_reset_no_sock(pkt);
-+ (void)virtio_transport_reset_no_sock(t, pkt);
- goto free_pkt;
- }
- }
---
-2.25.1
-