A fix for a circular refcounting in drm/client, one for a memory leak in
amdgpu and a virtio fence fix when interrupted -----BEGIN PGP SIGNATURE----- iHUEABYKAB0WIQRcEzekXsqa64kGDp7j7w1vZxhRxQUCY+SwWAAKCRDj7w1vZxhR xaNJAP4zryQ0LsvA+WpcrnkPVWp8TH+jAf8wdZdHNdoZVYgurAEA7dLQ6y6RPMS+ hwZVdsqUlew7yj8IFJCewXXv5SL/ygE= =Otvp -----END PGP SIGNATURE----- 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: Dave Airlie <airlied@redhat.com> From: Maxime Ripard <maxime@cerno.tech> Link: https://patchwork.freedesktop.org/patch/msgid/20230209083600.7hi6roht6xxgldgz@houat
This commit is contained in:
commit
337d5b5edc
@ -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
|
||||
* 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;
|
||||
}
|
||||
|
||||
r = amdgpu_sync_fence(&p->gang_leader->explicit_sync, fence);
|
||||
dma_fence_put(fence);
|
||||
if (r)
|
||||
return r;
|
||||
}
|
||||
|
@ -233,21 +233,17 @@ void drm_client_dev_restore(struct drm_device *dev)
|
||||
|
||||
static void drm_client_buffer_delete(struct drm_client_buffer *buffer)
|
||||
{
|
||||
struct drm_device *dev = buffer->client->dev;
|
||||
|
||||
if (buffer->gem) {
|
||||
drm_gem_vunmap_unlocked(buffer->gem, &buffer->map);
|
||||
drm_gem_object_put(buffer->gem);
|
||||
}
|
||||
|
||||
if (buffer->handle)
|
||||
drm_mode_destroy_dumb(dev, buffer->handle, buffer->client->file);
|
||||
|
||||
kfree(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);
|
||||
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
|
||||
if (ret)
|
||||
goto err_delete;
|
||||
|
||||
buffer->handle = dumb_args.handle;
|
||||
buffer->pitch = dumb_args.pitch;
|
||||
|
||||
obj = drm_gem_object_lookup(client->file, dumb_args.handle);
|
||||
if (!obj) {
|
||||
ret = -ENOENT;
|
||||
goto err_delete;
|
||||
}
|
||||
|
||||
buffer->pitch = dumb_args.pitch;
|
||||
buffer->gem = obj;
|
||||
*handle = dumb_args.handle;
|
||||
|
||||
return 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,
|
||||
u32 width, u32 height, u32 format)
|
||||
u32 width, u32 height, u32 format,
|
||||
u32 handle)
|
||||
{
|
||||
struct drm_client_dev *client = buffer->client;
|
||||
struct drm_mode_fb_cmd fb_req = { };
|
||||
@ -377,7 +373,7 @@ static int drm_client_buffer_addfb(struct drm_client_buffer *buffer,
|
||||
fb_req.depth = info->depth;
|
||||
fb_req.width = width;
|
||||
fb_req.height = height;
|
||||
fb_req.handle = buffer->handle;
|
||||
fb_req.handle = handle;
|
||||
fb_req.pitch = buffer->pitch;
|
||||
|
||||
ret = drm_mode_addfb(client->dev, &fb_req, client->file);
|
||||
@ -414,13 +410,24 @@ struct drm_client_buffer *
|
||||
drm_client_framebuffer_create(struct drm_client_dev *client, u32 width, u32 height, u32 format)
|
||||
{
|
||||
struct drm_client_buffer *buffer;
|
||||
u32 handle;
|
||||
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))
|
||||
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) {
|
||||
drm_client_buffer_delete(buffer);
|
||||
return ERR_PTR(ret);
|
||||
|
@ -126,7 +126,6 @@ static int virtio_gpu_execbuffer_ioctl(struct drm_device *dev, void *data,
|
||||
void __user *user_bo_handles = NULL;
|
||||
struct virtio_gpu_object_array *buflist = NULL;
|
||||
struct sync_file *sync_file;
|
||||
int in_fence_fd = exbuf->fence_fd;
|
||||
int out_fence_fd = -1;
|
||||
void *buf;
|
||||
uint64_t fence_ctx;
|
||||
@ -152,13 +151,11 @@ static int virtio_gpu_execbuffer_ioctl(struct drm_device *dev, void *data,
|
||||
ring_idx = exbuf->ring_idx;
|
||||
}
|
||||
|
||||
exbuf->fence_fd = -1;
|
||||
|
||||
virtio_gpu_create_context(dev, file);
|
||||
if (exbuf->flags & VIRTGPU_EXECBUF_FENCE_FD_IN) {
|
||||
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)
|
||||
return -EINVAL;
|
||||
|
@ -126,11 +126,6 @@ struct drm_client_buffer {
|
||||
*/
|
||||
struct drm_client_dev *client;
|
||||
|
||||
/**
|
||||
* @handle: Buffer handle
|
||||
*/
|
||||
u32 handle;
|
||||
|
||||
/**
|
||||
* @pitch: Buffer pitch
|
||||
*/
|
||||
|
@ -64,6 +64,7 @@ struct drm_virtgpu_map {
|
||||
__u32 pad;
|
||||
};
|
||||
|
||||
/* fence_fd is modified on success if VIRTGPU_EXECBUF_FENCE_FD_OUT flag is set. */
|
||||
struct drm_virtgpu_execbuffer {
|
||||
__u32 flags;
|
||||
__u32 size;
|
||||
|
Loading…
x
Reference in New Issue
Block a user