aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorThierry Reding <treding@nvidia.com>2017-02-28 09:46:38 -0500
committerThierry Reding <treding@nvidia.com>2017-02-28 10:14:55 -0500
commit020a218f95bd3ceff7dd1022ff7ebc0497bc7bf9 (patch)
tree343a200b9e4373a380dad7d00dd26fb90a8338e1
parent2135ea7aafa26b6bfbbd304459fdb624e82e021e (diff)
drm: Introduce drm_mode_object_{get,put}()
For consistency with other reference counting APIs in the kernel, add drm_mode_object_get() and drm_mode_object_put() to reference count DRM mode objects. Compatibility aliases are added to keep existing code working. To help speed up the transition, all the instances of the old functions in the DRM core are already replaced in this commit. A semantic patch is provided that can be used to convert all drivers to the new helpers. Reviewed-by: Sean Paul <seanpaul@chromium.org> Acked-by: Christian König <christian.koenig@amd.com> Signed-off-by: Thierry Reding <treding@nvidia.com> Link: http://patchwork.freedesktop.org/patch/msgid/20170228144643.5668-3-thierry.reding@gmail.com
-rw-r--r--drivers/gpu/drm/drm_atomic.c14
-rw-r--r--drivers/gpu/drm/drm_mode_object.c26
-rw-r--r--drivers/gpu/drm/drm_property.c6
-rw-r--r--include/drm/drm_mode_object.h36
-rw-r--r--scripts/coccinelle/api/drm-get-put.cocci42
5 files changed, 95 insertions, 29 deletions
diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c
index 08d03d4594ee..39e470eb8aea 100644
--- a/drivers/gpu/drm/drm_atomic.c
+++ b/drivers/gpu/drm/drm_atomic.c
@@ -2238,13 +2238,13 @@ retry:
2238 } 2238 }
2239 2239
2240 if (!obj->properties) { 2240 if (!obj->properties) {
2241 drm_mode_object_unreference(obj); 2241 drm_mode_object_put(obj);
2242 ret = -ENOENT; 2242 ret = -ENOENT;
2243 goto out; 2243 goto out;
2244 } 2244 }
2245 2245
2246 if (get_user(count_props, count_props_ptr + copied_objs)) { 2246 if (get_user(count_props, count_props_ptr + copied_objs)) {
2247 drm_mode_object_unreference(obj); 2247 drm_mode_object_put(obj);
2248 ret = -EFAULT; 2248 ret = -EFAULT;
2249 goto out; 2249 goto out;
2250 } 2250 }
@@ -2257,14 +2257,14 @@ retry:
2257 struct drm_property *prop; 2257 struct drm_property *prop;
2258 2258
2259 if (get_user(prop_id, props_ptr + copied_props)) { 2259 if (get_user(prop_id, props_ptr + copied_props)) {
2260 drm_mode_object_unreference(obj); 2260 drm_mode_object_put(obj);
2261 ret = -EFAULT; 2261 ret = -EFAULT;
2262 goto out; 2262 goto out;
2263 } 2263 }
2264 2264
2265 prop = drm_mode_obj_find_prop_id(obj, prop_id); 2265 prop = drm_mode_obj_find_prop_id(obj, prop_id);
2266 if (!prop) { 2266 if (!prop) {
2267 drm_mode_object_unreference(obj); 2267 drm_mode_object_put(obj);
2268 ret = -ENOENT; 2268 ret = -ENOENT;
2269 goto out; 2269 goto out;
2270 } 2270 }
@@ -2272,14 +2272,14 @@ retry:
2272 if (copy_from_user(&prop_value, 2272 if (copy_from_user(&prop_value,
2273 prop_values_ptr + copied_props, 2273 prop_values_ptr + copied_props,
2274 sizeof(prop_value))) { 2274 sizeof(prop_value))) {
2275 drm_mode_object_unreference(obj); 2275 drm_mode_object_put(obj);
2276 ret = -EFAULT; 2276 ret = -EFAULT;
2277 goto out; 2277 goto out;
2278 } 2278 }
2279 2279
2280 ret = atomic_set_prop(state, obj, prop, prop_value); 2280 ret = atomic_set_prop(state, obj, prop, prop_value);
2281 if (ret) { 2281 if (ret) {
2282 drm_mode_object_unreference(obj); 2282 drm_mode_object_put(obj);
2283 goto out; 2283 goto out;
2284 } 2284 }
2285 2285
@@ -2292,7 +2292,7 @@ retry:
2292 plane_mask |= (1 << drm_plane_index(plane)); 2292 plane_mask |= (1 << drm_plane_index(plane));
2293 plane->old_fb = plane->fb; 2293 plane->old_fb = plane->fb;
2294 } 2294 }
2295 drm_mode_object_unreference(obj); 2295 drm_mode_object_put(obj);
2296 } 2296 }
2297 2297
2298 ret = prepare_crtc_signaling(dev, state, arg, file_priv, &fence_state, 2298 ret = prepare_crtc_signaling(dev, state, arg, file_priv, &fence_state,
diff --git a/drivers/gpu/drm/drm_mode_object.c b/drivers/gpu/drm/drm_mode_object.c
index 2ab8ccf2ca98..2eb0792dfaf3 100644
--- a/drivers/gpu/drm/drm_mode_object.c
+++ b/drivers/gpu/drm/drm_mode_object.c
@@ -133,7 +133,7 @@ struct drm_mode_object *__drm_mode_object_find(struct drm_device *dev,
133 * 133 *
134 * This function is used to look up a modeset object. It will acquire a 134 * This function is used to look up a modeset object. It will acquire a
135 * reference for reference counted objects. This reference must be dropped again 135 * reference for reference counted objects. This reference must be dropped again
136 * by callind drm_mode_object_unreference(). 136 * by callind drm_mode_object_put().
137 */ 137 */
138struct drm_mode_object *drm_mode_object_find(struct drm_device *dev, 138struct drm_mode_object *drm_mode_object_find(struct drm_device *dev,
139 uint32_t id, uint32_t type) 139 uint32_t id, uint32_t type)
@@ -146,38 +146,38 @@ struct drm_mode_object *drm_mode_object_find(struct drm_device *dev,
146EXPORT_SYMBOL(drm_mode_object_find); 146EXPORT_SYMBOL(drm_mode_object_find);
147 147
148/** 148/**
149 * drm_mode_object_unreference - decr the object refcnt 149 * drm_mode_object_put - release a mode object reference
150 * @obj: mode_object 150 * @obj: DRM mode object
151 * 151 *
152 * This function decrements the object's refcount if it is a refcounted modeset 152 * This function decrements the object's refcount if it is a refcounted modeset
153 * object. It is a no-op on any other object. This is used to drop references 153 * object. It is a no-op on any other object. This is used to drop references
154 * acquired with drm_mode_object_reference(). 154 * acquired with drm_mode_object_get().
155 */ 155 */
156void drm_mode_object_unreference(struct drm_mode_object *obj) 156void drm_mode_object_put(struct drm_mode_object *obj)
157{ 157{
158 if (obj->free_cb) { 158 if (obj->free_cb) {
159 DRM_DEBUG("OBJ ID: %d (%d)\n", obj->id, atomic_read(&obj->refcount.refcount)); 159 DRM_DEBUG("OBJ ID: %d (%d)\n", obj->id, atomic_read(&obj->refcount.refcount));
160 kref_put(&obj->refcount, obj->free_cb); 160 kref_put(&obj->refcount, obj->free_cb);
161 } 161 }
162} 162}
163EXPORT_SYMBOL(drm_mode_object_unreference); 163EXPORT_SYMBOL(drm_mode_object_put);
164 164
165/** 165/**
166 * drm_mode_object_reference - incr the object refcnt 166 * drm_mode_object_get - acquire a mode object reference
167 * @obj: mode_object 167 * @obj: DRM mode object
168 * 168 *
169 * This function increments the object's refcount if it is a refcounted modeset 169 * This function increments the object's refcount if it is a refcounted modeset
170 * object. It is a no-op on any other object. References should be dropped again 170 * object. It is a no-op on any other object. References should be dropped again
171 * by calling drm_mode_object_unreference(). 171 * by calling drm_mode_object_put().
172 */ 172 */
173void drm_mode_object_reference(struct drm_mode_object *obj) 173void drm_mode_object_get(struct drm_mode_object *obj)
174{ 174{
175 if (obj->free_cb) { 175 if (obj->free_cb) {
176 DRM_DEBUG("OBJ ID: %d (%d)\n", obj->id, atomic_read(&obj->refcount.refcount)); 176 DRM_DEBUG("OBJ ID: %d (%d)\n", obj->id, atomic_read(&obj->refcount.refcount));
177 kref_get(&obj->refcount); 177 kref_get(&obj->refcount);
178 } 178 }
179} 179}
180EXPORT_SYMBOL(drm_mode_object_reference); 180EXPORT_SYMBOL(drm_mode_object_get);
181 181
182/** 182/**
183 * drm_object_attach_property - attach a property to a modeset object 183 * drm_object_attach_property - attach a property to a modeset object
@@ -363,7 +363,7 @@ int drm_mode_obj_get_properties_ioctl(struct drm_device *dev, void *data,
363 &arg->count_props); 363 &arg->count_props);
364 364
365out_unref: 365out_unref:
366 drm_mode_object_unreference(obj); 366 drm_mode_object_put(obj);
367out: 367out:
368 drm_modeset_unlock_all(dev); 368 drm_modeset_unlock_all(dev);
369 return ret; 369 return ret;
@@ -428,7 +428,7 @@ int drm_mode_obj_set_property_ioctl(struct drm_device *dev, void *data,
428 drm_property_change_valid_put(property, ref); 428 drm_property_change_valid_put(property, ref);
429 429
430out_unref: 430out_unref:
431 drm_mode_object_unreference(arg_obj); 431 drm_mode_object_put(arg_obj);
432out: 432out:
433 drm_modeset_unlock_all(dev); 433 drm_modeset_unlock_all(dev);
434 return ret; 434 return ret;
diff --git a/drivers/gpu/drm/drm_property.c b/drivers/gpu/drm/drm_property.c
index 411e470369c0..15af0d42e8be 100644
--- a/drivers/gpu/drm/drm_property.c
+++ b/drivers/gpu/drm/drm_property.c
@@ -597,7 +597,7 @@ void drm_property_unreference_blob(struct drm_property_blob *blob)
597 if (!blob) 597 if (!blob)
598 return; 598 return;
599 599
600 drm_mode_object_unreference(&blob->base); 600 drm_mode_object_put(&blob->base);
601} 601}
602EXPORT_SYMBOL(drm_property_unreference_blob); 602EXPORT_SYMBOL(drm_property_unreference_blob);
603 603
@@ -625,7 +625,7 @@ void drm_property_destroy_user_blobs(struct drm_device *dev,
625 */ 625 */
626struct drm_property_blob *drm_property_reference_blob(struct drm_property_blob *blob) 626struct drm_property_blob *drm_property_reference_blob(struct drm_property_blob *blob)
627{ 627{
628 drm_mode_object_reference(&blob->base); 628 drm_mode_object_get(&blob->base);
629 return blob; 629 return blob;
630} 630}
631EXPORT_SYMBOL(drm_property_reference_blob); 631EXPORT_SYMBOL(drm_property_reference_blob);
@@ -906,7 +906,7 @@ void drm_property_change_valid_put(struct drm_property *property,
906 return; 906 return;
907 907
908 if (drm_property_type_is(property, DRM_MODE_PROP_OBJECT)) { 908 if (drm_property_type_is(property, DRM_MODE_PROP_OBJECT)) {
909 drm_mode_object_unreference(ref); 909 drm_mode_object_put(ref);
910 } else if (drm_property_type_is(property, DRM_MODE_PROP_BLOB)) 910 } else if (drm_property_type_is(property, DRM_MODE_PROP_BLOB))
911 drm_property_unreference_blob(obj_to_blob(ref)); 911 drm_property_unreference_blob(obj_to_blob(ref));
912} 912}
diff --git a/include/drm/drm_mode_object.h b/include/drm/drm_mode_object.h
index 2c017adf6d74..a767b4a30a6d 100644
--- a/include/drm/drm_mode_object.h
+++ b/include/drm/drm_mode_object.h
@@ -45,10 +45,10 @@ struct drm_device;
45 * drm_object_attach_property() before the object is visible to userspace. 45 * drm_object_attach_property() before the object is visible to userspace.
46 * 46 *
47 * - For objects with dynamic lifetimes (as indicated by a non-NULL @free_cb) it 47 * - For objects with dynamic lifetimes (as indicated by a non-NULL @free_cb) it
48 * provides reference counting through drm_mode_object_reference() and 48 * provides reference counting through drm_mode_object_get() and
49 * drm_mode_object_unreference(). This is used by &drm_framebuffer, 49 * drm_mode_object_put(). This is used by &drm_framebuffer, &drm_connector
50 * &drm_connector and &drm_property_blob. These objects provide specialized 50 * and &drm_property_blob. These objects provide specialized reference
51 * reference counting wrappers. 51 * counting wrappers.
52 */ 52 */
53struct drm_mode_object { 53struct drm_mode_object {
54 uint32_t id; 54 uint32_t id;
@@ -114,8 +114,32 @@ struct drm_object_properties {
114 114
115struct drm_mode_object *drm_mode_object_find(struct drm_device *dev, 115struct drm_mode_object *drm_mode_object_find(struct drm_device *dev,
116 uint32_t id, uint32_t type); 116 uint32_t id, uint32_t type);
117void drm_mode_object_reference(struct drm_mode_object *obj); 117void drm_mode_object_get(struct drm_mode_object *obj);
118void drm_mode_object_unreference(struct drm_mode_object *obj); 118void drm_mode_object_put(struct drm_mode_object *obj);
119
120/**
121 * drm_mode_object_reference - acquire a mode object reference
122 * @obj: DRM mode object
123 *
124 * This is a compatibility alias for drm_mode_object_get() and should not be
125 * used by new code.
126 */
127static inline void drm_mode_object_reference(struct drm_mode_object *obj)
128{
129 drm_mode_object_get(obj);
130}
131
132/**
133 * drm_mode_object_unreference - release a mode object reference
134 * @obj: DRM mode object
135 *
136 * This is a compatibility alias for drm_mode_object_put() and should not be
137 * used by new code.
138 */
139static inline void drm_mode_object_unreference(struct drm_mode_object *obj)
140{
141 drm_mode_object_put(obj);
142}
119 143
120int drm_object_property_set_value(struct drm_mode_object *obj, 144int drm_object_property_set_value(struct drm_mode_object *obj,
121 struct drm_property *property, 145 struct drm_property *property,
diff --git a/scripts/coccinelle/api/drm-get-put.cocci b/scripts/coccinelle/api/drm-get-put.cocci
new file mode 100644
index 000000000000..a3742447c981
--- /dev/null
+++ b/scripts/coccinelle/api/drm-get-put.cocci
@@ -0,0 +1,42 @@
1///
2/// Use drm_*_get() and drm_*_put() helpers instead of drm_*_reference() and
3/// drm_*_unreference() helpers.
4///
5// Confidence: High
6// Copyright: (C) 2017 NVIDIA Corporation
7// Options: --no-includes --include-headers
8//
9
10virtual patch
11virtual report
12
13@depends on patch@
14expression object;
15@@
16
17(
18- drm_mode_object_reference(object)
19+ drm_mode_object_get(object)
20|
21- drm_mode_object_unreference(object)
22+ drm_mode_object_put(object)
23)
24
25@r depends on report@
26expression object;
27position p;
28@@
29
30(
31drm_mode_object_unreference@p(object)
32|
33drm_mode_object_reference@p(object)
34)
35
36@script:python depends on report@
37object << r.object;
38p << r.p;
39@@
40
41msg="WARNING: use get/put helpers to reference and dereference %s" % (object)
42coccilib.report.print_report(p[0], msg)