Commit 26618da3 authored by Marco Pinna's avatar Marco Pinna Committed by Michael S. Tsirkin
Browse files

vsock/virtio: refactor virtio_transport_send_pkt_work



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: default avatarLuigi Leonardi <luigi.leonardi@outlook.com>
Signed-off-by: default avatarLuigi Leonardi <luigi.leonardi@outlook.com>
Signed-off-by: default avatarMarco Pinna <marco.pinn95@gmail.com>
Reviewed-by: default avatarStefano Garzarella <sgarzare@redhat.com>
Message-Id: <20240730-pinna-v4-1-5c9179164db5@outlook.com>
Signed-off-by: default avatarMichael S. Tsirkin <mst@redhat.com>
parent 4a21d31d
Loading
Loading
Loading
Loading
+59 −46
Original line number Diff line number Diff line
@@ -94,33 +94,13 @@ static u32 virtio_transport_get_local_cid(void)
	return ret;
}

static void
virtio_transport_send_pkt_work(struct work_struct *work)
/* 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)
{
	struct virtio_vsock *vsock =
		container_of(work, struct virtio_vsock, send_pkt_work);
	struct virtqueue *vq;
	bool added = false;
	bool restart_rx = false;

	mutex_lock(&vsock->tx_lock);

	if (!vsock->tx_run)
		goto out;

	vq = vsock->vqs[VSOCK_VQ_TX];

	for (;;) {
	int ret, in_sg = 0, out_sg = 0;
	struct scatterlist **sgs;
		struct sk_buff *skb;
		bool reply;

		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)));
@@ -164,13 +144,46 @@ virtio_transport_send_pkt_work(struct work_struct *work)
	/* Usually this means that there is no more space available in
	 * the vq
	 */
	if (ret < 0)
		return ret;

	virtio_transport_deliver_tap_pkt(skb);
	return 0;
}

static void
virtio_transport_send_pkt_work(struct work_struct *work)
{
	struct virtio_vsock *vsock =
		container_of(work, struct virtio_vsock, send_pkt_work);
	struct virtqueue *vq;
	bool added = false;
	bool restart_rx = false;

	mutex_lock(&vsock->tx_lock);

	if (!vsock->tx_run)
		goto out;

	vq = vsock->vqs[VSOCK_VQ_TX];

	for (;;) {
		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);

		ret = virtio_transport_send_skb(skb, vq, vsock);
		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;