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
240240 }
241241 EXPORT_SYMBOL(drm_vma_offset_remove);
242242
243−/**
244− * drm_vma_node_allow - Add open-file to list of allowed users
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− */
263−int drm_vma_node_allow(struct drm_vma_offset_node *node, struct drm_file *tag)
243+static int vma_node_allow(struct drm_vma_offset_node *node,
244+ struct drm_file *tag, bool ref_counted)
264245 {
265246 struct rb_node **iter;
266247 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
282263 entry = rb_entry(*iter, struct drm_vma_offset_file, vm_rb);
283264
284265 if (tag == entry->vm_tag) {
285− entry->vm_count++;
266+ if (ref_counted)
267+ entry->vm_count++;
286268 goto unlock;
287269 } else if (tag > entry->vm_tag) {
288270 iter = &(*iter)->rb_right;
@@ -307,8 +289,58 @@ unlock: · 18 unmodified lines
307289 kfree(new);
308290 return ret;
309291 }
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+ */
313+int drm_vma_node_allow(struct drm_vma_offset_node *node, struct drm_file *tag)
314+{
315+ return vma_node_allow(node, tag, true);
316+}
310317 EXPORT_SYMBOL(drm_vma_node_allow);
311318
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+ */
338+int 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+}
342+EXPORT_SYMBOL(drm_vma_node_allow_once);
343+
312344 /**
313345 * drm_vma_node_revoke - Remove open-file from list of allowed users
314346 * @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
7474 struct drm_vma_offset_node *node);
7575
7676 int drm_vma_node_allow(struct drm_vma_offset_node *node, struct drm_file *tag);
77+int drm_vma_node_allow_once(struct drm_vma_offset_node *node, struct drm_file *tag);
7778 void drm_vma_node_revoke(struct drm_vma_offset_node *node,
7879 struct drm_file *tag);
7980 bool drm_vma_node_is_allowed(struct drm_vma_offset_node *node,