[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20240429030541.56702-1-liweishi@kylinos.cn>
Date: Mon, 29 Apr 2024 11:05:41 +0800
From: Weishi Li <liweishi@...inos.cn>
To: liweishi@...inos.cn
Cc: airlied@...hat.com,
daniel@...ll.ch,
dri-devel@...ts.freedesktop.org,
gurchetansingh@...omium.org,
kraxel@...hat.com,
linux-kernel@...r.kernel.org,
maarten.lankhorst@...ux.intel.com,
mripard@...nel.org,
olvaffe@...il.com,
tzimmermann@...e.de,
virtualization@...ts.linux.dev
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 virtqueue_add_sgs returns -EIO or -ENOMEM,
it means vbuf upload failed, and 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, when upload fails,vbuf needs to be free directly.
Signed-off-by: Weishi Li <liweishi@...inos.cn>
---
drivers/gpu/drm/virtio/virtgpu_vq.c | 14 +++++++++-----
1 file changed, 9 insertions(+), 5 deletions(-)
diff --git a/drivers/gpu/drm/virtio/virtgpu_vq.c b/drivers/gpu/drm/virtio/virtgpu_vq.c
index b1a00c0c25a7..26f2e45635c1 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,8 @@ 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);
} else {
vbuf->seqno = ++vgdev->cursorq.seqno;
trace_virtio_gpu_cmd_queue(vq,
--
2.25.1
Powered by blists - more mailing lists