Commit 337d5b5e authored by Dave Airlie's avatar Dave Airlie

Merge tag 'drm-misc-fixes-2023-02-09' of git://anongit.freedesktop.org/drm/drm-misc into drm-fixes

A fix for a circular refcounting in drm/client, one for a memory leak in
amdgpu and a virtio fence fix when interrupted
Signed-off-by: default avatarDave Airlie <airlied@redhat.com>

From: Maxime Ripard <maxime@cerno.tech>
Link: https://patchwork.freedesktop.org/patch/msgid/20230209083600.7hi6roht6xxgldgz@houat
parents 4684f5ce 85e26dd5
...@@ -1220,10 +1220,13 @@ static int amdgpu_cs_sync_rings(struct amdgpu_cs_parser *p) ...@@ -1220,10 +1220,13 @@ static int amdgpu_cs_sync_rings(struct amdgpu_cs_parser *p)
* next job actually sees the results from the previous one * next job actually sees the results from the previous one
* before we start executing on the same scheduler ring. * before we start executing on the same scheduler ring.
*/ */
if (!s_fence || s_fence->sched != sched) if (!s_fence || s_fence->sched != sched) {
dma_fence_put(fence);
continue; continue;
}
r = amdgpu_sync_fence(&p->gang_leader->explicit_sync, fence); r = amdgpu_sync_fence(&p->gang_leader->explicit_sync, fence);
dma_fence_put(fence);
if (r) if (r)
return r; return r;
} }
......
...@@ -233,21 +233,17 @@ void drm_client_dev_restore(struct drm_device *dev) ...@@ -233,21 +233,17 @@ void drm_client_dev_restore(struct drm_device *dev)
static void drm_client_buffer_delete(struct drm_client_buffer *buffer) static void drm_client_buffer_delete(struct drm_client_buffer *buffer)
{ {
struct drm_device *dev = buffer->client->dev;
if (buffer->gem) { if (buffer->gem) {
drm_gem_vunmap_unlocked(buffer->gem, &buffer->map); drm_gem_vunmap_unlocked(buffer->gem, &buffer->map);
drm_gem_object_put(buffer->gem); drm_gem_object_put(buffer->gem);
} }
if (buffer->handle)
drm_mode_destroy_dumb(dev, buffer->handle, buffer->client->file);
kfree(buffer); kfree(buffer);
} }
static struct drm_client_buffer * static struct drm_client_buffer *
drm_client_buffer_create(struct drm_client_dev *client, u32 width, u32 height, u32 format) drm_client_buffer_create(struct drm_client_dev *client, u32 width, u32 height,
u32 format, u32 *handle)
{ {
const struct drm_format_info *info = drm_format_info(format); const struct drm_format_info *info = drm_format_info(format);
struct drm_mode_create_dumb dumb_args = { }; struct drm_mode_create_dumb dumb_args = { };
...@@ -269,16 +265,15 @@ drm_client_buffer_create(struct drm_client_dev *client, u32 width, u32 height, u ...@@ -269,16 +265,15 @@ drm_client_buffer_create(struct drm_client_dev *client, u32 width, u32 height, u
if (ret) if (ret)
goto err_delete; goto err_delete;
buffer->handle = dumb_args.handle;
buffer->pitch = dumb_args.pitch;
obj = drm_gem_object_lookup(client->file, dumb_args.handle); obj = drm_gem_object_lookup(client->file, dumb_args.handle);
if (!obj) { if (!obj) {
ret = -ENOENT; ret = -ENOENT;
goto err_delete; goto err_delete;
} }
buffer->pitch = dumb_args.pitch;
buffer->gem = obj; buffer->gem = obj;
*handle = dumb_args.handle;
return buffer; return buffer;
...@@ -365,7 +360,8 @@ static void drm_client_buffer_rmfb(struct drm_client_buffer *buffer) ...@@ -365,7 +360,8 @@ static void drm_client_buffer_rmfb(struct drm_client_buffer *buffer)
} }
static int drm_client_buffer_addfb(struct drm_client_buffer *buffer, static int drm_client_buffer_addfb(struct drm_client_buffer *buffer,
u32 width, u32 height, u32 format) u32 width, u32 height, u32 format,
u32 handle)
{ {
struct drm_client_dev *client = buffer->client; struct drm_client_dev *client = buffer->client;
struct drm_mode_fb_cmd fb_req = { }; struct drm_mode_fb_cmd fb_req = { };
...@@ -377,7 +373,7 @@ static int drm_client_buffer_addfb(struct drm_client_buffer *buffer, ...@@ -377,7 +373,7 @@ static int drm_client_buffer_addfb(struct drm_client_buffer *buffer,
fb_req.depth = info->depth; fb_req.depth = info->depth;
fb_req.width = width; fb_req.width = width;
fb_req.height = height; fb_req.height = height;
fb_req.handle = buffer->handle; fb_req.handle = handle;
fb_req.pitch = buffer->pitch; fb_req.pitch = buffer->pitch;
ret = drm_mode_addfb(client->dev, &fb_req, client->file); ret = drm_mode_addfb(client->dev, &fb_req, client->file);
...@@ -414,13 +410,24 @@ struct drm_client_buffer * ...@@ -414,13 +410,24 @@ struct drm_client_buffer *
drm_client_framebuffer_create(struct drm_client_dev *client, u32 width, u32 height, u32 format) drm_client_framebuffer_create(struct drm_client_dev *client, u32 width, u32 height, u32 format)
{ {
struct drm_client_buffer *buffer; struct drm_client_buffer *buffer;
u32 handle;
int ret; int ret;
buffer = drm_client_buffer_create(client, width, height, format); buffer = drm_client_buffer_create(client, width, height, format,
&handle);
if (IS_ERR(buffer)) if (IS_ERR(buffer))
return buffer; return buffer;
ret = drm_client_buffer_addfb(buffer, width, height, format); ret = drm_client_buffer_addfb(buffer, width, height, format, handle);
/*
* The handle is only needed for creating the framebuffer, destroy it
* again to solve a circular dependency should anybody export the GEM
* object as DMA-buf. The framebuffer and our buffer structure are still
* holding references to the GEM object to prevent its destruction.
*/
drm_mode_destroy_dumb(client->dev, handle, client->file);
if (ret) { if (ret) {
drm_client_buffer_delete(buffer); drm_client_buffer_delete(buffer);
return ERR_PTR(ret); return ERR_PTR(ret);
......
...@@ -126,7 +126,6 @@ static int virtio_gpu_execbuffer_ioctl(struct drm_device *dev, void *data, ...@@ -126,7 +126,6 @@ static int virtio_gpu_execbuffer_ioctl(struct drm_device *dev, void *data,
void __user *user_bo_handles = NULL; void __user *user_bo_handles = NULL;
struct virtio_gpu_object_array *buflist = NULL; struct virtio_gpu_object_array *buflist = NULL;
struct sync_file *sync_file; struct sync_file *sync_file;
int in_fence_fd = exbuf->fence_fd;
int out_fence_fd = -1; int out_fence_fd = -1;
void *buf; void *buf;
uint64_t fence_ctx; uint64_t fence_ctx;
...@@ -152,13 +151,11 @@ static int virtio_gpu_execbuffer_ioctl(struct drm_device *dev, void *data, ...@@ -152,13 +151,11 @@ static int virtio_gpu_execbuffer_ioctl(struct drm_device *dev, void *data,
ring_idx = exbuf->ring_idx; ring_idx = exbuf->ring_idx;
} }
exbuf->fence_fd = -1;
virtio_gpu_create_context(dev, file); virtio_gpu_create_context(dev, file);
if (exbuf->flags & VIRTGPU_EXECBUF_FENCE_FD_IN) { if (exbuf->flags & VIRTGPU_EXECBUF_FENCE_FD_IN) {
struct dma_fence *in_fence; struct dma_fence *in_fence;
in_fence = sync_file_get_fence(in_fence_fd); in_fence = sync_file_get_fence(exbuf->fence_fd);
if (!in_fence) if (!in_fence)
return -EINVAL; return -EINVAL;
......
...@@ -126,11 +126,6 @@ struct drm_client_buffer { ...@@ -126,11 +126,6 @@ struct drm_client_buffer {
*/ */
struct drm_client_dev *client; struct drm_client_dev *client;
/**
* @handle: Buffer handle
*/
u32 handle;
/** /**
* @pitch: Buffer pitch * @pitch: Buffer pitch
*/ */
......
...@@ -64,6 +64,7 @@ struct drm_virtgpu_map { ...@@ -64,6 +64,7 @@ struct drm_virtgpu_map {
__u32 pad; __u32 pad;
}; };
/* fence_fd is modified on success if VIRTGPU_EXECBUF_FENCE_FD_OUT flag is set. */
struct drm_virtgpu_execbuffer { struct drm_virtgpu_execbuffer {
__u32 flags; __u32 flags;
__u32 size; __u32 size;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment