History

drm/drm_vma_manager: Add drm_vma_node_allow_once()

Currently there is no easy way for a drm driver to safely check and allow drm_vma_offset_node for a drm file just once. Allow drm drivers to call non-refcounted version of drm_vma_node_allow() so that a driver doesn't need to keep track of each drm_vma_node_allow() to call subsequent drm_vma_node_revoke() to prevent memory leak. Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Cc: Maxime Ripard <mripard@kernel.org> Cc: Thomas Zimmermann <tzimmermann@suse.de> Cc: David Airlie <airlied@gmail.com> Cc: Daniel Vetter <daniel@ffwll.ch> Cc: Tvrtko Ursulin <tvrtko.ursulin@linux.intel.com> Cc: Andi Shyti <andi.shyti@linux.intel.com>

Nirmoy Das committed 3 years ago

Commit 899d3a31 parent 2293a732 files · +55 −22Browse files

Unified · Split

2 files
  1. drivers/gpu/drm/drm_vma_manager.c +54 −22
  2. include/drm/drm_vma_manager.h +1 −0
drivers/gpu/drm/drm_vma_manager.c+54−22
@@ -240,27 +240,8 @@ void drm_vma_offset_remove(struct drm_vma_offset_manager *mgr, · 239 unmodified lines
240}240}
241EXPORT_SYMBOL(drm_vma_offset_remove);241EXPORT_SYMBOL(drm_vma_offset_remove);
242 242
243/**243static int vma_node_allow(struct drm_vma_offset_node *node,
244 * drm_vma_node_allow - Add open-file to list of allowed users244 struct drm_file *tag, bool ref_counted)
245 * @node: Node to modify
246 * @tag: Tag of file to remove
247 *
248 * Add @tag to the list of allowed open-files for this node. If @tag is
249 * already on this list, the ref-count is incremented.
250 *
251 * The list of allowed-users is preserved across drm_vma_offset_add() and
252 * drm_vma_offset_remove() calls. You may even call it if the node is currently
253 * not added to any offset-manager.
254 *
255 * You must remove all open-files the same number of times as you added them
256 * before destroying the node. Otherwise, you will leak memory.
257 *
258 * This is locked against concurrent access internally.
259 *
260 * RETURNS:
261 * 0 on success, negative error code on internal failure (out-of-mem)
262 */
263int drm_vma_node_allow(struct drm_vma_offset_node *node, struct drm_file *tag)
264{245{
265 struct rb_node **iter;246 struct rb_node **iter;
266 struct rb_node *parent = NULL;247 struct rb_node *parent = NULL;
@@ -282,7 +263,8 @@ int drm_vma_node_allow(struct drm_vma_offset_node *node, struct drm_file *tag) · 15 unmodified lines
282 entry = rb_entry(*iter, struct drm_vma_offset_file, vm_rb);263 entry = rb_entry(*iter, struct drm_vma_offset_file, vm_rb);
283 264
284 if (tag == entry->vm_tag) {265 if (tag == entry->vm_tag) {
285 entry->vm_count++;266 if (ref_counted)
267 entry->vm_count++;
286 goto unlock;268 goto unlock;
287 } else if (tag > entry->vm_tag) {269 } else if (tag > entry->vm_tag) {
288 iter = &(*iter)->rb_right;270 iter = &(*iter)->rb_right;
@@ -307,8 +289,58 @@ unlock: · 18 unmodified lines
307 kfree(new);289 kfree(new);
308 return ret;290 return ret;
309}291}
292
293/**
294 * drm_vma_node_allow - Add open-file to list of allowed users
295 * @node: Node to modify
296 * @tag: Tag of file to remove
297 *
298 * Add @tag to the list of allowed open-files for this node. If @tag is
299 * already on this list, the ref-count is incremented.
300 *
301 * The list of allowed-users is preserved across drm_vma_offset_add() and
302 * drm_vma_offset_remove() calls. You may even call it if the node is currently
303 * not added to any offset-manager.
304 *
305 * You must remove all open-files the same number of times as you added them
306 * before destroying the node. Otherwise, you will leak memory.
307 *
308 * This is locked against concurrent access internally.
309 *
310 * RETURNS:
311 * 0 on success, negative error code on internal failure (out-of-mem)
312 */
313int drm_vma_node_allow(struct drm_vma_offset_node *node, struct drm_file *tag)
314{
315 return vma_node_allow(node, tag, true);
316}
310EXPORT_SYMBOL(drm_vma_node_allow);317EXPORT_SYMBOL(drm_vma_node_allow);
311 318
319/**
320 * drm_vma_node_allow_once - Add open-file to list of allowed users
321 * @node: Node to modify
322 * @tag: Tag of file to remove
323 *
324 * Add @tag to the list of allowed open-files for this node.
325 *
326 * The list of allowed-users is preserved across drm_vma_offset_add() and
327 * drm_vma_offset_remove() calls. You may even call it if the node is currently
328 * not added to any offset-manager.
329 *
330 * This is not ref-counted unlike drm_vma_node_allow() hence drm_vma_node_revoke()
331 * should only be called once after this.
332 *
333 * This is locked against concurrent access internally.
334 *
335 * RETURNS:
336 * 0 on success, negative error code on internal failure (out-of-mem)
337 */
338int drm_vma_node_allow_once(struct drm_vma_offset_node *node, struct drm_file *tag)
339{
340 return vma_node_allow(node, tag, false);
341}
342EXPORT_SYMBOL(drm_vma_node_allow_once);
343
312/**344/**
313 * drm_vma_node_revoke - Remove open-file from list of allowed users345 * drm_vma_node_revoke - Remove open-file from list of allowed users
314 * @node: Node to modify346 * @node: Node to modify
include/drm/drm_vma_manager.h+1−0
@@ -74,6 +74,7 @@ void drm_vma_offset_remove(struct drm_vma_offset_manager *mgr, · 73 unmodified lines
74 struct drm_vma_offset_node *node);74 struct drm_vma_offset_node *node);
75 75
76int drm_vma_node_allow(struct drm_vma_offset_node *node, struct drm_file *tag);76int drm_vma_node_allow(struct drm_vma_offset_node *node, struct drm_file *tag);
77int drm_vma_node_allow_once(struct drm_vma_offset_node *node, struct drm_file *tag);
77void drm_vma_node_revoke(struct drm_vma_offset_node *node,78void drm_vma_node_revoke(struct drm_vma_offset_node *node,
78 struct drm_file *tag);79 struct drm_file *tag);
79bool drm_vma_node_is_allowed(struct drm_vma_offset_node *node,80bool drm_vma_node_is_allowed(struct drm_vma_offset_node *node,