diff --git a/drivers/gpu/drm/arc/arcpgu_drv.c b/drivers/gpu/drm/arc/arcpgu_drv.c index 76e187a5bde021fe523c5af5583a72f09413c4c4..69b5be0f9fb8af359d71c485b55f4ccb3fc64c87 100644 --- a/drivers/gpu/drm/arc/arcpgu_drv.c +++ b/drivers/gpu/drm/arc/arcpgu_drv.c @@ -92,7 +92,7 @@ static void arcpgu_preclose(struct drm_device *drm, struct drm_file *file) if (e->base.file_priv != file) continue; list_del(&e->base.link); - e->base.destroy(&e->base); + kfree(&e->base); } spin_unlock_irqrestore(&drm->event_lock, flags); } diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c index 674b2e490aa969f1d06b6fd6e15cc99f6a0c0346..1db198df301414d5b315b61c0844cddd51786534 100644 --- a/drivers/gpu/drm/drm_atomic.c +++ b/drivers/gpu/drm/drm_atomic.c @@ -1412,7 +1412,8 @@ EXPORT_SYMBOL(drm_atomic_nonblocking_commit); */ static struct drm_pending_vblank_event *create_vblank_event( - struct drm_device *dev, struct drm_file *file_priv, uint64_t user_data) + struct drm_device *dev, struct drm_file *file_priv, + struct fence *fence, uint64_t user_data) { struct drm_pending_vblank_event *e = NULL; int ret; @@ -1425,12 +1426,17 @@ static struct drm_pending_vblank_event *create_vblank_event( e->event.base.length = sizeof(e->event); e->event.user_data = user_data; - ret = drm_event_reserve_init(dev, file_priv, &e->base, &e->event.base); - if (ret) { - kfree(e); - return NULL; + if (file_priv) { + ret = drm_event_reserve_init(dev, file_priv, &e->base, + &e->event.base); + if (ret) { + kfree(e); + return NULL; + } } + e->base.fence = fence; + return e; } @@ -1670,7 +1676,8 @@ int drm_mode_atomic_ioctl(struct drm_device *dev, for_each_crtc_in_state(state, crtc, crtc_state, i) { struct drm_pending_vblank_event *e; - e = create_vblank_event(dev, file_priv, arg->user_data); + e = create_vblank_event(dev, file_priv, NULL, + arg->user_data); if (!e) { ret = -ENOMEM; goto out; diff --git a/drivers/gpu/drm/drm_fops.c b/drivers/gpu/drm/drm_fops.c index 7af7f8bcb3558244781c0ac4f486452e852deca9..efa980a54c75718aa50920341eb711e50205881b 100644 --- a/drivers/gpu/drm/drm_fops.c +++ b/drivers/gpu/drm/drm_fops.c @@ -368,7 +368,7 @@ static void drm_events_release(struct drm_file *file_priv) /* Remove unconsumed events */ list_for_each_entry_safe(e, et, &file_priv->event_list, link) { list_del(&e->link); - e->destroy(e); + kfree(e); } spin_unlock_irqrestore(&dev->event_lock, flags); @@ -636,7 +636,7 @@ ssize_t drm_read(struct file *filp, char __user *buffer, } ret += length; - e->destroy(e); + kfree(e); } } mutex_unlock(&file_priv->event_read_lock); @@ -713,9 +713,6 @@ int drm_event_reserve_init_locked(struct drm_device *dev, list_add(&p->pending_link, &file_priv->pending_event_list); p->file_priv = file_priv; - /* we *could* pass this in as arg, but everyone uses kfree: */ - p->destroy = (void (*) (struct drm_pending_event *)) kfree; - return 0; } EXPORT_SYMBOL(drm_event_reserve_init_locked); @@ -778,7 +775,7 @@ void drm_event_cancel_free(struct drm_device *dev, list_del(&p->pending_link); } spin_unlock_irqrestore(&dev->event_lock, flags); - p->destroy(p); + kfree(p); } EXPORT_SYMBOL(drm_event_cancel_free); @@ -800,8 +797,13 @@ void drm_send_event_locked(struct drm_device *dev, struct drm_pending_event *e) { assert_spin_locked(&dev->event_lock); + if (e->fence) { + fence_signal(e->fence); + fence_put(e->fence); + } + if (!e->file_priv) { - e->destroy(e); + kfree(e); return; } diff --git a/drivers/gpu/drm/nouveau/nouveau_usif.c b/drivers/gpu/drm/nouveau/nouveau_usif.c index 675e9e077a95c6ec7a69a6891a7d6f16b8c6b139..08f9c6fa0f7f210d3e3fd5a0fbe8f11ff40b1972 100644 --- a/drivers/gpu/drm/nouveau/nouveau_usif.c +++ b/drivers/gpu/drm/nouveau/nouveau_usif.c @@ -212,7 +212,6 @@ usif_notify_get(struct drm_file *f, void *data, u32 size, void *argv, u32 argc) ntfy->p->base.event = &ntfy->p->e.base; ntfy->p->base.file_priv = f; ntfy->p->base.pid = current->pid; - ntfy->p->base.destroy =(void(*)(struct drm_pending_event *))kfree; ntfy->p->e.base.type = DRM_NOUVEAU_EVENT_NVIF; ntfy->p->e.base.length = sizeof(ntfy->p->e.base) + ntfy->reply; diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c index 1c4d5b5a70a2b8b2b61f22581ee9428f47913c40..5567fb43e674aa5bbae7dd9b5adc9659a0061690 100644 --- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c +++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c @@ -889,7 +889,7 @@ static void vop_crtc_cancel_pending_vblank(struct drm_crtc *crtc, if (e && e->base.file_priv == file_priv) { vop->event = NULL; - e->base.destroy(&e->base); + kfree(&e->base); file_priv->event_space += sizeof(e->event); } spin_unlock_irqrestore(&drm->event_lock, flags); diff --git a/include/drm/drmP.h b/include/drm/drmP.h index 00518289105f9246d4c5b5e87acda5e05b7e43b5..9e5eefd6f733b884ccfd26f0eb90634f11d9d5b5 100644 --- a/include/drm/drmP.h +++ b/include/drm/drmP.h @@ -57,6 +57,7 @@ #include #include #include +#include #include #include @@ -283,12 +284,12 @@ struct drm_ioctl_desc { /* Event queued up for userspace to read */ struct drm_pending_event { struct drm_event *event; + struct fence *fence; struct list_head link; struct list_head pending_link; struct drm_file *file_priv; pid_t pid; /* pid of requester, no guarantee it's valid by the time we deliver the event, for tracing only */ - void (*destroy)(struct drm_pending_event *event); }; /* initial implementaton using a linked list - todo hashtab */