[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Message-Id: <20240509015225.38669-1-liweishi@kylinos.cn>
Date: Thu, 9 May 2024 09:52:25 +0800
From: Weishi Li <liweishi@...inos.cn>
To: airlied@...hat.com,
kraxel@...hat.com,
gurchetansingh@...omium.org,
olvaffe@...il.com,
maarten.lankhorst@...ux.intel.com,
mripard@...nel.org,
tzimmermann@...e.de,
daniel@...ll.ch
Cc: dri-devel@...ts.freedesktop.org,
virtualization@...ts.linux.dev,
linux-kernel@...r.kernel.org,
liweishi@...inos.cn
Subject: [PATCH] [PATCH RESEND] drm/virtio: fix memory leak of vbuf
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 <liweishi@...inos.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
Powered by blists - more mailing lists