[RFC] drm: atomic-rmfb semantics
Rob Clark
robdclark at gmail.com
Sun Apr 2 13:13:34 UTC 2017
On Sun, Apr 2, 2017 at 8:46 AM, Daniel Vetter <daniel at ffwll.ch> wrote:
> On Sat, Apr 01, 2017 at 03:11:36PM -0400, Rob Clark wrote:
>> We possibly missed the boat on redefining rmfb semantics for atomic
>> userspace to something more sane, unless perhaps the few existing atomic
>> userspaces (CrOS?) could confirm that this change won't cause problems
>> (in which case we could just call this a bug-fix, drop the cap, and
>> delete some code?).
>>
>> The old semantics of rmfb shutting down the display is kind of pointless
>> in an atomic world, and it is more awkward for userspace that creates
>> and destroys the fb every frame, since they need to defer the rmfb.
>> Since we have better ways for userspace to shut down the display pipe
>> and the legacy behaviour of rmfb is awkward, provide a way for atomic
>> userspace to simply make rmfb an unref.
>>
>> Signed-off-by: Rob Clark <robdclark at gmail.com>
>
> We can't change existing semantics, because we reuse atomic paths for
> legacy clients. But I think this here is real good. Please come up with
> the userspace side in any of the atomic compositors we have, and this is
> good to merge.
So, since this is done in rmfb ioctl fxn, I don't think it effects
internal use. It is really just making rmfb ioctl into an unref.
But, I'm thinking we should leave the fb on the file_priv->fbs list so
it gets cleaned up (and legacy behaviour of shutting down pipe is
preserved) at lastclose time..
And a small related change in drm_framebuffer_free() to make sure it
is removed from file_priv->fbs list.
BR,
-R
> Well, basic igt testcases would be lovely, too. We have some to exercise
> rmfb behaviour, so should be easy to adapt them.
> -Daniel
>
>> ---
>> drivers/gpu/drm/drm_framebuffer.c | 2 +-
>> drivers/gpu/drm/drm_ioctl.c | 9 +++++++++
>> include/drm/drm_file.h | 8 ++++++++
>> include/uapi/drm/drm.h | 7 +++++++
>> 4 files changed, 25 insertions(+), 1 deletion(-)
>>
>> diff --git a/drivers/gpu/drm/drm_framebuffer.c b/drivers/gpu/drm/drm_framebuffer.c
>> index e4909ae..c5127dd0 100644
>> --- a/drivers/gpu/drm/drm_framebuffer.c
>> +++ b/drivers/gpu/drm/drm_framebuffer.c
>> @@ -383,7 +383,7 @@ int drm_mode_rmfb(struct drm_device *dev,
>> * so run this in a separate stack as there's no way to correctly
>> * handle this after the fb is already removed from the lookup table.
>> */
>> - if (drm_framebuffer_read_refcount(fb) > 1) {
>> + if (drm_framebuffer_read_refcount(fb) > 1 && !file_priv->atomic_rmfb) {
>> struct drm_mode_rmfb_work arg;
>>
>> INIT_WORK_ONSTACK(&arg.work, drm_mode_rmfb_work_fn);
>> diff --git a/drivers/gpu/drm/drm_ioctl.c b/drivers/gpu/drm/drm_ioctl.c
>> index a7c61c2..b42348f 100644
>> --- a/drivers/gpu/drm/drm_ioctl.c
>> +++ b/drivers/gpu/drm/drm_ioctl.c
>> @@ -318,6 +318,15 @@ drm_setclientcap(struct drm_device *dev, void *data, struct drm_file *file_priv)
>> file_priv->atomic = req->value;
>> file_priv->universal_planes = req->value;
>> break;
>> + case DRM_CLIENT_CAP_ATOMIC_RMFB:
>> + if (!drm_core_check_feature(dev, DRIVER_ATOMIC))
>> + return -EINVAL;
>> + if (req->value > 1)
>> + return -EINVAL;
>> + file_priv->atomic = req->value;
>> + file_priv->universal_planes = req->value;
>> + file_priv->atomic_rmfb = req->value;
>> + break;
>> default:
>> return -EINVAL;
>> }
>> diff --git a/include/drm/drm_file.h b/include/drm/drm_file.h
>> index 5dd27ae..2a41c29 100644
>> --- a/include/drm/drm_file.h
>> +++ b/include/drm/drm_file.h
>> @@ -181,6 +181,14 @@ struct drm_file {
>> unsigned atomic:1;
>>
>> /**
>> + * @atomic_rmfb:
>> + *
>> + * True if client wants new semantics for rmfb, ie. simply dropping
>> + * refcnt without tearing down the display.
>> + */
>> + unsigned atomic_rmfb:1;
>> +
>> + /**
>> * @is_master:
>> *
>> * This client is the creator of @master. Protected by struct
>> diff --git a/include/uapi/drm/drm.h b/include/uapi/drm/drm.h
>> index b2c5284..4063cc8 100644
>> --- a/include/uapi/drm/drm.h
>> +++ b/include/uapi/drm/drm.h
>> @@ -678,6 +678,13 @@ struct drm_get_cap {
>> */
>> #define DRM_CLIENT_CAP_ATOMIC 3
>>
>> +/**
>> + * DRM_CLIENT_CAP_ATOMIC_RMFB
>> + *
>> + * If set to 1, the DRM core will not shutdown display pipe on rmfb ioctl.
>> + */
>> +#define DRM_CLIENT_CAP_ATOMIC_RMFB 4
>> +
>> /** DRM_IOCTL_SET_CLIENT_CAP ioctl argument type */
>> struct drm_set_client_cap {
>> __u64 capability;
>> --
>> 2.9.3
>>
>
> --
> Daniel Vetter
> Software Engineer, Intel Corporation
> http://blog.ffwll.ch
More information about the dri-devel
mailing list