Both virtio_gpu_queue_ctrl_buffer and virtio_gpu_queue_cursor use
virtqueue_add_sgs to upload the structure virtio_gpu_vbuffer * vbuf
to virtqueue. However, when the vbuf fails to upload and virtqueue_add_sgs
returns -EIO or -ENOMEM, the vbuf will not be able to be free by
virtio_gpu_dequeue_*_func, resulting in a continuous increase
in memory allocated to vgdev ->vbufs.

Therefore, make virtio_gpu_queue_ctrl_sgs and virtio_gpu_queue_cursor
free vbuf directly after virtqueue_add_sgs returns -EIO or -ENOMEM.

Signed-off-by: Weishi Li <liwei...@kylinos.cn>
---
 drivers/gpu/drm/virtio/virtgpu_vq.c | 15 ++++++++++-----
 1 file changed, 10 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/virtio/virtgpu_vq.c 
b/drivers/gpu/drm/virtio/virtgpu_vq.c
index b1a00c0c25a7..6701ce9d0ee8 100644
--- a/drivers/gpu/drm/virtio/virtgpu_vq.c
+++ b/drivers/gpu/drm/virtio/virtgpu_vq.c
@@ -356,12 +356,14 @@ static int virtio_gpu_queue_ctrl_sgs(struct 
virtio_gpu_device *vgdev,
 
        ret = virtqueue_add_sgs(vq, sgs, outcnt, incnt, vbuf, GFP_ATOMIC);
        WARN_ON(ret);
+       if (ret < 0 && ret != -ENOSPC) {
+               free_vbuf(vgdev, vbuf);
+       } else {
+               vbuf->seqno = ++vgdev->ctrlq.seqno;
+               trace_virtio_gpu_cmd_queue(vq, virtio_gpu_vbuf_ctrl_hdr(vbuf), 
vbuf->seqno);
 
-       vbuf->seqno = ++vgdev->ctrlq.seqno;
-       trace_virtio_gpu_cmd_queue(vq, virtio_gpu_vbuf_ctrl_hdr(vbuf), 
vbuf->seqno);
-
-       atomic_inc(&vgdev->pending_commands);
-
+               atomic_inc(&vgdev->pending_commands);
+       }
        spin_unlock(&vgdev->ctrlq.qlock);
 
        drm_dev_exit(idx);
@@ -469,6 +471,9 @@ static void virtio_gpu_queue_cursor(struct 
virtio_gpu_device *vgdev,
                wait_event(vgdev->cursorq.ack_queue, vq->num_free >= outcnt);
                spin_lock(&vgdev->cursorq.qlock);
                goto retry;
+       } else if (ret < 0) {
+               free_vbuf(vgdev, vbuf);
+               notify = false;
        } else {
                vbuf->seqno = ++vgdev->cursorq.seqno;
                trace_virtio_gpu_cmd_queue(vq,
-- 
2.25.1

Reply via email to