drm: allow property validation for refcnted props
Subsystems (2)
PATCH 1/1 drm: allow property validation for refcnted props
We can already have object properties, which technically can be fb's. Switch the property validation logic over to a get/put style interface so it can take a ref to refcnt'd objects, and then drop that ref after the driver has a chance to take it's own ref.
Signed-off-by Rob Clark <[email protected]>
---
Alternative approach to:
http://lists.freedesktop.org/archives/dri-devel/2014-November/072925.html
This allows us to take a ref to the property as part of the validate step, and drop the ref after it has been pushed down to driver.
drivers/gpu/drm/drm_crtc.c | 57 ++++++++++++++++++++++++++++++++++------------ 1 file changed, 42 insertions(+), 15 deletions(-)
drivers/gpu/drm/drm_crtc.c +42 -15
@@ -4162,12 +4162,22 @@ int drm_mode_connector_update_edid_property(struct drm_connector *connector, }EXPORT_SYMBOL (drm_mode_connector_update_edid_property); -static bool drm_property_change_is_valid (struct drm_property *property, -uint64_t value) +/* Some properties could refer to dynamic refcnt'd objects, or things that +* need special locking to handle lifetime issues (ie. to ensure the prop +* value doesn't become invalid part way through the property update due to +* race). The value returned by reference via 'obj' should be passed back +* to drm_property_change_valid_put() after the property is set (and the +* object to which the property is attached has a chance to take it's own +* reference). +*/ +static bool drm_property_change_valid_get (struct drm_property *property, +uint64_t value,void **ref) {if (property->flags &DRM_MODE_PROP_IMMUTABLE )return false; + *ref =NULL ; +if (drm_property_type_is (property,DRM_MODE_PROP_RANGE )) {if (value < property->values[0 ] || value > property->values[1 ])return false;
@@ -4188,19 +4198,23 @@ static bool drm_property_change_is_valid(struct drm_property *property,/* Only the driver knows */ return true; }else if (drm_property_type_is (property,DRM_MODE_PROP_OBJECT )) { -struct drm_mode_object *obj;/* a zero value for an object property translates to null: */ if (value ==0 )return true; -/* -* NOTE: use _object_find() directly to bypass restriction on -* looking up refcnt'd objects (ie. fb's). For a refcnt'd -* object this could race against object finalization, so it -* simply tells us that the object *was* valid. Which is good -* enough. -*/ - obj =_object_find (property->dev, value, property->values[0 ]); -return obj !=NULL ; + +/* handle refcnt'd objects specially: */ +if (property->values[0 ] ==DRM_MODE_OBJECT_FB ) { +struct drm_framebuffer *fb; + fb =drm_framebuffer_lookup (property->dev, value); +if (fb) { + *ref = fb; +return true; + }else { +return false; + } + }else { +return _object_find (property->dev, value, property->values[0 ]) !=NULL ; + } }else {int i;for (i =0 ; i < property->num_values; i++)
@@ -4210,6 +4224,17 @@ static bool drm_property_change_is_valid(struct drm_property *property, } } +static void drm_property_change_valid_put (struct drm_property *property,void *ref) +{ +if (!ref) +return ; + +if (drm_property_type_is (property,DRM_MODE_PROP_OBJECT )) { +if (property->values[0 ] ==DRM_MODE_OBJECT_FB ) +drm_framebuffer_unreference (ref); + } +} +/** * drm_mode_connector_property_set_ioctl - set the current value of a connector property * @dev: DRM device
@@ -4404,8 +4429,8 @@ int drm_mode_obj_set_property_ioctl(struct drm_device *dev, void *data,struct drm_mode_object *arg_obj;struct drm_mode_object *prop_obj;struct drm_property *property; -int ret = -EINVAL ; -int i; +int i, ret = -EINVAL ; +void *ref;if (!drm_core_check_feature (dev,DRIVER_MODESET ))return -EINVAL ;
@@ -4435,7 +4460,7 @@ int drm_mode_obj_set_property_ioctl(struct drm_device *dev, void *data, } property =obj_to_property (prop_obj); -if (!drm_property_change_is_valid (property, arg->value)) +if (!drm_property_change_valid_get (property, arg->value, &ref)) goto out;switch (arg_obj->type) {
@@ -4452,6 +4477,8 @@ int drm_mode_obj_set_property_ioctl(struct drm_device *dev, void *data,break ; } +drm_property_change_valid_put (property, ref); + out:drm_modeset_unlock_all (dev);return ret;
Signature · 6 lines
1.9.3 _______________________________________________ dri-devel mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/dri-devel