dri-devel.lists.freedesktop.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 00/51] drm_device managed resources, v4
@ 2020-03-02 22:25 Daniel Vetter
  2020-03-02 22:25 ` [PATCH 01/51] mm/sl[uo]b: export __kmalloc_track(_node)_caller Daniel Vetter
                   ` (50 more replies)
  0 siblings, 51 replies; 111+ messages in thread
From: Daniel Vetter @ 2020-03-02 22:25 UTC (permalink / raw)
  To: DRI Development; +Cc: Daniel Vetter, Intel Graphics Development

Hi all,

Another round, another attempt at fixing the intel-gfx-ci issues in the
selftests. Plus a pile of polish all over, and a bunch more acks/reviews
added.

We're still missing quite a bit of review, so feedback very much welcome.

Thanks, Daniel

Daniel Vetter (51):
  mm/sl[uo]b: export __kmalloc_track(_node)_caller
  drm/i915: Don't clear drvdata in ->release
  drm: add managed resources tied to drm_device
  drm: Set final_kfree in drm_dev_alloc
  drm/mipi_dbi: Use drmm_add_final_kfree in all drivers
  drm/udl: Use drmm_add_final_kfree
  drm/qxl: Use drmm_add_final_kfree
  drm/i915: Use drmm_add_final_kfree
  drm/cirrus: Use drmm_add_final_kfree
  drm/v3d: Use drmm_add_final_kfree
  drm/tidss: Use drmm_add_final_kfree
  drm/mcde: Use drmm_add_final_kfree
  drm/vgem: Use drmm_add_final_kfree
  drm/vkms: Use drmm_add_final_kfree
  drm/repaper: Use drmm_add_final_kfree
  drm/ingenic: Use drmm_add_final_kfree
  drm/gm12u320: Use drmm_add_final_kfree
  drm/<drivers>: Use drmm_add_final_kfree
  drm: Cleanups after drmm_add_final_kfree rollout
  drm: Handle dev->unique with drmm_
  drm: Use drmm_ for drm_dev_init cleanup
  drm: manage drm_minor cleanup with drmm_
  drm: Manage drm_gem_init with drmm_
  drm: Manage drm_vblank_cleanup with drmm_
  drm: Garbage collect drm_dev_fini
  drm: Manage drm_mode_config_init with drmm_
  drm/bochs: Remove leftover drm_atomic_helper_shutdown
  drm/bochs: Drop explicit drm_mode_config_cleanup
  drm/cirrus: Drop explicit drm_mode_config_cleanup call
  drm/cirrus: Fully embrace devm_
  drm/ingenic: Drop explicit drm_mode_config_cleanup call
  drm/mcde: Drop explicit drm_mode_config_cleanup call
  drm/mcde: More devm_drm_dev_init
  drm/meson: Drop explicit drm_mode_config_cleanup call
  drm/pl111: Drop explicit drm_mode_config_cleanup call
  drm/rcar-du: Drop explicit drm_mode_config_cleanup call
  drm/rockchip: Drop explicit drm_mode_config_cleanup call
  drm/stm: Drop explicit drm_mode_config_cleanup call
  drm/shmob: Drop explicit drm_mode_config_cleanup call
  drm/mtk: Drop explicit drm_mode_config_cleanup call
  drm/tidss: Drop explicit drm_mode_config_cleanup call
  drm/gm12u320: More drmm_
  drm/gm12u320: Use devm_drm_dev_init
  drm/gm12u320: Use helpers for shutdown/suspend/resume
  drm/gm12u320: Simplify upload work
  drm/repaper: Drop explicit drm_mode_config_cleanup call
  drm/mipi-dbi: Move drm_mode_config_init into mipi library
  drm/mipi-dbi: Drop explicit drm_mode_config_cleanup call
  drm/udl: Drop explicit drm_mode_config_cleanup call
  drm/udl: drop drm_driver.release hook
  drm: Add docs for managed resources

 Documentation/gpu/drm-internals.rst           |  12 +
 drivers/gpu/drm/Makefile                      |   3 +-
 .../gpu/drm/arm/display/komeda/komeda_kms.c   |   2 +
 drivers/gpu/drm/armada/armada_drv.c           |   2 +
 drivers/gpu/drm/bochs/bochs.h                 |   1 -
 drivers/gpu/drm/bochs/bochs_drv.c             |   6 +-
 drivers/gpu/drm/bochs/bochs_kms.c             |  15 +-
 drivers/gpu/drm/cirrus/cirrus.c               |  74 ++---
 drivers/gpu/drm/drm_drv.c                     | 220 ++++++-------
 drivers/gpu/drm/drm_gem.c                     |  21 +-
 drivers/gpu/drm/drm_internal.h                |   5 +-
 drivers/gpu/drm/drm_managed.c                 | 305 ++++++++++++++++++
 drivers/gpu/drm/drm_mipi_dbi.c                |  24 +-
 drivers/gpu/drm/drm_mode_config.c             |  13 +-
 drivers/gpu/drm/drm_vblank.c                  |  31 +-
 drivers/gpu/drm/i915/i915_drv.c               |  22 +-
 drivers/gpu/drm/i915/i915_drv.h               |   3 +
 .../gpu/drm/i915/selftests/mock_gem_device.c  |  32 +-
 drivers/gpu/drm/ingenic/ingenic-drm.c         |  17 +-
 drivers/gpu/drm/mcde/mcde_drv.c               |  35 +-
 drivers/gpu/drm/mediatek/mtk_drm_drv.c        |   9 +-
 drivers/gpu/drm/meson/meson_drv.c             |   5 +-
 drivers/gpu/drm/pl111/pl111_drv.c             |  12 +-
 drivers/gpu/drm/qxl/qxl_drv.c                 |   2 -
 drivers/gpu/drm/qxl/qxl_kms.c                 |   2 +
 drivers/gpu/drm/rcar-du/rcar_du_drv.c         |   1 -
 drivers/gpu/drm/rcar-du/rcar_du_kms.c         |   4 +-
 drivers/gpu/drm/rockchip/rockchip_drm_drv.c   |  14 +-
 drivers/gpu/drm/shmobile/shmob_drm_drv.c      |   2 -
 drivers/gpu/drm/shmobile/shmob_drm_kms.c      |   6 +-
 drivers/gpu/drm/stm/drv.c                     |  10 +-
 drivers/gpu/drm/tidss/tidss_drv.c             |  10 +-
 drivers/gpu/drm/tidss/tidss_kms.c             |  19 +-
 drivers/gpu/drm/tidss/tidss_kms.h             |   1 -
 drivers/gpu/drm/tiny/gm12u320.c               | 226 +++++--------
 drivers/gpu/drm/tiny/hx8357d.c                |   5 +-
 drivers/gpu/drm/tiny/ili9225.c                |   5 +-
 drivers/gpu/drm/tiny/ili9341.c                |   5 +-
 drivers/gpu/drm/tiny/ili9486.c                |   5 +-
 drivers/gpu/drm/tiny/mi0283qt.c               |   5 +-
 drivers/gpu/drm/tiny/repaper.c                |  18 +-
 drivers/gpu/drm/tiny/st7586.c                 |   5 +-
 drivers/gpu/drm/tiny/st7735r.c                |   5 +-
 drivers/gpu/drm/udl/udl_drv.c                 |  16 +-
 drivers/gpu/drm/udl/udl_drv.h                 |   2 -
 drivers/gpu/drm/udl/udl_main.c                |  10 -
 drivers/gpu/drm/udl/udl_modeset.c             |  21 +-
 drivers/gpu/drm/v3d/v3d_drv.c                 |  38 +--
 drivers/gpu/drm/vboxvideo/vbox_drv.c          |   2 +
 drivers/gpu/drm/vgem/vgem_drv.c               |  15 +-
 drivers/gpu/drm/vkms/vkms_drv.c               |  19 +-
 drivers/gpu/drm/xen/xen_drm_front.c           |   4 +-
 include/drm/drm_device.h                      |  15 +
 include/drm/drm_drv.h                         |   9 +-
 include/drm/drm_managed.h                     | 116 +++++++
 include/drm/drm_mipi_dbi.h                    |   1 -
 include/drm/drm_mode_config.h                 |  19 +-
 include/drm/drm_print.h                       |   6 +
 mm/slob.c                                     |   2 +
 mm/slub.c                                     |   2 +
 60 files changed, 906 insertions(+), 610 deletions(-)
 create mode 100644 drivers/gpu/drm/drm_managed.c
 create mode 100644 include/drm/drm_managed.h

-- 
2.24.1

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 111+ messages in thread

* [PATCH 01/51] mm/sl[uo]b: export __kmalloc_track(_node)_caller
  2020-03-02 22:25 [PATCH 00/51] drm_device managed resources, v4 Daniel Vetter
@ 2020-03-02 22:25 ` Daniel Vetter
  2020-03-02 22:25 ` [PATCH 02/51] drm/i915: Don't clear drvdata in ->release Daniel Vetter
                   ` (49 subsequent siblings)
  50 siblings, 0 replies; 111+ messages in thread
From: Daniel Vetter @ 2020-03-02 22:25 UTC (permalink / raw)
  To: DRI Development
  Cc: linux-mm, Daniel Vetter, Intel Graphics Development,
	Pekka Enberg, Joonsoo Kim, David Rientjes, Daniel Vetter,
	Christoph Lameter, Andrew Morton

slab does this already, and I want to use this in a memory allocation
tracker in drm for stuff that's tied to the lifetime of a drm_device,
not the underlying struct device. Kinda like devres, but for drm.

Acked-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
Cc: Christoph Lameter <cl@linux.com>
Cc: Pekka Enberg <penberg@kernel.org>
Cc: David Rientjes <rientjes@google.com>
Cc: Joonsoo Kim <iamjoonsoo.kim@lge.com>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: linux-mm@kvack.org
--
I plan to merge this through drm-misc-next (with Andrew's ack) once
the remainder of the drm series is in shape.
-Daniel
---
 mm/slob.c | 2 ++
 mm/slub.c | 2 ++
 2 files changed, 4 insertions(+)

diff --git a/mm/slob.c b/mm/slob.c
index fa53e9f73893..ac2aecfbc7a8 100644
--- a/mm/slob.c
+++ b/mm/slob.c
@@ -524,6 +524,7 @@ void *__kmalloc_track_caller(size_t size, gfp_t gfp, unsigned long caller)
 {
 	return __do_kmalloc_node(size, gfp, NUMA_NO_NODE, caller);
 }
+EXPORT_SYMBOL(__kmalloc_track_caller);
 
 #ifdef CONFIG_NUMA
 void *__kmalloc_node_track_caller(size_t size, gfp_t gfp,
@@ -531,6 +532,7 @@ void *__kmalloc_node_track_caller(size_t size, gfp_t gfp,
 {
 	return __do_kmalloc_node(size, gfp, node, caller);
 }
+EXPORT_SYMBOL(__kmalloc_node_track_caller);
 #endif
 
 void kfree(const void *block)
diff --git a/mm/slub.c b/mm/slub.c
index be2854b5b1c9..7271fb235ed8 100644
--- a/mm/slub.c
+++ b/mm/slub.c
@@ -4358,6 +4358,7 @@ void *__kmalloc_track_caller(size_t size, gfp_t gfpflags, unsigned long caller)
 
 	return ret;
 }
+EXPORT_SYMBOL(__kmalloc_track_caller);
 
 #ifdef CONFIG_NUMA
 void *__kmalloc_node_track_caller(size_t size, gfp_t gfpflags,
@@ -4388,6 +4389,7 @@ void *__kmalloc_node_track_caller(size_t size, gfp_t gfpflags,
 
 	return ret;
 }
+EXPORT_SYMBOL(__kmalloc_node_track_caller);
 #endif
 
 #ifdef CONFIG_SYSFS
-- 
2.24.1

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 111+ messages in thread

* [PATCH 02/51] drm/i915: Don't clear drvdata in ->release
  2020-03-02 22:25 [PATCH 00/51] drm_device managed resources, v4 Daniel Vetter
  2020-03-02 22:25 ` [PATCH 01/51] mm/sl[uo]b: export __kmalloc_track(_node)_caller Daniel Vetter
@ 2020-03-02 22:25 ` Daniel Vetter
  2020-03-02 22:25 ` [PATCH 03/51] drm: add managed resources tied to drm_device Daniel Vetter
                   ` (48 subsequent siblings)
  50 siblings, 0 replies; 111+ messages in thread
From: Daniel Vetter @ 2020-03-02 22:25 UTC (permalink / raw)
  To: DRI Development
  Cc: Daniel Vetter, Daniel Vetter, Intel Graphics Development,
	Greg Kroah-Hartman

For two reasons:

- The driver core clears this already for us after we're unloaded in
  __device_release_driver().

- It's way too late, the drm_device ->release callback might massively
  outlive the underlying physical device, since a drm_device can't be
  kept alive by open drm_file or well really anything else userspace
  is still hanging onto. So if we clear this ourselves, we should
  clear it in the pci ->remove callback, not in the drm_device
  ->relase callback.

Looking at git history this was fixed in the driver core with

commit 0998d0631001288a5974afc0b2a5f568bcdecb4d
Author: Hans de Goede <hdegoede@redhat.com>
Date:   Wed May 23 00:09:34 2012 +0200

    device-core: Ensure drvdata = NULL when no driver is bound

v2: Cite the core fix in the commit message (Chris).

Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: Chris Wilson <chris@chris-wilson.co.uk>
Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
---
 drivers/gpu/drm/i915/i915_drv.c | 3 ---
 1 file changed, 3 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
index e7c339255de5..5997b4507f29 100644
--- a/drivers/gpu/drm/i915/i915_drv.c
+++ b/drivers/gpu/drm/i915/i915_drv.c
@@ -914,9 +914,6 @@ static void i915_driver_destroy(struct drm_i915_private *i915)
 
 	drm_dev_fini(&i915->drm);
 	kfree(i915);
-
-	/* And make sure we never chase our dangling pointer from pci_dev */
-	pci_set_drvdata(pdev, NULL);
 }
 
 /**
-- 
2.24.1

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 111+ messages in thread

* [PATCH 03/51] drm: add managed resources tied to drm_device
  2020-03-02 22:25 [PATCH 00/51] drm_device managed resources, v4 Daniel Vetter
  2020-03-02 22:25 ` [PATCH 01/51] mm/sl[uo]b: export __kmalloc_track(_node)_caller Daniel Vetter
  2020-03-02 22:25 ` [PATCH 02/51] drm/i915: Don't clear drvdata in ->release Daniel Vetter
@ 2020-03-02 22:25 ` Daniel Vetter
  2020-03-03  8:04   ` Dan Carpenter
                     ` (3 more replies)
  2020-03-02 22:25 ` [PATCH 04/51] drm: Set final_kfree in drm_dev_alloc Daniel Vetter
                   ` (47 subsequent siblings)
  50 siblings, 4 replies; 111+ messages in thread
From: Daniel Vetter @ 2020-03-02 22:25 UTC (permalink / raw)
  To: DRI Development
  Cc: Rafael J. Wysocki, Daniel Vetter, Intel Graphics Development,
	Laurent Pinchart, Greg Kroah-Hartman, Daniel Vetter,
	Sam Ravnborg

We have lots of these. And the cleanup code tends to be of dubious
quality. The biggest wrong pattern is that developers use devm_, which
ties the release action to the underlying struct device, whereas
all the userspace visible stuff attached to a drm_device can long
outlive that one (e.g. after a hotunplug while userspace has open
files and mmap'ed buffers). Give people what they want, but with more
correctness.

Mostly copied from devres.c, with types adjusted to fit drm_device and
a few simplifications - I didn't (yet) copy over everything. Since
the types don't match code sharing looked like a hopeless endeavour.

For now it's only super simplified, no groups, you can't remove
actions (but kfree exists, we'll need that soon). Plus all specific to
drm_device ofc, including the logging. Which I didn't bother to make
compile-time optional, since none of the other drm logging is compile
time optional either.

One tricky bit here is the chicken&egg between allocating your
drm_device structure and initiliazing it with drm_dev_init. For
perfect onion unwinding we'd need to have the action to kfree the
allocation registered before drm_dev_init registers any of its own
release handlers. But drm_dev_init doesn't know where exactly the
drm_device is emebedded into the overall structure, and by the time it
returns it'll all be too late. And forcing drivers to be able clean up
everything except the one kzalloc is silly.

Work around this by having a very special final_kfree pointer. This
also avoids troubles with the list head possibly disappearing from
underneath us when we release all resources attached to the
drm_device.

v2: Do all the kerneldoc at the end, to avoid lots of fairly pointless
shuffling while getting everything into shape.

v3: Add static to add/del_dr (Neil)
Move typo fix to the right patch (Neil)

v4: Enforce contract for drmm_add_final_kfree:

Use ksize() to check that the drm_device is indeed contained somewhere
in the final kfree(). Because we need that or the entire managed
release logic blows up in a pile of use-after-frees. Motivated by a
discussion with Laurent.

v5: Review from Laurent:
- %zu instead of casting size_t
- header guards
- sorting of includes
- guarding of data assignment if we didn't allocate it for a NULL
  pointer
- delete spurious newline
- cast void* data parameter correctly in ->release call, no idea how
  this even worked before

v3: Review from Sam
- Add the kerneldoc for the managed sub-struct back in, even if it
  doesn't show up in the generated html somehow.
- Explain why __always_inline.
- Fix bisectability around the final kfree() in drm_dev_relase(). This
  is just interim code which will disappear again.
- Some whitespace polish.
- Add debug output when drmm_add_action or drmm_kmalloc fail.

Cc: Sam Ravnborg <sam@ravnborg.org>
Cc: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Cc: Neil Armstrong <narmstrong@baylibre.com
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: "Rafael J. Wysocki" <rafael@kernel.org>
Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
---
 Documentation/gpu/drm-internals.rst |   6 +
 drivers/gpu/drm/Makefile            |   3 +-
 drivers/gpu/drm/drm_drv.c           |  12 ++
 drivers/gpu/drm/drm_internal.h      |   3 +
 drivers/gpu/drm/drm_managed.c       | 186 ++++++++++++++++++++++++++++
 include/drm/drm_device.h            |  15 +++
 include/drm/drm_managed.h           |  30 +++++
 include/drm/drm_print.h             |   6 +
 8 files changed, 260 insertions(+), 1 deletion(-)
 create mode 100644 drivers/gpu/drm/drm_managed.c
 create mode 100644 include/drm/drm_managed.h

diff --git a/Documentation/gpu/drm-internals.rst b/Documentation/gpu/drm-internals.rst
index a73320576ca9..a6b6145fda78 100644
--- a/Documentation/gpu/drm-internals.rst
+++ b/Documentation/gpu/drm-internals.rst
@@ -132,6 +132,12 @@ be unmapped; on many devices, the ROM address decoder is shared with
 other BARs, so leaving it mapped could cause undesired behaviour like
 hangs or memory corruption.
 
+Managed Resources
+-----------------
+
+.. kernel-doc:: drivers/gpu/drm/drm_managed.c
+   :doc: managed resources
+
 Bus-specific Device Registration and PCI Support
 ------------------------------------------------
 
diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile
index 7f72ef5e7811..183c60048307 100644
--- a/drivers/gpu/drm/Makefile
+++ b/drivers/gpu/drm/Makefile
@@ -17,7 +17,8 @@ drm-y       :=	drm_auth.o drm_cache.o \
 		drm_plane.o drm_color_mgmt.o drm_print.o \
 		drm_dumb_buffers.o drm_mode_config.o drm_vblank.o \
 		drm_syncobj.o drm_lease.o drm_writeback.o drm_client.o \
-		drm_client_modeset.o drm_atomic_uapi.o drm_hdcp.o
+		drm_client_modeset.o drm_atomic_uapi.o drm_hdcp.o \
+		drm_managed.o
 
 drm-$(CONFIG_DRM_LEGACY) += drm_legacy_misc.o drm_bufs.o drm_context.o drm_dma.o drm_scatter.o drm_lock.o
 drm-$(CONFIG_DRM_LIB_RANDOM) += lib/drm_random.o
diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c
index 9fcd6ab3c154..153050fc926c 100644
--- a/drivers/gpu/drm/drm_drv.c
+++ b/drivers/gpu/drm/drm_drv.c
@@ -629,6 +629,9 @@ int drm_dev_init(struct drm_device *dev,
 	dev->dev = get_device(parent);
 	dev->driver = driver;
 
+	INIT_LIST_HEAD(&dev->managed.resources);
+	spin_lock_init(&dev->managed.lock);
+
 	/* no per-device feature limits by default */
 	dev->driver_features = ~0u;
 
@@ -828,8 +831,17 @@ static void drm_dev_release(struct kref *ref)
 		dev->driver->release(dev);
 	} else {
 		drm_dev_fini(dev);
+	}
+
+	drm_managed_release(dev);
+
+	if (!dev->driver->release && !dev->managed.final_kfree) {
+		WARN_ON(!list_empty(&dev->managed.resources));
 		kfree(dev);
 	}
+
+	if (dev->managed.final_kfree)
+		kfree(dev->managed.final_kfree);
 }
 
 /**
diff --git a/drivers/gpu/drm/drm_internal.h b/drivers/gpu/drm/drm_internal.h
index aeec2e68d772..8c2628dfc6c7 100644
--- a/drivers/gpu/drm/drm_internal.h
+++ b/drivers/gpu/drm/drm_internal.h
@@ -89,6 +89,9 @@ void drm_prime_remove_buf_handle_locked(struct drm_prime_file_private *prime_fpr
 struct drm_minor *drm_minor_acquire(unsigned int minor_id);
 void drm_minor_release(struct drm_minor *minor);
 
+/* drm_managed.c */
+void drm_managed_release(struct drm_device *dev);
+
 /* drm_vblank.c */
 void drm_vblank_disable_and_save(struct drm_device *dev, unsigned int pipe);
 void drm_vblank_cleanup(struct drm_device *dev);
diff --git a/drivers/gpu/drm/drm_managed.c b/drivers/gpu/drm/drm_managed.c
new file mode 100644
index 000000000000..57dc79fa90af
--- /dev/null
+++ b/drivers/gpu/drm/drm_managed.c
@@ -0,0 +1,186 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2020 Intel
+ *
+ * Based on drivers/base/devres.c
+ */
+
+#include <drm/drm_managed.h>
+
+#include <linux/list.h>
+#include <linux/slab.h>
+#include <linux/spinlock.h>
+
+#include <drm/drm_device.h>
+#include <drm/drm_print.h>
+
+/**
+ * DOC: managed resources
+ *
+ * Inspired by struct &device managed resources, but tied to the lifetime of
+ * struct &drm_device, which can outlive the underlying physical device, usually
+ * when userspace has some open files and other handles to resources still open.
+ */
+struct drmres_node {
+	struct list_head	entry;
+	drmres_release_t	release;
+	const char		*name;
+	size_t			size;
+};
+
+struct drmres {
+	struct drmres_node		node;
+	/*
+	 * Some archs want to perform DMA into kmalloc caches
+	 * and need a guaranteed alignment larger than
+	 * the alignment of a 64-bit integer.
+	 * Thus we use ARCH_KMALLOC_MINALIGN here and get exactly the same
+	 * buffer alignment as if it was allocated by plain kmalloc().
+	 */
+	u8 __aligned(ARCH_KMALLOC_MINALIGN) data[];
+};
+
+void drm_managed_release(struct drm_device *dev)
+{
+	struct drmres *dr, *tmp;
+
+	drm_dbg_drmres(dev, "drmres release begin\n");
+	list_for_each_entry_safe(dr, tmp, &dev->managed.resources, node.entry) {
+		drm_dbg_drmres(dev, "REL %p %s (%zu bytes)\n",
+			       dr, dr->node.name, dr->node.size);
+
+		if (dr->node.release)
+			dr->node.release(dev, dr->node.size ? *(void **)&dr->data : NULL);
+
+		list_del(&dr->node.entry);
+		kfree(dr);
+	}
+	drm_dbg_drmres(dev, "drmres release end\n");
+}
+
+/*
+ * Always inline so that kmallc_track_caller tracks the actual interesting
+ * caller outside of drm_managed.c.
+ */
+static __always_inline struct drmres * alloc_dr(drmres_release_t release,
+						size_t size, gfp_t gfp, int nid)
+{
+	size_t tot_size;
+	struct drmres *dr;
+
+	/* We must catch any near-SIZE_MAX cases that could overflow. */
+	if (unlikely(check_add_overflow(sizeof(*dr), size, &tot_size)))
+		return NULL;
+
+	dr = kmalloc_node_track_caller(tot_size, gfp, nid);
+	if (unlikely(!dr))
+		return NULL;
+
+	memset(dr, 0, offsetof(struct drmres, data));
+
+	INIT_LIST_HEAD(&dr->node.entry);
+	dr->node.release = release;
+	dr->node.size = size;
+
+	return dr;
+}
+
+static void del_dr(struct drm_device *dev, struct drmres *dr)
+{
+	list_del_init(&dr->node.entry);
+
+	drm_dbg_drmres(dev, "DEL %p %s (%lu bytes)\n",
+		       dr, dr->node.name, (unsigned long) dr->node.size);
+}
+
+static void add_dr(struct drm_device *dev, struct drmres *dr)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&dev->managed.lock, flags);
+	list_add(&dr->node.entry, &dev->managed.resources);
+	spin_unlock_irqrestore(&dev->managed.lock, flags);
+
+	drm_dbg_drmres(dev, "ADD %p %s (%lu bytes)\n",
+		       dr, dr->node.name, (unsigned long) dr->node.size);
+}
+
+void drmm_add_final_kfree(struct drm_device *dev, void *parent)
+{
+	WARN_ON(dev->managed.final_kfree);
+	WARN_ON(dev < (struct drm_device *) parent);
+	WARN_ON(dev + 1 >= (struct drm_device *) (parent + ksize(parent)));
+	dev->managed.final_kfree = parent;
+}
+EXPORT_SYMBOL(drmm_add_final_kfree);
+
+int __drmm_add_action(struct drm_device *dev,
+		      drmres_release_t action,
+		      void *data, const char *name)
+{
+	struct drmres *dr;
+	void **void_ptr;
+
+	dr = alloc_dr(action, data ? sizeof(void*) : 0,
+		      GFP_KERNEL | __GFP_ZERO,
+		      dev_to_node(dev->dev));
+	if (!dr) {
+		drm_dbg_drmres(dev, "failed to add action %s for %p\n",
+			       name, data);
+		return -ENOMEM;
+	}
+
+	dr->node.name = name;
+	if (data) {
+		void_ptr = (void **)&dr->data;
+		*void_ptr = data;
+	}
+
+	add_dr(dev, dr);
+
+	return 0;
+}
+EXPORT_SYMBOL(__drmm_add_action);
+
+void *drmm_kmalloc(struct drm_device *dev, size_t size, gfp_t gfp)
+{
+	struct drmres *dr;
+
+	dr = alloc_dr(NULL, size, gfp, dev_to_node(dev->dev));
+	if (!dr) {
+		drm_dbg_drmres(dev, "failed to allocate %zu bytes, %u flags\n",
+			       size, gfp);
+		return NULL;
+	}
+	dr->node.name = "kmalloc";
+
+	add_dr(dev, dr);
+
+	return dr->data;
+}
+EXPORT_SYMBOL(drmm_kmalloc);
+
+void drmm_kfree(struct drm_device *dev, void *data)
+{
+	struct drmres *dr_match = NULL, *dr;
+	unsigned long flags;
+
+	if (!data)
+		return;
+
+	spin_lock_irqsave(&dev->managed.lock, flags);
+	list_for_each_entry(dr, &dev->managed.resources, node.entry) {
+		if (dr->data == data) {
+			dr_match = dr;
+			del_dr(dev, dr_match);
+			break;
+		}
+	}
+	spin_unlock_irqrestore(&dev->managed.lock, flags);
+
+	if (WARN_ON(!dr_match))
+		return;
+
+	kfree(dr_match);
+}
+EXPORT_SYMBOL(drmm_kfree);
diff --git a/include/drm/drm_device.h b/include/drm/drm_device.h
index bb60a949f416..d39132b477dd 100644
--- a/include/drm/drm_device.h
+++ b/include/drm/drm_device.h
@@ -67,6 +67,21 @@ struct drm_device {
 	/** @dev: Device structure of bus-device */
 	struct device *dev;
 
+	/**
+	 * @managed:
+	 *
+	 * Managed resources linked to the lifetime of this &drm_device as
+	 * tracked by @ref.
+	 */
+	struct {
+		/** @managed.resources: managed resources list */
+		struct list_head resources;
+		/** @managed.final_kfree: pointer for final kfree() call */
+		void *final_kfree;
+		/** @managed.lock: protects @managed.resources */
+		spinlock_t lock;
+	} managed;
+
 	/** @driver: DRM driver managing the device */
 	struct drm_driver *driver;
 
diff --git a/include/drm/drm_managed.h b/include/drm/drm_managed.h
new file mode 100644
index 000000000000..7b5df7d09b19
--- /dev/null
+++ b/include/drm/drm_managed.h
@@ -0,0 +1,30 @@
+// SPDX-License-Identifier: GPL-2.0
+
+#ifndef _DRM_MANAGED_H_
+#define _DRM_MANAGED_H_
+
+#include <linux/gfp.h>
+#include <linux/types.h>
+
+struct drm_device;
+
+typedef void (*drmres_release_t)(struct drm_device *dev, void *res);
+
+#define drmm_add_action(dev, action, data) \
+	__drmm_add_action(dev, action, data, #action)
+
+int __must_check __drmm_add_action(struct drm_device *dev,
+				   drmres_release_t action,
+				   void *data, const char *name);
+
+void drmm_add_final_kfree(struct drm_device *dev, void *parent);
+
+void *drmm_kmalloc(struct drm_device *dev, size_t size, gfp_t gfp) __malloc;
+static inline void *drmm_kzalloc(struct drm_device *dev, size_t size, gfp_t gfp)
+{
+	return drmm_kmalloc(dev, size, gfp | __GFP_ZERO);
+}
+
+void drmm_kfree(struct drm_device *dev, void *data);
+
+#endif
diff --git a/include/drm/drm_print.h b/include/drm/drm_print.h
index ca7cee8e728a..1c9417430d08 100644
--- a/include/drm/drm_print.h
+++ b/include/drm/drm_print.h
@@ -313,6 +313,10 @@ enum drm_debug_category {
 	 * @DRM_UT_DP: Used in the DP code.
 	 */
 	DRM_UT_DP		= 0x100,
+	/**
+	 * @DRM_UT_DRMRES: Used in the drm managed resources code.
+	 */
+	DRM_UT_DRMRES		= 0x200,
 };
 
 static inline bool drm_debug_enabled(enum drm_debug_category category)
@@ -442,6 +446,8 @@ void drm_dev_dbg(const struct device *dev, enum drm_debug_category category,
 	drm_dev_dbg((drm)->dev, DRM_UT_LEASE, fmt, ##__VA_ARGS__)
 #define drm_dbg_dp(drm, fmt, ...)					\
 	drm_dev_dbg((drm)->dev, DRM_UT_DP, fmt, ##__VA_ARGS__)
+#define drm_dbg_drmres(drm, fmt, ...)					\
+	drm_dev_dbg((drm)->dev, DRM_UT_DRMRES, fmt, ##__VA_ARGS__)
 
 
 /*
-- 
2.24.1

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 111+ messages in thread

* [PATCH 04/51] drm: Set final_kfree in drm_dev_alloc
  2020-03-02 22:25 [PATCH 00/51] drm_device managed resources, v4 Daniel Vetter
                   ` (2 preceding siblings ...)
  2020-03-02 22:25 ` [PATCH 03/51] drm: add managed resources tied to drm_device Daniel Vetter
@ 2020-03-02 22:25 ` Daniel Vetter
  2020-03-03  7:44   ` Gerd Hoffmann
                     ` (2 more replies)
  2020-03-02 22:25 ` [PATCH 05/51] drm/mipi_dbi: Use drmm_add_final_kfree in all drivers Daniel Vetter
                   ` (46 subsequent siblings)
  50 siblings, 3 replies; 111+ messages in thread
From: Daniel Vetter @ 2020-03-02 22:25 UTC (permalink / raw)
  To: DRI Development
  Cc: Oleksandr Andrushchenko, David Airlie, Daniel Vetter,
	Intel Graphics Development, Gerd Hoffmann, Thomas Zimmermann,
	xen-devel, Daniel Vetter

I also did a full review of all callers, and only the xen driver
forgot to call drm_dev_put in the failure path. Fix that up too.

v2: I noticed that xen has a drm_driver.release hook, and uses
drm_dev_alloc(). We need to remove the kfree from
xen_drm_drv_release().

bochs also has a release hook, but leaked the drm_device ever since

commit 0a6659bdc5e8221da99eebb176fd9591435e38de
Author: Gerd Hoffmann <kraxel@redhat.com>
Date:   Tue Dec 17 18:04:46 2013 +0100

    drm/bochs: new driver

This patch here fixes that leak.

Same for virtio, started leaking with

commit b1df3a2b24a917f8853d43fe9683c0e360d2c33a
Author: Gerd Hoffmann <kraxel@redhat.com>
Date:   Tue Feb 11 14:58:04 2020 +0100

    drm/virtio: add drm_driver.release callback.

Cc: Gerd Hoffmann <kraxel@redhat.com>
Cc: Oleksandr Andrushchenko <oleksandr_andrushchenko@epam.com>
Cc: xen-devel@lists.xenproject.org

Reviewed-by: Oleksandr Andrushchenko <oleksandr_andrushchenko@epam.com>
Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
Cc: Maxime Ripard <mripard@kernel.org>
Cc: Thomas Zimmermann <tzimmermann@suse.de>
Cc: David Airlie <airlied@linux.ie>
Cc: Daniel Vetter <daniel@ffwll.ch>
Cc: Oleksandr Andrushchenko <oleksandr_andrushchenko@epam.com>
Cc: xen-devel@lists.xenproject.org
---
 drivers/gpu/drm/drm_drv.c           | 3 +++
 drivers/gpu/drm/xen/xen_drm_front.c | 2 +-
 2 files changed, 4 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c
index 153050fc926c..7b84ee8a5eb5 100644
--- a/drivers/gpu/drm/drm_drv.c
+++ b/drivers/gpu/drm/drm_drv.c
@@ -39,6 +39,7 @@
 #include <drm/drm_color_mgmt.h>
 #include <drm/drm_drv.h>
 #include <drm/drm_file.h>
+#include <drm/drm_managed.h>
 #include <drm/drm_mode_object.h>
 #include <drm/drm_print.h>
 
@@ -819,6 +820,8 @@ struct drm_device *drm_dev_alloc(struct drm_driver *driver,
 		return ERR_PTR(ret);
 	}
 
+	drmm_add_final_kfree(dev, dev);
+
 	return dev;
 }
 EXPORT_SYMBOL(drm_dev_alloc);
diff --git a/drivers/gpu/drm/xen/xen_drm_front.c b/drivers/gpu/drm/xen/xen_drm_front.c
index 4be49c1aef51..d22b5da38935 100644
--- a/drivers/gpu/drm/xen/xen_drm_front.c
+++ b/drivers/gpu/drm/xen/xen_drm_front.c
@@ -461,7 +461,6 @@ static void xen_drm_drv_release(struct drm_device *dev)
 	drm_mode_config_cleanup(dev);
 
 	drm_dev_fini(dev);
-	kfree(dev);
 
 	if (front_info->cfg.be_alloc)
 		xenbus_switch_state(front_info->xb_dev,
@@ -561,6 +560,7 @@ static int xen_drm_drv_init(struct xen_drm_front_info *front_info)
 fail_modeset:
 	drm_kms_helper_poll_fini(drm_dev);
 	drm_mode_config_cleanup(drm_dev);
+	drm_dev_put(drm_dev);
 fail:
 	kfree(drm_info);
 	return ret;
-- 
2.24.1

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 111+ messages in thread

* [PATCH 05/51] drm/mipi_dbi: Use drmm_add_final_kfree in all drivers
  2020-03-02 22:25 [PATCH 00/51] drm_device managed resources, v4 Daniel Vetter
                   ` (3 preceding siblings ...)
  2020-03-02 22:25 ` [PATCH 04/51] drm: Set final_kfree in drm_dev_alloc Daniel Vetter
@ 2020-03-02 22:25 ` Daniel Vetter
  2020-03-02 22:25 ` [PATCH 06/51] drm/udl: Use drmm_add_final_kfree Daniel Vetter
                   ` (45 subsequent siblings)
  50 siblings, 0 replies; 111+ messages in thread
From: Daniel Vetter @ 2020-03-02 22:25 UTC (permalink / raw)
  To: DRI Development
  Cc: David Airlie, Daniel Vetter, Intel Graphics Development,
	Thomas Zimmermann, Daniel Vetter, Kamlesh Gurudasani,
	Sam Ravnborg, David Lechner

They all share mipi_dbi_release so we need to switch them all
together. With this we can drop the final kfree from the release
function.

Aside, I think we could perhaps have a tiny additional helper for
these mipi_dbi drivers, the first few lines around devm_drm_dev_init
are all the same (except for the drm_driver pointer).

Acked-by: Sam Ravnborg <sam@ravnborg.org>
Reviewed-by: Noralf Trønnes <noralf@tronnes.org>
Tested-by: Noralf Trønnes <noralf@tronnes.org>
Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
Cc: Maxime Ripard <mripard@kernel.org>
Cc: Thomas Zimmermann <tzimmermann@suse.de>
Cc: David Airlie <airlied@linux.ie>
Cc: Daniel Vetter <daniel@ffwll.ch>
Cc: Eric Anholt <eric@anholt.net>
Cc: David Lechner <david@lechnology.com>
Cc: Kamlesh Gurudasani <kamlesh.gurudasani@gmail.com>
Cc: "Noralf Trønnes" <noralf@tronnes.org>
Cc: Sam Ravnborg <sam@ravnborg.org>
Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
---
 drivers/gpu/drm/drm_mipi_dbi.c  | 3 ---
 drivers/gpu/drm/tiny/hx8357d.c  | 2 ++
 drivers/gpu/drm/tiny/ili9225.c  | 2 ++
 drivers/gpu/drm/tiny/ili9341.c  | 2 ++
 drivers/gpu/drm/tiny/ili9486.c  | 2 ++
 drivers/gpu/drm/tiny/mi0283qt.c | 2 ++
 drivers/gpu/drm/tiny/st7586.c   | 2 ++
 drivers/gpu/drm/tiny/st7735r.c  | 2 ++
 8 files changed, 14 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/drm_mipi_dbi.c b/drivers/gpu/drm/drm_mipi_dbi.c
index 558baf989f5a..069603dfcd10 100644
--- a/drivers/gpu/drm/drm_mipi_dbi.c
+++ b/drivers/gpu/drm/drm_mipi_dbi.c
@@ -588,13 +588,10 @@ EXPORT_SYMBOL(mipi_dbi_dev_init);
  */
 void mipi_dbi_release(struct drm_device *drm)
 {
-	struct mipi_dbi_dev *dbidev = drm_to_mipi_dbi_dev(drm);
-
 	DRM_DEBUG_DRIVER("\n");
 
 	drm_mode_config_cleanup(drm);
 	drm_dev_fini(drm);
-	kfree(dbidev);
 }
 EXPORT_SYMBOL(mipi_dbi_release);
 
diff --git a/drivers/gpu/drm/tiny/hx8357d.c b/drivers/gpu/drm/tiny/hx8357d.c
index 9af8ff84974f..42bc5dadcb1c 100644
--- a/drivers/gpu/drm/tiny/hx8357d.c
+++ b/drivers/gpu/drm/tiny/hx8357d.c
@@ -21,6 +21,7 @@
 #include <drm/drm_fb_helper.h>
 #include <drm/drm_gem_cma_helper.h>
 #include <drm/drm_gem_framebuffer_helper.h>
+#include <drm/drm_managed.h>
 #include <drm/drm_mipi_dbi.h>
 #include <drm/drm_modeset_helper.h>
 #include <video/mipi_display.h>
@@ -236,6 +237,7 @@ static int hx8357d_probe(struct spi_device *spi)
 		kfree(dbidev);
 		return ret;
 	}
+	drmm_add_final_kfree(drm, dbidev);
 
 	drm_mode_config_init(drm);
 
diff --git a/drivers/gpu/drm/tiny/ili9225.c b/drivers/gpu/drm/tiny/ili9225.c
index 802fb8dde1b6..aae88dc5b3f7 100644
--- a/drivers/gpu/drm/tiny/ili9225.c
+++ b/drivers/gpu/drm/tiny/ili9225.c
@@ -24,6 +24,7 @@
 #include <drm/drm_fourcc.h>
 #include <drm/drm_gem_cma_helper.h>
 #include <drm/drm_gem_framebuffer_helper.h>
+#include <drm/drm_managed.h>
 #include <drm/drm_mipi_dbi.h>
 #include <drm/drm_rect.h>
 
@@ -387,6 +388,7 @@ static int ili9225_probe(struct spi_device *spi)
 		kfree(dbidev);
 		return ret;
 	}
+	drmm_add_final_kfree(drm, dbidev);
 
 	drm_mode_config_init(drm);
 
diff --git a/drivers/gpu/drm/tiny/ili9341.c b/drivers/gpu/drm/tiny/ili9341.c
index 33b51dc7faa8..7d40cb4ff72b 100644
--- a/drivers/gpu/drm/tiny/ili9341.c
+++ b/drivers/gpu/drm/tiny/ili9341.c
@@ -20,6 +20,7 @@
 #include <drm/drm_fb_helper.h>
 #include <drm/drm_gem_cma_helper.h>
 #include <drm/drm_gem_framebuffer_helper.h>
+#include <drm/drm_managed.h>
 #include <drm/drm_mipi_dbi.h>
 #include <drm/drm_modeset_helper.h>
 #include <video/mipi_display.h>
@@ -194,6 +195,7 @@ static int ili9341_probe(struct spi_device *spi)
 		kfree(dbidev);
 		return ret;
 	}
+	drmm_add_final_kfree(drm, dbidev);
 
 	drm_mode_config_init(drm);
 
diff --git a/drivers/gpu/drm/tiny/ili9486.c b/drivers/gpu/drm/tiny/ili9486.c
index 5084b38c1a71..7d735fc67498 100644
--- a/drivers/gpu/drm/tiny/ili9486.c
+++ b/drivers/gpu/drm/tiny/ili9486.c
@@ -19,6 +19,7 @@
 #include <drm/drm_fb_helper.h>
 #include <drm/drm_gem_cma_helper.h>
 #include <drm/drm_gem_framebuffer_helper.h>
+#include <drm/drm_managed.h>
 #include <drm/drm_mipi_dbi.h>
 #include <drm/drm_modeset_helper.h>
 
@@ -208,6 +209,7 @@ static int ili9486_probe(struct spi_device *spi)
 		kfree(dbidev);
 		return ret;
 	}
+	drmm_add_final_kfree(drm, dbidev);
 
 	drm_mode_config_init(drm);
 
diff --git a/drivers/gpu/drm/tiny/mi0283qt.c b/drivers/gpu/drm/tiny/mi0283qt.c
index e2cfd9a17143..8555a56bce8c 100644
--- a/drivers/gpu/drm/tiny/mi0283qt.c
+++ b/drivers/gpu/drm/tiny/mi0283qt.c
@@ -18,6 +18,7 @@
 #include <drm/drm_fb_helper.h>
 #include <drm/drm_gem_cma_helper.h>
 #include <drm/drm_gem_framebuffer_helper.h>
+#include <drm/drm_managed.h>
 #include <drm/drm_mipi_dbi.h>
 #include <drm/drm_modeset_helper.h>
 #include <video/mipi_display.h>
@@ -198,6 +199,7 @@ static int mi0283qt_probe(struct spi_device *spi)
 		kfree(dbidev);
 		return ret;
 	}
+	drmm_add_final_kfree(drm, dbidev);
 
 	drm_mode_config_init(drm);
 
diff --git a/drivers/gpu/drm/tiny/st7586.c b/drivers/gpu/drm/tiny/st7586.c
index 9ef559dd3191..427c2561f5f4 100644
--- a/drivers/gpu/drm/tiny/st7586.c
+++ b/drivers/gpu/drm/tiny/st7586.c
@@ -21,6 +21,7 @@
 #include <drm/drm_format_helper.h>
 #include <drm/drm_gem_cma_helper.h>
 #include <drm/drm_gem_framebuffer_helper.h>
+#include <drm/drm_managed.h>
 #include <drm/drm_mipi_dbi.h>
 #include <drm/drm_rect.h>
 
@@ -328,6 +329,7 @@ static int st7586_probe(struct spi_device *spi)
 		kfree(dbidev);
 		return ret;
 	}
+	drmm_add_final_kfree(drm, dbidev);
 
 	drm_mode_config_init(drm);
 
diff --git a/drivers/gpu/drm/tiny/st7735r.c b/drivers/gpu/drm/tiny/st7735r.c
index 18b925df6e51..b447235c3d47 100644
--- a/drivers/gpu/drm/tiny/st7735r.c
+++ b/drivers/gpu/drm/tiny/st7735r.c
@@ -21,6 +21,7 @@
 #include <drm/drm_fb_helper.h>
 #include <drm/drm_gem_cma_helper.h>
 #include <drm/drm_gem_framebuffer_helper.h>
+#include <drm/drm_managed.h>
 #include <drm/drm_mipi_dbi.h>
 
 #define ST7735R_FRMCTR1		0xb1
@@ -209,6 +210,7 @@ static int st7735r_probe(struct spi_device *spi)
 		kfree(dbidev);
 		return ret;
 	}
+	drmm_add_final_kfree(drm, dbidev);
 
 	drm_mode_config_init(drm);
 
-- 
2.24.1

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 111+ messages in thread

* [PATCH 06/51] drm/udl: Use drmm_add_final_kfree
  2020-03-02 22:25 [PATCH 00/51] drm_device managed resources, v4 Daniel Vetter
                   ` (4 preceding siblings ...)
  2020-03-02 22:25 ` [PATCH 05/51] drm/mipi_dbi: Use drmm_add_final_kfree in all drivers Daniel Vetter
@ 2020-03-02 22:25 ` Daniel Vetter
  2020-03-11  9:10   ` Thomas Zimmermann
  2020-03-02 22:25 ` [PATCH 07/51] drm/qxl: " Daniel Vetter
                   ` (44 subsequent siblings)
  50 siblings, 1 reply; 111+ messages in thread
From: Daniel Vetter @ 2020-03-02 22:25 UTC (permalink / raw)
  To: DRI Development
  Cc: Sean Paul, Daniel Vetter, Intel Graphics Development,
	Emil Velikov, Laurent Pinchart, Thomas Zimmermann, Daniel Vetter,
	Dave Airlie, Thomas Gleixner, Sam Ravnborg

With this we can drop the final kfree from the release function.

v2: We need drm_dev_put to unroll the driver creation (once
drm_dev_init and drmm_add_final_kfree suceeded), otherwise
the drmm_ magic doesn't happen.

v3: Actually squash in the fixup (Laurent).

Acked-by: Sam Ravnborg <sam@ravnborg.org>
Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
Cc: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Cc: Dave Airlie <airlied@redhat.com>
Cc: Sean Paul <sean@poorly.run>
Cc: Thomas Zimmermann <tzimmermann@suse.de>
Cc: Emil Velikov <emil.l.velikov@gmail.com>
Cc: Daniel Vetter <daniel.vetter@ffwll.ch>
Cc: "Noralf Trønnes" <noralf@tronnes.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Sam Ravnborg <sam@ravnborg.org>
---
 drivers/gpu/drm/udl/udl_drv.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/udl/udl_drv.c b/drivers/gpu/drm/udl/udl_drv.c
index e6c1cd77d4d4..6a5594946096 100644
--- a/drivers/gpu/drm/udl/udl_drv.c
+++ b/drivers/gpu/drm/udl/udl_drv.c
@@ -10,6 +10,7 @@
 #include <drm/drm_fb_helper.h>
 #include <drm/drm_file.h>
 #include <drm/drm_gem_shmem_helper.h>
+#include <drm/drm_managed.h>
 #include <drm/drm_ioctl.h>
 #include <drm/drm_probe_helper.h>
 #include <drm/drm_print.h>
@@ -38,7 +39,6 @@ static void udl_driver_release(struct drm_device *dev)
 	udl_fini(dev);
 	udl_modeset_cleanup(dev);
 	drm_dev_fini(dev);
-	kfree(dev);
 }
 
 static struct drm_driver driver = {
@@ -77,11 +77,11 @@ static struct udl_device *udl_driver_create(struct usb_interface *interface)
 
 	udl->udev = udev;
 	udl->drm.dev_private = udl;
+	drmm_add_final_kfree(&udl->drm, udl);
 
 	r = udl_init(udl);
 	if (r) {
-		drm_dev_fini(&udl->drm);
-		kfree(udl);
+		drm_dev_put(&udl->drm);
 		return ERR_PTR(r);
 	}
 
-- 
2.24.1

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 111+ messages in thread

* [PATCH 07/51] drm/qxl: Use drmm_add_final_kfree
  2020-03-02 22:25 [PATCH 00/51] drm_device managed resources, v4 Daniel Vetter
                   ` (5 preceding siblings ...)
  2020-03-02 22:25 ` [PATCH 06/51] drm/udl: Use drmm_add_final_kfree Daniel Vetter
@ 2020-03-02 22:25 ` Daniel Vetter
  2020-03-03  7:44   ` Gerd Hoffmann
  2020-03-02 22:25 ` [PATCH 08/51] drm/i915: " Daniel Vetter
                   ` (43 subsequent siblings)
  50 siblings, 1 reply; 111+ messages in thread
From: Daniel Vetter @ 2020-03-02 22:25 UTC (permalink / raw)
  To: DRI Development
  Cc: spice-devel, Daniel Vetter, Intel Graphics Development,
	virtualization, Gerd Hoffmann, Daniel Vetter, Dave Airlie

With this we can drop the final kfree from the release function.

Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
Cc: Dave Airlie <airlied@redhat.com>
Cc: Gerd Hoffmann <kraxel@redhat.com>
Cc: virtualization@lists.linux-foundation.org
Cc: spice-devel@lists.freedesktop.org
---
 drivers/gpu/drm/qxl/qxl_drv.c | 2 --
 drivers/gpu/drm/qxl/qxl_kms.c | 2 ++
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/qxl/qxl_drv.c b/drivers/gpu/drm/qxl/qxl_drv.c
index 4fda3f9b29f4..09102e2efabc 100644
--- a/drivers/gpu/drm/qxl/qxl_drv.c
+++ b/drivers/gpu/drm/qxl/qxl_drv.c
@@ -144,8 +144,6 @@ static void qxl_drm_release(struct drm_device *dev)
 	 */
 	qxl_modeset_fini(qdev);
 	qxl_device_fini(qdev);
-	dev->dev_private = NULL;
-	kfree(qdev);
 }
 
 static void
diff --git a/drivers/gpu/drm/qxl/qxl_kms.c b/drivers/gpu/drm/qxl/qxl_kms.c
index 70b20ee4741a..09d7b5f6d172 100644
--- a/drivers/gpu/drm/qxl/qxl_kms.c
+++ b/drivers/gpu/drm/qxl/qxl_kms.c
@@ -27,6 +27,7 @@
 #include <linux/pci.h>
 
 #include <drm/drm_drv.h>
+#include <drm/drm_managed.h>
 #include <drm/drm_probe_helper.h>
 
 #include "qxl_drv.h"
@@ -121,6 +122,7 @@ int qxl_device_init(struct qxl_device *qdev,
 	qdev->ddev.pdev = pdev;
 	pci_set_drvdata(pdev, &qdev->ddev);
 	qdev->ddev.dev_private = qdev;
+	drmm_add_final_kfree(&qdev->ddev, qdev);
 
 	mutex_init(&qdev->gem.mutex);
 	mutex_init(&qdev->update_area_mutex);
-- 
2.24.1

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 111+ messages in thread

* [PATCH 08/51] drm/i915: Use drmm_add_final_kfree
  2020-03-02 22:25 [PATCH 00/51] drm_device managed resources, v4 Daniel Vetter
                   ` (6 preceding siblings ...)
  2020-03-02 22:25 ` [PATCH 07/51] drm/qxl: " Daniel Vetter
@ 2020-03-02 22:25 ` Daniel Vetter
  2020-03-02 22:25 ` [PATCH 09/51] drm/cirrus: " Daniel Vetter
                   ` (42 subsequent siblings)
  50 siblings, 0 replies; 111+ messages in thread
From: Daniel Vetter @ 2020-03-02 22:25 UTC (permalink / raw)
  To: DRI Development
  Cc: Abdiel Janulgue, Mika Kuoppala, Andi Shyti, Tvrtko Ursulin,
	Daniel Vetter, Intel Graphics Development,
	Daniele Ceraolo Spurio, Matthew Auld, Rodrigo Vivi,
	Daniel Vetter

With this we can drop the final kfree from the release function.

The mock device in the selftests needed it's pci_device split
up from the drm_device. In the future we could simplify this again
by allocating the pci_device as a managed allocation too.

v2: I overlooked that i915_driver_destroy is also called in the
unwind code of the error path. There we need a drm_dev_put.
Similar for the mock object.

Now the problem with that is that the drm_driver->release callbacks
for both the real driver and the mock one assume everything has been
set up. Hence going through that path for a partially set up driver
will result in issues. Quickest fix is to disable the ->release() hook
until the driver is fully initialized, and keep the onion unwinding.
Long term would be cleanest to move everything over to drmm_ release
actions, but that's a lot of work for a big driver like i915. Plus
more core work needed first anyway.

v3: Fix i915_drm pointer wrangling in mock_gem_device. Also switch
over to start using drm_dev_put() to clean up even on the error path.
Aside I think the current error path is leaking the allocation.

v4: more fixes for intel-gfx-ci, some if it damage from v3 :-/

Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
Cc: Jani Nikula <jani.nikula@linux.intel.com>
Cc: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Cc: Rodrigo Vivi <rodrigo.vivi@intel.com>
Cc: Chris Wilson <chris@chris-wilson.co.uk>
Cc: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
Cc: Matthew Auld <matthew.auld@intel.com>
Cc: Andi Shyti <andi.shyti@intel.com>
Cc: Mika Kuoppala <mika.kuoppala@linux.intel.com>
Cc: Daniele Ceraolo Spurio <daniele.ceraolospurio@intel.com>
Cc: Daniel Vetter <daniel.vetter@ffwll.ch>
Cc: Abdiel Janulgue <abdiel.janulgue@linux.intel.com>
Cc: intel-gfx@lists.freedesktop.org
---
 drivers/gpu/drm/i915/i915_drv.c               | 10 ++++++-
 drivers/gpu/drm/i915/i915_drv.h               |  3 ++
 .../gpu/drm/i915/selftests/mock_gem_device.c  | 30 ++++++++++++++-----
 3 files changed, 35 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
index 5997b4507f29..bb14209beeed 100644
--- a/drivers/gpu/drm/i915/i915_drv.c
+++ b/drivers/gpu/drm/i915/i915_drv.c
@@ -43,6 +43,7 @@
 #include <drm/drm_atomic_helper.h>
 #include <drm/drm_ioctl.h>
 #include <drm/drm_irq.h>
+#include <drm/drm_managed.h>
 #include <drm/drm_probe_helper.h>
 
 #include "display/intel_acpi.h"
@@ -895,6 +896,8 @@ i915_driver_create(struct pci_dev *pdev, const struct pci_device_id *ent)
 		return ERR_PTR(err);
 	}
 
+	drmm_add_final_kfree(&i915->drm, i915);
+
 	i915->drm.pdev = pdev;
 	pci_set_drvdata(pdev, i915);
 
@@ -913,7 +916,6 @@ static void i915_driver_destroy(struct drm_i915_private *i915)
 	struct pci_dev *pdev = i915->drm.pdev;
 
 	drm_dev_fini(&i915->drm);
-	kfree(i915);
 }
 
 /**
@@ -997,6 +999,8 @@ int i915_driver_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 
 	i915_welcome_messages(i915);
 
+	i915->do_release = true;
+
 	return 0;
 
 out_cleanup_irq:
@@ -1017,6 +1021,7 @@ int i915_driver_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 out_fini:
 	i915_probe_error(i915, "Device initialization failed (%d)\n", ret);
 	i915_driver_destroy(i915);
+	drm_dev_put(&i915->drm);
 	return ret;
 }
 
@@ -1056,6 +1061,9 @@ static void i915_driver_release(struct drm_device *dev)
 	struct drm_i915_private *dev_priv = to_i915(dev);
 	struct intel_runtime_pm *rpm = &dev_priv->runtime_pm;
 
+	if (!dev_priv->do_release)
+		return;
+
 	disable_rpm_wakeref_asserts(rpm);
 
 	i915_gem_driver_release(dev_priv);
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index b621df933212..865865ca3b42 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -884,6 +884,9 @@ struct i915_selftest_stash {
 struct drm_i915_private {
 	struct drm_device drm;
 
+	/* FIXME: Device release actions should all be moved to drmm_ */
+	bool do_release;
+
 	const struct intel_device_info __info; /* Use INTEL_INFO() to access. */
 	struct intel_runtime_info __runtime; /* Use RUNTIME_INFO() to access. */
 	struct intel_driver_caps caps;
diff --git a/drivers/gpu/drm/i915/selftests/mock_gem_device.c b/drivers/gpu/drm/i915/selftests/mock_gem_device.c
index 754d0eb6beaa..acf889e4b993 100644
--- a/drivers/gpu/drm/i915/selftests/mock_gem_device.c
+++ b/drivers/gpu/drm/i915/selftests/mock_gem_device.c
@@ -25,6 +25,8 @@
 #include <linux/pm_domain.h>
 #include <linux/pm_runtime.h>
 
+#include <drm/drm_managed.h>
+
 #include "gt/intel_gt.h"
 #include "gt/intel_gt_requests.h"
 #include "gt/mock_engine.h"
@@ -55,6 +57,9 @@ static void mock_device_release(struct drm_device *dev)
 {
 	struct drm_i915_private *i915 = to_i915(dev);
 
+	if (!i915->do_release)
+		goto out;
+
 	mock_device_flush(i915);
 	intel_gt_driver_remove(&i915->gt);
 
@@ -72,7 +77,9 @@ static void mock_device_release(struct drm_device *dev)
 	drm_mode_config_cleanup(&i915->drm);
 
 	drm_dev_fini(&i915->drm);
+out:
 	put_device(&i915->drm.pdev->dev);
+	i915->drm.pdev = NULL;
 }
 
 static struct drm_driver mock_driver = {
@@ -114,9 +121,14 @@ struct drm_i915_private *mock_gem_device(void)
 	struct pci_dev *pdev;
 	int err;
 
-	pdev = kzalloc(sizeof(*pdev) + sizeof(*i915), GFP_KERNEL);
+	pdev = kzalloc(sizeof(*pdev), GFP_KERNEL);
 	if (!pdev)
-		goto err;
+		return NULL;
+	i915 = kzalloc(sizeof(*i915), GFP_KERNEL);
+	if (!i915) {
+		kfree(pdev);
+		return NULL;
+	}
 
 	device_initialize(&pdev->dev);
 	pdev->class = PCI_BASE_CLASS_DISPLAY << 16;
@@ -129,7 +141,6 @@ struct drm_i915_private *mock_gem_device(void)
 	pdev->dev.archdata.iommu = (void *)-1;
 #endif
 
-	i915 = (struct drm_i915_private *)(pdev + 1);
 	pci_set_drvdata(pdev, i915);
 
 	dev_pm_domain_set(&pdev->dev, &pm_domain);
@@ -141,9 +152,13 @@ struct drm_i915_private *mock_gem_device(void)
 	err = drm_dev_init(&i915->drm, &mock_driver, &pdev->dev);
 	if (err) {
 		pr_err("Failed to initialise mock GEM device: err=%d\n", err);
-		goto put_device;
+		put_device(&pdev->dev);
+		kfree(i915);
+
+		return NULL;
 	}
 	i915->drm.pdev = pdev;
+	drmm_add_final_kfree(&i915->drm, i915);
 
 	intel_runtime_pm_init_early(&i915->runtime_pm);
 
@@ -188,6 +203,8 @@ struct drm_i915_private *mock_gem_device(void)
 	__clear_bit(I915_WEDGED, &i915->gt.reset.flags);
 	intel_engines_driver_register(i915);
 
+	i915->do_release = true;
+
 	return i915;
 
 err_context:
@@ -199,8 +216,7 @@ struct drm_i915_private *mock_gem_device(void)
 	intel_memory_regions_driver_release(i915);
 	drm_mode_config_cleanup(&i915->drm);
 	drm_dev_fini(&i915->drm);
-put_device:
-	put_device(&pdev->dev);
-err:
+	drm_dev_put(&i915->drm);
+
 	return NULL;
 }
-- 
2.24.1

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 111+ messages in thread

* [PATCH 09/51] drm/cirrus: Use drmm_add_final_kfree
  2020-03-02 22:25 [PATCH 00/51] drm_device managed resources, v4 Daniel Vetter
                   ` (7 preceding siblings ...)
  2020-03-02 22:25 ` [PATCH 08/51] drm/i915: " Daniel Vetter
@ 2020-03-02 22:25 ` Daniel Vetter
  2020-03-03  7:49   ` Gerd Hoffmann
  2020-03-02 22:25 ` [PATCH 10/51] drm/v3d: " Daniel Vetter
                   ` (41 subsequent siblings)
  50 siblings, 1 reply; 111+ messages in thread
From: Daniel Vetter @ 2020-03-02 22:25 UTC (permalink / raw)
  To: DRI Development
  Cc: Daniel Vetter, Intel Graphics Development, virtualization,
	Gerd Hoffmann, Thomas Zimmermann, Daniel Vetter, Dave Airlie,
	Sam Ravnborg

With this we can drop the final kfree from the release function.

I also noticed that cirrus forgot to call drm_dev_fini().

v2: Don't call kfree(cirrus) after we've handed overship of that to
drm_device and the drmm_ stuff.

Acked-by: Sam Ravnborg <sam@ravnborg.org>
Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
Cc: Dave Airlie <airlied@redhat.com>
Cc: Gerd Hoffmann <kraxel@redhat.com>
Cc: Daniel Vetter <daniel.vetter@ffwll.ch>
Cc: "Noralf Trønnes" <noralf@tronnes.org>
Cc: Linus Walleij <linus.walleij@linaro.org>
Cc: Sam Ravnborg <sam@ravnborg.org>
Cc: Thomas Zimmermann <tzimmermann@suse.de>
Cc: virtualization@lists.linux-foundation.org
---
 drivers/gpu/drm/cirrus/cirrus.c | 14 +++++++-------
 1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/cirrus/cirrus.c b/drivers/gpu/drm/cirrus/cirrus.c
index d2ff63ce8eaf..2232556ce34c 100644
--- a/drivers/gpu/drm/cirrus/cirrus.c
+++ b/drivers/gpu/drm/cirrus/cirrus.c
@@ -35,6 +35,7 @@
 #include <drm/drm_gem_shmem_helper.h>
 #include <drm/drm_gem_framebuffer_helper.h>
 #include <drm/drm_ioctl.h>
+#include <drm/drm_managed.h>
 #include <drm/drm_modeset_helper_vtables.h>
 #include <drm/drm_probe_helper.h>
 #include <drm/drm_simple_kms_helper.h>
@@ -527,10 +528,8 @@ static void cirrus_mode_config_init(struct cirrus_device *cirrus)
 
 static void cirrus_release(struct drm_device *dev)
 {
-	struct cirrus_device *cirrus = dev->dev_private;
-
 	drm_mode_config_cleanup(dev);
-	kfree(cirrus);
+	drm_dev_fini(dev);
 }
 
 DEFINE_DRM_GEM_FOPS(cirrus_fops);
@@ -575,9 +574,12 @@ static int cirrus_pci_probe(struct pci_dev *pdev,
 
 	dev = &cirrus->dev;
 	ret = drm_dev_init(dev, &cirrus_driver, &pdev->dev);
-	if (ret)
-		goto err_free_cirrus;
+	if (ret) {
+		kfree(cirrus);
+		goto err_pci_release;
+	}
 	dev->dev_private = cirrus;
+	drmm_add_final_kfree(dev, cirrus);
 
 	ret = -ENOMEM;
 	cirrus->vram = ioremap(pci_resource_start(pdev, 0),
@@ -618,8 +620,6 @@ static int cirrus_pci_probe(struct pci_dev *pdev,
 	iounmap(cirrus->vram);
 err_dev_put:
 	drm_dev_put(dev);
-err_free_cirrus:
-	kfree(cirrus);
 err_pci_release:
 	pci_release_regions(pdev);
 	return ret;
-- 
2.24.1

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 111+ messages in thread

* [PATCH 10/51] drm/v3d: Use drmm_add_final_kfree
  2020-03-02 22:25 [PATCH 00/51] drm_device managed resources, v4 Daniel Vetter
                   ` (8 preceding siblings ...)
  2020-03-02 22:25 ` [PATCH 09/51] drm/cirrus: " Daniel Vetter
@ 2020-03-02 22:25 ` Daniel Vetter
  2020-03-02 22:25 ` [PATCH 11/51] drm/tidss: " Daniel Vetter
                   ` (40 subsequent siblings)
  50 siblings, 0 replies; 111+ messages in thread
From: Daniel Vetter @ 2020-03-02 22:25 UTC (permalink / raw)
  To: DRI Development; +Cc: Daniel Vetter, Daniel Vetter, Intel Graphics Development

With this we can drop the final kfree from the release function.

I also noticed that the unwind code is wrong, after drm_dev_init the
drm_device owns the v3d allocation, so the kfree(v3d) is a double-free.
Reorder the setup to fix this issue.

After a bit more prep in drivers and drm core v3d should be able to
switch over to devm_drm_dev_init, which should clean this up further.

Acked-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
Cc: Eric Anholt <eric@anholt.net>
---
 drivers/gpu/drm/v3d/v3d_drv.c | 38 ++++++++++++++++++-----------------
 1 file changed, 20 insertions(+), 18 deletions(-)

diff --git a/drivers/gpu/drm/v3d/v3d_drv.c b/drivers/gpu/drm/v3d/v3d_drv.c
index eaa8e9682373..8d0c0daaac81 100644
--- a/drivers/gpu/drm/v3d/v3d_drv.c
+++ b/drivers/gpu/drm/v3d/v3d_drv.c
@@ -25,6 +25,7 @@
 #include <drm/drm_drv.h>
 #include <drm/drm_fb_cma_helper.h>
 #include <drm/drm_fb_helper.h>
+#include <drm/drm_managed.h>
 #include <uapi/drm/v3d_drm.h>
 
 #include "v3d_drv.h"
@@ -257,13 +258,23 @@ static int v3d_platform_drm_probe(struct platform_device *pdev)
 	v3d->pdev = pdev;
 	drm = &v3d->drm;
 
+	ret = drm_dev_init(&v3d->drm, &v3d_drm_driver, dev);
+	if (ret) {
+		kfree(v3d);
+		return ret;
+	}
+
+	platform_set_drvdata(pdev, drm);
+	drm->dev_private = v3d;
+	drmm_add_final_kfree(drm, v3d);
+
 	ret = map_regs(v3d, &v3d->hub_regs, "hub");
 	if (ret)
-		goto dev_free;
+		goto dev_destroy;
 
 	ret = map_regs(v3d, &v3d->core_regs[0], "core0");
 	if (ret)
-		goto dev_free;
+		goto dev_destroy;
 
 	mmu_debug = V3D_READ(V3D_MMU_DEBUG_INFO);
 	dev->coherent_dma_mask =
@@ -281,21 +292,21 @@ static int v3d_platform_drm_probe(struct platform_device *pdev)
 		ret = PTR_ERR(v3d->reset);
 
 		if (ret == -EPROBE_DEFER)
-			goto dev_free;
+			goto dev_destroy;
 
 		v3d->reset = NULL;
 		ret = map_regs(v3d, &v3d->bridge_regs, "bridge");
 		if (ret) {
 			dev_err(dev,
 				"Failed to get reset control or bridge regs\n");
-			goto dev_free;
+			goto dev_destroy;
 		}
 	}
 
 	if (v3d->ver < 41) {
 		ret = map_regs(v3d, &v3d->gca_regs, "gca");
 		if (ret)
-			goto dev_free;
+			goto dev_destroy;
 	}
 
 	v3d->mmu_scratch = dma_alloc_wc(dev, 4096, &v3d->mmu_scratch_paddr,
@@ -303,23 +314,16 @@ static int v3d_platform_drm_probe(struct platform_device *pdev)
 	if (!v3d->mmu_scratch) {
 		dev_err(dev, "Failed to allocate MMU scratch page\n");
 		ret = -ENOMEM;
-		goto dev_free;
+		goto dev_destroy;
 	}
 
 	pm_runtime_use_autosuspend(dev);
 	pm_runtime_set_autosuspend_delay(dev, 50);
 	pm_runtime_enable(dev);
 
-	ret = drm_dev_init(&v3d->drm, &v3d_drm_driver, dev);
-	if (ret)
-		goto dma_free;
-
-	platform_set_drvdata(pdev, drm);
-	drm->dev_private = v3d;
-
 	ret = v3d_gem_init(drm);
 	if (ret)
-		goto dev_destroy;
+		goto dma_free;
 
 	ret = v3d_irq_init(v3d);
 	if (ret)
@@ -335,12 +339,10 @@ static int v3d_platform_drm_probe(struct platform_device *pdev)
 	v3d_irq_disable(v3d);
 gem_destroy:
 	v3d_gem_destroy(drm);
-dev_destroy:
-	drm_dev_put(drm);
 dma_free:
 	dma_free_wc(dev, 4096, v3d->mmu_scratch, v3d->mmu_scratch_paddr);
-dev_free:
-	kfree(v3d);
+dev_destroy:
+	drm_dev_put(drm);
 	return ret;
 }
 
-- 
2.24.1

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 111+ messages in thread

* [PATCH 11/51] drm/tidss: Use drmm_add_final_kfree
  2020-03-02 22:25 [PATCH 00/51] drm_device managed resources, v4 Daniel Vetter
                   ` (9 preceding siblings ...)
  2020-03-02 22:25 ` [PATCH 10/51] drm/v3d: " Daniel Vetter
@ 2020-03-02 22:25 ` Daniel Vetter
  2020-03-02 22:25 ` [PATCH 12/51] drm/mcde: " Daniel Vetter
                   ` (39 subsequent siblings)
  50 siblings, 0 replies; 111+ messages in thread
From: Daniel Vetter @ 2020-03-02 22:25 UTC (permalink / raw)
  To: DRI Development
  Cc: Daniel Vetter, Intel Graphics Development, Tomi Valkeinen,
	Jyri Sarha, Daniel Vetter

With this we can drop the final kfree from the release function.

Acked-by: Jyri Sarha <jsarha@ti.com>
Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
Cc: Jyri Sarha <jsarha@ti.com>
Cc: Tomi Valkeinen <tomi.valkeinen@ti.com>
---
 drivers/gpu/drm/tidss/tidss_drv.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/tidss/tidss_drv.c b/drivers/gpu/drm/tidss/tidss_drv.c
index d95e4be2c7b9..32a85628dbec 100644
--- a/drivers/gpu/drm/tidss/tidss_drv.c
+++ b/drivers/gpu/drm/tidss/tidss_drv.c
@@ -17,6 +17,7 @@
 #include <drm/drm_fb_helper.h>
 #include <drm/drm_gem_cma_helper.h>
 #include <drm/drm_irq.h>
+#include <drm/drm_managed.h>
 #include <drm/drm_probe_helper.h>
 
 #include "tidss_dispc.h"
@@ -109,8 +110,6 @@ static void tidss_release(struct drm_device *ddev)
 	tidss_modeset_cleanup(tidss);
 
 	drm_dev_fini(ddev);
-
-	kfree(tidss);
 }
 
 DEFINE_DRM_GEM_CMA_FOPS(tidss_fops);
@@ -154,6 +153,7 @@ static int tidss_probe(struct platform_device *pdev)
 		kfree(ddev);
 		return ret;
 	}
+	drmm_add_final_kfree(ddev, tidss);
 
 	tidss->dev = dev;
 	tidss->feat = of_device_get_match_data(dev);
-- 
2.24.1

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 111+ messages in thread

* [PATCH 12/51] drm/mcde: Use drmm_add_final_kfree
  2020-03-02 22:25 [PATCH 00/51] drm_device managed resources, v4 Daniel Vetter
                   ` (10 preceding siblings ...)
  2020-03-02 22:25 ` [PATCH 11/51] drm/tidss: " Daniel Vetter
@ 2020-03-02 22:25 ` Daniel Vetter
  2020-03-02 22:25 ` [PATCH 13/51] drm/vgem: " Daniel Vetter
                   ` (38 subsequent siblings)
  50 siblings, 0 replies; 111+ messages in thread
From: Daniel Vetter @ 2020-03-02 22:25 UTC (permalink / raw)
  To: DRI Development; +Cc: Daniel Vetter, Intel Graphics Development, Daniel Vetter

With this we can drop the final kfree from the release function.

Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
Cc: Linus Walleij <linus.walleij@linaro.org>
---
 drivers/gpu/drm/mcde/mcde_drv.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/mcde/mcde_drv.c b/drivers/gpu/drm/mcde/mcde_drv.c
index f28cb7a576ba..7474481503a1 100644
--- a/drivers/gpu/drm/mcde/mcde_drv.c
+++ b/drivers/gpu/drm/mcde/mcde_drv.c
@@ -72,6 +72,7 @@
 #include <drm/drm_gem.h>
 #include <drm/drm_gem_cma_helper.h>
 #include <drm/drm_gem_framebuffer_helper.h>
+#include <drm/drm_managed.h>
 #include <drm/drm_of.h>
 #include <drm/drm_probe_helper.h>
 #include <drm/drm_panel.h>
@@ -223,7 +224,6 @@ static void mcde_release(struct drm_device *drm)
 
 	drm_mode_config_cleanup(drm);
 	drm_dev_fini(drm);
-	kfree(mcde);
 }
 
 DEFINE_DRM_GEM_CMA_FOPS(drm_fops);
@@ -330,6 +330,7 @@ static int mcde_probe(struct platform_device *pdev)
 	}
 	drm = &mcde->drm;
 	drm->dev_private = mcde;
+	drmm_add_final_kfree(drm, mcde);
 	platform_set_drvdata(pdev, drm);
 
 	/* Enable continuous updates: this is what Linux' framebuffer expects */
-- 
2.24.1

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 111+ messages in thread

* [PATCH 13/51] drm/vgem: Use drmm_add_final_kfree
  2020-03-02 22:25 [PATCH 00/51] drm_device managed resources, v4 Daniel Vetter
                   ` (11 preceding siblings ...)
  2020-03-02 22:25 ` [PATCH 12/51] drm/mcde: " Daniel Vetter
@ 2020-03-02 22:25 ` Daniel Vetter
  2020-03-02 22:25 ` [PATCH 14/51] drm/vkms: " Daniel Vetter
                   ` (37 subsequent siblings)
  50 siblings, 0 replies; 111+ messages in thread
From: Daniel Vetter @ 2020-03-02 22:25 UTC (permalink / raw)
  To: DRI Development
  Cc: Rob Clark, Daniel Vetter, Intel Graphics Development, Sean Paul,
	Daniel Vetter, Sam Ravnborg, Emil Velikov

With this we can drop the final kfree from the release function.

v2: After drm_dev_init/drmm_add_final_kfree we need to clean up
everything through a drm_dev_put. Rework the unwind code to match
that.

Acked-by: Sam Ravnborg <sam@ravnborg.org>
Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
Cc: Daniel Vetter <daniel.vetter@ffwll.ch>
Cc: Emil Velikov <emil.velikov@collabora.com>
Cc: Chris Wilson <chris@chris-wilson.co.uk>
Cc: Sean Paul <seanpaul@chromium.org>
Cc: Eric Anholt <eric@anholt.net>
Cc: Rob Clark <robdclark@chromium.org>
Cc: Sam Ravnborg <sam@ravnborg.org>
---
 drivers/gpu/drm/vgem/vgem_drv.c | 14 ++++++++------
 1 file changed, 8 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/vgem/vgem_drv.c b/drivers/gpu/drm/vgem/vgem_drv.c
index 909eba43664a..7486014e9149 100644
--- a/drivers/gpu/drm/vgem/vgem_drv.c
+++ b/drivers/gpu/drm/vgem/vgem_drv.c
@@ -39,6 +39,7 @@
 #include <drm/drm_drv.h>
 #include <drm/drm_file.h>
 #include <drm/drm_ioctl.h>
+#include <drm/drm_managed.h>
 #include <drm/drm_prime.h>
 
 #include "vgem_drv.h"
@@ -432,8 +433,6 @@ static void vgem_release(struct drm_device *dev)
 
 	platform_device_unregister(vgem->platform);
 	drm_dev_fini(&vgem->drm);
-
-	kfree(vgem);
 }
 
 static struct drm_driver vgem_driver = {
@@ -489,16 +488,19 @@ static int __init vgem_init(void)
 			   &vgem_device->platform->dev);
 	if (ret)
 		goto out_unregister;
+	drmm_add_final_kfree(&vgem_device->drm, vgem_device);
 
 	/* Final step: expose the device/driver to userspace */
-	ret  = drm_dev_register(&vgem_device->drm, 0);
+	ret = drm_dev_register(&vgem_device->drm, 0);
 	if (ret)
-		goto out_fini;
+		goto out_put;
 
 	return 0;
 
-out_fini:
-	drm_dev_fini(&vgem_device->drm);
+out_put:
+	drm_dev_put(&vgem_device->drm);
+	return ret;
+
 out_unregister:
 	platform_device_unregister(vgem_device->platform);
 out_free:
-- 
2.24.1

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 111+ messages in thread

* [PATCH 14/51] drm/vkms: Use drmm_add_final_kfree
  2020-03-02 22:25 [PATCH 00/51] drm_device managed resources, v4 Daniel Vetter
                   ` (12 preceding siblings ...)
  2020-03-02 22:25 ` [PATCH 13/51] drm/vgem: " Daniel Vetter
@ 2020-03-02 22:25 ` Daniel Vetter
  2020-03-02 22:25 ` [PATCH 15/51] drm/repaper: " Daniel Vetter
                   ` (36 subsequent siblings)
  50 siblings, 0 replies; 111+ messages in thread
From: Daniel Vetter @ 2020-03-02 22:25 UTC (permalink / raw)
  To: DRI Development
  Cc: Haneen Mohammed, Rodrigo Siqueira, Daniel Vetter,
	Intel Graphics Development, Daniel Vetter

With this we can drop the final kfree from the release function.

v2: After drm_dev_init/drmm_add_final_kfree we need to clean up
everything through a drm_dev_put. Rework the unwind code to match
that.

Reviewed-by: Rodrigo Siqueira <rodrigosiqueiramelo@gmail.com>
Tested-by: Rodrigo Siqueira <rodrigosiqueiramelo@gmail.com>
Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
Cc: Rodrigo Siqueira <rodrigosiqueiramelo@gmail.com>
Cc: Haneen Mohammed <hamohammed.sa@gmail.com>
Cc: Daniel Vetter <daniel@ffwll.ch>
---
 drivers/gpu/drm/vkms/vkms_drv.c | 18 +++++++++---------
 1 file changed, 9 insertions(+), 9 deletions(-)

diff --git a/drivers/gpu/drm/vkms/vkms_drv.c b/drivers/gpu/drm/vkms/vkms_drv.c
index 860de052e820..2f35fe789343 100644
--- a/drivers/gpu/drm/vkms/vkms_drv.c
+++ b/drivers/gpu/drm/vkms/vkms_drv.c
@@ -21,6 +21,7 @@
 #include <drm/drm_file.h>
 #include <drm/drm_gem_framebuffer_helper.h>
 #include <drm/drm_ioctl.h>
+#include <drm/drm_managed.h>
 #include <drm/drm_probe_helper.h>
 #include <drm/drm_vblank.h>
 
@@ -158,13 +159,14 @@ static int __init vkms_init(void)
 			   &vkms_device->platform->dev);
 	if (ret)
 		goto out_unregister;
+	drmm_add_final_kfree(&vkms_device->drm, vkms_device);
 
 	ret = dma_coerce_mask_and_coherent(vkms_device->drm.dev,
 					   DMA_BIT_MASK(64));
 
 	if (ret) {
 		DRM_ERROR("Could not initialize DMA support\n");
-		goto out_fini;
+		goto out_put;
 	}
 
 	vkms_device->drm.irq_enabled = true;
@@ -172,25 +174,25 @@ static int __init vkms_init(void)
 	ret = drm_vblank_init(&vkms_device->drm, 1);
 	if (ret) {
 		DRM_ERROR("Failed to vblank\n");
-		goto out_fini;
+		goto out_put;
 	}
 
 	ret = vkms_modeset_init(vkms_device);
 	if (ret)
-		goto out_fini;
+		goto out_put;
 
 	ret = drm_dev_register(&vkms_device->drm, 0);
 	if (ret)
-		goto out_fini;
+		goto out_put;
 
 	return 0;
 
-out_fini:
-	drm_dev_fini(&vkms_device->drm);
+out_put:
+	drm_dev_put(&vkms_device->drm);
+	return ret;
 
 out_unregister:
 	platform_device_unregister(vkms_device->platform);
-
 out_free:
 	kfree(vkms_device);
 	return ret;
@@ -205,8 +207,6 @@ static void __exit vkms_exit(void)
 
 	drm_dev_unregister(&vkms_device->drm);
 	drm_dev_put(&vkms_device->drm);
-
-	kfree(vkms_device);
 }
 
 module_init(vkms_init);
-- 
2.24.1

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 111+ messages in thread

* [PATCH 15/51] drm/repaper: Use drmm_add_final_kfree
  2020-03-02 22:25 [PATCH 00/51] drm_device managed resources, v4 Daniel Vetter
                   ` (13 preceding siblings ...)
  2020-03-02 22:25 ` [PATCH 14/51] drm/vkms: " Daniel Vetter
@ 2020-03-02 22:25 ` Daniel Vetter
  2020-03-06 20:27   ` Sam Ravnborg
  2020-03-02 22:25 ` [PATCH 16/51] drm/ingenic: " Daniel Vetter
                   ` (35 subsequent siblings)
  50 siblings, 1 reply; 111+ messages in thread
From: Daniel Vetter @ 2020-03-02 22:25 UTC (permalink / raw)
  To: DRI Development; +Cc: Daniel Vetter, Intel Graphics Development, Daniel Vetter

With this we can drop the final kfree from the release function.

Reviewed-by: Noralf Trønnes <noralf@tronnes.org>
Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
Cc: "Noralf Trønnes" <noralf@tronnes.org>
---
 drivers/gpu/drm/tiny/repaper.c | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/tiny/repaper.c b/drivers/gpu/drm/tiny/repaper.c
index f5ebcaf7ee3a..df5654ef53ee 100644
--- a/drivers/gpu/drm/tiny/repaper.c
+++ b/drivers/gpu/drm/tiny/repaper.c
@@ -31,6 +31,7 @@
 #include <drm/drm_format_helper.h>
 #include <drm/drm_gem_cma_helper.h>
 #include <drm/drm_gem_framebuffer_helper.h>
+#include <drm/drm_managed.h>
 #include <drm/drm_modes.h>
 #include <drm/drm_rect.h>
 #include <drm/drm_probe_helper.h>
@@ -910,13 +911,10 @@ static const struct drm_mode_config_funcs repaper_mode_config_funcs = {
 
 static void repaper_release(struct drm_device *drm)
 {
-	struct repaper_epd *epd = drm_to_epd(drm);
-
 	DRM_DEBUG_DRIVER("\n");
 
 	drm_mode_config_cleanup(drm);
 	drm_dev_fini(drm);
-	kfree(epd);
 }
 
 static const uint32_t repaper_formats[] = {
@@ -1024,6 +1022,7 @@ static int repaper_probe(struct spi_device *spi)
 		kfree(epd);
 		return ret;
 	}
+	drmm_add_final_kfree(drm, epd);
 
 	drm_mode_config_init(drm);
 	drm->mode_config.funcs = &repaper_mode_config_funcs;
-- 
2.24.1

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 111+ messages in thread

* [PATCH 16/51] drm/ingenic: Use drmm_add_final_kfree
  2020-03-02 22:25 [PATCH 00/51] drm_device managed resources, v4 Daniel Vetter
                   ` (14 preceding siblings ...)
  2020-03-02 22:25 ` [PATCH 15/51] drm/repaper: " Daniel Vetter
@ 2020-03-02 22:25 ` Daniel Vetter
  2020-03-06 20:27   ` Sam Ravnborg
  2020-03-02 22:25 ` [PATCH 17/51] drm/gm12u320: " Daniel Vetter
                   ` (34 subsequent siblings)
  50 siblings, 1 reply; 111+ messages in thread
From: Daniel Vetter @ 2020-03-02 22:25 UTC (permalink / raw)
  To: DRI Development
  Cc: Paul Cercueil, Daniel Vetter, Intel Graphics Development, Daniel Vetter

With this we can drop the final kfree from the release function.

Reviewed-by: Paul Cercueil <paul@crapouillou.net>
Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
Cc: Paul Cercueil <paul@crapouillou.net>
---
 drivers/gpu/drm/ingenic/ingenic-drm.c | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/ingenic/ingenic-drm.c b/drivers/gpu/drm/ingenic/ingenic-drm.c
index 9dfe7cb530e1..e2c832eb4e9a 100644
--- a/drivers/gpu/drm/ingenic/ingenic-drm.c
+++ b/drivers/gpu/drm/ingenic/ingenic-drm.c
@@ -23,6 +23,7 @@
 #include <drm/drm_fourcc.h>
 #include <drm/drm_gem_framebuffer_helper.h>
 #include <drm/drm_irq.h>
+#include <drm/drm_managed.h>
 #include <drm/drm_of.h>
 #include <drm/drm_panel.h>
 #include <drm/drm_plane.h>
@@ -490,11 +491,8 @@ static irqreturn_t ingenic_drm_irq_handler(int irq, void *arg)
 
 static void ingenic_drm_release(struct drm_device *drm)
 {
-	struct ingenic_drm *priv = drm_device_get_priv(drm);
-
 	drm_mode_config_cleanup(drm);
 	drm_dev_fini(drm);
-	kfree(priv);
 }
 
 static int ingenic_drm_enable_vblank(struct drm_crtc *crtc)
@@ -639,6 +637,7 @@ static int ingenic_drm_probe(struct platform_device *pdev)
 		kfree(priv);
 		return ret;
 	}
+	drmm_add_final_kfree(drm, priv);
 
 	drm_mode_config_init(drm);
 	drm->mode_config.min_width = 0;
-- 
2.24.1

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 111+ messages in thread

* [PATCH 17/51] drm/gm12u320: Use drmm_add_final_kfree
  2020-03-02 22:25 [PATCH 00/51] drm_device managed resources, v4 Daniel Vetter
                   ` (15 preceding siblings ...)
  2020-03-02 22:25 ` [PATCH 16/51] drm/ingenic: " Daniel Vetter
@ 2020-03-02 22:25 ` Daniel Vetter
  2020-03-06 20:27   ` Sam Ravnborg
  2020-03-02 22:25 ` [PATCH 18/51] drm/<drivers>: " Daniel Vetter
                   ` (33 subsequent siblings)
  50 siblings, 1 reply; 111+ messages in thread
From: Daniel Vetter @ 2020-03-02 22:25 UTC (permalink / raw)
  To: DRI Development
  Cc: Daniel Vetter, Daniel Vetter, Intel Graphics Development, Hans de Goede

With this we can drop the final kfree from the release function.

Reviewed-by: Hans de Goede <hdegoede@redhat.com>
Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
Cc: Hans de Goede <hdegoede@redhat.com>
---
 drivers/gpu/drm/tiny/gm12u320.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/tiny/gm12u320.c b/drivers/gpu/drm/tiny/gm12u320.c
index a48173441ae0..524ca0941cf9 100644
--- a/drivers/gpu/drm/tiny/gm12u320.c
+++ b/drivers/gpu/drm/tiny/gm12u320.c
@@ -19,6 +19,7 @@
 #include <drm/drm_gem_shmem_helper.h>
 #include <drm/drm_gem_framebuffer_helper.h>
 #include <drm/drm_ioctl.h>
+#include <drm/drm_managed.h>
 #include <drm/drm_modeset_helper_vtables.h>
 #include <drm/drm_probe_helper.h>
 #include <drm/drm_simple_kms_helper.h>
@@ -637,7 +638,6 @@ static void gm12u320_driver_release(struct drm_device *dev)
 	gm12u320_usb_free(gm12u320);
 	drm_mode_config_cleanup(dev);
 	drm_dev_fini(dev);
-	kfree(gm12u320);
 }
 
 DEFINE_DRM_GEM_FOPS(gm12u320_fops);
@@ -692,6 +692,7 @@ static int gm12u320_usb_probe(struct usb_interface *interface,
 		return ret;
 	}
 	dev->dev_private = gm12u320;
+	drmm_add_final_kfree(dev, gm12u320);
 
 	drm_mode_config_init(dev);
 	dev->mode_config.min_width = GM12U320_USER_WIDTH;
-- 
2.24.1

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 111+ messages in thread

* [PATCH 18/51] drm/<drivers>: Use drmm_add_final_kfree
  2020-03-02 22:25 [PATCH 00/51] drm_device managed resources, v4 Daniel Vetter
                   ` (16 preceding siblings ...)
  2020-03-02 22:25 ` [PATCH 17/51] drm/gm12u320: " Daniel Vetter
@ 2020-03-02 22:25 ` Daniel Vetter
  2020-03-06 20:28   ` Sam Ravnborg
  2020-03-02 22:25 ` [PATCH 19/51] drm: Cleanups after drmm_add_final_kfree rollout Daniel Vetter
                   ` (32 subsequent siblings)
  50 siblings, 1 reply; 111+ messages in thread
From: Daniel Vetter @ 2020-03-02 22:25 UTC (permalink / raw)
  To: DRI Development
  Cc: Daniel Vetter, Intel Graphics Development, Liviu Dudau,
	Russell King, Hans de Goede, James (Qian) Wang, Daniel Vetter,
	Mihail Atanassov

These are the leftover drivers that didn't have a ->release hook that
needed to be updated.

Acked-by: Liviu Dudau <liviu.dudau@arm.com>
Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
Cc: "James (Qian) Wang" <james.qian.wang@arm.com>
Cc: Liviu Dudau <liviu.dudau@arm.com>
Cc: Mihail Atanassov <mihail.atanassov@arm.com>
Cc: Russell King <linux@armlinux.org.uk>
Cc: Hans de Goede <hdegoede@redhat.com>
---
 drivers/gpu/drm/arm/display/komeda/komeda_kms.c | 2 ++
 drivers/gpu/drm/armada/armada_drv.c             | 2 ++
 drivers/gpu/drm/vboxvideo/vbox_drv.c            | 2 ++
 3 files changed, 6 insertions(+)

diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_kms.c b/drivers/gpu/drm/arm/display/komeda/komeda_kms.c
index 442d4656150a..16dfd5cdb66c 100644
--- a/drivers/gpu/drm/arm/display/komeda/komeda_kms.c
+++ b/drivers/gpu/drm/arm/display/komeda/komeda_kms.c
@@ -14,6 +14,7 @@
 #include <drm/drm_gem_cma_helper.h>
 #include <drm/drm_gem_framebuffer_helper.h>
 #include <drm/drm_irq.h>
+#include <drm/drm_managed.h>
 #include <drm/drm_probe_helper.h>
 #include <drm/drm_vblank.h>
 
@@ -271,6 +272,7 @@ struct komeda_kms_dev *komeda_kms_attach(struct komeda_dev *mdev)
 	err = drm_dev_init(drm, &komeda_kms_driver, mdev->dev);
 	if (err)
 		goto free_kms;
+	drmm_add_final_kfree(drm, kms);
 
 	drm->dev_private = mdev;
 
diff --git a/drivers/gpu/drm/armada/armada_drv.c b/drivers/gpu/drm/armada/armada_drv.c
index 197dca3fc84c..dd9ed71ed942 100644
--- a/drivers/gpu/drm/armada/armada_drv.c
+++ b/drivers/gpu/drm/armada/armada_drv.c
@@ -12,6 +12,7 @@
 #include <drm/drm_atomic_helper.h>
 #include <drm/drm_drv.h>
 #include <drm/drm_ioctl.h>
+#include <drm/drm_managed.h>
 #include <drm/drm_prime.h>
 #include <drm/drm_probe_helper.h>
 #include <drm/drm_fb_helper.h>
@@ -103,6 +104,7 @@ static int armada_drm_bind(struct device *dev)
 		kfree(priv);
 		return ret;
 	}
+	drmm_add_final_kfree(&priv->drm, priv);
 
 	/* Remove early framebuffers */
 	ret = drm_fb_helper_remove_conflicting_framebuffers(NULL,
diff --git a/drivers/gpu/drm/vboxvideo/vbox_drv.c b/drivers/gpu/drm/vboxvideo/vbox_drv.c
index 8512d970a09f..13eaae7921f5 100644
--- a/drivers/gpu/drm/vboxvideo/vbox_drv.c
+++ b/drivers/gpu/drm/vboxvideo/vbox_drv.c
@@ -17,6 +17,7 @@
 #include <drm/drm_fb_helper.h>
 #include <drm/drm_file.h>
 #include <drm/drm_ioctl.h>
+#include <drm/drm_managed.h>
 
 #include "vbox_drv.h"
 
@@ -54,6 +55,7 @@ static int vbox_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 	vbox->ddev.pdev = pdev;
 	vbox->ddev.dev_private = vbox;
 	pci_set_drvdata(pdev, vbox);
+	drmm_add_final_kfree(&vbox->ddev, vbox);
 	mutex_init(&vbox->hw_mutex);
 
 	ret = pci_enable_device(pdev);
-- 
2.24.1

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 111+ messages in thread

* [PATCH 19/51] drm: Cleanups after drmm_add_final_kfree rollout
  2020-03-02 22:25 [PATCH 00/51] drm_device managed resources, v4 Daniel Vetter
                   ` (17 preceding siblings ...)
  2020-03-02 22:25 ` [PATCH 18/51] drm/<drivers>: " Daniel Vetter
@ 2020-03-02 22:25 ` Daniel Vetter
  2020-03-03  8:45   ` [PATCH] " Daniel Vetter
                     ` (2 more replies)
  2020-03-02 22:26 ` [PATCH 20/51] drm: Handle dev->unique with drmm_ Daniel Vetter
                   ` (31 subsequent siblings)
  50 siblings, 3 replies; 111+ messages in thread
From: Daniel Vetter @ 2020-03-02 22:25 UTC (permalink / raw)
  To: DRI Development; +Cc: Daniel Vetter, Intel Graphics Development, Daniel Vetter

A few things:
- Update the example driver in the documentation.
- We can drop the old kfree in drm_dev_release.
- Add a WARN_ON check in drm_dev_register to make sure everyone calls
  drmm_add_final_kfree and there's no leaks.

Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
---
 drivers/gpu/drm/drm_drv.c | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c
index 7b84ee8a5eb5..1a048325f30e 100644
--- a/drivers/gpu/drm/drm_drv.c
+++ b/drivers/gpu/drm/drm_drv.c
@@ -297,8 +297,6 @@ void drm_minor_release(struct drm_minor *minor)
  *
  *		drm_mode_config_cleanup(drm);
  *		drm_dev_fini(drm);
- *		kfree(priv->userspace_facing);
- *		kfree(priv);
  *	}
  *
  *	static struct drm_driver driver_drm_driver = {
@@ -326,10 +324,11 @@ void drm_minor_release(struct drm_minor *minor)
  *			kfree(drm);
  *			return ret;
  *		}
+ *		drmm_add_final_kfree(drm, priv);
  *
  *		drm_mode_config_init(drm);
  *
- *		priv->userspace_facing = kzalloc(..., GFP_KERNEL);
+ *		priv->userspace_facing = drmm_kzalloc(..., GFP_KERNEL);
  *		if (!priv->userspace_facing)
  *			return -ENOMEM;
  *
@@ -961,6 +960,8 @@ int drm_dev_register(struct drm_device *dev, unsigned long flags)
 	struct drm_driver *driver = dev->driver;
 	int ret;
 
+	WARN_ON(!dev->managed.final_kfree);
+
 	if (drm_dev_needs_global_mutex(dev))
 		mutex_lock(&drm_global_mutex);
 
-- 
2.24.1

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 111+ messages in thread

* [PATCH 20/51] drm: Handle dev->unique with drmm_
  2020-03-02 22:25 [PATCH 00/51] drm_device managed resources, v4 Daniel Vetter
                   ` (18 preceding siblings ...)
  2020-03-02 22:25 ` [PATCH 19/51] drm: Cleanups after drmm_add_final_kfree rollout Daniel Vetter
@ 2020-03-02 22:26 ` Daniel Vetter
  2020-03-06 20:37   ` Sam Ravnborg
  2020-03-11  9:19   ` Thomas Zimmermann
  2020-03-02 22:26 ` [PATCH 21/51] drm: Use drmm_ for drm_dev_init cleanup Daniel Vetter
                   ` (30 subsequent siblings)
  50 siblings, 2 replies; 111+ messages in thread
From: Daniel Vetter @ 2020-03-02 22:26 UTC (permalink / raw)
  To: DRI Development; +Cc: Daniel Vetter, Intel Graphics Development, Daniel Vetter

We need to add a drmm_kstrdup for this, but let's start somewhere.

This is not exactly perfect onion unwinding, but it's jsut a kfree so
doesn't really matter at all.

Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
---
 drivers/gpu/drm/drm_drv.c     |  5 ++---
 drivers/gpu/drm/drm_managed.c | 16 ++++++++++++++++
 include/drm/drm_managed.h     |  1 +
 3 files changed, 19 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c
index 1a048325f30e..ef79c03e311c 100644
--- a/drivers/gpu/drm/drm_drv.c
+++ b/drivers/gpu/drm/drm_drv.c
@@ -777,7 +777,6 @@ void drm_dev_fini(struct drm_device *dev)
 	mutex_destroy(&dev->filelist_mutex);
 	mutex_destroy(&dev->struct_mutex);
 	drm_legacy_destroy_members(dev);
-	kfree(dev->unique);
 }
 EXPORT_SYMBOL(drm_dev_fini);
 
@@ -1068,8 +1067,8 @@ EXPORT_SYMBOL(drm_dev_unregister);
  */
 int drm_dev_set_unique(struct drm_device *dev, const char *name)
 {
-	kfree(dev->unique);
-	dev->unique = kstrdup(name, GFP_KERNEL);
+	drmm_kfree(dev, dev->unique);
+	dev->unique = drmm_kstrdup(dev, name, GFP_KERNEL);
 
 	return dev->unique ? 0 : -ENOMEM;
 }
diff --git a/drivers/gpu/drm/drm_managed.c b/drivers/gpu/drm/drm_managed.c
index 57dc79fa90af..514d5bd42446 100644
--- a/drivers/gpu/drm/drm_managed.c
+++ b/drivers/gpu/drm/drm_managed.c
@@ -160,6 +160,22 @@ void *drmm_kmalloc(struct drm_device *dev, size_t size, gfp_t gfp)
 }
 EXPORT_SYMBOL(drmm_kmalloc);
 
+char *drmm_kstrdup(struct drm_device *dev, const char *s, gfp_t gfp)
+{
+	size_t size;
+	char *buf;
+
+	if (!s)
+		return NULL;
+
+	size = strlen(s) + 1;
+	buf = drmm_kmalloc(dev, size, gfp);
+	if (buf)
+		memcpy(buf, s, size);
+	return buf;
+}
+EXPORT_SYMBOL_GPL(drmm_kstrdup);
+
 void drmm_kfree(struct drm_device *dev, void *data)
 {
 	struct drmres *dr_match = NULL, *dr;
diff --git a/include/drm/drm_managed.h b/include/drm/drm_managed.h
index 7b5df7d09b19..89e6fce9f689 100644
--- a/include/drm/drm_managed.h
+++ b/include/drm/drm_managed.h
@@ -24,6 +24,7 @@ static inline void *drmm_kzalloc(struct drm_device *dev, size_t size, gfp_t gfp)
 {
 	return drmm_kmalloc(dev, size, gfp | __GFP_ZERO);
 }
+char *drmm_kstrdup(struct drm_device *dev, const char *s, gfp_t gfp);
 
 void drmm_kfree(struct drm_device *dev, void *data);
 
-- 
2.24.1

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 111+ messages in thread

* [PATCH 21/51] drm: Use drmm_ for drm_dev_init cleanup
  2020-03-02 22:25 [PATCH 00/51] drm_device managed resources, v4 Daniel Vetter
                   ` (19 preceding siblings ...)
  2020-03-02 22:26 ` [PATCH 20/51] drm: Handle dev->unique with drmm_ Daniel Vetter
@ 2020-03-02 22:26 ` Daniel Vetter
  2020-03-11  9:39   ` Thomas Zimmermann
  2020-03-02 22:26 ` [PATCH 22/51] drm: manage drm_minor cleanup with drmm_ Daniel Vetter
                   ` (29 subsequent siblings)
  50 siblings, 1 reply; 111+ messages in thread
From: Daniel Vetter @ 2020-03-02 22:26 UTC (permalink / raw)
  To: DRI Development; +Cc: Daniel Vetter, Intel Graphics Development, Daniel Vetter

Well for the simple stuff at least, vblank, gem and minor cleanup I
want to further split up as a demonstration.

v2: We need to clear drm_device->dev otherwise the debug drm printing
after our cleanup hook (e.g. in drm_manged_release) will chase
released memory and result in a use-after-free. Not really pretty, but
oh well.

Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
---
 drivers/gpu/drm/drm_drv.c | 48 ++++++++++++++++++++-------------------
 1 file changed, 25 insertions(+), 23 deletions(-)

diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c
index ef79c03e311c..23e5b0e7e041 100644
--- a/drivers/gpu/drm/drm_drv.c
+++ b/drivers/gpu/drm/drm_drv.c
@@ -580,6 +580,23 @@ static void drm_fs_inode_free(struct inode *inode)
  *    used.
  */
 
+static void drm_dev_init_release(struct drm_device *dev, void *res)
+{
+	drm_legacy_ctxbitmap_cleanup(dev);
+	drm_legacy_remove_map_hash(dev);
+	drm_fs_inode_free(dev->anon_inode);
+
+	put_device(dev->dev);
+	/* Prevent use-after-free in drm_managed_release when debugging is
+	 * enabled. Slightly awkward, but can't really be helped. */
+	dev->dev = NULL;
+	mutex_destroy(&dev->master_mutex);
+	mutex_destroy(&dev->clientlist_mutex);
+	mutex_destroy(&dev->filelist_mutex);
+	mutex_destroy(&dev->struct_mutex);
+	drm_legacy_destroy_members(dev);
+}
+
 /**
  * drm_dev_init - Initialise new DRM device
  * @dev: DRM device
@@ -647,11 +664,15 @@ int drm_dev_init(struct drm_device *dev,
 	mutex_init(&dev->clientlist_mutex);
 	mutex_init(&dev->master_mutex);
 
+	ret = drmm_add_action(dev, drm_dev_init_release, NULL);
+	if (ret)
+		return ret;
+
 	dev->anon_inode = drm_fs_inode_new();
 	if (IS_ERR(dev->anon_inode)) {
 		ret = PTR_ERR(dev->anon_inode);
 		DRM_ERROR("Cannot allocate anonymous inode: %d\n", ret);
-		goto err_free;
+		goto err;
 	}
 
 	if (drm_core_check_feature(dev, DRIVER_RENDER)) {
@@ -688,19 +709,12 @@ int drm_dev_init(struct drm_device *dev,
 	if (drm_core_check_feature(dev, DRIVER_GEM))
 		drm_gem_destroy(dev);
 err_ctxbitmap:
-	drm_legacy_ctxbitmap_cleanup(dev);
-	drm_legacy_remove_map_hash(dev);
 err_minors:
 	drm_minor_free(dev, DRM_MINOR_PRIMARY);
 	drm_minor_free(dev, DRM_MINOR_RENDER);
-	drm_fs_inode_free(dev->anon_inode);
-err_free:
-	put_device(dev->dev);
-	mutex_destroy(&dev->master_mutex);
-	mutex_destroy(&dev->clientlist_mutex);
-	mutex_destroy(&dev->filelist_mutex);
-	mutex_destroy(&dev->struct_mutex);
-	drm_legacy_destroy_members(dev);
+err:
+	drm_managed_release(dev);
+
 	return ret;
 }
 EXPORT_SYMBOL(drm_dev_init);
@@ -763,20 +777,8 @@ void drm_dev_fini(struct drm_device *dev)
 	if (drm_core_check_feature(dev, DRIVER_GEM))
 		drm_gem_destroy(dev);
 
-	drm_legacy_ctxbitmap_cleanup(dev);
-	drm_legacy_remove_map_hash(dev);
-	drm_fs_inode_free(dev->anon_inode);
-
 	drm_minor_free(dev, DRM_MINOR_PRIMARY);
 	drm_minor_free(dev, DRM_MINOR_RENDER);
-
-	put_device(dev->dev);
-
-	mutex_destroy(&dev->master_mutex);
-	mutex_destroy(&dev->clientlist_mutex);
-	mutex_destroy(&dev->filelist_mutex);
-	mutex_destroy(&dev->struct_mutex);
-	drm_legacy_destroy_members(dev);
 }
 EXPORT_SYMBOL(drm_dev_fini);
 
-- 
2.24.1

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 111+ messages in thread

* [PATCH 22/51] drm: manage drm_minor cleanup with drmm_
  2020-03-02 22:25 [PATCH 00/51] drm_device managed resources, v4 Daniel Vetter
                   ` (20 preceding siblings ...)
  2020-03-02 22:26 ` [PATCH 21/51] drm: Use drmm_ for drm_dev_init cleanup Daniel Vetter
@ 2020-03-02 22:26 ` Daniel Vetter
  2020-03-11  9:59   ` Thomas Zimmermann
  2020-03-02 22:26 ` [PATCH 23/51] drm: Manage drm_gem_init " Daniel Vetter
                   ` (28 subsequent siblings)
  50 siblings, 1 reply; 111+ messages in thread
From: Daniel Vetter @ 2020-03-02 22:26 UTC (permalink / raw)
  To: DRI Development
  Cc: Daniel Vetter, Intel Graphics Development, Laurent Pinchart,
	Daniel Vetter

The cleanup here is somewhat tricky, since we can't tell apart the
allocated minor index from 0. So register a cleanup action first, and
if the index allocation fails, unregister that cleanup action again to
avoid bad mistakes.

The kdev for the minor already handles NULL, so no problem there.

Hence add drmm_remove_action() to the drm_managed library.

v2: Make pointer math around void ** consistent with what Laurent
suggested.

Cc: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
---
 drivers/gpu/drm/drm_drv.c     | 74 +++++++++++++----------------------
 drivers/gpu/drm/drm_managed.c | 28 +++++++++++++
 include/drm/drm_managed.h     |  4 ++
 3 files changed, 59 insertions(+), 47 deletions(-)

diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c
index 23e5b0e7e041..29d106195ab3 100644
--- a/drivers/gpu/drm/drm_drv.c
+++ b/drivers/gpu/drm/drm_drv.c
@@ -93,19 +93,35 @@ static struct drm_minor **drm_minor_get_slot(struct drm_device *dev,
 	}
 }
 
+static void drm_minor_alloc_release(struct drm_device *dev, void *data)
+{
+	struct drm_minor *minor = data;
+	unsigned long flags;
+
+	put_device(minor->kdev);
+
+	spin_lock_irqsave(&drm_minor_lock, flags);
+	idr_remove(&drm_minors_idr, minor->index);
+	spin_unlock_irqrestore(&drm_minor_lock, flags);
+}
+
 static int drm_minor_alloc(struct drm_device *dev, unsigned int type)
 {
 	struct drm_minor *minor;
 	unsigned long flags;
 	int r;
 
-	minor = kzalloc(sizeof(*minor), GFP_KERNEL);
+	minor = drmm_kzalloc(dev, sizeof(*minor), GFP_KERNEL);
 	if (!minor)
 		return -ENOMEM;
 
 	minor->type = type;
 	minor->dev = dev;
 
+	r = drmm_add_action(dev, drm_minor_alloc_release, minor);
+	if (r)
+		return r;
+
 	idr_preload(GFP_KERNEL);
 	spin_lock_irqsave(&drm_minor_lock, flags);
 	r = idr_alloc(&drm_minors_idr,
@@ -116,47 +132,18 @@ static int drm_minor_alloc(struct drm_device *dev, unsigned int type)
 	spin_unlock_irqrestore(&drm_minor_lock, flags);
 	idr_preload_end();
 
-	if (r < 0)
-		goto err_free;
+	if (r < 0) {
+		drmm_remove_action(dev, drm_minor_alloc_release, minor);
+		return r;
+	}
 
 	minor->index = r;
-
 	minor->kdev = drm_sysfs_minor_alloc(minor);
-	if (IS_ERR(minor->kdev)) {
-		r = PTR_ERR(minor->kdev);
-		goto err_index;
-	}
+	if (IS_ERR(minor->kdev))
+		return PTR_ERR(minor->kdev);
 
 	*drm_minor_get_slot(dev, type) = minor;
 	return 0;
-
-err_index:
-	spin_lock_irqsave(&drm_minor_lock, flags);
-	idr_remove(&drm_minors_idr, minor->index);
-	spin_unlock_irqrestore(&drm_minor_lock, flags);
-err_free:
-	kfree(minor);
-	return r;
-}
-
-static void drm_minor_free(struct drm_device *dev, unsigned int type)
-{
-	struct drm_minor **slot, *minor;
-	unsigned long flags;
-
-	slot = drm_minor_get_slot(dev, type);
-	minor = *slot;
-	if (!minor)
-		return;
-
-	put_device(minor->kdev);
-
-	spin_lock_irqsave(&drm_minor_lock, flags);
-	idr_remove(&drm_minors_idr, minor->index);
-	spin_unlock_irqrestore(&drm_minor_lock, flags);
-
-	kfree(minor);
-	*slot = NULL;
 }
 
 static int drm_minor_register(struct drm_device *dev, unsigned int type)
@@ -678,16 +665,16 @@ int drm_dev_init(struct drm_device *dev,
 	if (drm_core_check_feature(dev, DRIVER_RENDER)) {
 		ret = drm_minor_alloc(dev, DRM_MINOR_RENDER);
 		if (ret)
-			goto err_minors;
+			goto err;
 	}
 
 	ret = drm_minor_alloc(dev, DRM_MINOR_PRIMARY);
 	if (ret)
-		goto err_minors;
+		goto err;
 
 	ret = drm_legacy_create_map_hash(dev);
 	if (ret)
-		goto err_minors;
+		goto err;
 
 	drm_legacy_ctxbitmap_init(dev);
 
@@ -695,7 +682,7 @@ int drm_dev_init(struct drm_device *dev,
 		ret = drm_gem_init(dev);
 		if (ret) {
 			DRM_ERROR("Cannot initialize graphics execution manager (GEM)\n");
-			goto err_ctxbitmap;
+			goto err;
 		}
 	}
 
@@ -708,10 +695,6 @@ int drm_dev_init(struct drm_device *dev,
 err_setunique:
 	if (drm_core_check_feature(dev, DRIVER_GEM))
 		drm_gem_destroy(dev);
-err_ctxbitmap:
-err_minors:
-	drm_minor_free(dev, DRM_MINOR_PRIMARY);
-	drm_minor_free(dev, DRM_MINOR_RENDER);
 err:
 	drm_managed_release(dev);
 
@@ -776,9 +759,6 @@ void drm_dev_fini(struct drm_device *dev)
 
 	if (drm_core_check_feature(dev, DRIVER_GEM))
 		drm_gem_destroy(dev);
-
-	drm_minor_free(dev, DRM_MINOR_PRIMARY);
-	drm_minor_free(dev, DRM_MINOR_RENDER);
 }
 EXPORT_SYMBOL(drm_dev_fini);
 
diff --git a/drivers/gpu/drm/drm_managed.c b/drivers/gpu/drm/drm_managed.c
index 514d5bd42446..0883615c2088 100644
--- a/drivers/gpu/drm/drm_managed.c
+++ b/drivers/gpu/drm/drm_managed.c
@@ -142,6 +142,34 @@ int __drmm_add_action(struct drm_device *dev,
 }
 EXPORT_SYMBOL(__drmm_add_action);
 
+void drmm_remove_action(struct drm_device *dev,
+			drmres_release_t action,
+			void *data)
+{
+	struct drmres *dr = NULL, *tmp;
+	unsigned long flags;
+
+	if (!data)
+		return;
+
+	spin_lock_irqsave(&dev->managed.lock, flags);
+	list_for_each_entry(tmp, &dev->managed.resources, node.entry) {
+		if (tmp->node.release == action &&
+		    *(void **)&tmp->data == data) {
+			dr = tmp;
+			del_dr(dev, dr);
+			break;
+		}
+	}
+	spin_unlock_irqrestore(&dev->managed.lock, flags);
+
+	if (WARN_ON(!dr))
+		return;
+
+	kfree(dr);
+}
+EXPORT_SYMBOL(drmm_remove_action);
+
 void *drmm_kmalloc(struct drm_device *dev, size_t size, gfp_t gfp)
 {
 	struct drmres *dr;
diff --git a/include/drm/drm_managed.h b/include/drm/drm_managed.h
index 89e6fce9f689..5280209dff92 100644
--- a/include/drm/drm_managed.h
+++ b/include/drm/drm_managed.h
@@ -17,6 +17,10 @@ int __must_check __drmm_add_action(struct drm_device *dev,
 				   drmres_release_t action,
 				   void *data, const char *name);
 
+void drmm_remove_action(struct drm_device *dev,
+			drmres_release_t action,
+			void *data);
+
 void drmm_add_final_kfree(struct drm_device *dev, void *parent);
 
 void *drmm_kmalloc(struct drm_device *dev, size_t size, gfp_t gfp) __malloc;
-- 
2.24.1

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 111+ messages in thread

* [PATCH 23/51] drm: Manage drm_gem_init with drmm_
  2020-03-02 22:25 [PATCH 00/51] drm_device managed resources, v4 Daniel Vetter
                   ` (21 preceding siblings ...)
  2020-03-02 22:26 ` [PATCH 22/51] drm: manage drm_minor cleanup with drmm_ Daniel Vetter
@ 2020-03-02 22:26 ` Daniel Vetter
  2020-03-07  8:20   ` Sam Ravnborg
  2020-03-02 22:26 ` [PATCH 24/51] drm: Manage drm_vblank_cleanup " Daniel Vetter
                   ` (27 subsequent siblings)
  50 siblings, 1 reply; 111+ messages in thread
From: Daniel Vetter @ 2020-03-02 22:26 UTC (permalink / raw)
  To: DRI Development; +Cc: Daniel Vetter, Intel Graphics Development, Daniel Vetter

We might want to look into pushing this down into drm_mm_init, but
that would mean rolling out return codes to a pile of functions
unfortunately. So let's leave that for now.

Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
---
 drivers/gpu/drm/drm_drv.c      |  8 +-------
 drivers/gpu/drm/drm_gem.c      | 21 ++++++++++-----------
 drivers/gpu/drm/drm_internal.h |  1 -
 3 files changed, 11 insertions(+), 19 deletions(-)

diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c
index 29d106195ab3..9a646155dfc6 100644
--- a/drivers/gpu/drm/drm_drv.c
+++ b/drivers/gpu/drm/drm_drv.c
@@ -688,13 +688,10 @@ int drm_dev_init(struct drm_device *dev,
 
 	ret = drm_dev_set_unique(dev, dev_name(parent));
 	if (ret)
-		goto err_setunique;
+		goto err;
 
 	return 0;
 
-err_setunique:
-	if (drm_core_check_feature(dev, DRIVER_GEM))
-		drm_gem_destroy(dev);
 err:
 	drm_managed_release(dev);
 
@@ -756,9 +753,6 @@ EXPORT_SYMBOL(devm_drm_dev_init);
 void drm_dev_fini(struct drm_device *dev)
 {
 	drm_vblank_cleanup(dev);
-
-	if (drm_core_check_feature(dev, DRIVER_GEM))
-		drm_gem_destroy(dev);
 }
 EXPORT_SYMBOL(drm_dev_fini);
 
diff --git a/drivers/gpu/drm/drm_gem.c b/drivers/gpu/drm/drm_gem.c
index 0b6e6623735e..31095e0f6b9f 100644
--- a/drivers/gpu/drm/drm_gem.c
+++ b/drivers/gpu/drm/drm_gem.c
@@ -44,6 +44,7 @@
 #include <drm/drm_drv.h>
 #include <drm/drm_file.h>
 #include <drm/drm_gem.h>
+#include <drm/drm_managed.h>
 #include <drm/drm_print.h>
 #include <drm/drm_vma_manager.h>
 
@@ -77,6 +78,12 @@
  * up at a later date, and as our interface with shmfs for memory allocation.
  */
 
+static void
+drm_gem_init_release(struct drm_device *dev, void *ptr)
+{
+	drm_vma_offset_manager_destroy(dev->vma_offset_manager);
+}
+
 /**
  * drm_gem_init - Initialize the GEM device fields
  * @dev: drm_devic structure to initialize
@@ -89,7 +96,8 @@ drm_gem_init(struct drm_device *dev)
 	mutex_init(&dev->object_name_lock);
 	idr_init_base(&dev->object_name_idr, 1);
 
-	vma_offset_manager = kzalloc(sizeof(*vma_offset_manager), GFP_KERNEL);
+	vma_offset_manager = drmm_kzalloc(dev, sizeof(*vma_offset_manager),
+					  GFP_KERNEL);
 	if (!vma_offset_manager) {
 		DRM_ERROR("out of memory\n");
 		return -ENOMEM;
@@ -100,16 +108,7 @@ drm_gem_init(struct drm_device *dev)
 				    DRM_FILE_PAGE_OFFSET_START,
 				    DRM_FILE_PAGE_OFFSET_SIZE);
 
-	return 0;
-}
-
-void
-drm_gem_destroy(struct drm_device *dev)
-{
-
-	drm_vma_offset_manager_destroy(dev->vma_offset_manager);
-	kfree(dev->vma_offset_manager);
-	dev->vma_offset_manager = NULL;
+	return drmm_add_action(dev, drm_gem_init_release, NULL);
 }
 
 /**
diff --git a/drivers/gpu/drm/drm_internal.h b/drivers/gpu/drm/drm_internal.h
index 8c2628dfc6c7..cb09e95a795e 100644
--- a/drivers/gpu/drm/drm_internal.h
+++ b/drivers/gpu/drm/drm_internal.h
@@ -144,7 +144,6 @@ void drm_sysfs_lease_event(struct drm_device *dev);
 /* drm_gem.c */
 struct drm_gem_object;
 int drm_gem_init(struct drm_device *dev);
-void drm_gem_destroy(struct drm_device *dev);
 int drm_gem_handle_create_tail(struct drm_file *file_priv,
 			       struct drm_gem_object *obj,
 			       u32 *handlep);
-- 
2.24.1

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 111+ messages in thread

* [PATCH 24/51] drm: Manage drm_vblank_cleanup with drmm_
  2020-03-02 22:25 [PATCH 00/51] drm_device managed resources, v4 Daniel Vetter
                   ` (22 preceding siblings ...)
  2020-03-02 22:26 ` [PATCH 23/51] drm: Manage drm_gem_init " Daniel Vetter
@ 2020-03-02 22:26 ` Daniel Vetter
  2020-03-07  8:28   ` Sam Ravnborg
  2020-03-02 22:26 ` [PATCH 25/51] drm: Garbage collect drm_dev_fini Daniel Vetter
                   ` (26 subsequent siblings)
  50 siblings, 1 reply; 111+ messages in thread
From: Daniel Vetter @ 2020-03-02 22:26 UTC (permalink / raw)
  To: DRI Development; +Cc: Daniel Vetter, Intel Graphics Development, Daniel Vetter

Nothing special here, except that this is the first time that we
automatically clean up something that's initialized with an explicit
driver call. But the cleanup was done at the very of the release
sequence for all drivers, and that's still the case. At least without
more uses of drmm_ through explicit driver calls.

Also for this one we need drmm_kcalloc, so lets add those

v2: Sort includes (Laurent)

Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
---
 drivers/gpu/drm/drm_drv.c      |  1 -
 drivers/gpu/drm/drm_internal.h |  1 -
 drivers/gpu/drm/drm_vblank.c   | 31 ++++++++++++-------------------
 include/drm/drm_managed.h      | 16 ++++++++++++++++
 4 files changed, 28 insertions(+), 21 deletions(-)

diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c
index 9a646155dfc6..90b6ae81d431 100644
--- a/drivers/gpu/drm/drm_drv.c
+++ b/drivers/gpu/drm/drm_drv.c
@@ -752,7 +752,6 @@ EXPORT_SYMBOL(devm_drm_dev_init);
  */
 void drm_dev_fini(struct drm_device *dev)
 {
-	drm_vblank_cleanup(dev);
 }
 EXPORT_SYMBOL(drm_dev_fini);
 
diff --git a/drivers/gpu/drm/drm_internal.h b/drivers/gpu/drm/drm_internal.h
index cb09e95a795e..e67015d07c4c 100644
--- a/drivers/gpu/drm/drm_internal.h
+++ b/drivers/gpu/drm/drm_internal.h
@@ -94,7 +94,6 @@ void drm_managed_release(struct drm_device *dev);
 
 /* drm_vblank.c */
 void drm_vblank_disable_and_save(struct drm_device *dev, unsigned int pipe);
-void drm_vblank_cleanup(struct drm_device *dev);
 
 /* IOCTLS */
 int drm_wait_vblank_ioctl(struct drm_device *dev, void *data,
diff --git a/drivers/gpu/drm/drm_vblank.c b/drivers/gpu/drm/drm_vblank.c
index 47fc4339ec7f..5a6ec8aa0873 100644
--- a/drivers/gpu/drm/drm_vblank.c
+++ b/drivers/gpu/drm/drm_vblank.c
@@ -30,6 +30,7 @@
 #include <drm/drm_crtc.h>
 #include <drm/drm_drv.h>
 #include <drm/drm_framebuffer.h>
+#include <drm/drm_managed.h>
 #include <drm/drm_modeset_helper_vtables.h>
 #include <drm/drm_print.h>
 #include <drm/drm_vblank.h>
@@ -425,14 +426,10 @@ static void vblank_disable_fn(struct timer_list *t)
 	spin_unlock_irqrestore(&dev->vbl_lock, irqflags);
 }
 
-void drm_vblank_cleanup(struct drm_device *dev)
+static void drm_vblank_init_release(struct drm_device *dev, void *ptr)
 {
 	unsigned int pipe;
 
-	/* Bail if the driver didn't call drm_vblank_init() */
-	if (dev->num_crtcs == 0)
-		return;
-
 	for (pipe = 0; pipe < dev->num_crtcs; pipe++) {
 		struct drm_vblank_crtc *vblank = &dev->vblank[pipe];
 
@@ -441,10 +438,6 @@ void drm_vblank_cleanup(struct drm_device *dev)
 
 		del_timer_sync(&vblank->disable_timer);
 	}
-
-	kfree(dev->vblank);
-
-	dev->num_crtcs = 0;
 }
 
 /**
@@ -453,25 +446,29 @@ void drm_vblank_cleanup(struct drm_device *dev)
  * @num_crtcs: number of CRTCs supported by @dev
  *
  * This function initializes vblank support for @num_crtcs display pipelines.
- * Cleanup is handled by the DRM core, or through calling drm_dev_fini() for
- * drivers with a &drm_driver.release callback.
+ * Cleanup is handled automatically through a cleanup function added with
+ * drmm_add_action().
  *
  * Returns:
  * Zero on success or a negative error code on failure.
  */
 int drm_vblank_init(struct drm_device *dev, unsigned int num_crtcs)
 {
-	int ret = -ENOMEM;
+	int ret;
 	unsigned int i;
 
 	spin_lock_init(&dev->vbl_lock);
 	spin_lock_init(&dev->vblank_time_lock);
 
+	dev->vblank = drmm_kcalloc(dev, num_crtcs, sizeof(*dev->vblank), GFP_KERNEL);
+	if (!dev->vblank)
+		return -ENOMEM;
+
 	dev->num_crtcs = num_crtcs;
 
-	dev->vblank = kcalloc(num_crtcs, sizeof(*dev->vblank), GFP_KERNEL);
-	if (!dev->vblank)
-		goto err;
+	ret = drmm_add_action(dev, drm_vblank_init_release, NULL);
+	if (ret)
+		return ret;
 
 	for (i = 0; i < num_crtcs; i++) {
 		struct drm_vblank_crtc *vblank = &dev->vblank[i];
@@ -486,10 +483,6 @@ int drm_vblank_init(struct drm_device *dev, unsigned int num_crtcs)
 	DRM_INFO("Supports vblank timestamp caching Rev 2 (21.10.2013).\n");
 
 	return 0;
-
-err:
-	dev->num_crtcs = 0;
-	return ret;
 }
 EXPORT_SYMBOL(drm_vblank_init);
 
diff --git a/include/drm/drm_managed.h b/include/drm/drm_managed.h
index 5280209dff92..2b1ba2ad5582 100644
--- a/include/drm/drm_managed.h
+++ b/include/drm/drm_managed.h
@@ -4,6 +4,7 @@
 #define _DRM_MANAGED_H_
 
 #include <linux/gfp.h>
+#include <linux/overflow.h>
 #include <linux/types.h>
 
 struct drm_device;
@@ -28,6 +29,21 @@ static inline void *drmm_kzalloc(struct drm_device *dev, size_t size, gfp_t gfp)
 {
 	return drmm_kmalloc(dev, size, gfp | __GFP_ZERO);
 }
+static inline void *drmm_kmalloc_array(struct drm_device *dev,
+				       size_t n, size_t size, gfp_t flags)
+{
+	size_t bytes;
+
+	if (unlikely(check_mul_overflow(n, size, &bytes)))
+		return NULL;
+
+	return drmm_kmalloc(dev, bytes, flags);
+}
+static inline void *drmm_kcalloc(struct drm_device *dev,
+				 size_t n, size_t size, gfp_t flags)
+{
+	return drmm_kmalloc_array(dev, n, size, flags | __GFP_ZERO);
+}
 char *drmm_kstrdup(struct drm_device *dev, const char *s, gfp_t gfp);
 
 void drmm_kfree(struct drm_device *dev, void *data);
-- 
2.24.1

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 111+ messages in thread

* [PATCH 25/51] drm: Garbage collect drm_dev_fini
  2020-03-02 22:25 [PATCH 00/51] drm_device managed resources, v4 Daniel Vetter
                   ` (23 preceding siblings ...)
  2020-03-02 22:26 ` [PATCH 24/51] drm: Manage drm_vblank_cleanup " Daniel Vetter
@ 2020-03-02 22:26 ` Daniel Vetter
  2020-03-07  8:30   ` Sam Ravnborg
  2020-03-02 22:26 ` [PATCH 26/51] drm: Manage drm_mode_config_init with drmm_ Daniel Vetter
                   ` (25 subsequent siblings)
  50 siblings, 1 reply; 111+ messages in thread
From: Daniel Vetter @ 2020-03-02 22:26 UTC (permalink / raw)
  To: DRI Development; +Cc: Daniel Vetter, Intel Graphics Development, Daniel Vetter

It has become empty. Given the few users I figured not much point
splitting this up.

v2: Rebase over i915 changes.

Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
---
 drivers/gpu/drm/cirrus/cirrus.c               |  1 -
 drivers/gpu/drm/drm_drv.c                     | 23 +------------------
 drivers/gpu/drm/drm_mipi_dbi.c                |  1 -
 drivers/gpu/drm/i915/i915_drv.c               |  9 --------
 .../gpu/drm/i915/selftests/mock_gem_device.c  |  2 --
 drivers/gpu/drm/ingenic/ingenic-drm.c         |  1 -
 drivers/gpu/drm/mcde/mcde_drv.c               |  1 -
 drivers/gpu/drm/tidss/tidss_drv.c             |  2 --
 drivers/gpu/drm/tiny/gm12u320.c               |  1 -
 drivers/gpu/drm/tiny/repaper.c                |  1 -
 drivers/gpu/drm/udl/udl_drv.c                 |  1 -
 drivers/gpu/drm/vgem/vgem_drv.c               |  1 -
 drivers/gpu/drm/vkms/vkms_drv.c               |  1 -
 drivers/gpu/drm/xen/xen_drm_front.c           |  2 --
 include/drm/drm_drv.h                         |  5 +---
 15 files changed, 2 insertions(+), 50 deletions(-)

diff --git a/drivers/gpu/drm/cirrus/cirrus.c b/drivers/gpu/drm/cirrus/cirrus.c
index 2232556ce34c..a9d789a56536 100644
--- a/drivers/gpu/drm/cirrus/cirrus.c
+++ b/drivers/gpu/drm/cirrus/cirrus.c
@@ -529,7 +529,6 @@ static void cirrus_mode_config_init(struct cirrus_device *cirrus)
 static void cirrus_release(struct drm_device *dev)
 {
 	drm_mode_config_cleanup(dev);
-	drm_dev_fini(dev);
 }
 
 DEFINE_DRM_GEM_FOPS(cirrus_fops);
diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c
index 90b6ae81d431..c709a0ce018c 100644
--- a/drivers/gpu/drm/drm_drv.c
+++ b/drivers/gpu/drm/drm_drv.c
@@ -283,7 +283,6 @@ void drm_minor_release(struct drm_minor *minor)
  *		struct driver_device *priv = container_of(...);
  *
  *		drm_mode_config_cleanup(drm);
- *		drm_dev_fini(drm);
  *	}
  *
  *	static struct drm_driver driver_drm_driver = {
@@ -738,23 +737,6 @@ int devm_drm_dev_init(struct device *parent,
 }
 EXPORT_SYMBOL(devm_drm_dev_init);
 
-/**
- * drm_dev_fini - Finalize a dead DRM device
- * @dev: DRM device
- *
- * Finalize a dead DRM device. This is the converse to drm_dev_init() and
- * frees up all data allocated by it. All driver private data should be
- * finalized first. Note that this function does not free the @dev, that is
- * left to the caller.
- *
- * The ref-count of @dev must be zero, and drm_dev_fini() should only be called
- * from a &drm_driver.release callback.
- */
-void drm_dev_fini(struct drm_device *dev)
-{
-}
-EXPORT_SYMBOL(drm_dev_fini);
-
 /**
  * drm_dev_alloc - Allocate new DRM device
  * @driver: DRM driver to allocate device for
@@ -803,11 +785,8 @@ static void drm_dev_release(struct kref *ref)
 {
 	struct drm_device *dev = container_of(ref, struct drm_device, ref);
 
-	if (dev->driver->release) {
+	if (dev->driver->release)
 		dev->driver->release(dev);
-	} else {
-		drm_dev_fini(dev);
-	}
 
 	drm_managed_release(dev);
 
diff --git a/drivers/gpu/drm/drm_mipi_dbi.c b/drivers/gpu/drm/drm_mipi_dbi.c
index 069603dfcd10..a678e07508d4 100644
--- a/drivers/gpu/drm/drm_mipi_dbi.c
+++ b/drivers/gpu/drm/drm_mipi_dbi.c
@@ -591,7 +591,6 @@ void mipi_dbi_release(struct drm_device *drm)
 	DRM_DEBUG_DRIVER("\n");
 
 	drm_mode_config_cleanup(drm);
-	drm_dev_fini(drm);
 }
 EXPORT_SYMBOL(mipi_dbi_release);
 
diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
index bb14209beeed..ff24ca5df7ed 100644
--- a/drivers/gpu/drm/i915/i915_drv.c
+++ b/drivers/gpu/drm/i915/i915_drv.c
@@ -911,13 +911,6 @@ i915_driver_create(struct pci_dev *pdev, const struct pci_device_id *ent)
 	return i915;
 }
 
-static void i915_driver_destroy(struct drm_i915_private *i915)
-{
-	struct pci_dev *pdev = i915->drm.pdev;
-
-	drm_dev_fini(&i915->drm);
-}
-
 /**
  * i915_driver_probe - setup chip and create an initial config
  * @pdev: PCI device
@@ -1020,7 +1013,6 @@ int i915_driver_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 	pci_disable_device(pdev);
 out_fini:
 	i915_probe_error(i915, "Device initialization failed (%d)\n", ret);
-	i915_driver_destroy(i915);
 	drm_dev_put(&i915->drm);
 	return ret;
 }
@@ -1077,7 +1069,6 @@ static void i915_driver_release(struct drm_device *dev)
 	intel_runtime_pm_driver_release(rpm);
 
 	i915_driver_late_release(dev_priv);
-	i915_driver_destroy(dev_priv);
 }
 
 static int i915_driver_open(struct drm_device *dev, struct drm_file *file)
diff --git a/drivers/gpu/drm/i915/selftests/mock_gem_device.c b/drivers/gpu/drm/i915/selftests/mock_gem_device.c
index acf889e4b993..2b4407ac26de 100644
--- a/drivers/gpu/drm/i915/selftests/mock_gem_device.c
+++ b/drivers/gpu/drm/i915/selftests/mock_gem_device.c
@@ -76,7 +76,6 @@ static void mock_device_release(struct drm_device *dev)
 
 	drm_mode_config_cleanup(&i915->drm);
 
-	drm_dev_fini(&i915->drm);
 out:
 	put_device(&i915->drm.pdev->dev);
 	i915->drm.pdev = NULL;
@@ -215,7 +214,6 @@ struct drm_i915_private *mock_gem_device(void)
 	intel_gt_driver_late_release(&i915->gt);
 	intel_memory_regions_driver_release(i915);
 	drm_mode_config_cleanup(&i915->drm);
-	drm_dev_fini(&i915->drm);
 	drm_dev_put(&i915->drm);
 
 	return NULL;
diff --git a/drivers/gpu/drm/ingenic/ingenic-drm.c b/drivers/gpu/drm/ingenic/ingenic-drm.c
index e2c832eb4e9a..192aaa4421a3 100644
--- a/drivers/gpu/drm/ingenic/ingenic-drm.c
+++ b/drivers/gpu/drm/ingenic/ingenic-drm.c
@@ -492,7 +492,6 @@ static irqreturn_t ingenic_drm_irq_handler(int irq, void *arg)
 static void ingenic_drm_release(struct drm_device *drm)
 {
 	drm_mode_config_cleanup(drm);
-	drm_dev_fini(drm);
 }
 
 static int ingenic_drm_enable_vblank(struct drm_crtc *crtc)
diff --git a/drivers/gpu/drm/mcde/mcde_drv.c b/drivers/gpu/drm/mcde/mcde_drv.c
index 7474481503a1..a543ebf3d541 100644
--- a/drivers/gpu/drm/mcde/mcde_drv.c
+++ b/drivers/gpu/drm/mcde/mcde_drv.c
@@ -223,7 +223,6 @@ static void mcde_release(struct drm_device *drm)
 	struct mcde *mcde = drm->dev_private;
 
 	drm_mode_config_cleanup(drm);
-	drm_dev_fini(drm);
 }
 
 DEFINE_DRM_GEM_CMA_FOPS(drm_fops);
diff --git a/drivers/gpu/drm/tidss/tidss_drv.c b/drivers/gpu/drm/tidss/tidss_drv.c
index 32a85628dbec..460d5e9d0cf4 100644
--- a/drivers/gpu/drm/tidss/tidss_drv.c
+++ b/drivers/gpu/drm/tidss/tidss_drv.c
@@ -108,8 +108,6 @@ static void tidss_release(struct drm_device *ddev)
 	drm_kms_helper_poll_fini(ddev);
 
 	tidss_modeset_cleanup(tidss);
-
-	drm_dev_fini(ddev);
 }
 
 DEFINE_DRM_GEM_CMA_FOPS(tidss_fops);
diff --git a/drivers/gpu/drm/tiny/gm12u320.c b/drivers/gpu/drm/tiny/gm12u320.c
index 524ca0941cf9..3928f69bbd3d 100644
--- a/drivers/gpu/drm/tiny/gm12u320.c
+++ b/drivers/gpu/drm/tiny/gm12u320.c
@@ -637,7 +637,6 @@ static void gm12u320_driver_release(struct drm_device *dev)
 
 	gm12u320_usb_free(gm12u320);
 	drm_mode_config_cleanup(dev);
-	drm_dev_fini(dev);
 }
 
 DEFINE_DRM_GEM_FOPS(gm12u320_fops);
diff --git a/drivers/gpu/drm/tiny/repaper.c b/drivers/gpu/drm/tiny/repaper.c
index df5654ef53ee..4741ff670ec9 100644
--- a/drivers/gpu/drm/tiny/repaper.c
+++ b/drivers/gpu/drm/tiny/repaper.c
@@ -914,7 +914,6 @@ static void repaper_release(struct drm_device *drm)
 	DRM_DEBUG_DRIVER("\n");
 
 	drm_mode_config_cleanup(drm);
-	drm_dev_fini(drm);
 }
 
 static const uint32_t repaper_formats[] = {
diff --git a/drivers/gpu/drm/udl/udl_drv.c b/drivers/gpu/drm/udl/udl_drv.c
index 6a5594946096..8b78c356beb5 100644
--- a/drivers/gpu/drm/udl/udl_drv.c
+++ b/drivers/gpu/drm/udl/udl_drv.c
@@ -38,7 +38,6 @@ static void udl_driver_release(struct drm_device *dev)
 {
 	udl_fini(dev);
 	udl_modeset_cleanup(dev);
-	drm_dev_fini(dev);
 }
 
 static struct drm_driver driver = {
diff --git a/drivers/gpu/drm/vgem/vgem_drv.c b/drivers/gpu/drm/vgem/vgem_drv.c
index 7486014e9149..ec1a8ebb6f1b 100644
--- a/drivers/gpu/drm/vgem/vgem_drv.c
+++ b/drivers/gpu/drm/vgem/vgem_drv.c
@@ -432,7 +432,6 @@ static void vgem_release(struct drm_device *dev)
 	struct vgem_device *vgem = container_of(dev, typeof(*vgem), drm);
 
 	platform_device_unregister(vgem->platform);
-	drm_dev_fini(&vgem->drm);
 }
 
 static struct drm_driver vgem_driver = {
diff --git a/drivers/gpu/drm/vkms/vkms_drv.c b/drivers/gpu/drm/vkms/vkms_drv.c
index 2f35fe789343..eef85f1a0ce5 100644
--- a/drivers/gpu/drm/vkms/vkms_drv.c
+++ b/drivers/gpu/drm/vkms/vkms_drv.c
@@ -64,7 +64,6 @@ static void vkms_release(struct drm_device *dev)
 	platform_device_unregister(vkms->platform);
 	drm_atomic_helper_shutdown(&vkms->drm);
 	drm_mode_config_cleanup(&vkms->drm);
-	drm_dev_fini(&vkms->drm);
 	destroy_workqueue(vkms->output.composer_workq);
 }
 
diff --git a/drivers/gpu/drm/xen/xen_drm_front.c b/drivers/gpu/drm/xen/xen_drm_front.c
index d22b5da38935..b91d23b5f3ae 100644
--- a/drivers/gpu/drm/xen/xen_drm_front.c
+++ b/drivers/gpu/drm/xen/xen_drm_front.c
@@ -460,8 +460,6 @@ static void xen_drm_drv_release(struct drm_device *dev)
 	drm_atomic_helper_shutdown(dev);
 	drm_mode_config_cleanup(dev);
 
-	drm_dev_fini(dev);
-
 	if (front_info->cfg.be_alloc)
 		xenbus_switch_state(front_info->xb_dev,
 				    XenbusStateInitialising);
diff --git a/include/drm/drm_drv.h b/include/drm/drm_drv.h
index cbd050419ab8..edee40e31e4b 100644
--- a/include/drm/drm_drv.h
+++ b/include/drm/drm_drv.h
@@ -265,9 +265,7 @@ struct drm_driver {
 	 * @release:
 	 *
 	 * Optional callback for destroying device data after the final
-	 * reference is released, i.e. the device is being destroyed. Drivers
-	 * using this callback are responsible for calling drm_dev_fini()
-	 * to finalize the device and then freeing the struct themselves.
+	 * reference is released, i.e. the device is being destroyed.
 	 */
 	void (*release) (struct drm_device *);
 
@@ -623,7 +621,6 @@ int drm_dev_init(struct drm_device *dev,
 int devm_drm_dev_init(struct device *parent,
 		      struct drm_device *dev,
 		      struct drm_driver *driver);
-void drm_dev_fini(struct drm_device *dev);
 
 struct drm_device *drm_dev_alloc(struct drm_driver *driver,
 				 struct device *parent);
-- 
2.24.1

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 111+ messages in thread

* [PATCH 26/51] drm: Manage drm_mode_config_init with drmm_
  2020-03-02 22:25 [PATCH 00/51] drm_device managed resources, v4 Daniel Vetter
                   ` (24 preceding siblings ...)
  2020-03-02 22:26 ` [PATCH 25/51] drm: Garbage collect drm_dev_fini Daniel Vetter
@ 2020-03-02 22:26 ` Daniel Vetter
  2020-03-06 20:04   ` Sam Ravnborg
  2020-03-02 22:26 ` [PATCH 27/51] drm/bochs: Remove leftover drm_atomic_helper_shutdown Daniel Vetter
                   ` (24 subsequent siblings)
  50 siblings, 1 reply; 111+ messages in thread
From: Daniel Vetter @ 2020-03-02 22:26 UTC (permalink / raw)
  To: DRI Development
  Cc: Daniel Vetter, Intel Graphics Development, Laurent Pinchart,
	Thomas Zimmermann, Daniel Vetter, Sam Ravnborg

drm_mode_config_cleanup is idempotent, so no harm in calling this
twice. This allows us to gradually switch drivers over by removing
explicit drm_mode_config_cleanup calls.

With this step it's now also possible that (at least for simple
drivers) automatic resource cleanup can be done correctly without a
drm_driver->release hook. Therefore allow this now in
devm_drm_dev_init().

Also with drmm_ explicit drm_driver->release hooks are kinda not the
best option: Drivers can always just register their current release
hook with drmm_add_action, but even better they could split them up to
simplify the unwinding for the driver load failure case. So deprecate
that hook to discourage future users.

v2: Fixup the example in the kerneldoc too.

v3:
- For paranoia, double check that minor->dev == dev in the release
  hook, because I botched the pointer math in the drmm library.
- Call drm_mode_config_cleanup when drmm_add_action fails, we'd be
  missing some mutex_destroy and ida_cleanup otherwise (Laurent)

v4: Add a drmm_add_action_or_reset (like devm_ has) to encapsulate this
pattern (Noralf).

v5: Fix oversight in the new drmm_add_action_or_reset macro (Noralf)

v4: Review from Sam:
- drmm_mode_config_init wrapper (also suggested by Thomas)
- improve commit message, explain better why ->relase is deprecated

Cc: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Cc: "Noralf Trønnes" <noralf@tronnes.org>
Cc: Sam Ravnborg <sam@ravnborg.org>
Cc: Thomas Zimmermann <tzimmermann@suse.de>
Acked-by: Noralf Trønnes <noralf@tronnes.org>
Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
---
 drivers/gpu/drm/drm_drv.c         | 23 +++++++----------------
 drivers/gpu/drm/drm_managed.c     | 14 ++++++++++++++
 drivers/gpu/drm/drm_mode_config.c | 13 ++++++++++++-
 include/drm/drm_managed.h         |  7 +++++++
 include/drm/drm_mode_config.h     | 19 ++++++++++++++++++-
 5 files changed, 58 insertions(+), 18 deletions(-)

diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c
index c709a0ce018c..a82702d0c2fb 100644
--- a/drivers/gpu/drm/drm_drv.c
+++ b/drivers/gpu/drm/drm_drv.c
@@ -98,6 +98,8 @@ static void drm_minor_alloc_release(struct drm_device *dev, void *data)
 	struct drm_minor *minor = data;
 	unsigned long flags;
 
+	WARN_ON(dev != minor->dev);
+
 	put_device(minor->kdev);
 
 	spin_lock_irqsave(&drm_minor_lock, flags);
@@ -267,8 +269,7 @@ void drm_minor_release(struct drm_minor *minor)
  *
  * The following example shows a typical structure of a DRM display driver.
  * The example focus on the probe() function and the other functions that is
- * almost always present and serves as a demonstration of devm_drm_dev_init()
- * usage with its accompanying drm_driver->release callback.
+ * almost always present and serves as a demonstration of devm_drm_dev_init().
  *
  * .. code-block:: c
  *
@@ -278,16 +279,8 @@ void drm_minor_release(struct drm_minor *minor)
  *		struct clk *pclk;
  *	};
  *
- *	static void driver_drm_release(struct drm_device *drm)
- *	{
- *		struct driver_device *priv = container_of(...);
- *
- *		drm_mode_config_cleanup(drm);
- *	}
- *
  *	static struct drm_driver driver_drm_driver = {
  *		[...]
- *		.release = driver_drm_release,
  *	};
  *
  *	static int driver_probe(struct platform_device *pdev)
@@ -312,7 +305,9 @@ void drm_minor_release(struct drm_minor *minor)
  *		}
  *		drmm_add_final_kfree(drm, priv);
  *
- *		drm_mode_config_init(drm);
+ *		ret = drm_mode_config_init(drm);
+ *		if (ret)
+ *			return ret;
  *
  *		priv->userspace_facing = drmm_kzalloc(..., GFP_KERNEL);
  *		if (!priv->userspace_facing)
@@ -710,8 +705,7 @@ static void devm_drm_dev_init_release(void *data)
  * @driver: DRM driver
  *
  * Managed drm_dev_init(). The DRM device initialized with this function is
- * automatically put on driver detach using drm_dev_put(). You must supply a
- * &drm_driver.release callback to control the finalization explicitly.
+ * automatically put on driver detach using drm_dev_put().
  *
  * RETURNS:
  * 0 on success, or error code on failure.
@@ -722,9 +716,6 @@ int devm_drm_dev_init(struct device *parent,
 {
 	int ret;
 
-	if (WARN_ON(!driver->release))
-		return -EINVAL;
-
 	ret = drm_dev_init(dev, driver, parent);
 	if (ret)
 		return ret;
diff --git a/drivers/gpu/drm/drm_managed.c b/drivers/gpu/drm/drm_managed.c
index 0883615c2088..8c5f1f03c485 100644
--- a/drivers/gpu/drm/drm_managed.c
+++ b/drivers/gpu/drm/drm_managed.c
@@ -142,6 +142,20 @@ int __drmm_add_action(struct drm_device *dev,
 }
 EXPORT_SYMBOL(__drmm_add_action);
 
+int __drmm_add_action_or_reset(struct drm_device *dev,
+			       drmres_release_t action,
+			       void *data, const char *name)
+{
+	int ret;
+
+	ret = __drmm_add_action(dev, action, data, name);
+	if (ret)
+		action(dev, data);
+
+	return ret;
+}
+EXPORT_SYMBOL(__drmm_add_action_or_reset);
+
 void drmm_remove_action(struct drm_device *dev,
 			drmres_release_t action,
 			void *data)
diff --git a/drivers/gpu/drm/drm_mode_config.c b/drivers/gpu/drm/drm_mode_config.c
index 08e6eff6a179..6f7005bc597f 100644
--- a/drivers/gpu/drm/drm_mode_config.c
+++ b/drivers/gpu/drm/drm_mode_config.c
@@ -25,6 +25,7 @@
 #include <drm/drm_drv.h>
 #include <drm/drm_encoder.h>
 #include <drm/drm_file.h>
+#include <drm/drm_managed.h>
 #include <drm/drm_mode_config.h>
 #include <drm/drm_print.h>
 #include <linux/dma-resv.h>
@@ -373,6 +374,11 @@ static int drm_mode_create_standard_properties(struct drm_device *dev)
 	return 0;
 }
 
+static void drm_mode_config_init_release(struct drm_device *dev, void *ptr)
+{
+	drm_mode_config_cleanup(dev);
+}
+
 /**
  * drm_mode_config_init - initialize DRM mode_configuration structure
  * @dev: DRM device
@@ -384,8 +390,10 @@ static int drm_mode_create_standard_properties(struct drm_device *dev)
  * problem, since this should happen single threaded at init time. It is the
  * driver's problem to ensure this guarantee.
  *
+ * Cleanup is automatically handled through registering drm_mode_config_cleanup
+ * with drmm_add_action().
  */
-void drm_mode_config_init(struct drm_device *dev)
+int drm_mode_config_init(struct drm_device *dev)
 {
 	mutex_init(&dev->mode_config.mutex);
 	drm_modeset_lock_init(&dev->mode_config.connection_mutex);
@@ -443,6 +451,9 @@ void drm_mode_config_init(struct drm_device *dev)
 		drm_modeset_acquire_fini(&modeset_ctx);
 		dma_resv_fini(&resv);
 	}
+
+	return drmm_add_action_or_reset(dev, drm_mode_config_init_release,
+					NULL);
 }
 EXPORT_SYMBOL(drm_mode_config_init);
 
diff --git a/include/drm/drm_managed.h b/include/drm/drm_managed.h
index 2b1ba2ad5582..1e6291407586 100644
--- a/include/drm/drm_managed.h
+++ b/include/drm/drm_managed.h
@@ -18,6 +18,13 @@ int __must_check __drmm_add_action(struct drm_device *dev,
 				   drmres_release_t action,
 				   void *data, const char *name);
 
+#define drmm_add_action_or_reset(dev, action, data) \
+	__drmm_add_action_or_reset(dev, action, data, #action)
+
+int __must_check __drmm_add_action_or_reset(struct drm_device *dev,
+					    drmres_release_t action,
+					    void *data, const char *name);
+
 void drmm_remove_action(struct drm_device *dev,
 			drmres_release_t action,
 			void *data);
diff --git a/include/drm/drm_mode_config.h b/include/drm/drm_mode_config.h
index 3bcbe30339f0..aa6288bf04df 100644
--- a/include/drm/drm_mode_config.h
+++ b/include/drm/drm_mode_config.h
@@ -929,7 +929,24 @@ struct drm_mode_config {
 	const struct drm_mode_config_helper_funcs *helper_private;
 };
 
-void drm_mode_config_init(struct drm_device *dev);
+int drm_mode_config_init(struct drm_device *dev);
+
+/**
+ * drmm_mode_config_init - managed DRM mode_configuration structure
+ * 	initialization
+ * @dev: DRM device
+ *
+ * This is a managed version of drm_mode_config_init(). The only difference is
+ * that this version is annotated with __must_check, to make sure that drivers
+ * can actually rely on the automatic cleanup.
+ *
+ * Returns: 0 on success, negative error value on failure.
+ */
+static inline __must_check int drmm_mode_config_init(struct drm_device *dev)
+{
+	return drm_mode_config_init(dev);
+}
+
 void drm_mode_config_reset(struct drm_device *dev);
 void drm_mode_config_cleanup(struct drm_device *dev);
 
-- 
2.24.1

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 111+ messages in thread

* [PATCH 27/51] drm/bochs: Remove leftover drm_atomic_helper_shutdown
  2020-03-02 22:25 [PATCH 00/51] drm_device managed resources, v4 Daniel Vetter
                   ` (25 preceding siblings ...)
  2020-03-02 22:26 ` [PATCH 26/51] drm: Manage drm_mode_config_init with drmm_ Daniel Vetter
@ 2020-03-02 22:26 ` Daniel Vetter
  2020-03-03  7:49   ` Gerd Hoffmann
  2020-03-02 22:26 ` [PATCH 28/51] drm/bochs: Drop explicit drm_mode_config_cleanup Daniel Vetter
                   ` (23 subsequent siblings)
  50 siblings, 1 reply; 111+ messages in thread
From: Daniel Vetter @ 2020-03-02 22:26 UTC (permalink / raw)
  To: DRI Development
  Cc: Daniel Vetter, Intel Graphics Development, Gerd Hoffmann, Daniel Vetter

Small mistake that crept into

commit 81da8c3b8d3df6f05b11300b7d17ccd1f3017fab
Author: Gerd Hoffmann <kraxel@redhat.com>
Date:   Tue Feb 11 14:52:18 2020 +0100

    drm/bochs: add drm_driver.release callback

where drm_atomic_helper_shutdown was left in both places. The
->release callback really shouldn't touch hardware.

Cc: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
---
 drivers/gpu/drm/bochs/bochs_kms.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/drivers/gpu/drm/bochs/bochs_kms.c b/drivers/gpu/drm/bochs/bochs_kms.c
index 8066d7d370d5..e8cc8156d773 100644
--- a/drivers/gpu/drm/bochs/bochs_kms.c
+++ b/drivers/gpu/drm/bochs/bochs_kms.c
@@ -166,6 +166,5 @@ void bochs_kms_fini(struct bochs_device *bochs)
 	if (!bochs->dev->mode_config.num_connector)
 		return;
 
-	drm_atomic_helper_shutdown(bochs->dev);
 	drm_mode_config_cleanup(bochs->dev);
 }
-- 
2.24.1

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 111+ messages in thread

* [PATCH 28/51] drm/bochs: Drop explicit drm_mode_config_cleanup
  2020-03-02 22:25 [PATCH 00/51] drm_device managed resources, v4 Daniel Vetter
                   ` (26 preceding siblings ...)
  2020-03-02 22:26 ` [PATCH 27/51] drm/bochs: Remove leftover drm_atomic_helper_shutdown Daniel Vetter
@ 2020-03-02 22:26 ` Daniel Vetter
  2020-03-03  7:50   ` Gerd Hoffmann
  2020-03-06 20:14   ` Sam Ravnborg
  2020-03-02 22:26 ` [PATCH 29/51] drm/cirrus: Drop explicit drm_mode_config_cleanup call Daniel Vetter
                   ` (22 subsequent siblings)
  50 siblings, 2 replies; 111+ messages in thread
From: Daniel Vetter @ 2020-03-02 22:26 UTC (permalink / raw)
  To: DRI Development
  Cc: Daniel Vetter, Intel Graphics Development, virtualization,
	Laurent Pinchart, Thomas Zimmermann, Daniel Vetter, Sam Ravnborg,
	Gerd Hoffmann

Instead rely on the automatic clean, for which we just need to check
that drm_mode_config_init succeeded. To avoid an inversion in the
cleanup we also have to move the dev_private allocation over to
drmm_kzalloc.

This is made possible by a preceeding patch which added a drmm_
cleanup action to drm_mode_config_init(), hence all we need to do to
ensure that drm_mode_config_cleanup() is run on final drm_device
cleanup is check the new error code for _init().

v2: Explain why this cleanup is possible (Laurent).

v3: Use drmm_mode_config_init() for more clarity (Sam, Thomas)

Cc: Sam Ravnborg <sam@ravnborg.org>
Cc: Thomas Zimmermann <tzimmermann@suse.de>
Cc: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
Cc: Gerd Hoffmann <kraxel@redhat.com>
Cc: virtualization@lists.linux-foundation.org
---
 drivers/gpu/drm/bochs/bochs.h     |  1 -
 drivers/gpu/drm/bochs/bochs_drv.c |  6 ++----
 drivers/gpu/drm/bochs/bochs_kms.c | 14 +++++---------
 3 files changed, 7 insertions(+), 14 deletions(-)

diff --git a/drivers/gpu/drm/bochs/bochs.h b/drivers/gpu/drm/bochs/bochs.h
index 917767173ee6..e5bd1d517a18 100644
--- a/drivers/gpu/drm/bochs/bochs.h
+++ b/drivers/gpu/drm/bochs/bochs.h
@@ -92,7 +92,6 @@ void bochs_mm_fini(struct bochs_device *bochs);
 
 /* bochs_kms.c */
 int bochs_kms_init(struct bochs_device *bochs);
-void bochs_kms_fini(struct bochs_device *bochs);
 
 /* bochs_fbdev.c */
 extern const struct drm_mode_config_funcs bochs_mode_funcs;
diff --git a/drivers/gpu/drm/bochs/bochs_drv.c b/drivers/gpu/drm/bochs/bochs_drv.c
index addb0568c1af..e18c51de1196 100644
--- a/drivers/gpu/drm/bochs/bochs_drv.c
+++ b/drivers/gpu/drm/bochs/bochs_drv.c
@@ -7,6 +7,7 @@
 
 #include <drm/drm_drv.h>
 #include <drm/drm_atomic_helper.h>
+#include <drm/drm_managed.h>
 
 #include "bochs.h"
 
@@ -21,10 +22,7 @@ static void bochs_unload(struct drm_device *dev)
 {
 	struct bochs_device *bochs = dev->dev_private;
 
-	bochs_kms_fini(bochs);
 	bochs_mm_fini(bochs);
-	kfree(bochs);
-	dev->dev_private = NULL;
 }
 
 static int bochs_load(struct drm_device *dev)
@@ -32,7 +30,7 @@ static int bochs_load(struct drm_device *dev)
 	struct bochs_device *bochs;
 	int ret;
 
-	bochs = kzalloc(sizeof(*bochs), GFP_KERNEL);
+	bochs = drmm_kzalloc(dev, sizeof(*bochs), GFP_KERNEL);
 	if (bochs == NULL)
 		return -ENOMEM;
 	dev->dev_private = bochs;
diff --git a/drivers/gpu/drm/bochs/bochs_kms.c b/drivers/gpu/drm/bochs/bochs_kms.c
index e8cc8156d773..7f4bcfad87e9 100644
--- a/drivers/gpu/drm/bochs/bochs_kms.c
+++ b/drivers/gpu/drm/bochs/bochs_kms.c
@@ -134,7 +134,11 @@ const struct drm_mode_config_funcs bochs_mode_funcs = {
 
 int bochs_kms_init(struct bochs_device *bochs)
 {
-	drm_mode_config_init(bochs->dev);
+	int ret;
+
+	ret = drmm_mode_config_init(bochs->dev);
+	if (ret)
+		return ret;
 
 	bochs->dev->mode_config.max_width = 8192;
 	bochs->dev->mode_config.max_height = 8192;
@@ -160,11 +164,3 @@ int bochs_kms_init(struct bochs_device *bochs)
 
 	return 0;
 }
-
-void bochs_kms_fini(struct bochs_device *bochs)
-{
-	if (!bochs->dev->mode_config.num_connector)
-		return;
-
-	drm_mode_config_cleanup(bochs->dev);
-}
-- 
2.24.1

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 111+ messages in thread

* [PATCH 29/51] drm/cirrus: Drop explicit drm_mode_config_cleanup call
  2020-03-02 22:25 [PATCH 00/51] drm_device managed resources, v4 Daniel Vetter
                   ` (27 preceding siblings ...)
  2020-03-02 22:26 ` [PATCH 28/51] drm/bochs: Drop explicit drm_mode_config_cleanup Daniel Vetter
@ 2020-03-02 22:26 ` Daniel Vetter
  2020-03-03  7:51   ` Gerd Hoffmann
  2020-03-02 22:26 ` [PATCH 30/51] drm/cirrus: Fully embrace devm_ Daniel Vetter
                   ` (21 subsequent siblings)
  50 siblings, 1 reply; 111+ messages in thread
From: Daniel Vetter @ 2020-03-02 22:26 UTC (permalink / raw)
  To: DRI Development
  Cc: Daniel Vetter, Intel Graphics Development, virtualization,
	Laurent Pinchart, Thomas Zimmermann, Dave Airlie, Daniel Vetter,
	Sam Ravnborg, Gerd Hoffmann

We can even delete the drm_driver.release hook now!

This is made possible by a preceeding patch which added a drmm_
cleanup action to drm_mode_config_init(), hence all we need to do to
ensure that drm_mode_config_cleanup() is run on final drm_device
cleanup is check the new error code for _init().

v2: Explain why this cleanup is possible (Laurent).

v3: Use drmm_mode_config_init() for more clarity (Sam, Thomas)

Cc: Sam Ravnborg <sam@ravnborg.org>
Acked-by: Sam Ravnborg <sam@ravnborg.org>
Cc: Thomas Zimmermann <tzimmermann@suse.de>
Cc: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
Cc: Dave Airlie <airlied@redhat.com>
Cc: Gerd Hoffmann <kraxel@redhat.com>
Cc: Daniel Vetter <daniel.vetter@ffwll.ch>
Cc: "Noralf Trønnes" <noralf@tronnes.org>
Cc: Sam Ravnborg <sam@ravnborg.org>
Cc: Thomas Zimmermann <tzimmermann@suse.de>
Cc: virtualization@lists.linux-foundation.org
---
 drivers/gpu/drm/cirrus/cirrus.c | 21 +++++++++++----------
 1 file changed, 11 insertions(+), 10 deletions(-)

diff --git a/drivers/gpu/drm/cirrus/cirrus.c b/drivers/gpu/drm/cirrus/cirrus.c
index a9d789a56536..bd8784ea9d64 100644
--- a/drivers/gpu/drm/cirrus/cirrus.c
+++ b/drivers/gpu/drm/cirrus/cirrus.c
@@ -510,11 +510,15 @@ static const struct drm_mode_config_funcs cirrus_mode_config_funcs = {
 	.atomic_commit = drm_atomic_helper_commit,
 };
 
-static void cirrus_mode_config_init(struct cirrus_device *cirrus)
+static int cirrus_mode_config_init(struct cirrus_device *cirrus)
 {
 	struct drm_device *dev = &cirrus->dev;
+	int ret;
+
+	ret = drmm_mode_config_init(dev);
+	if (ret)
+		return ret;
 
-	drm_mode_config_init(dev);
 	dev->mode_config.min_width = 0;
 	dev->mode_config.min_height = 0;
 	dev->mode_config.max_width = CIRRUS_MAX_PITCH / 2;
@@ -522,15 +526,12 @@ static void cirrus_mode_config_init(struct cirrus_device *cirrus)
 	dev->mode_config.preferred_depth = 16;
 	dev->mode_config.prefer_shadow = 0;
 	dev->mode_config.funcs = &cirrus_mode_config_funcs;
+
+	return 0;
 }
 
 /* ------------------------------------------------------------------ */
 
-static void cirrus_release(struct drm_device *dev)
-{
-	drm_mode_config_cleanup(dev);
-}
-
 DEFINE_DRM_GEM_FOPS(cirrus_fops);
 
 static struct drm_driver cirrus_driver = {
@@ -544,7 +545,6 @@ static struct drm_driver cirrus_driver = {
 
 	.fops		 = &cirrus_fops,
 	DRM_GEM_SHMEM_DRIVER_OPS,
-	.release         = cirrus_release,
 };
 
 static int cirrus_pci_probe(struct pci_dev *pdev,
@@ -591,7 +591,9 @@ static int cirrus_pci_probe(struct pci_dev *pdev,
 	if (cirrus->mmio == NULL)
 		goto err_unmap_vram;
 
-	cirrus_mode_config_init(cirrus);
+	ret = cirrus_mode_config_init(cirrus);
+	if (ret)
+		goto err_cleanup;
 
 	ret = cirrus_conn_init(cirrus);
 	if (ret < 0)
@@ -613,7 +615,6 @@ static int cirrus_pci_probe(struct pci_dev *pdev,
 	return 0;
 
 err_cleanup:
-	drm_mode_config_cleanup(dev);
 	iounmap(cirrus->mmio);
 err_unmap_vram:
 	iounmap(cirrus->vram);
-- 
2.24.1

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 111+ messages in thread

* [PATCH 30/51] drm/cirrus: Fully embrace devm_
  2020-03-02 22:25 [PATCH 00/51] drm_device managed resources, v4 Daniel Vetter
                   ` (28 preceding siblings ...)
  2020-03-02 22:26 ` [PATCH 29/51] drm/cirrus: Drop explicit drm_mode_config_cleanup call Daniel Vetter
@ 2020-03-02 22:26 ` Daniel Vetter
  2020-03-03  7:51   ` Gerd Hoffmann
  2020-03-02 22:26 ` [PATCH 31/51] drm/ingenic: Drop explicit drm_mode_config_cleanup call Daniel Vetter
                   ` (20 subsequent siblings)
  50 siblings, 1 reply; 111+ messages in thread
From: Daniel Vetter @ 2020-03-02 22:26 UTC (permalink / raw)
  To: DRI Development
  Cc: Daniel Vetter, Intel Graphics Development, virtualization,
	Gerd Hoffmann, Thomas Zimmermann, Daniel Vetter, Dave Airlie,
	Emil Velikov

With the drm_device lifetime fun cleaned up there's nothing in the way
anymore to use devm_ for everything hw releated. Do it, and in the
process, throw out the entire onion unwinding.

Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
Cc: Dave Airlie <airlied@redhat.com>
Cc: Gerd Hoffmann <kraxel@redhat.com>
Cc: Daniel Vetter <daniel.vetter@ffwll.ch>
Cc: "Noralf Trønnes" <noralf@tronnes.org>
Cc: Emil Velikov <emil.velikov@collabora.com>
Cc: Thomas Zimmermann <tzimmermann@suse.de>
Cc: virtualization@lists.linux-foundation.org
---
 drivers/gpu/drm/cirrus/cirrus.c | 44 +++++++++++----------------------
 1 file changed, 14 insertions(+), 30 deletions(-)

diff --git a/drivers/gpu/drm/cirrus/cirrus.c b/drivers/gpu/drm/cirrus/cirrus.c
index bd8784ea9d64..a36269717c3b 100644
--- a/drivers/gpu/drm/cirrus/cirrus.c
+++ b/drivers/gpu/drm/cirrus/cirrus.c
@@ -558,7 +558,7 @@ static int cirrus_pci_probe(struct pci_dev *pdev,
 	if (ret)
 		return ret;
 
-	ret = pci_enable_device(pdev);
+	ret = pcim_enable_device(pdev);
 	if (ret)
 		return ret;
 
@@ -569,39 +569,38 @@ static int cirrus_pci_probe(struct pci_dev *pdev,
 	ret = -ENOMEM;
 	cirrus = kzalloc(sizeof(*cirrus), GFP_KERNEL);
 	if (cirrus == NULL)
-		goto err_pci_release;
+		return ret;
 
 	dev = &cirrus->dev;
-	ret = drm_dev_init(dev, &cirrus_driver, &pdev->dev);
+	ret = devm_drm_dev_init(&pdev->dev, dev, &cirrus_driver);
 	if (ret) {
 		kfree(cirrus);
-		goto err_pci_release;
+		return ret;
 	}
 	dev->dev_private = cirrus;
 	drmm_add_final_kfree(dev, cirrus);
 
-	ret = -ENOMEM;
-	cirrus->vram = ioremap(pci_resource_start(pdev, 0),
-			       pci_resource_len(pdev, 0));
+	cirrus->vram = devm_ioremap(&pdev->dev, pci_resource_start(pdev, 0),
+				    pci_resource_len(pdev, 0));
 	if (cirrus->vram == NULL)
-		goto err_dev_put;
+		return -ENOMEM;
 
-	cirrus->mmio = ioremap(pci_resource_start(pdev, 1),
-			       pci_resource_len(pdev, 1));
+	cirrus->mmio = devm_ioremap(&pdev->dev, pci_resource_start(pdev, 1),
+				    pci_resource_len(pdev, 1));
 	if (cirrus->mmio == NULL)
-		goto err_unmap_vram;
+		return -ENOMEM;
 
 	ret = cirrus_mode_config_init(cirrus);
 	if (ret)
-		goto err_cleanup;
+		return ret;
 
 	ret = cirrus_conn_init(cirrus);
 	if (ret < 0)
-		goto err_cleanup;
+		return ret;
 
 	ret = cirrus_pipe_init(cirrus);
 	if (ret < 0)
-		goto err_cleanup;
+		return ret;
 
 	drm_mode_config_reset(dev);
 
@@ -609,33 +608,18 @@ static int cirrus_pci_probe(struct pci_dev *pdev,
 	pci_set_drvdata(pdev, dev);
 	ret = drm_dev_register(dev, 0);
 	if (ret)
-		goto err_cleanup;
+		return ret;
 
 	drm_fbdev_generic_setup(dev, dev->mode_config.preferred_depth);
 	return 0;
-
-err_cleanup:
-	iounmap(cirrus->mmio);
-err_unmap_vram:
-	iounmap(cirrus->vram);
-err_dev_put:
-	drm_dev_put(dev);
-err_pci_release:
-	pci_release_regions(pdev);
-	return ret;
 }
 
 static void cirrus_pci_remove(struct pci_dev *pdev)
 {
 	struct drm_device *dev = pci_get_drvdata(pdev);
-	struct cirrus_device *cirrus = dev->dev_private;
 
 	drm_dev_unplug(dev);
 	drm_atomic_helper_shutdown(dev);
-	iounmap(cirrus->mmio);
-	iounmap(cirrus->vram);
-	drm_dev_put(dev);
-	pci_release_regions(pdev);
 }
 
 static const struct pci_device_id pciidlist[] = {
-- 
2.24.1

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 111+ messages in thread

* [PATCH 31/51] drm/ingenic: Drop explicit drm_mode_config_cleanup call
  2020-03-02 22:25 [PATCH 00/51] drm_device managed resources, v4 Daniel Vetter
                   ` (29 preceding siblings ...)
  2020-03-02 22:26 ` [PATCH 30/51] drm/cirrus: Fully embrace devm_ Daniel Vetter
@ 2020-03-02 22:26 ` Daniel Vetter
  2020-03-06 20:17   ` Sam Ravnborg
  2020-03-02 22:26 ` [PATCH 32/51] drm/mcde: " Daniel Vetter
                   ` (19 subsequent siblings)
  50 siblings, 1 reply; 111+ messages in thread
From: Daniel Vetter @ 2020-03-02 22:26 UTC (permalink / raw)
  To: DRI Development
  Cc: Daniel Vetter, Intel Graphics Development, Paul Cercueil,
	Laurent Pinchart, Thomas Zimmermann, Daniel Vetter, Sam Ravnborg

Allows us to drop the drm_driver.release callback.

This is made possible by a preceeding patch which added a drmm_
cleanup action to drm_mode_config_init(), hence all we need to do to
ensure that drm_mode_config_cleanup() is run on final drm_device
cleanup is check the new error code for _init().

v2: Explain why this cleanup is possible (Laurent).

v3: Use drmm_mode_config_init() for more clarity (Sam, Thomas)

Cc: Sam Ravnborg <sam@ravnborg.org>
Cc: Thomas Zimmermann <tzimmermann@suse.de>
Reviewed-by: Paul Cercueil <paul@crapouillou.net> (v2)
Cc: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
Cc: Paul Cercueil <paul@crapouillou.net>
---
 drivers/gpu/drm/ingenic/ingenic-drm.c | 11 ++++-------
 1 file changed, 4 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/ingenic/ingenic-drm.c b/drivers/gpu/drm/ingenic/ingenic-drm.c
index 192aaa4421a3..a9bc6623b488 100644
--- a/drivers/gpu/drm/ingenic/ingenic-drm.c
+++ b/drivers/gpu/drm/ingenic/ingenic-drm.c
@@ -489,11 +489,6 @@ static irqreturn_t ingenic_drm_irq_handler(int irq, void *arg)
 	return IRQ_HANDLED;
 }
 
-static void ingenic_drm_release(struct drm_device *drm)
-{
-	drm_mode_config_cleanup(drm);
-}
-
 static int ingenic_drm_enable_vblank(struct drm_crtc *crtc)
 {
 	struct ingenic_drm *priv = drm_crtc_get_priv(crtc);
@@ -537,7 +532,6 @@ static struct drm_driver ingenic_drm_driver_data = {
 	.gem_prime_mmap		= drm_gem_cma_prime_mmap,
 
 	.irq_handler		= ingenic_drm_irq_handler,
-	.release		= ingenic_drm_release,
 };
 
 static const struct drm_plane_funcs ingenic_drm_primary_plane_funcs = {
@@ -638,7 +632,10 @@ static int ingenic_drm_probe(struct platform_device *pdev)
 	}
 	drmm_add_final_kfree(drm, priv);
 
-	drm_mode_config_init(drm);
+	ret = drmm_mode_config_init(drm);
+	if (ret)
+		return ret;
+
 	drm->mode_config.min_width = 0;
 	drm->mode_config.min_height = 0;
 	drm->mode_config.max_width = soc_info->max_width;
-- 
2.24.1

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 111+ messages in thread

* [PATCH 32/51] drm/mcde: Drop explicit drm_mode_config_cleanup call
  2020-03-02 22:25 [PATCH 00/51] drm_device managed resources, v4 Daniel Vetter
                   ` (30 preceding siblings ...)
  2020-03-02 22:26 ` [PATCH 31/51] drm/ingenic: Drop explicit drm_mode_config_cleanup call Daniel Vetter
@ 2020-03-02 22:26 ` Daniel Vetter
  2020-03-06 20:18   ` Sam Ravnborg
  2020-03-02 22:26 ` [PATCH 33/51] drm/mcde: More devm_drm_dev_init Daniel Vetter
                   ` (18 subsequent siblings)
  50 siblings, 1 reply; 111+ messages in thread
From: Daniel Vetter @ 2020-03-02 22:26 UTC (permalink / raw)
  To: DRI Development
  Cc: Daniel Vetter, Intel Graphics Development, Laurent Pinchart,
	Thomas Zimmermann, Daniel Vetter, Sam Ravnborg

Allows us to drop the drm_driver.release callback.

This is made possible by a preceeding patch which added a drmm_
cleanup action to drm_mode_config_init(), hence all we need to do to
ensure that drm_mode_config_cleanup() is run on final drm_device
cleanup is check the new error code for _init().

v2: Explain why this cleanup is possible (Laurent).

v3: Use drmm_mode_config_init() for more clarity (Sam, Thomas)

Cc: Sam Ravnborg <sam@ravnborg.org>
Cc: Thomas Zimmermann <tzimmermann@suse.de>
Reviewed-by: Linus Walleij <linus.walleij@linaro.org> (v2)
Cc: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
Cc: Linus Walleij <linus.walleij@linaro.org>
---
 drivers/gpu/drm/mcde/mcde_drv.c | 22 ++++++----------------
 1 file changed, 6 insertions(+), 16 deletions(-)

diff --git a/drivers/gpu/drm/mcde/mcde_drv.c b/drivers/gpu/drm/mcde/mcde_drv.c
index a543ebf3d541..03d2e1a00810 100644
--- a/drivers/gpu/drm/mcde/mcde_drv.c
+++ b/drivers/gpu/drm/mcde/mcde_drv.c
@@ -184,13 +184,13 @@ static int mcde_modeset_init(struct drm_device *drm)
 	ret = drm_vblank_init(drm, 1);
 	if (ret) {
 		dev_err(drm->dev, "failed to init vblank\n");
-		goto out_config;
+		return ret;
 	}
 
 	ret = mcde_display_init(drm);
 	if (ret) {
 		dev_err(drm->dev, "failed to init display\n");
-		goto out_config;
+		return ret;
 	}
 
 	/*
@@ -204,7 +204,7 @@ static int mcde_modeset_init(struct drm_device *drm)
 						    mcde->bridge);
 	if (ret) {
 		dev_err(drm->dev, "failed to attach display output bridge\n");
-		goto out_config;
+		return ret;
 	}
 
 	drm_mode_config_reset(drm);
@@ -212,17 +212,6 @@ static int mcde_modeset_init(struct drm_device *drm)
 	drm_fbdev_generic_setup(drm, 32);
 
 	return 0;
-
-out_config:
-	drm_mode_config_cleanup(drm);
-	return ret;
-}
-
-static void mcde_release(struct drm_device *drm)
-{
-	struct mcde *mcde = drm->dev_private;
-
-	drm_mode_config_cleanup(drm);
 }
 
 DEFINE_DRM_GEM_CMA_FOPS(drm_fops);
@@ -230,7 +219,6 @@ DEFINE_DRM_GEM_CMA_FOPS(drm_fops);
 static struct drm_driver mcde_drm_driver = {
 	.driver_features =
 		DRIVER_MODESET | DRIVER_GEM | DRIVER_ATOMIC,
-	.release = mcde_release,
 	.lastclose = drm_fb_helper_lastclose,
 	.ioctls = NULL,
 	.fops = &drm_fops,
@@ -258,7 +246,9 @@ static int mcde_drm_bind(struct device *dev)
 	struct drm_device *drm = dev_get_drvdata(dev);
 	int ret;
 
-	drm_mode_config_init(drm);
+	ret = drmm_mode_config_init(drm);
+	if (ret)
+		return ret;
 
 	ret = component_bind_all(drm->dev, drm);
 	if (ret) {
-- 
2.24.1

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 111+ messages in thread

* [PATCH 33/51] drm/mcde: More devm_drm_dev_init
  2020-03-02 22:25 [PATCH 00/51] drm_device managed resources, v4 Daniel Vetter
                   ` (31 preceding siblings ...)
  2020-03-02 22:26 ` [PATCH 32/51] drm/mcde: " Daniel Vetter
@ 2020-03-02 22:26 ` Daniel Vetter
  2020-03-02 22:26 ` [PATCH 34/51] drm/meson: Drop explicit drm_mode_config_cleanup call Daniel Vetter
                   ` (17 subsequent siblings)
  50 siblings, 0 replies; 111+ messages in thread
From: Daniel Vetter @ 2020-03-02 22:26 UTC (permalink / raw)
  To: DRI Development; +Cc: Daniel Vetter, Intel Graphics Development, Daniel Vetter

Auto-unwind ftw, now possible with the fixed drm_device related
management.

Aside, clk/regulator seem to be missing devm versions for a bunch of
functions, preventing a pile of these simpler drivers from outright
losing their ->remove hook.

Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
Cc: Linus Walleij <linus.walleij@linaro.org>
---
 drivers/gpu/drm/mcde/mcde_drv.c | 9 +++------
 1 file changed, 3 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/mcde/mcde_drv.c b/drivers/gpu/drm/mcde/mcde_drv.c
index 03d2e1a00810..88cc6b4a7a64 100644
--- a/drivers/gpu/drm/mcde/mcde_drv.c
+++ b/drivers/gpu/drm/mcde/mcde_drv.c
@@ -312,7 +312,7 @@ static int mcde_probe(struct platform_device *pdev)
 		return -ENOMEM;
 	mcde->dev = dev;
 
-	ret = drm_dev_init(&mcde->drm, &mcde_drm_driver, dev);
+	ret = devm_drm_dev_init(dev, &mcde->drm, &mcde_drm_driver);
 	if (ret) {
 		kfree(mcde);
 		return ret;
@@ -331,12 +331,12 @@ static int mcde_probe(struct platform_device *pdev)
 	if (IS_ERR(mcde->epod)) {
 		ret = PTR_ERR(mcde->epod);
 		dev_err(dev, "can't get EPOD regulator\n");
-		goto dev_unref;
+		return ret;
 	}
 	ret = regulator_enable(mcde->epod);
 	if (ret) {
 		dev_err(dev, "can't enable EPOD regulator\n");
-		goto dev_unref;
+		return ret;
 	}
 	mcde->vana = devm_regulator_get(dev, "vana");
 	if (IS_ERR(mcde->vana)) {
@@ -487,8 +487,6 @@ static int mcde_probe(struct platform_device *pdev)
 	regulator_disable(mcde->vana);
 regulator_epod_off:
 	regulator_disable(mcde->epod);
-dev_unref:
-	drm_dev_put(drm);
 	return ret;
 
 }
@@ -502,7 +500,6 @@ static int mcde_remove(struct platform_device *pdev)
 	clk_disable_unprepare(mcde->mcde_clk);
 	regulator_disable(mcde->vana);
 	regulator_disable(mcde->epod);
-	drm_dev_put(drm);
 
 	return 0;
 }
-- 
2.24.1

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 111+ messages in thread

* [PATCH 34/51] drm/meson: Drop explicit drm_mode_config_cleanup call
  2020-03-02 22:25 [PATCH 00/51] drm_device managed resources, v4 Daniel Vetter
                   ` (32 preceding siblings ...)
  2020-03-02 22:26 ` [PATCH 33/51] drm/mcde: More devm_drm_dev_init Daniel Vetter
@ 2020-03-02 22:26 ` Daniel Vetter
  2020-03-02 22:26 ` [PATCH 35/51] drm/pl111: " Daniel Vetter
                   ` (16 subsequent siblings)
  50 siblings, 0 replies; 111+ messages in thread
From: Daniel Vetter @ 2020-03-02 22:26 UTC (permalink / raw)
  To: DRI Development
  Cc: Neil Armstrong, Daniel Vetter, Intel Graphics Development,
	Laurent Pinchart, Thomas Zimmermann, Kevin Hilman, Daniel Vetter,
	linux-amlogic, Sam Ravnborg, linux-arm-kernel

It's right above the drm_dev_put().

This is made possible by a preceeding patch which added a drmm_
cleanup action to drm_mode_config_init(), hence all we need to do to
ensure that drm_mode_config_cleanup() is run on final drm_device
cleanup is check the new error code for _init().

Aside: This driver gets its devm_ stuff all wrong wrt drm_device and
anything hanging off that. Not the only one unfortunately.

v2: Explain why this cleanup is possible (Laurent).

v3: Use drmm_mode_config_init() for more clarity (Sam, Thomas)

Cc: Sam Ravnborg <sam@ravnborg.org>
Cc: Thomas Zimmermann <tzimmermann@suse.de>
Reviewed-by: Neil Armstrong <narmstrong@baylibre.com> (v2)
Cc: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
Cc: Neil Armstrong <narmstrong@baylibre.com>
Cc: Kevin Hilman <khilman@baylibre.com>
Cc: linux-amlogic@lists.infradead.org
Cc: linux-arm-kernel@lists.infradead.org
---
 drivers/gpu/drm/meson/meson_drv.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/meson/meson_drv.c b/drivers/gpu/drm/meson/meson_drv.c
index b5f5eb7b4bb9..6f29fab79952 100644
--- a/drivers/gpu/drm/meson/meson_drv.c
+++ b/drivers/gpu/drm/meson/meson_drv.c
@@ -284,7 +284,9 @@ static int meson_drv_bind_master(struct device *dev, bool has_components)
 	/* Remove early framebuffers (ie. simplefb) */
 	meson_remove_framebuffers();
 
-	drm_mode_config_init(drm);
+	ret = drmm_mode_config_init(drm);
+	if (ret)
+		goto free_drm;
 	drm->mode_config.max_width = 3840;
 	drm->mode_config.max_height = 2160;
 	drm->mode_config.funcs = &meson_mode_config_funcs;
@@ -379,7 +381,6 @@ static void meson_drv_unbind(struct device *dev)
 	drm_dev_unregister(drm);
 	drm_irq_uninstall(drm);
 	drm_kms_helper_poll_fini(drm);
-	drm_mode_config_cleanup(drm);
 	drm_dev_put(drm);
 }
 
-- 
2.24.1

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 111+ messages in thread

* [PATCH 35/51] drm/pl111: Drop explicit drm_mode_config_cleanup call
  2020-03-02 22:25 [PATCH 00/51] drm_device managed resources, v4 Daniel Vetter
                   ` (33 preceding siblings ...)
  2020-03-02 22:26 ` [PATCH 34/51] drm/meson: Drop explicit drm_mode_config_cleanup call Daniel Vetter
@ 2020-03-02 22:26 ` Daniel Vetter
  2020-03-07  8:37   ` Sam Ravnborg
  2020-03-02 22:26 ` [PATCH 36/51] drm/rcar-du: " Daniel Vetter
                   ` (15 subsequent siblings)
  50 siblings, 1 reply; 111+ messages in thread
From: Daniel Vetter @ 2020-03-02 22:26 UTC (permalink / raw)
  To: DRI Development
  Cc: Daniel Vetter, Intel Graphics Development, Laurent Pinchart,
	Thomas Zimmermann, Daniel Vetter, Sam Ravnborg

It's right above the drm_dev_put().

This is made possible by a preceeding patch which added a drmm_
cleanup action to drm_mode_config_init(), hence all we need to do to
ensure that drm_mode_config_cleanup() is run on final drm_device
cleanup is check the new error code for _init().

Aside: This driver gets its devm_ stuff all wrong wrt drm_device and
anything hanging off that. Not the only one unfortunately.

v2: Explain why this cleanup is possible (Laurent).

v3: Use drmm_mode_config_init() for more clarity (Sam, Thomas)

Cc: Sam Ravnborg <sam@ravnborg.org>
Cc: Thomas Zimmermann <tzimmermann@suse.de>
Cc: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
Cc: Eric Anholt <eric@anholt.net>
---
 drivers/gpu/drm/pl111/pl111_drv.c | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/pl111/pl111_drv.c b/drivers/gpu/drm/pl111/pl111_drv.c
index aa8aa8d9e405..f9ca0f3edbbb 100644
--- a/drivers/gpu/drm/pl111/pl111_drv.c
+++ b/drivers/gpu/drm/pl111/pl111_drv.c
@@ -90,10 +90,13 @@ static int pl111_modeset_init(struct drm_device *dev)
 	struct drm_panel *panel = NULL;
 	struct drm_bridge *bridge = NULL;
 	bool defer = false;
-	int ret = 0;
+	int ret;
 	int i;
 
-	drm_mode_config_init(dev);
+	ret = drmm_mode_config_init(dev);
+	if (ret)
+		return ret;
+
 	mode_config = &dev->mode_config;
 	mode_config->funcs = &mode_config_funcs;
 	mode_config->min_width = 1;
@@ -154,7 +157,7 @@ static int pl111_modeset_init(struct drm_device *dev)
 						    DRM_MODE_CONNECTOR_Unknown);
 		if (IS_ERR(bridge)) {
 			ret = PTR_ERR(bridge);
-			goto out_config;
+			goto finish;
 		}
 	} else if (bridge) {
 		dev_info(dev->dev, "Using non-panel bridge\n");
@@ -197,8 +200,6 @@ static int pl111_modeset_init(struct drm_device *dev)
 out_bridge:
 	if (panel)
 		drm_panel_bridge_remove(bridge);
-out_config:
-	drm_mode_config_cleanup(dev);
 finish:
 	return ret;
 }
@@ -343,7 +344,6 @@ static int pl111_amba_remove(struct amba_device *amba_dev)
 	drm_dev_unregister(drm);
 	if (priv->panel)
 		drm_panel_bridge_remove(priv->bridge);
-	drm_mode_config_cleanup(drm);
 	drm_dev_put(drm);
 	of_reserved_mem_device_release(dev);
 
-- 
2.24.1

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 111+ messages in thread

* [PATCH 36/51] drm/rcar-du: Drop explicit drm_mode_config_cleanup call
  2020-03-02 22:25 [PATCH 00/51] drm_device managed resources, v4 Daniel Vetter
                   ` (34 preceding siblings ...)
  2020-03-02 22:26 ` [PATCH 35/51] drm/pl111: " Daniel Vetter
@ 2020-03-02 22:26 ` Daniel Vetter
  2020-03-02 22:26 ` [PATCH 37/51] drm/rockchip: " Daniel Vetter
                   ` (14 subsequent siblings)
  50 siblings, 0 replies; 111+ messages in thread
From: Daniel Vetter @ 2020-03-02 22:26 UTC (permalink / raw)
  To: DRI Development
  Cc: Daniel Vetter, Intel Graphics Development, linux-renesas-soc,
	Kieran Bingham, Laurent Pinchart, Thomas Zimmermann,
	Daniel Vetter, Sam Ravnborg

It's right above the drm_dev_put().

This is made possible by a preceeding patch which added a drmm_
cleanup action to drm_mode_config_init(), hence all we need to do to
ensure that drm_mode_config_cleanup() is run on final drm_device
cleanup is check the new error code for _init().

Aside: Another driver with a bit much devm_kzalloc, which should
probably use drmm_kzalloc instead ...

v2: Explain why this cleanup is possible (Laurent).

v3: Use drmm_mode_config_init() for more clarity (Sam, Thomas)

Cc: Sam Ravnborg <sam@ravnborg.org>
Cc: Thomas Zimmermann <tzimmermann@suse.de>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> (v2)
Cc: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
Cc: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Cc: Kieran Bingham <kieran.bingham+renesas@ideasonboard.com>
Cc: linux-renesas-soc@vger.kernel.org
---
 drivers/gpu/drm/rcar-du/rcar_du_drv.c | 1 -
 drivers/gpu/drm/rcar-du/rcar_du_kms.c | 4 +++-
 2 files changed, 3 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/rcar-du/rcar_du_drv.c b/drivers/gpu/drm/rcar-du/rcar_du_drv.c
index 654e2dd08146..3e67cf70f040 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_drv.c
+++ b/drivers/gpu/drm/rcar-du/rcar_du_drv.c
@@ -530,7 +530,6 @@ static int rcar_du_remove(struct platform_device *pdev)
 	drm_dev_unregister(ddev);
 
 	drm_kms_helper_poll_fini(ddev);
-	drm_mode_config_cleanup(ddev);
 
 	drm_dev_put(ddev);
 
diff --git a/drivers/gpu/drm/rcar-du/rcar_du_kms.c b/drivers/gpu/drm/rcar-du/rcar_du_kms.c
index fcfd916227d1..482329102f19 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_kms.c
+++ b/drivers/gpu/drm/rcar-du/rcar_du_kms.c
@@ -712,7 +712,9 @@ int rcar_du_modeset_init(struct rcar_du_device *rcdu)
 	unsigned int i;
 	int ret;
 
-	drm_mode_config_init(dev);
+	ret = drmm_mode_config_init(dev);
+	if (ret)
+		return ret;
 
 	dev->mode_config.min_width = 0;
 	dev->mode_config.min_height = 0;
-- 
2.24.1

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 111+ messages in thread

* [PATCH 37/51] drm/rockchip: Drop explicit drm_mode_config_cleanup call
  2020-03-02 22:25 [PATCH 00/51] drm_device managed resources, v4 Daniel Vetter
                   ` (35 preceding siblings ...)
  2020-03-02 22:26 ` [PATCH 36/51] drm/rcar-du: " Daniel Vetter
@ 2020-03-02 22:26 ` Daniel Vetter
  2020-03-07  8:38   ` Sam Ravnborg
  2020-03-02 22:26 ` [PATCH 38/51] drm/stm: " Daniel Vetter
                   ` (13 subsequent siblings)
  50 siblings, 1 reply; 111+ messages in thread
From: Daniel Vetter @ 2020-03-02 22:26 UTC (permalink / raw)
  To: DRI Development
  Cc: Francesco Lavra, Daniel Vetter, Intel Graphics Development,
	Sandy Huang, linux-rockchip, Laurent Pinchart, Thomas Zimmermann,
	Daniel Vetter, Sam Ravnborg, linux-arm-kernel

It's (almost, there's some iommu stuff without significance) right
above the drm_dev_put().

This is made possible by a preceeding patch which added a drmm_
cleanup action to drm_mode_config_init(), hence all we need to do to
ensure that drm_mode_config_cleanup() is run on final drm_device
cleanup is check the new error code for _init().

Aside: Another driver with a bit much devm_kzalloc, which should
probably use drmm_kzalloc instead ...

v2: Explain why this cleanup is possible (Laurent).

v3: Jump out at the right label (Francesco)

v4: Try again, kbuild caught that I didn't build test this properly
...

v5: Use drmm_mode_config_init() for more clarity (Sam, Thomas)

Cc: Sam Ravnborg <sam@ravnborg.org>
Cc: Thomas Zimmermann <tzimmermann@suse.de>
Cc: Francesco Lavra <francescolavra.fl@gmail.com>
Cc: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
Cc: Sandy Huang <hjc@rock-chips.com>
Cc: "Heiko Stübner" <heiko@sntech.de>
Cc: linux-arm-kernel@lists.infradead.org
Cc: linux-rockchip@lists.infradead.org
---
 drivers/gpu/drm/rockchip/rockchip_drm_drv.c | 14 +++++---------
 1 file changed, 5 insertions(+), 9 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_drv.c b/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
index 20ecb1508a22..0f3eb392fe39 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
@@ -135,14 +135,16 @@ static int rockchip_drm_bind(struct device *dev)
 	if (ret)
 		goto err_free;
 
-	drm_mode_config_init(drm_dev);
+	ret = drmm_mode_config_init(drm_dev);
+	if (ret)
+		goto err_iommu_cleanup;
 
 	rockchip_drm_mode_config_init(drm_dev);
 
 	/* Try to bind all sub drivers. */
 	ret = component_bind_all(dev, drm_dev);
 	if (ret)
-		goto err_mode_config_cleanup;
+		goto err_iommu_cleanup;
 
 	ret = drm_vblank_init(drm_dev, drm_dev->mode_config.num_crtc);
 	if (ret)
@@ -173,12 +175,9 @@ static int rockchip_drm_bind(struct device *dev)
 	rockchip_drm_fbdev_fini(drm_dev);
 err_unbind_all:
 	component_unbind_all(dev, drm_dev);
-err_mode_config_cleanup:
-	drm_mode_config_cleanup(drm_dev);
+err_iommu_cleanup:
 	rockchip_iommu_cleanup(drm_dev);
 err_free:
-	drm_dev->dev_private = NULL;
-	dev_set_drvdata(dev, NULL);
 	drm_dev_put(drm_dev);
 	return ret;
 }
@@ -194,11 +193,8 @@ static void rockchip_drm_unbind(struct device *dev)
 
 	drm_atomic_helper_shutdown(drm_dev);
 	component_unbind_all(dev, drm_dev);
-	drm_mode_config_cleanup(drm_dev);
 	rockchip_iommu_cleanup(drm_dev);
 
-	drm_dev->dev_private = NULL;
-	dev_set_drvdata(dev, NULL);
 	drm_dev_put(drm_dev);
 }
 
-- 
2.24.1

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 111+ messages in thread

* [PATCH 38/51] drm/stm: Drop explicit drm_mode_config_cleanup call
  2020-03-02 22:25 [PATCH 00/51] drm_device managed resources, v4 Daniel Vetter
                   ` (36 preceding siblings ...)
  2020-03-02 22:26 ` [PATCH 37/51] drm/rockchip: " Daniel Vetter
@ 2020-03-02 22:26 ` Daniel Vetter
  2020-03-07  9:25   ` Sam Ravnborg
  2020-03-02 22:26 ` [PATCH 39/51] drm/shmob: " Daniel Vetter
                   ` (12 subsequent siblings)
  50 siblings, 1 reply; 111+ messages in thread
From: Daniel Vetter @ 2020-03-02 22:26 UTC (permalink / raw)
  To: DRI Development
  Cc: Maxime Coquelin, Vincent Abriou, Daniel Vetter,
	Intel Graphics Development, Philippe Cornu, Yannick Fertre,
	Laurent Pinchart, Thomas Zimmermann, Daniel Vetter, Sam Ravnborg,
	linux-stm32, linux-arm-kernel, Alexandre Torgue

It's right above the drm_dev_put().

This is made possible by a preceeding patch which added a drmm_
cleanup action to drm_mode_config_init(), hence all we need to do to
ensure that drm_mode_config_cleanup() is run on final drm_device
cleanup is check the new error code for _init().

Aside: Another driver with a bit much devm_kzalloc, which should
probably use drmm_kzalloc instead ...

v2: Explain why this cleanup is possible (Laurent).

v3: Use drmm_mode_config_init() for more clarity (Sam, Thomas)

Cc: Sam Ravnborg <sam@ravnborg.org>
Cc: Thomas Zimmermann <tzimmermann@suse.de>
Acked-by: Philippe Cornu <philippe.cornu@st.com>
Cc: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
Cc: Yannick Fertre <yannick.fertre@st.com>
Cc: Philippe Cornu <philippe.cornu@st.com>
Cc: Benjamin Gaignard <benjamin.gaignard@linaro.org>
Cc: Vincent Abriou <vincent.abriou@st.com>
Cc: Maxime Coquelin <mcoquelin.stm32@gmail.com>
Cc: Alexandre Torgue <alexandre.torgue@st.com>
Cc: linux-stm32@st-md-mailman.stormreply.com
Cc: linux-arm-kernel@lists.infradead.org
---
 drivers/gpu/drm/stm/drv.c | 10 ++++------
 1 file changed, 4 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/stm/drv.c b/drivers/gpu/drm/stm/drv.c
index ea9fcbdc68b3..0f85dd86cafa 100644
--- a/drivers/gpu/drm/stm/drv.c
+++ b/drivers/gpu/drm/stm/drv.c
@@ -88,7 +88,9 @@ static int drv_load(struct drm_device *ddev)
 
 	ddev->dev_private = (void *)ldev;
 
-	drm_mode_config_init(ddev);
+	ret = drmm_mode_config_init(ddev);
+	if (ret)
+		return ret;
 
 	/*
 	 * set max width and height as default value.
@@ -103,7 +105,7 @@ static int drv_load(struct drm_device *ddev)
 
 	ret = ltdc_load(ddev);
 	if (ret)
-		goto err;
+		return ret;
 
 	drm_mode_config_reset(ddev);
 	drm_kms_helper_poll_init(ddev);
@@ -111,9 +113,6 @@ static int drv_load(struct drm_device *ddev)
 	platform_set_drvdata(pdev, ddev);
 
 	return 0;
-err:
-	drm_mode_config_cleanup(ddev);
-	return ret;
 }
 
 static void drv_unload(struct drm_device *ddev)
@@ -122,7 +121,6 @@ static void drv_unload(struct drm_device *ddev)
 
 	drm_kms_helper_poll_fini(ddev);
 	ltdc_unload(ddev);
-	drm_mode_config_cleanup(ddev);
 }
 
 static __maybe_unused int drv_suspend(struct device *dev)
-- 
2.24.1

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 111+ messages in thread

* [PATCH 39/51] drm/shmob: Drop explicit drm_mode_config_cleanup call
  2020-03-02 22:25 [PATCH 00/51] drm_device managed resources, v4 Daniel Vetter
                   ` (37 preceding siblings ...)
  2020-03-02 22:26 ` [PATCH 38/51] drm/stm: " Daniel Vetter
@ 2020-03-02 22:26 ` Daniel Vetter
  2020-03-02 22:26 ` [PATCH 40/51] drm/mtk: " Daniel Vetter
                   ` (11 subsequent siblings)
  50 siblings, 0 replies; 111+ messages in thread
From: Daniel Vetter @ 2020-03-02 22:26 UTC (permalink / raw)
  To: DRI Development
  Cc: Daniel Vetter, Intel Graphics Development, linux-renesas-soc,
	Kieran Bingham, Laurent Pinchart, Thomas Zimmermann,
	Daniel Vetter, Sam Ravnborg

It's right above the drm_dev_put().

This is made possible by a preceeding patch which added a drmm_
cleanup action to drm_mode_config_init(), hence all we need to do to
ensure that drm_mode_config_cleanup() is run on final drm_device
cleanup is check the new error code for _init().

Aside: Another driver with a bit much devm_kzalloc, which should
probably use drmm_kzalloc instead ...

v2: Explain why this cleanup is possible (Laurent).

v3: Use drmm_mode_config_init() for more clarity (Sam, Thomas)

Cc: Sam Ravnborg <sam@ravnborg.org>
Cc: Thomas Zimmermann <tzimmermann@suse.de>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> (v2)
Cc: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
Cc: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Cc: Kieran Bingham <kieran.bingham+renesas@ideasonboard.com>
Cc: linux-renesas-soc@vger.kernel.org
---
 drivers/gpu/drm/shmobile/shmob_drm_drv.c | 2 --
 drivers/gpu/drm/shmobile/shmob_drm_kms.c | 6 +++++-
 2 files changed, 5 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/shmobile/shmob_drm_drv.c b/drivers/gpu/drm/shmobile/shmob_drm_drv.c
index b8c0930959c7..ae9d6b8d3ca8 100644
--- a/drivers/gpu/drm/shmobile/shmob_drm_drv.c
+++ b/drivers/gpu/drm/shmobile/shmob_drm_drv.c
@@ -192,7 +192,6 @@ static int shmob_drm_remove(struct platform_device *pdev)
 
 	drm_dev_unregister(ddev);
 	drm_kms_helper_poll_fini(ddev);
-	drm_mode_config_cleanup(ddev);
 	drm_irq_uninstall(ddev);
 	drm_dev_put(ddev);
 
@@ -288,7 +287,6 @@ static int shmob_drm_probe(struct platform_device *pdev)
 	drm_irq_uninstall(ddev);
 err_modeset_cleanup:
 	drm_kms_helper_poll_fini(ddev);
-	drm_mode_config_cleanup(ddev);
 err_free_drm_dev:
 	drm_dev_put(ddev);
 
diff --git a/drivers/gpu/drm/shmobile/shmob_drm_kms.c b/drivers/gpu/drm/shmobile/shmob_drm_kms.c
index c51197b6fd85..7a866d6ce6bb 100644
--- a/drivers/gpu/drm/shmobile/shmob_drm_kms.c
+++ b/drivers/gpu/drm/shmobile/shmob_drm_kms.c
@@ -126,7 +126,11 @@ static const struct drm_mode_config_funcs shmob_drm_mode_config_funcs = {
 
 int shmob_drm_modeset_init(struct shmob_drm_device *sdev)
 {
-	drm_mode_config_init(sdev->ddev);
+	int ret;
+
+	ret = drmm_mode_config_init(sdev->ddev);
+	if (ret)
+		return ret;
 
 	shmob_drm_crtc_create(sdev);
 	shmob_drm_encoder_create(sdev);
-- 
2.24.1

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 111+ messages in thread

* [PATCH 40/51] drm/mtk: Drop explicit drm_mode_config_cleanup call
  2020-03-02 22:25 [PATCH 00/51] drm_device managed resources, v4 Daniel Vetter
                   ` (38 preceding siblings ...)
  2020-03-02 22:26 ` [PATCH 39/51] drm/shmob: " Daniel Vetter
@ 2020-03-02 22:26 ` Daniel Vetter
  2020-03-07  9:26   ` Sam Ravnborg
  2020-03-02 22:26 ` [PATCH 41/51] drm/tidss: " Daniel Vetter
                   ` (10 subsequent siblings)
  50 siblings, 1 reply; 111+ messages in thread
From: Daniel Vetter @ 2020-03-02 22:26 UTC (permalink / raw)
  To: DRI Development
  Cc: Daniel Vetter, Intel Graphics Development, Laurent Pinchart,
	Thomas Zimmermann, Daniel Vetter, Sam Ravnborg

It's right above the drm_dev_put().

This is made possible by a preceeding patch which added a drmm_
cleanup action to drm_mode_config_init(), hence all we need to do to
ensure that drm_mode_config_cleanup() is run on final drm_device
cleanup is check the new error code for _init().

Aside: Another driver with a bit much devm_kzalloc, which should
probably use drmm_kzalloc instead ...

v2: Explain why this cleanup is possible (Laurent).

v3: Use drmm_mode_config_init() for more clarity (Sam, Thomas)

Cc: Sam Ravnborg <sam@ravnborg.org>
Cc: Thomas Zimmermann <tzimmermann@suse.de>
Cc: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
---
 drivers/gpu/drm/mediatek/mtk_drm_drv.c | 9 ++++-----
 1 file changed, 4 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_drm_drv.c b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
index 0563c6813333..2eaa9080d250 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_drv.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
@@ -162,7 +162,9 @@ static int mtk_drm_kms_init(struct drm_device *drm)
 	}
 	private->mutex_dev = &pdev->dev;
 
-	drm_mode_config_init(drm);
+	ret = drmm_mode_config_init(drm);
+	if (ret)
+		return ret;
 
 	drm->mode_config.min_width = 64;
 	drm->mode_config.min_height = 64;
@@ -179,7 +181,7 @@ static int mtk_drm_kms_init(struct drm_device *drm)
 
 	ret = component_bind_all(drm->dev, drm);
 	if (ret)
-		goto err_config_cleanup;
+		return ret;
 
 	/*
 	 * We currently support two fixed data streams, each optional,
@@ -255,8 +257,6 @@ static int mtk_drm_kms_init(struct drm_device *drm)
 		dma_dev->dma_parms = NULL;
 err_component_unbind:
 	component_unbind_all(drm->dev, drm);
-err_config_cleanup:
-	drm_mode_config_cleanup(drm);
 
 	return ret;
 }
@@ -272,7 +272,6 @@ static void mtk_drm_kms_deinit(struct drm_device *drm)
 		private->dma_dev->dma_parms = NULL;
 
 	component_unbind_all(drm->dev, drm);
-	drm_mode_config_cleanup(drm);
 }
 
 static const struct file_operations mtk_drm_fops = {
-- 
2.24.1

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 111+ messages in thread

* [PATCH 41/51] drm/tidss: Drop explicit drm_mode_config_cleanup call
  2020-03-02 22:25 [PATCH 00/51] drm_device managed resources, v4 Daniel Vetter
                   ` (39 preceding siblings ...)
  2020-03-02 22:26 ` [PATCH 40/51] drm/mtk: " Daniel Vetter
@ 2020-03-02 22:26 ` Daniel Vetter
  2020-03-02 22:26 ` [PATCH 42/51] drm/gm12u320: More drmm_ Daniel Vetter
                   ` (9 subsequent siblings)
  50 siblings, 0 replies; 111+ messages in thread
From: Daniel Vetter @ 2020-03-02 22:26 UTC (permalink / raw)
  To: DRI Development
  Cc: Daniel Vetter, Intel Graphics Development, Jyri Sarha,
	Tomi Valkeinen, Laurent Pinchart, Thomas Zimmermann,
	Daniel Vetter, Sam Ravnborg

It's right above the drm_dev_put().

This is made possible by a preceeding patch which added a drmm_
cleanup action to drm_mode_config_init(), hence all we need to do to
ensure that drm_mode_config_cleanup() is run on final drm_device
cleanup is check the new error code for _init().

Aside: Another driver with a bit much devm_kzalloc, which should
probably use drmm_kzalloc instead ...

I'm pretty sure this one blows up already under KASAN because it's
using devm_drm_dev_init, and later on devm_kzalloc. Hence the memory
will get freed before the final drm_dev_put (all from the devres
code), but the cleanup in that final drm_dev_put will access the just
freed memory.

Unfortunately fixing this properly needs slightly more work, namely
drmm_ versions for all the drm objects (planes, crtc, ...), so that
the cleanup actually happens before even drmm_kzalloc would release
the underlying memory. Not quite there yet.

v2: Explain why this cleanup is possible (Laurent).

v3: Use drmm_mode_config_init() for more clarity (Sam, Thomas)

Cc: Sam Ravnborg <sam@ravnborg.org>
Cc: Thomas Zimmermann <tzimmermann@suse.de>
Acked-by: Jyri Sarha <jsarha@ti.com>
Cc: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
Cc: Jyri Sarha <jsarha@ti.com>
Cc: Tomi Valkeinen <tomi.valkeinen@ti.com>
---
 drivers/gpu/drm/tidss/tidss_drv.c |  4 ----
 drivers/gpu/drm/tidss/tidss_kms.c | 19 +++++--------------
 drivers/gpu/drm/tidss/tidss_kms.h |  1 -
 3 files changed, 5 insertions(+), 19 deletions(-)

diff --git a/drivers/gpu/drm/tidss/tidss_drv.c b/drivers/gpu/drm/tidss/tidss_drv.c
index 460d5e9d0cf4..ad449d104306 100644
--- a/drivers/gpu/drm/tidss/tidss_drv.c
+++ b/drivers/gpu/drm/tidss/tidss_drv.c
@@ -103,11 +103,7 @@ static const struct dev_pm_ops tidss_pm_ops = {
 
 static void tidss_release(struct drm_device *ddev)
 {
-	struct tidss_device *tidss = ddev->dev_private;
-
 	drm_kms_helper_poll_fini(ddev);
-
-	tidss_modeset_cleanup(tidss);
 }
 
 DEFINE_DRM_GEM_CMA_FOPS(tidss_fops);
diff --git a/drivers/gpu/drm/tidss/tidss_kms.c b/drivers/gpu/drm/tidss/tidss_kms.c
index 7d419960b030..4bd339a467a4 100644
--- a/drivers/gpu/drm/tidss/tidss_kms.c
+++ b/drivers/gpu/drm/tidss/tidss_kms.c
@@ -258,7 +258,9 @@ int tidss_modeset_init(struct tidss_device *tidss)
 
 	dev_dbg(tidss->dev, "%s\n", __func__);
 
-	drm_mode_config_init(ddev);
+	ret = drmm_mode_config_init(ddev);
+	if (ret)
+		return ret;
 
 	ddev->mode_config.min_width = 8;
 	ddev->mode_config.min_height = 8;
@@ -270,11 +272,11 @@ int tidss_modeset_init(struct tidss_device *tidss)
 
 	ret = tidss_dispc_modeset_init(tidss);
 	if (ret)
-		goto err_mode_config_cleanup;
+		return ret;
 
 	ret = drm_vblank_init(ddev, tidss->num_crtcs);
 	if (ret)
-		goto err_mode_config_cleanup;
+		return ret;
 
 	/* Start with vertical blanking interrupt reporting disabled. */
 	for (i = 0; i < tidss->num_crtcs; ++i)
@@ -285,15 +287,4 @@ int tidss_modeset_init(struct tidss_device *tidss)
 	dev_dbg(tidss->dev, "%s done\n", __func__);
 
 	return 0;
-
-err_mode_config_cleanup:
-	drm_mode_config_cleanup(ddev);
-	return ret;
-}
-
-void tidss_modeset_cleanup(struct tidss_device *tidss)
-{
-	struct drm_device *ddev = &tidss->ddev;
-
-	drm_mode_config_cleanup(ddev);
 }
diff --git a/drivers/gpu/drm/tidss/tidss_kms.h b/drivers/gpu/drm/tidss/tidss_kms.h
index dda5625d0128..99aaff099f22 100644
--- a/drivers/gpu/drm/tidss/tidss_kms.h
+++ b/drivers/gpu/drm/tidss/tidss_kms.h
@@ -10,6 +10,5 @@
 struct tidss_device;
 
 int tidss_modeset_init(struct tidss_device *tidss);
-void tidss_modeset_cleanup(struct tidss_device *tidss);
 
 #endif
-- 
2.24.1

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 111+ messages in thread

* [PATCH 42/51] drm/gm12u320: More drmm_
  2020-03-02 22:25 [PATCH 00/51] drm_device managed resources, v4 Daniel Vetter
                   ` (40 preceding siblings ...)
  2020-03-02 22:26 ` [PATCH 41/51] drm/tidss: " Daniel Vetter
@ 2020-03-02 22:26 ` Daniel Vetter
  2020-03-02 22:26 ` [PATCH 43/51] drm/gm12u320: Use devm_drm_dev_init Daniel Vetter
                   ` (8 subsequent siblings)
  50 siblings, 0 replies; 111+ messages in thread
From: Daniel Vetter @ 2020-03-02 22:26 UTC (permalink / raw)
  To: DRI Development
  Cc: Daniel Vetter, Intel Graphics Development, Hans de Goede,
	Thomas Zimmermann, Daniel Vetter, Sam Ravnborg

The drm_mode_config_cleanup call we can drop, and all the allocations
we can switch over to drmm_kzalloc. Unfortunately the work queue is
still present, so can't get rid of the drm_driver->release function
outright.

v2: Use drmm_mode_config_init() for more clarity (Sam, Thomas)

Cc: Sam Ravnborg <sam@ravnborg.org>
Cc: Thomas Zimmermann <tzimmermann@suse.de>
Reviewed-by: Hans de Goede <hdegoede@redhat.com> (v1)
Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
Cc: Hans de Goede <hdegoede@redhat.com>
Cc: "Noralf Trønnes" <noralf@tronnes.org>
---
 drivers/gpu/drm/tiny/gm12u320.c | 18 +++++++-----------
 1 file changed, 7 insertions(+), 11 deletions(-)

diff --git a/drivers/gpu/drm/tiny/gm12u320.c b/drivers/gpu/drm/tiny/gm12u320.c
index 3928f69bbd3d..3349f3c2a765 100644
--- a/drivers/gpu/drm/tiny/gm12u320.c
+++ b/drivers/gpu/drm/tiny/gm12u320.c
@@ -160,7 +160,7 @@ static int gm12u320_usb_alloc(struct gm12u320_device *gm12u320)
 	int i, block_size;
 	const char *hdr;
 
-	gm12u320->cmd_buf = kmalloc(CMD_SIZE, GFP_KERNEL);
+	gm12u320->cmd_buf = drmm_kmalloc(&gm12u320->dev, CMD_SIZE, GFP_KERNEL);
 	if (!gm12u320->cmd_buf)
 		return -ENOMEM;
 
@@ -173,7 +173,8 @@ static int gm12u320_usb_alloc(struct gm12u320_device *gm12u320)
 			hdr = data_block_header;
 		}
 
-		gm12u320->data_buf[i] = kzalloc(block_size, GFP_KERNEL);
+		gm12u320->data_buf[i] = drmm_kzalloc(&gm12u320->dev,
+						     block_size, GFP_KERNEL);
 		if (!gm12u320->data_buf[i])
 			return -ENOMEM;
 
@@ -192,15 +193,8 @@ static int gm12u320_usb_alloc(struct gm12u320_device *gm12u320)
 
 static void gm12u320_usb_free(struct gm12u320_device *gm12u320)
 {
-	int i;
-
 	if (gm12u320->fb_update.workq)
 		destroy_workqueue(gm12u320->fb_update.workq);
-
-	for (i = 0; i < GM12U320_BLOCK_COUNT; i++)
-		kfree(gm12u320->data_buf[i]);
-
-	kfree(gm12u320->cmd_buf);
 }
 
 static int gm12u320_misc_request(struct gm12u320_device *gm12u320,
@@ -636,7 +630,6 @@ static void gm12u320_driver_release(struct drm_device *dev)
 	struct gm12u320_device *gm12u320 = dev->dev_private;
 
 	gm12u320_usb_free(gm12u320);
-	drm_mode_config_cleanup(dev);
 }
 
 DEFINE_DRM_GEM_FOPS(gm12u320_fops);
@@ -693,7 +686,10 @@ static int gm12u320_usb_probe(struct usb_interface *interface,
 	dev->dev_private = gm12u320;
 	drmm_add_final_kfree(dev, gm12u320);
 
-	drm_mode_config_init(dev);
+	ret = drmm_mode_config_init(dev);
+	if (ret)
+		goto err_put;
+
 	dev->mode_config.min_width = GM12U320_USER_WIDTH;
 	dev->mode_config.max_width = GM12U320_USER_WIDTH;
 	dev->mode_config.min_height = GM12U320_HEIGHT;
-- 
2.24.1

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 111+ messages in thread

* [PATCH 43/51] drm/gm12u320: Use devm_drm_dev_init
  2020-03-02 22:25 [PATCH 00/51] drm_device managed resources, v4 Daniel Vetter
                   ` (41 preceding siblings ...)
  2020-03-02 22:26 ` [PATCH 42/51] drm/gm12u320: More drmm_ Daniel Vetter
@ 2020-03-02 22:26 ` Daniel Vetter
  2020-03-02 22:26 ` [PATCH 44/51] drm/gm12u320: Use helpers for shutdown/suspend/resume Daniel Vetter
                   ` (7 subsequent siblings)
  50 siblings, 0 replies; 111+ messages in thread
From: Daniel Vetter @ 2020-03-02 22:26 UTC (permalink / raw)
  To: DRI Development
  Cc: Daniel Vetter, Daniel Vetter, Intel Graphics Development, Hans de Goede

Only drops the drm_dev_put, but hey a few lines!

Reviewed-by: Hans de Goede <hdegoede@redhat.com>
Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
Cc: Hans de Goede <hdegoede@redhat.com>
Cc: "Noralf Trønnes" <noralf@tronnes.org>
---
 drivers/gpu/drm/tiny/gm12u320.c | 19 +++++++------------
 1 file changed, 7 insertions(+), 12 deletions(-)

diff --git a/drivers/gpu/drm/tiny/gm12u320.c b/drivers/gpu/drm/tiny/gm12u320.c
index 3349f3c2a765..9fb579fc3412 100644
--- a/drivers/gpu/drm/tiny/gm12u320.c
+++ b/drivers/gpu/drm/tiny/gm12u320.c
@@ -678,7 +678,7 @@ static int gm12u320_usb_probe(struct usb_interface *interface,
 	init_waitqueue_head(&gm12u320->fb_update.waitq);
 
 	dev = &gm12u320->dev;
-	ret = drm_dev_init(dev, &gm12u320_drm_driver, &interface->dev);
+	ret = devm_drm_dev_init(&interface->dev, dev, &gm12u320_drm_driver);
 	if (ret) {
 		kfree(gm12u320);
 		return ret;
@@ -688,7 +688,7 @@ static int gm12u320_usb_probe(struct usb_interface *interface,
 
 	ret = drmm_mode_config_init(dev);
 	if (ret)
-		goto err_put;
+		return ret;
 
 	dev->mode_config.min_width = GM12U320_USER_WIDTH;
 	dev->mode_config.max_width = GM12U320_USER_WIDTH;
@@ -698,15 +698,15 @@ static int gm12u320_usb_probe(struct usb_interface *interface,
 
 	ret = gm12u320_usb_alloc(gm12u320);
 	if (ret)
-		goto err_put;
+		return ret;
 
 	ret = gm12u320_set_ecomode(gm12u320);
 	if (ret)
-		goto err_put;
+		return ret;
 
 	ret = gm12u320_conn_init(gm12u320);
 	if (ret)
-		goto err_put;
+		return ret;
 
 	ret = drm_simple_display_pipe_init(&gm12u320->dev,
 					   &gm12u320->pipe,
@@ -716,22 +716,18 @@ static int gm12u320_usb_probe(struct usb_interface *interface,
 					   gm12u320_pipe_modifiers,
 					   &gm12u320->conn);
 	if (ret)
-		goto err_put;
+		return ret;
 
 	drm_mode_config_reset(dev);
 
 	usb_set_intfdata(interface, dev);
 	ret = drm_dev_register(dev, 0);
 	if (ret)
-		goto err_put;
+		return ret;
 
 	drm_fbdev_generic_setup(dev, 0);
 
 	return 0;
-
-err_put:
-	drm_dev_put(dev);
-	return ret;
 }
 
 static void gm12u320_usb_disconnect(struct usb_interface *interface)
@@ -741,7 +737,6 @@ static void gm12u320_usb_disconnect(struct usb_interface *interface)
 
 	gm12u320_stop_fb_update(gm12u320);
 	drm_dev_unplug(dev);
-	drm_dev_put(dev);
 }
 
 static __maybe_unused int gm12u320_suspend(struct usb_interface *interface,
-- 
2.24.1

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 111+ messages in thread

* [PATCH 44/51] drm/gm12u320: Use helpers for shutdown/suspend/resume
  2020-03-02 22:25 [PATCH 00/51] drm_device managed resources, v4 Daniel Vetter
                   ` (42 preceding siblings ...)
  2020-03-02 22:26 ` [PATCH 43/51] drm/gm12u320: Use devm_drm_dev_init Daniel Vetter
@ 2020-03-02 22:26 ` Daniel Vetter
  2020-03-02 22:26 ` [PATCH 45/51] drm/gm12u320: Simplify upload work Daniel Vetter
                   ` (6 subsequent siblings)
  50 siblings, 0 replies; 111+ messages in thread
From: Daniel Vetter @ 2020-03-02 22:26 UTC (permalink / raw)
  To: DRI Development
  Cc: Daniel Vetter, Daniel Vetter, Intel Graphics Development, Hans de Goede

Also there's a race in the disconnect implemenation. First shut
down, then unplug, leaves a window where userspace could sneak
in and restart the entire machinery.

With this we can also delete the very un-atomic global pipe_enabled
tracking.

Reviewed-by: Hans de Goede <hdegoede@redhat.com>
Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
Cc: Hans de Goede <hdegoede@redhat.com>
Cc: "Noralf Trønnes" <noralf@tronnes.org>
---
 drivers/gpu/drm/tiny/gm12u320.c | 16 +++-------------
 1 file changed, 3 insertions(+), 13 deletions(-)

diff --git a/drivers/gpu/drm/tiny/gm12u320.c b/drivers/gpu/drm/tiny/gm12u320.c
index 9fb579fc3412..9627cbc3ec64 100644
--- a/drivers/gpu/drm/tiny/gm12u320.c
+++ b/drivers/gpu/drm/tiny/gm12u320.c
@@ -88,7 +88,6 @@ struct gm12u320_device {
 	struct usb_device               *udev;
 	unsigned char                   *cmd_buf;
 	unsigned char                   *data_buf[GM12U320_BLOCK_COUNT];
-	bool                             pipe_enabled;
 	struct {
 		bool                     run;
 		struct workqueue_struct *workq;
@@ -589,7 +588,6 @@ static void gm12u320_pipe_enable(struct drm_simple_display_pipe *pipe,
 
 	gm12u320_fb_mark_dirty(plane_state->fb, &rect);
 	gm12u320_start_fb_update(gm12u320);
-	gm12u320->pipe_enabled = true;
 }
 
 static void gm12u320_pipe_disable(struct drm_simple_display_pipe *pipe)
@@ -597,7 +595,6 @@ static void gm12u320_pipe_disable(struct drm_simple_display_pipe *pipe)
 	struct gm12u320_device *gm12u320 = pipe->crtc.dev->dev_private;
 
 	gm12u320_stop_fb_update(gm12u320);
-	gm12u320->pipe_enabled = false;
 }
 
 static void gm12u320_pipe_update(struct drm_simple_display_pipe *pipe,
@@ -733,22 +730,17 @@ static int gm12u320_usb_probe(struct usb_interface *interface,
 static void gm12u320_usb_disconnect(struct usb_interface *interface)
 {
 	struct drm_device *dev = usb_get_intfdata(interface);
-	struct gm12u320_device *gm12u320 = dev->dev_private;
 
-	gm12u320_stop_fb_update(gm12u320);
 	drm_dev_unplug(dev);
+	drm_atomic_helper_shutdown(dev);
 }
 
 static __maybe_unused int gm12u320_suspend(struct usb_interface *interface,
 					   pm_message_t message)
 {
 	struct drm_device *dev = usb_get_intfdata(interface);
-	struct gm12u320_device *gm12u320 = dev->dev_private;
 
-	if (gm12u320->pipe_enabled)
-		gm12u320_stop_fb_update(gm12u320);
-
-	return 0;
+	return drm_mode_config_helper_suspend(dev);
 }
 
 static __maybe_unused int gm12u320_resume(struct usb_interface *interface)
@@ -757,10 +749,8 @@ static __maybe_unused int gm12u320_resume(struct usb_interface *interface)
 	struct gm12u320_device *gm12u320 = dev->dev_private;
 
 	gm12u320_set_ecomode(gm12u320);
-	if (gm12u320->pipe_enabled)
-		gm12u320_start_fb_update(gm12u320);
 
-	return 0;
+	return drm_mode_config_helper_resume(dev);
 }
 
 static const struct usb_device_id id_table[] = {
-- 
2.24.1

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 111+ messages in thread

* [PATCH 45/51] drm/gm12u320: Simplify upload work
  2020-03-02 22:25 [PATCH 00/51] drm_device managed resources, v4 Daniel Vetter
                   ` (43 preceding siblings ...)
  2020-03-02 22:26 ` [PATCH 44/51] drm/gm12u320: Use helpers for shutdown/suspend/resume Daniel Vetter
@ 2020-03-02 22:26 ` Daniel Vetter
  2020-03-02 22:26 ` [PATCH 46/51] drm/repaper: Drop explicit drm_mode_config_cleanup call Daniel Vetter
                   ` (5 subsequent siblings)
  50 siblings, 0 replies; 111+ messages in thread
From: Daniel Vetter @ 2020-03-02 22:26 UTC (permalink / raw)
  To: DRI Development
  Cc: Daniel Vetter, Daniel Vetter, Intel Graphics Development, Hans de Goede

Instead of having a work item that never stops (which really should be
a kthread), with a dedicated workqueue to not upset anyone else, use a
delayed work. A bunch of changes:

- We can throw out all the custom wakeup and requeue logic and state
  tracking. If we schedule the work with a 0 delay it'll get
  scheduled immediately.

- Persistent state (frame & draw_status_timeout) need to be moved out
  of the work.

- diff is bigger than the changes, biggest chunk is reindenting the
  work fn because it lost its while loop.

Lots of code deleting as consequence all over. Specifically we can
delete the drm_driver.release code now!

v2: Review from Hans:
- Use mod_delayed_work in the plane update path to make sure we do
  actually schedule immediately). In the worker we still want
  queue_delayed_work, which won't modify the timeout when the work is
  already scheduled. Which is exactly what we want if the work races
  with a plane update.
- Switch to system_long_wq, Hans says on usb2 a plane upload can take
  80 ms.

Reviewed-by: Hans de Goede <hdegoede@redhat.com>
Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
Cc: Hans de Goede <hdegoede@redhat.com>
Cc: "Noralf Trønnes" <noralf@tronnes.org>
---
 drivers/gpu/drm/tiny/gm12u320.c | 171 +++++++++++++-------------------
 1 file changed, 68 insertions(+), 103 deletions(-)

diff --git a/drivers/gpu/drm/tiny/gm12u320.c b/drivers/gpu/drm/tiny/gm12u320.c
index 9627cbc3ec64..6f0ea2827d62 100644
--- a/drivers/gpu/drm/tiny/gm12u320.c
+++ b/drivers/gpu/drm/tiny/gm12u320.c
@@ -89,13 +89,12 @@ struct gm12u320_device {
 	unsigned char                   *cmd_buf;
 	unsigned char                   *data_buf[GM12U320_BLOCK_COUNT];
 	struct {
-		bool                     run;
-		struct workqueue_struct *workq;
-		struct work_struct       work;
-		wait_queue_head_t        waitq;
+		struct delayed_work       work;
 		struct mutex             lock;
 		struct drm_framebuffer  *fb;
 		struct drm_rect          rect;
+		int frame;
+		int draw_status_timeout;
 	} fb_update;
 };
 
@@ -183,19 +182,9 @@ static int gm12u320_usb_alloc(struct gm12u320_device *gm12u320)
 		       data_block_footer, DATA_BLOCK_FOOTER_SIZE);
 	}
 
-	gm12u320->fb_update.workq = create_singlethread_workqueue(DRIVER_NAME);
-	if (!gm12u320->fb_update.workq)
-		return -ENOMEM;
-
 	return 0;
 }
 
-static void gm12u320_usb_free(struct gm12u320_device *gm12u320)
-{
-	if (gm12u320->fb_update.workq)
-		destroy_workqueue(gm12u320->fb_update.workq);
-}
-
 static int gm12u320_misc_request(struct gm12u320_device *gm12u320,
 				 u8 req_a, u8 req_b,
 				 u8 arg_a, u8 arg_b, u8 arg_c, u8 arg_d)
@@ -338,80 +327,77 @@ static void gm12u320_copy_fb_to_blocks(struct gm12u320_device *gm12u320)
 static void gm12u320_fb_update_work(struct work_struct *work)
 {
 	struct gm12u320_device *gm12u320 =
-		container_of(work, struct gm12u320_device, fb_update.work);
-	int draw_status_timeout = FIRST_FRAME_TIMEOUT;
+		container_of(to_delayed_work(work), struct gm12u320_device,
+			     fb_update.work);
 	int block, block_size, len;
-	int frame = 0;
 	int ret = 0;
 
-	while (gm12u320->fb_update.run) {
-		gm12u320_copy_fb_to_blocks(gm12u320);
-
-		for (block = 0; block < GM12U320_BLOCK_COUNT; block++) {
-			if (block == GM12U320_BLOCK_COUNT - 1)
-				block_size = DATA_LAST_BLOCK_SIZE;
-			else
-				block_size = DATA_BLOCK_SIZE;
-
-			/* Send data command to device */
-			memcpy(gm12u320->cmd_buf, cmd_data, CMD_SIZE);
-			gm12u320->cmd_buf[8] = block_size & 0xff;
-			gm12u320->cmd_buf[9] = block_size >> 8;
-			gm12u320->cmd_buf[20] = 0xfc - block * 4;
-			gm12u320->cmd_buf[21] = block | (frame << 7);
-
-			ret = usb_bulk_msg(gm12u320->udev,
-				usb_sndbulkpipe(gm12u320->udev, DATA_SND_EPT),
-				gm12u320->cmd_buf, CMD_SIZE, &len,
-				CMD_TIMEOUT);
-			if (ret || len != CMD_SIZE)
-				goto err;
-
-			/* Send data block to device */
-			ret = usb_bulk_msg(gm12u320->udev,
-				usb_sndbulkpipe(gm12u320->udev, DATA_SND_EPT),
-				gm12u320->data_buf[block], block_size,
-				&len, DATA_TIMEOUT);
-			if (ret || len != block_size)
-				goto err;
-
-			/* Read status */
-			ret = usb_bulk_msg(gm12u320->udev,
-				usb_rcvbulkpipe(gm12u320->udev, DATA_RCV_EPT),
-				gm12u320->cmd_buf, READ_STATUS_SIZE, &len,
-				CMD_TIMEOUT);
-			if (ret || len != READ_STATUS_SIZE)
-				goto err;
-		}
+	gm12u320_copy_fb_to_blocks(gm12u320);
+
+	for (block = 0; block < GM12U320_BLOCK_COUNT; block++) {
+		if (block == GM12U320_BLOCK_COUNT - 1)
+			block_size = DATA_LAST_BLOCK_SIZE;
+		else
+			block_size = DATA_BLOCK_SIZE;
+
+		/* Send data command to device */
+		memcpy(gm12u320->cmd_buf, cmd_data, CMD_SIZE);
+		gm12u320->cmd_buf[8] = block_size & 0xff;
+		gm12u320->cmd_buf[9] = block_size >> 8;
+		gm12u320->cmd_buf[20] = 0xfc - block * 4;
+		gm12u320->cmd_buf[21] =
+			block | (gm12u320->fb_update.frame << 7);
 
-		/* Send draw command to device */
-		memcpy(gm12u320->cmd_buf, cmd_draw, CMD_SIZE);
 		ret = usb_bulk_msg(gm12u320->udev,
 			usb_sndbulkpipe(gm12u320->udev, DATA_SND_EPT),
-			gm12u320->cmd_buf, CMD_SIZE, &len, CMD_TIMEOUT);
+			gm12u320->cmd_buf, CMD_SIZE, &len,
+			CMD_TIMEOUT);
 		if (ret || len != CMD_SIZE)
 			goto err;
 
+		/* Send data block to device */
+		ret = usb_bulk_msg(gm12u320->udev,
+			usb_sndbulkpipe(gm12u320->udev, DATA_SND_EPT),
+			gm12u320->data_buf[block], block_size,
+			&len, DATA_TIMEOUT);
+		if (ret || len != block_size)
+			goto err;
+
 		/* Read status */
 		ret = usb_bulk_msg(gm12u320->udev,
 			usb_rcvbulkpipe(gm12u320->udev, DATA_RCV_EPT),
 			gm12u320->cmd_buf, READ_STATUS_SIZE, &len,
-			draw_status_timeout);
+			CMD_TIMEOUT);
 		if (ret || len != READ_STATUS_SIZE)
 			goto err;
-
-		draw_status_timeout = CMD_TIMEOUT;
-		frame = !frame;
-
-		/*
-		 * We must draw a frame every 2s otherwise the projector
-		 * switches back to showing its logo.
-		 */
-		wait_event_timeout(gm12u320->fb_update.waitq,
-				   !gm12u320->fb_update.run ||
-					gm12u320->fb_update.fb != NULL,
-				   IDLE_TIMEOUT);
 	}
+
+	/* Send draw command to device */
+	memcpy(gm12u320->cmd_buf, cmd_draw, CMD_SIZE);
+	ret = usb_bulk_msg(gm12u320->udev,
+		usb_sndbulkpipe(gm12u320->udev, DATA_SND_EPT),
+		gm12u320->cmd_buf, CMD_SIZE, &len, CMD_TIMEOUT);
+	if (ret || len != CMD_SIZE)
+		goto err;
+
+	/* Read status */
+	ret = usb_bulk_msg(gm12u320->udev,
+		usb_rcvbulkpipe(gm12u320->udev, DATA_RCV_EPT),
+		gm12u320->cmd_buf, READ_STATUS_SIZE, &len,
+		gm12u320->fb_update.draw_status_timeout);
+	if (ret || len != READ_STATUS_SIZE)
+		goto err;
+
+	gm12u320->fb_update.draw_status_timeout = CMD_TIMEOUT;
+	gm12u320->fb_update.frame = !gm12u320->fb_update.frame;
+
+	/*
+	 * We must draw a frame every 2s otherwise the projector
+	 * switches back to showing its logo.
+	 */
+	queue_delayed_work(system_long_wq, &gm12u320->fb_update.work,
+			   IDLE_TIMEOUT);
+
 	return;
 err:
 	/* Do not log errors caused by module unload or device unplug */
@@ -446,36 +432,24 @@ static void gm12u320_fb_mark_dirty(struct drm_framebuffer *fb,
 	mutex_unlock(&gm12u320->fb_update.lock);
 
 	if (wakeup)
-		wake_up(&gm12u320->fb_update.waitq);
+		mod_delayed_work(system_long_wq, &gm12u320->fb_update.work, 0);
 
 	if (old_fb)
 		drm_framebuffer_put(old_fb);
 }
 
-static void gm12u320_start_fb_update(struct gm12u320_device *gm12u320)
-{
-	mutex_lock(&gm12u320->fb_update.lock);
-	gm12u320->fb_update.run = true;
-	mutex_unlock(&gm12u320->fb_update.lock);
-
-	queue_work(gm12u320->fb_update.workq, &gm12u320->fb_update.work);
-}
-
 static void gm12u320_stop_fb_update(struct gm12u320_device *gm12u320)
 {
-	mutex_lock(&gm12u320->fb_update.lock);
-	gm12u320->fb_update.run = false;
-	mutex_unlock(&gm12u320->fb_update.lock);
+	struct drm_framebuffer *old_fb;
 
-	wake_up(&gm12u320->fb_update.waitq);
-	cancel_work_sync(&gm12u320->fb_update.work);
+	cancel_delayed_work_sync(&gm12u320->fb_update.work);
 
 	mutex_lock(&gm12u320->fb_update.lock);
-	if (gm12u320->fb_update.fb) {
-		drm_framebuffer_put(gm12u320->fb_update.fb);
-		gm12u320->fb_update.fb = NULL;
-	}
+	old_fb = gm12u320->fb_update.fb;
+	gm12u320->fb_update.fb = NULL;
 	mutex_unlock(&gm12u320->fb_update.lock);
+
+	drm_framebuffer_put(old_fb);
 }
 
 static int gm12u320_set_ecomode(struct gm12u320_device *gm12u320)
@@ -583,11 +557,11 @@ static void gm12u320_pipe_enable(struct drm_simple_display_pipe *pipe,
 				 struct drm_crtc_state *crtc_state,
 				 struct drm_plane_state *plane_state)
 {
-	struct gm12u320_device *gm12u320 = pipe->crtc.dev->dev_private;
 	struct drm_rect rect = { 0, 0, GM12U320_USER_WIDTH, GM12U320_HEIGHT };
+	struct gm12u320_device *gm12u320 = pipe->crtc.dev->dev_private;
 
+	gm12u320->fb_update.draw_status_timeout = FIRST_FRAME_TIMEOUT;
 	gm12u320_fb_mark_dirty(plane_state->fb, &rect);
-	gm12u320_start_fb_update(gm12u320);
 }
 
 static void gm12u320_pipe_disable(struct drm_simple_display_pipe *pipe)
@@ -622,13 +596,6 @@ static const uint64_t gm12u320_pipe_modifiers[] = {
 	DRM_FORMAT_MOD_INVALID
 };
 
-static void gm12u320_driver_release(struct drm_device *dev)
-{
-	struct gm12u320_device *gm12u320 = dev->dev_private;
-
-	gm12u320_usb_free(gm12u320);
-}
-
 DEFINE_DRM_GEM_FOPS(gm12u320_fops);
 
 static struct drm_driver gm12u320_drm_driver = {
@@ -640,7 +607,6 @@ static struct drm_driver gm12u320_drm_driver = {
 	.major		 = DRIVER_MAJOR,
 	.minor		 = DRIVER_MINOR,
 
-	.release	 = gm12u320_driver_release,
 	.fops		 = &gm12u320_fops,
 	DRM_GEM_SHMEM_DRIVER_OPS,
 };
@@ -670,9 +636,8 @@ static int gm12u320_usb_probe(struct usb_interface *interface,
 		return -ENOMEM;
 
 	gm12u320->udev = interface_to_usbdev(interface);
-	INIT_WORK(&gm12u320->fb_update.work, gm12u320_fb_update_work);
+	INIT_DELAYED_WORK(&gm12u320->fb_update.work, gm12u320_fb_update_work);
 	mutex_init(&gm12u320->fb_update.lock);
-	init_waitqueue_head(&gm12u320->fb_update.waitq);
 
 	dev = &gm12u320->dev;
 	ret = devm_drm_dev_init(&interface->dev, dev, &gm12u320_drm_driver);
-- 
2.24.1

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 111+ messages in thread

* [PATCH 46/51] drm/repaper: Drop explicit drm_mode_config_cleanup call
  2020-03-02 22:25 [PATCH 00/51] drm_device managed resources, v4 Daniel Vetter
                   ` (44 preceding siblings ...)
  2020-03-02 22:26 ` [PATCH 45/51] drm/gm12u320: Simplify upload work Daniel Vetter
@ 2020-03-02 22:26 ` Daniel Vetter
  2020-03-07  9:31   ` Sam Ravnborg
  2020-03-02 22:26 ` [PATCH 47/51] drm/mipi-dbi: Move drm_mode_config_init into mipi library Daniel Vetter
                   ` (4 subsequent siblings)
  50 siblings, 1 reply; 111+ messages in thread
From: Daniel Vetter @ 2020-03-02 22:26 UTC (permalink / raw)
  To: DRI Development
  Cc: Daniel Vetter, Intel Graphics Development, Laurent Pinchart,
	Thomas Zimmermann, Daniel Vetter, Sam Ravnborg

Allows us to drop the drm_driver.release callback.

This is made possible by a preceeding patch which added a drmm_
cleanup action to drm_mode_config_init(), hence all we need to do to
ensure that drm_mode_config_cleanup() is run on final drm_device
cleanup is check the new error code for _init().

v2: Explain why this cleanup is possible (Laurent).

v3: Use drmm_mode_config_init() for more clarity (Sam, Thomas)
I also noticed that I've failed to add the error checking,
__must_check caught that.

Cc: Sam Ravnborg <sam@ravnborg.org>
Cc: Thomas Zimmermann <tzimmermann@suse.de>
Cc: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Noralf Trønnes <noralf@tronnes.org> (v2)
Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
Cc: "Noralf Trønnes" <noralf@tronnes.org>
---
 drivers/gpu/drm/tiny/repaper.c | 12 +++---------
 1 file changed, 3 insertions(+), 9 deletions(-)

diff --git a/drivers/gpu/drm/tiny/repaper.c b/drivers/gpu/drm/tiny/repaper.c
index 4741ff670ec9..862c3ee6055d 100644
--- a/drivers/gpu/drm/tiny/repaper.c
+++ b/drivers/gpu/drm/tiny/repaper.c
@@ -909,13 +909,6 @@ static const struct drm_mode_config_funcs repaper_mode_config_funcs = {
 	.atomic_commit = drm_atomic_helper_commit,
 };
 
-static void repaper_release(struct drm_device *drm)
-{
-	DRM_DEBUG_DRIVER("\n");
-
-	drm_mode_config_cleanup(drm);
-}
-
 static const uint32_t repaper_formats[] = {
 	DRM_FORMAT_XRGB8888,
 };
@@ -953,7 +946,6 @@ DEFINE_DRM_GEM_CMA_FOPS(repaper_fops);
 static struct drm_driver repaper_driver = {
 	.driver_features	= DRIVER_GEM | DRIVER_MODESET | DRIVER_ATOMIC,
 	.fops			= &repaper_fops,
-	.release		= repaper_release,
 	DRM_GEM_CMA_VMAP_DRIVER_OPS,
 	.name			= "repaper",
 	.desc			= "Pervasive Displays RePaper e-ink panels",
@@ -1023,7 +1015,9 @@ static int repaper_probe(struct spi_device *spi)
 	}
 	drmm_add_final_kfree(drm, epd);
 
-	drm_mode_config_init(drm);
+	ret = drmm_mode_config_init(drm);
+	if (ret)
+		return ret;
 	drm->mode_config.funcs = &repaper_mode_config_funcs;
 
 	epd->spi = spi;
-- 
2.24.1

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 111+ messages in thread

* [PATCH 47/51] drm/mipi-dbi: Move drm_mode_config_init into mipi library
  2020-03-02 22:25 [PATCH 00/51] drm_device managed resources, v4 Daniel Vetter
                   ` (45 preceding siblings ...)
  2020-03-02 22:26 ` [PATCH 46/51] drm/repaper: Drop explicit drm_mode_config_cleanup call Daniel Vetter
@ 2020-03-02 22:26 ` Daniel Vetter
  2020-03-02 22:26 ` [PATCH 48/51] drm/mipi-dbi: Drop explicit drm_mode_config_cleanup call Daniel Vetter
                   ` (3 subsequent siblings)
  50 siblings, 0 replies; 111+ messages in thread
From: Daniel Vetter @ 2020-03-02 22:26 UTC (permalink / raw)
  To: DRI Development
  Cc: David Airlie, Daniel Vetter, Intel Graphics Development,
	Thomas Zimmermann, Daniel Vetter, Kamlesh Gurudasani,
	Sam Ravnborg, David Lechner

7/7 drivers agree that's the right choice, let's do this.

This avoids duplicating the same old error checking code over all 7
drivers, which is the motivation here.

Acked-by: Sam Ravnborg <sam@ravnborg.org>
Reviewed-by: Noralf Trønnes <noralf@tronnes.org>
Tested-by: Noralf Trønnes <noralf@tronnes.org>
Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
Cc: Maxime Ripard <mripard@kernel.org>
Cc: Thomas Zimmermann <tzimmermann@suse.de>
Cc: David Airlie <airlied@linux.ie>
Cc: Daniel Vetter <daniel@ffwll.ch>
Cc: Eric Anholt <eric@anholt.net>
Cc: David Lechner <david@lechnology.com>
Cc: Kamlesh Gurudasani <kamlesh.gurudasani@gmail.com>
Cc: "Noralf Trønnes" <noralf@tronnes.org>
Cc: Sam Ravnborg <sam@ravnborg.org>
---
 drivers/gpu/drm/drm_mipi_dbi.c  | 4 ++++
 drivers/gpu/drm/tiny/hx8357d.c  | 2 --
 drivers/gpu/drm/tiny/ili9225.c  | 2 --
 drivers/gpu/drm/tiny/ili9341.c  | 2 --
 drivers/gpu/drm/tiny/ili9486.c  | 2 --
 drivers/gpu/drm/tiny/mi0283qt.c | 2 --
 drivers/gpu/drm/tiny/st7586.c   | 2 --
 drivers/gpu/drm/tiny/st7735r.c  | 2 --
 8 files changed, 4 insertions(+), 14 deletions(-)

diff --git a/drivers/gpu/drm/drm_mipi_dbi.c b/drivers/gpu/drm/drm_mipi_dbi.c
index a678e07508d4..9de1586659be 100644
--- a/drivers/gpu/drm/drm_mipi_dbi.c
+++ b/drivers/gpu/drm/drm_mipi_dbi.c
@@ -510,6 +510,10 @@ int mipi_dbi_dev_init_with_formats(struct mipi_dbi_dev *dbidev,
 	if (!dbidev->dbi.command)
 		return -EINVAL;
 
+	ret = drm_mode_config_init(drm);
+	if (ret)
+		return ret;
+
 	dbidev->tx_buf = devm_kmalloc(drm->dev, tx_buf_size, GFP_KERNEL);
 	if (!dbidev->tx_buf)
 		return -ENOMEM;
diff --git a/drivers/gpu/drm/tiny/hx8357d.c b/drivers/gpu/drm/tiny/hx8357d.c
index 42bc5dadcb1c..c88b84366dc5 100644
--- a/drivers/gpu/drm/tiny/hx8357d.c
+++ b/drivers/gpu/drm/tiny/hx8357d.c
@@ -239,8 +239,6 @@ static int hx8357d_probe(struct spi_device *spi)
 	}
 	drmm_add_final_kfree(drm, dbidev);
 
-	drm_mode_config_init(drm);
-
 	dc = devm_gpiod_get(dev, "dc", GPIOD_OUT_LOW);
 	if (IS_ERR(dc)) {
 		DRM_DEV_ERROR(dev, "Failed to get gpio 'dc'\n");
diff --git a/drivers/gpu/drm/tiny/ili9225.c b/drivers/gpu/drm/tiny/ili9225.c
index aae88dc5b3f7..fa998a16026c 100644
--- a/drivers/gpu/drm/tiny/ili9225.c
+++ b/drivers/gpu/drm/tiny/ili9225.c
@@ -390,8 +390,6 @@ static int ili9225_probe(struct spi_device *spi)
 	}
 	drmm_add_final_kfree(drm, dbidev);
 
-	drm_mode_config_init(drm);
-
 	dbi->reset = devm_gpiod_get(dev, "reset", GPIOD_OUT_HIGH);
 	if (IS_ERR(dbi->reset)) {
 		DRM_DEV_ERROR(dev, "Failed to get gpio 'reset'\n");
diff --git a/drivers/gpu/drm/tiny/ili9341.c b/drivers/gpu/drm/tiny/ili9341.c
index 7d40cb4ff72b..945e15169866 100644
--- a/drivers/gpu/drm/tiny/ili9341.c
+++ b/drivers/gpu/drm/tiny/ili9341.c
@@ -197,8 +197,6 @@ static int ili9341_probe(struct spi_device *spi)
 	}
 	drmm_add_final_kfree(drm, dbidev);
 
-	drm_mode_config_init(drm);
-
 	dbi->reset = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_HIGH);
 	if (IS_ERR(dbi->reset)) {
 		DRM_DEV_ERROR(dev, "Failed to get gpio 'reset'\n");
diff --git a/drivers/gpu/drm/tiny/ili9486.c b/drivers/gpu/drm/tiny/ili9486.c
index 7d735fc67498..38d293cf5377 100644
--- a/drivers/gpu/drm/tiny/ili9486.c
+++ b/drivers/gpu/drm/tiny/ili9486.c
@@ -211,8 +211,6 @@ static int ili9486_probe(struct spi_device *spi)
 	}
 	drmm_add_final_kfree(drm, dbidev);
 
-	drm_mode_config_init(drm);
-
 	dbi->reset = devm_gpiod_get(dev, "reset", GPIOD_OUT_HIGH);
 	if (IS_ERR(dbi->reset)) {
 		DRM_DEV_ERROR(dev, "Failed to get gpio 'reset'\n");
diff --git a/drivers/gpu/drm/tiny/mi0283qt.c b/drivers/gpu/drm/tiny/mi0283qt.c
index 8555a56bce8c..b8c973bc2347 100644
--- a/drivers/gpu/drm/tiny/mi0283qt.c
+++ b/drivers/gpu/drm/tiny/mi0283qt.c
@@ -201,8 +201,6 @@ static int mi0283qt_probe(struct spi_device *spi)
 	}
 	drmm_add_final_kfree(drm, dbidev);
 
-	drm_mode_config_init(drm);
-
 	dbi->reset = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_HIGH);
 	if (IS_ERR(dbi->reset)) {
 		DRM_DEV_ERROR(dev, "Failed to get gpio 'reset'\n");
diff --git a/drivers/gpu/drm/tiny/st7586.c b/drivers/gpu/drm/tiny/st7586.c
index 427c2561f5f4..1f1a576be93c 100644
--- a/drivers/gpu/drm/tiny/st7586.c
+++ b/drivers/gpu/drm/tiny/st7586.c
@@ -331,8 +331,6 @@ static int st7586_probe(struct spi_device *spi)
 	}
 	drmm_add_final_kfree(drm, dbidev);
 
-	drm_mode_config_init(drm);
-
 	bufsize = (st7586_mode.vdisplay + 2) / 3 * st7586_mode.hdisplay;
 
 	dbi->reset = devm_gpiod_get(dev, "reset", GPIOD_OUT_HIGH);
diff --git a/drivers/gpu/drm/tiny/st7735r.c b/drivers/gpu/drm/tiny/st7735r.c
index b447235c3d47..0f48a5a2d3d7 100644
--- a/drivers/gpu/drm/tiny/st7735r.c
+++ b/drivers/gpu/drm/tiny/st7735r.c
@@ -212,8 +212,6 @@ static int st7735r_probe(struct spi_device *spi)
 	}
 	drmm_add_final_kfree(drm, dbidev);
 
-	drm_mode_config_init(drm);
-
 	dbi->reset = devm_gpiod_get(dev, "reset", GPIOD_OUT_HIGH);
 	if (IS_ERR(dbi->reset)) {
 		DRM_DEV_ERROR(dev, "Failed to get gpio 'reset'\n");
-- 
2.24.1

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 111+ messages in thread

* [PATCH 48/51] drm/mipi-dbi: Drop explicit drm_mode_config_cleanup call
  2020-03-02 22:25 [PATCH 00/51] drm_device managed resources, v4 Daniel Vetter
                   ` (46 preceding siblings ...)
  2020-03-02 22:26 ` [PATCH 47/51] drm/mipi-dbi: Move drm_mode_config_init into mipi library Daniel Vetter
@ 2020-03-02 22:26 ` Daniel Vetter
  2020-03-02 22:26 ` [PATCH 49/51] drm/udl: " Daniel Vetter
                   ` (2 subsequent siblings)
  50 siblings, 0 replies; 111+ messages in thread
From: Daniel Vetter @ 2020-03-02 22:26 UTC (permalink / raw)
  To: DRI Development
  Cc: David Airlie, Daniel Vetter, Intel Graphics Development,
	Laurent Pinchart, Thomas Zimmermann, Daniel Vetter,
	Kamlesh Gurudasani, Sam Ravnborg, David Lechner

Allows us to drop the drm_driver.release callback from all
drivers, and remove the mipi_dbi_release() function.

This is made possible by a preceeding patch which added a drmm_
cleanup action to drm_mode_config_init(), hence all we need to do to
ensure that drm_mode_config_cleanup() is run on final drm_device
cleanup is check the new error code for _init().

v2: Explain why this cleanup is possible (Laurent).

v3: Use drmm_mode_config_init() for more clarity (Sam, Thomas)

Cc: Sam Ravnborg <sam@ravnborg.org>
Cc: Thomas Zimmermann <tzimmermann@suse.de>
Acked-by: Sam Ravnborg <sam@ravnborg.org>
Cc: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Noralf Trønnes <noralf@tronnes.org> (v2)
Tested-by: Noralf Trønnes <noralf@tronnes.org>
Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
Cc: Maxime Ripard <mripard@kernel.org>
Cc: Thomas Zimmermann <tzimmermann@suse.de>
Cc: David Airlie <airlied@linux.ie>
Cc: Daniel Vetter <daniel@ffwll.ch>
Cc: Eric Anholt <eric@anholt.net>
Cc: David Lechner <david@lechnology.com>
Cc: Kamlesh Gurudasani <kamlesh.gurudasani@gmail.com>
Cc: "Noralf Trønnes" <noralf@tronnes.org>
Cc: Sam Ravnborg <sam@ravnborg.org>
---
 drivers/gpu/drm/drm_mipi_dbi.c  | 18 +-----------------
 drivers/gpu/drm/tiny/hx8357d.c  |  1 -
 drivers/gpu/drm/tiny/ili9225.c  |  1 -
 drivers/gpu/drm/tiny/ili9341.c  |  1 -
 drivers/gpu/drm/tiny/ili9486.c  |  1 -
 drivers/gpu/drm/tiny/mi0283qt.c |  1 -
 drivers/gpu/drm/tiny/st7586.c   |  1 -
 drivers/gpu/drm/tiny/st7735r.c  |  1 -
 include/drm/drm_mipi_dbi.h      |  1 -
 9 files changed, 1 insertion(+), 25 deletions(-)

diff --git a/drivers/gpu/drm/drm_mipi_dbi.c b/drivers/gpu/drm/drm_mipi_dbi.c
index 9de1586659be..604f9d971649 100644
--- a/drivers/gpu/drm/drm_mipi_dbi.c
+++ b/drivers/gpu/drm/drm_mipi_dbi.c
@@ -510,7 +510,7 @@ int mipi_dbi_dev_init_with_formats(struct mipi_dbi_dev *dbidev,
 	if (!dbidev->dbi.command)
 		return -EINVAL;
 
-	ret = drm_mode_config_init(drm);
+	ret = drmm_mode_config_init(drm);
 	if (ret)
 		return ret;
 
@@ -582,22 +582,6 @@ int mipi_dbi_dev_init(struct mipi_dbi_dev *dbidev,
 }
 EXPORT_SYMBOL(mipi_dbi_dev_init);
 
-/**
- * mipi_dbi_release - DRM driver release helper
- * @drm: DRM device
- *
- * This function finalizes and frees &mipi_dbi.
- *
- * Drivers can use this as their &drm_driver->release callback.
- */
-void mipi_dbi_release(struct drm_device *drm)
-{
-	DRM_DEBUG_DRIVER("\n");
-
-	drm_mode_config_cleanup(drm);
-}
-EXPORT_SYMBOL(mipi_dbi_release);
-
 /**
  * mipi_dbi_hw_reset - Hardware reset of controller
  * @dbi: MIPI DBI structure
diff --git a/drivers/gpu/drm/tiny/hx8357d.c b/drivers/gpu/drm/tiny/hx8357d.c
index c88b84366dc5..af7f3d10aac3 100644
--- a/drivers/gpu/drm/tiny/hx8357d.c
+++ b/drivers/gpu/drm/tiny/hx8357d.c
@@ -196,7 +196,6 @@ DEFINE_DRM_GEM_CMA_FOPS(hx8357d_fops);
 static struct drm_driver hx8357d_driver = {
 	.driver_features	= DRIVER_GEM | DRIVER_MODESET | DRIVER_ATOMIC,
 	.fops			= &hx8357d_fops,
-	.release		= mipi_dbi_release,
 	DRM_GEM_CMA_VMAP_DRIVER_OPS,
 	.debugfs_init		= mipi_dbi_debugfs_init,
 	.name			= "hx8357d",
diff --git a/drivers/gpu/drm/tiny/ili9225.c b/drivers/gpu/drm/tiny/ili9225.c
index fa998a16026c..118477af4491 100644
--- a/drivers/gpu/drm/tiny/ili9225.c
+++ b/drivers/gpu/drm/tiny/ili9225.c
@@ -346,7 +346,6 @@ DEFINE_DRM_GEM_CMA_FOPS(ili9225_fops);
 static struct drm_driver ili9225_driver = {
 	.driver_features	= DRIVER_GEM | DRIVER_MODESET | DRIVER_ATOMIC,
 	.fops			= &ili9225_fops,
-	.release		= mipi_dbi_release,
 	DRM_GEM_CMA_VMAP_DRIVER_OPS,
 	.name			= "ili9225",
 	.desc			= "Ilitek ILI9225",
diff --git a/drivers/gpu/drm/tiny/ili9341.c b/drivers/gpu/drm/tiny/ili9341.c
index 945e15169866..e152de369019 100644
--- a/drivers/gpu/drm/tiny/ili9341.c
+++ b/drivers/gpu/drm/tiny/ili9341.c
@@ -152,7 +152,6 @@ DEFINE_DRM_GEM_CMA_FOPS(ili9341_fops);
 static struct drm_driver ili9341_driver = {
 	.driver_features	= DRIVER_GEM | DRIVER_MODESET | DRIVER_ATOMIC,
 	.fops			= &ili9341_fops,
-	.release		= mipi_dbi_release,
 	DRM_GEM_CMA_VMAP_DRIVER_OPS,
 	.debugfs_init		= mipi_dbi_debugfs_init,
 	.name			= "ili9341",
diff --git a/drivers/gpu/drm/tiny/ili9486.c b/drivers/gpu/drm/tiny/ili9486.c
index 38d293cf5377..577aea662aa4 100644
--- a/drivers/gpu/drm/tiny/ili9486.c
+++ b/drivers/gpu/drm/tiny/ili9486.c
@@ -165,7 +165,6 @@ DEFINE_DRM_GEM_CMA_FOPS(ili9486_fops);
 static struct drm_driver ili9486_driver = {
 	.driver_features	= DRIVER_GEM | DRIVER_MODESET | DRIVER_ATOMIC,
 	.fops			= &ili9486_fops,
-	.release		= mipi_dbi_release,
 	DRM_GEM_CMA_VMAP_DRIVER_OPS,
 	.debugfs_init		= mipi_dbi_debugfs_init,
 	.name			= "ili9486",
diff --git a/drivers/gpu/drm/tiny/mi0283qt.c b/drivers/gpu/drm/tiny/mi0283qt.c
index b8c973bc2347..decaf57053ff 100644
--- a/drivers/gpu/drm/tiny/mi0283qt.c
+++ b/drivers/gpu/drm/tiny/mi0283qt.c
@@ -156,7 +156,6 @@ DEFINE_DRM_GEM_CMA_FOPS(mi0283qt_fops);
 static struct drm_driver mi0283qt_driver = {
 	.driver_features	= DRIVER_GEM | DRIVER_MODESET | DRIVER_ATOMIC,
 	.fops			= &mi0283qt_fops,
-	.release		= mipi_dbi_release,
 	DRM_GEM_CMA_VMAP_DRIVER_OPS,
 	.debugfs_init		= mipi_dbi_debugfs_init,
 	.name			= "mi0283qt",
diff --git a/drivers/gpu/drm/tiny/st7586.c b/drivers/gpu/drm/tiny/st7586.c
index 1f1a576be93c..c3295c717ba6 100644
--- a/drivers/gpu/drm/tiny/st7586.c
+++ b/drivers/gpu/drm/tiny/st7586.c
@@ -285,7 +285,6 @@ DEFINE_DRM_GEM_CMA_FOPS(st7586_fops);
 static struct drm_driver st7586_driver = {
 	.driver_features	= DRIVER_GEM | DRIVER_MODESET | DRIVER_ATOMIC,
 	.fops			= &st7586_fops,
-	.release		= mipi_dbi_release,
 	DRM_GEM_CMA_VMAP_DRIVER_OPS,
 	.debugfs_init		= mipi_dbi_debugfs_init,
 	.name			= "st7586",
diff --git a/drivers/gpu/drm/tiny/st7735r.c b/drivers/gpu/drm/tiny/st7735r.c
index 0f48a5a2d3d7..631801c36f46 100644
--- a/drivers/gpu/drm/tiny/st7735r.c
+++ b/drivers/gpu/drm/tiny/st7735r.c
@@ -157,7 +157,6 @@ DEFINE_DRM_GEM_CMA_FOPS(st7735r_fops);
 static struct drm_driver st7735r_driver = {
 	.driver_features	= DRIVER_GEM | DRIVER_MODESET | DRIVER_ATOMIC,
 	.fops			= &st7735r_fops,
-	.release		= mipi_dbi_release,
 	DRM_GEM_CMA_VMAP_DRIVER_OPS,
 	.debugfs_init		= mipi_dbi_debugfs_init,
 	.name			= "st7735r",
diff --git a/include/drm/drm_mipi_dbi.h b/include/drm/drm_mipi_dbi.h
index 33f325f5af2b..4129bba55873 100644
--- a/include/drm/drm_mipi_dbi.h
+++ b/include/drm/drm_mipi_dbi.h
@@ -152,7 +152,6 @@ int mipi_dbi_dev_init_with_formats(struct mipi_dbi_dev *dbidev,
 int mipi_dbi_dev_init(struct mipi_dbi_dev *dbidev,
 		      const struct drm_simple_display_pipe_funcs *funcs,
 		      const struct drm_display_mode *mode, unsigned int rotation);
-void mipi_dbi_release(struct drm_device *drm);
 void mipi_dbi_pipe_update(struct drm_simple_display_pipe *pipe,
 			  struct drm_plane_state *old_state);
 void mipi_dbi_enable_flush(struct mipi_dbi_dev *dbidev,
-- 
2.24.1

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 111+ messages in thread

* [PATCH 49/51] drm/udl: Drop explicit drm_mode_config_cleanup call
  2020-03-02 22:25 [PATCH 00/51] drm_device managed resources, v4 Daniel Vetter
                   ` (47 preceding siblings ...)
  2020-03-02 22:26 ` [PATCH 48/51] drm/mipi-dbi: Drop explicit drm_mode_config_cleanup call Daniel Vetter
@ 2020-03-02 22:26 ` Daniel Vetter
  2020-03-02 22:26 ` [PATCH 50/51] drm/udl: drop drm_driver.release hook Daniel Vetter
  2020-03-02 22:26 ` [PATCH 51/51] drm: Add docs for managed resources Daniel Vetter
  50 siblings, 0 replies; 111+ messages in thread
From: Daniel Vetter @ 2020-03-02 22:26 UTC (permalink / raw)
  To: DRI Development
  Cc: Sean Paul, Daniel Vetter, Intel Graphics Development,
	Emil Velikov, Laurent Pinchart, Thomas Zimmermann, Dave Airlie,
	Daniel Vetter, Thomas Gleixner, Sam Ravnborg, Gerd Hoffmann

It's right above the drm_dev_put().

This allows us to delete a bit of onion unwinding in
udl_modeset_init().

This is made possible by a preceeding patch which added a drmm_
cleanup action to drm_mode_config_init(), hence all we need to do to
ensure that drm_mode_config_cleanup() is run on final drm_device
cleanup is check the new error code for _init().

v2: Explain why this cleanup is possible (Laurent).

v3: Use drmm_mode_config_init() for more clarity (Sam, Thomas)

Cc: Sam Ravnborg <sam@ravnborg.org>
Cc: Thomas Zimmermann <tzimmermann@suse.de>
Acked-by: Sam Ravnborg <sam@ravnborg.org>
Cc: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
Cc: Dave Airlie <airlied@redhat.com>
Cc: Sean Paul <sean@poorly.run>
Cc: Daniel Vetter <daniel.vetter@ffwll.ch>
Cc: Thomas Zimmermann <tzimmermann@suse.de>
Cc: Emil Velikov <emil.l.velikov@gmail.com>
Cc: Gerd Hoffmann <kraxel@redhat.com>
Cc: "Noralf Trønnes" <noralf@tronnes.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Sam Ravnborg <sam@ravnborg.org>
---
 drivers/gpu/drm/udl/udl_drv.c     |  1 -
 drivers/gpu/drm/udl/udl_drv.h     |  1 -
 drivers/gpu/drm/udl/udl_modeset.c | 21 ++++++---------------
 3 files changed, 6 insertions(+), 17 deletions(-)

diff --git a/drivers/gpu/drm/udl/udl_drv.c b/drivers/gpu/drm/udl/udl_drv.c
index 8b78c356beb5..b447fb053e78 100644
--- a/drivers/gpu/drm/udl/udl_drv.c
+++ b/drivers/gpu/drm/udl/udl_drv.c
@@ -37,7 +37,6 @@ DEFINE_DRM_GEM_FOPS(udl_driver_fops);
 static void udl_driver_release(struct drm_device *dev)
 {
 	udl_fini(dev);
-	udl_modeset_cleanup(dev);
 }
 
 static struct drm_driver driver = {
diff --git a/drivers/gpu/drm/udl/udl_drv.h b/drivers/gpu/drm/udl/udl_drv.h
index e67227c44cc4..1de7eb1b6aac 100644
--- a/drivers/gpu/drm/udl/udl_drv.h
+++ b/drivers/gpu/drm/udl/udl_drv.h
@@ -68,7 +68,6 @@ struct udl_device {
 
 /* modeset */
 int udl_modeset_init(struct drm_device *dev);
-void udl_modeset_cleanup(struct drm_device *dev);
 struct drm_connector *udl_connector_init(struct drm_device *dev);
 
 struct urb *udl_get_urb(struct drm_device *dev);
diff --git a/drivers/gpu/drm/udl/udl_modeset.c b/drivers/gpu/drm/udl/udl_modeset.c
index d59ebac70b15..8cad01f3d163 100644
--- a/drivers/gpu/drm/udl/udl_modeset.c
+++ b/drivers/gpu/drm/udl/udl_modeset.c
@@ -468,7 +468,9 @@ int udl_modeset_init(struct drm_device *dev)
 	struct drm_connector *connector;
 	int ret;
 
-	drm_mode_config_init(dev);
+	ret = drmm_mode_config_init(dev);
+	if (ret)
+		return ret;
 
 	dev->mode_config.min_width = 640;
 	dev->mode_config.min_height = 480;
@@ -482,10 +484,8 @@ int udl_modeset_init(struct drm_device *dev)
 	dev->mode_config.funcs = &udl_mode_funcs;
 
 	connector = udl_connector_init(dev);
-	if (IS_ERR(connector)) {
-		ret = PTR_ERR(connector);
-		goto err_drm_mode_config_cleanup;
-	}
+	if (IS_ERR(connector))
+		return PTR_ERR(connector);
 
 	format_count = ARRAY_SIZE(udl_simple_display_pipe_formats);
 
@@ -494,18 +494,9 @@ int udl_modeset_init(struct drm_device *dev)
 					   udl_simple_display_pipe_formats,
 					   format_count, NULL, connector);
 	if (ret)
-		goto err_drm_mode_config_cleanup;
+		return ret;
 
 	drm_mode_config_reset(dev);
 
 	return 0;
-
-err_drm_mode_config_cleanup:
-	drm_mode_config_cleanup(dev);
-	return ret;
-}
-
-void udl_modeset_cleanup(struct drm_device *dev)
-{
-	drm_mode_config_cleanup(dev);
 }
-- 
2.24.1

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 111+ messages in thread

* [PATCH 50/51] drm/udl: drop drm_driver.release hook
  2020-03-02 22:25 [PATCH 00/51] drm_device managed resources, v4 Daniel Vetter
                   ` (48 preceding siblings ...)
  2020-03-02 22:26 ` [PATCH 49/51] drm/udl: " Daniel Vetter
@ 2020-03-02 22:26 ` Daniel Vetter
  2020-03-03  7:57   ` Thomas Zimmermann
  2020-03-02 22:26 ` [PATCH 51/51] drm: Add docs for managed resources Daniel Vetter
  50 siblings, 1 reply; 111+ messages in thread
From: Daniel Vetter @ 2020-03-02 22:26 UTC (permalink / raw)
  To: DRI Development
  Cc: Sam Ravnborg, Daniel Vetter, Intel Graphics Development,
	Emil Velikov, Gerd Hoffmann, Thomas Zimmermann, Daniel Vetter,
	Alex Deucher, Dave Airlie, Thomas Gleixner, Sean Paul

There's only two functions called from that:
drm_kms_helper_poll_fini() and udl_free_urb_list(). Both of these are
also called from the ubs_driver->disconnect hook, so entirely
pointless to do the same again in the ->release hook.

Furthermore by the time we clean up the drm_driver we really shouldn't
be touching hardware anymore, so stopping the poll worker and freeing
the urb allocations in ->disconnect is the right thing to do.

Now disconnect still cleans things up before unregistering the driver,
but that's a different issue.

v2: Use _fini, not _disable in unplug, motivated by discussions with
Thomas. _disable/_enable are for suspend/resume.

Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
Cc: Dave Airlie <airlied@redhat.com>
Cc: Sean Paul <sean@poorly.run>
Cc: Daniel Vetter <daniel.vetter@ffwll.ch>
Cc: Thomas Zimmermann <tzimmermann@suse.de>
Cc: Emil Velikov <emil.l.velikov@gmail.com>
Cc: Gerd Hoffmann <kraxel@redhat.com>
Cc: "Noralf Trønnes" <noralf@tronnes.org>
Cc: Sam Ravnborg <sam@ravnborg.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Alex Deucher <alexander.deucher@amd.com>
---
 drivers/gpu/drm/udl/udl_drv.c  |  8 +-------
 drivers/gpu/drm/udl/udl_drv.h  |  1 -
 drivers/gpu/drm/udl/udl_main.c | 10 ----------
 3 files changed, 1 insertion(+), 18 deletions(-)

diff --git a/drivers/gpu/drm/udl/udl_drv.c b/drivers/gpu/drm/udl/udl_drv.c
index b447fb053e78..1ce2d865c36d 100644
--- a/drivers/gpu/drm/udl/udl_drv.c
+++ b/drivers/gpu/drm/udl/udl_drv.c
@@ -34,14 +34,8 @@ static int udl_usb_resume(struct usb_interface *interface)
 
 DEFINE_DRM_GEM_FOPS(udl_driver_fops);
 
-static void udl_driver_release(struct drm_device *dev)
-{
-	udl_fini(dev);
-}
-
 static struct drm_driver driver = {
 	.driver_features = DRIVER_ATOMIC | DRIVER_GEM | DRIVER_MODESET,
-	.release = udl_driver_release,
 
 	/* gem hooks */
 	.gem_create_object = udl_driver_gem_create_object,
@@ -120,7 +114,7 @@ static void udl_usb_disconnect(struct usb_interface *interface)
 {
 	struct drm_device *dev = usb_get_intfdata(interface);
 
-	drm_kms_helper_poll_disable(dev);
+	drm_kms_helper_poll_fini(dev);
 	udl_drop_usb(dev);
 	drm_dev_unplug(dev);
 	drm_dev_put(dev);
diff --git a/drivers/gpu/drm/udl/udl_drv.h b/drivers/gpu/drm/udl/udl_drv.h
index 1de7eb1b6aac..2642f94a63fc 100644
--- a/drivers/gpu/drm/udl/udl_drv.h
+++ b/drivers/gpu/drm/udl/udl_drv.h
@@ -76,7 +76,6 @@ int udl_submit_urb(struct drm_device *dev, struct urb *urb, size_t len);
 void udl_urb_completion(struct urb *urb);
 
 int udl_init(struct udl_device *udl);
-void udl_fini(struct drm_device *dev);
 
 int udl_render_hline(struct drm_device *dev, int log_bpp, struct urb **urb_ptr,
 		     const char *front, char **urb_buf_ptr,
diff --git a/drivers/gpu/drm/udl/udl_main.c b/drivers/gpu/drm/udl/udl_main.c
index 538718919916..f5d27f2a5654 100644
--- a/drivers/gpu/drm/udl/udl_main.c
+++ b/drivers/gpu/drm/udl/udl_main.c
@@ -351,13 +351,3 @@ int udl_drop_usb(struct drm_device *dev)
 	udl_free_urb_list(dev);
 	return 0;
 }
-
-void udl_fini(struct drm_device *dev)
-{
-	struct udl_device *udl = to_udl(dev);
-
-	drm_kms_helper_poll_fini(dev);
-
-	if (udl->urbs.count)
-		udl_free_urb_list(dev);
-}
-- 
2.24.1

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 111+ messages in thread

* [PATCH 51/51] drm: Add docs for managed resources
  2020-03-02 22:25 [PATCH 00/51] drm_device managed resources, v4 Daniel Vetter
                   ` (49 preceding siblings ...)
  2020-03-02 22:26 ` [PATCH 50/51] drm/udl: drop drm_driver.release hook Daniel Vetter
@ 2020-03-02 22:26 ` Daniel Vetter
  2020-03-07 10:07   ` Sam Ravnborg
  50 siblings, 1 reply; 111+ messages in thread
From: Daniel Vetter @ 2020-03-02 22:26 UTC (permalink / raw)
  To: DRI Development
  Cc: linux-doc, Daniel Vetter, Intel Graphics Development,
	Jonathan Corbet, Laurent Pinchart, Greg Kroah-Hartman,
	Rafael J. Wysocki, Daniel Vetter, Sam Ravnborg

All collected together to provide a consistent story in one patch,
instead of the somewhat bumpy refactor-evolution leading to this.

Also some thoughts on what the next steps could be:

- Create a macro called devm_drm_dev_alloc() which essentially wraps
  the kzalloc(); devm_drm_dev_init(); drmm_add_final_kfree() combo.
  Needs to be a macro since we'll have to do some typeof trickery and
  casting to make this fully generic for all drivers that embed struct
  drm_device into their own thing.

- A lot of the simple drivers now have essentially just
  drm_dev_unplug(); drm_atomic_helper_shutdown(); as their
  $bus_driver->remove hook. We could create a devm_mode_config_reset
  which sets drm_atomic_helper_shutdown as it's cleanup action, and a
  devm_drm_dev_register with drm_dev_unplug as it's cleanup action,
  and simple drivers wouldn't have a need for a ->remove function at
  all, and we could delete them.

- For more complicated drivers we need drmm_ versions of a _lot_ more
  things. All the userspace visible objects (crtc, plane, encoder,
  crtc), anything else hanging of those (maybe a drmm_get_edid, at
  least for panels and other built-in stuff).

Also some more thoughts on why we're not reusing devm_ with maybe a
fake struct device embedded into the drm_device (we can't use the
kdev, since that's in each drm_minor).

- Code review gets extremely tricky, since every time you see a devm_
  you need to carefully check whether the fake device (with the
  drm_device lifetim) or the real device (with the lifetim of the
  underlying physical device and driver binding) are used. That's not
  going to help at all, and we have enormous amounts of drivers who
  use devm_ where they really shouldn't. Having different types makes
  sure the compiler type checks this for us and ensures correctness.

- The set of functions are very much non-overlapping. E.g.
  devm_ioremap makes total sense, drmm_ioremap has the wrong lifetime,
  since hw resources need to be cleaned out at driver unbind and wont
  outlive that like a drm_device. Similar, but other way round for
  drmm_connector_init (which is the only correct version, devm_ for
  drm_connector is just buggy). Simply not having the wrong version
  again prevents bugs.

Finally I guess this opens a huge todo for all the drivers. I'm
semi-tempted to do a tree-wide s/devm_kzalloc/drmm_kzalloc/ since most
likely that'll fix an enormous amount of bugs and most likely not
cause any issues at all (aside from maybe holding onto memory slightly
too long).

v2:
- Doc improvements from Laurent.
- Also add kerneldoc for the new drmm_add_action_or_reset.

Cc: Sam Ravnborg <sam@ravnborg.org>
Cc: Jonathan Corbet <corbet@lwn.net>
Cc: linux-doc@vger.kernel.org
Cc: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: "Rafael J. Wysocki" <rafael@kernel.org>
Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
---
 Documentation/gpu/drm-internals.rst |  6 +++
 drivers/gpu/drm/drm_drv.c           | 18 +++++++--
 drivers/gpu/drm/drm_managed.c       | 61 +++++++++++++++++++++++++++++
 include/drm/drm_drv.h               |  4 ++
 include/drm/drm_managed.h           | 58 +++++++++++++++++++++++++++
 5 files changed, 144 insertions(+), 3 deletions(-)

diff --git a/Documentation/gpu/drm-internals.rst b/Documentation/gpu/drm-internals.rst
index a6b6145fda78..12272b168580 100644
--- a/Documentation/gpu/drm-internals.rst
+++ b/Documentation/gpu/drm-internals.rst
@@ -138,6 +138,12 @@ Managed Resources
 .. kernel-doc:: drivers/gpu/drm/drm_managed.c
    :doc: managed resources
 
+.. kernel-doc:: drivers/gpu/drm/drm_managed.c
+   :export:
+
+.. kernel-doc:: include/drm/drm_managed.h
+   :internal:
+
 Bus-specific Device Registration and PCI Support
 ------------------------------------------------
 
diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c
index a82702d0c2fb..cd172080649c 100644
--- a/drivers/gpu/drm/drm_drv.c
+++ b/drivers/gpu/drm/drm_drv.c
@@ -260,9 +260,15 @@ void drm_minor_release(struct drm_minor *minor)
  * any other resources allocated at device initialization and drop the driver's
  * reference to &drm_device using drm_dev_put().
  *
- * Note that the lifetime rules for &drm_device instance has still a lot of
- * historical baggage. Hence use the reference counting provided by
- * drm_dev_get() and drm_dev_put() only carefully.
+ * Note that any allocation or resource which is visible to userspace must be
+ * released only when the final drm_dev_put() is called, and not when the
+ * driver is unbound from the underlying physical struct &device. Best to use
+ * &drm_device managed resources with drmm_add_action(), drmm_kmalloc() and
+ * related functions.
+ *
+ * devres managed resources like devm_kmalloc() can only be used for resources
+ * directly related to the underlying hardware device, and only used in code
+ * paths fully protected by drm_dev_enter() and drm_dev_exit().
  *
  * Display driver example
  * ~~~~~~~~~~~~~~~~~~~~~~
@@ -606,6 +612,9 @@ static void drm_dev_init_release(struct drm_device *dev, void *res)
  * arbitrary offset, you must supply a &drm_driver.release callback and control
  * the finalization explicitly.
  *
+ * Note that drivers must call drmm_add_final_kfree() after this function has
+ * completed successfully.
+ *
  * RETURNS:
  * 0 on success, or error code on failure.
  */
@@ -707,6 +716,9 @@ static void devm_drm_dev_init_release(void *data)
  * Managed drm_dev_init(). The DRM device initialized with this function is
  * automatically put on driver detach using drm_dev_put().
  *
+ * Note that drivers must call drmm_add_final_kfree() after this function has
+ * completed successfully.
+ *
  * RETURNS:
  * 0 on success, or error code on failure.
  */
diff --git a/drivers/gpu/drm/drm_managed.c b/drivers/gpu/drm/drm_managed.c
index 8c5f1f03c485..5148ef786c3b 100644
--- a/drivers/gpu/drm/drm_managed.c
+++ b/drivers/gpu/drm/drm_managed.c
@@ -20,7 +20,19 @@
  * Inspired by struct &device managed resources, but tied to the lifetime of
  * struct &drm_device, which can outlive the underlying physical device, usually
  * when userspace has some open files and other handles to resources still open.
+ *
+ * Release actions can be added with drmm_add_action(), memory allocations can
+ * be done directly with drmm_kmalloc() and the related functions. Everything
+ * will be released on the final drm_dev_put() in reverse order of how the
+ * release actions have been added and memory has been allocated since driver
+ * loading started with drm_dev_init().
+ *
+ * Note that release actions and managed memory can also be added and removed
+ * during the lifetime of the driver, all the functions are fully concurrent
+ * safe. But it is recommended to use managed resources only for resources that
+ * change rarely, if ever, during the lifetime of the &drm_device instance.
  */
+
 struct drmres_node {
 	struct list_head	entry;
 	drmres_release_t	release;
@@ -105,6 +117,18 @@ static void add_dr(struct drm_device *dev, struct drmres *dr)
 		       dr, dr->node.name, (unsigned long) dr->node.size);
 }
 
+/**
+ * drmm_add_final_kfree - add release action for the final kfree()
+ * @dev: DRM device
+ * @parent: pointer to the kmalloc allocation containing @dev
+ *
+ * Since the allocation containing the struct &drm_device must be allocated
+ * before it can be initialized with drm_dev_init() there's no way to allocate
+ * that memory with drmm_kmalloc(). To side-step this chicken-egg problem the
+ * pointer for this final kfree() must be specified by calling this function. It
+ * will be released in the final drm_dev_put() for @dev, after all other release
+ * actions installed through drmm_add_action() have been processed.
+ */
 void drmm_add_final_kfree(struct drm_device *dev, void *parent)
 {
 	WARN_ON(dev->managed.final_kfree);
@@ -156,6 +180,14 @@ int __drmm_add_action_or_reset(struct drm_device *dev,
 }
 EXPORT_SYMBOL(__drmm_add_action_or_reset);
 
+/**
+ * drmm_add_action - remove a managed release action to a &drm_device
+ * @dev: DRM device
+ * @action: release function
+ * @data: opaque pointer, passed to @action
+ *
+ * This function removes a release action added by drmm_add_action().
+ */
 void drmm_remove_action(struct drm_device *dev,
 			drmres_release_t action,
 			void *data)
@@ -184,6 +216,16 @@ void drmm_remove_action(struct drm_device *dev,
 }
 EXPORT_SYMBOL(drmm_remove_action);
 
+/**
+ * drmm_kmalloc - &drm_device managed kmalloc()
+ * @dev: DRM device
+ * @size: size of the memory allocation
+ * @gfp: GFP allocation flags
+ *
+ * This is a &drm_device managed version of kmalloc(). The allocated memory is
+ * automatically freed on the final drm_dev_put(). Memory can also be freed
+ * before the final drm_dev_put() by calling drmm_kfree().
+ */
 void *drmm_kmalloc(struct drm_device *dev, size_t size, gfp_t gfp)
 {
 	struct drmres *dr;
@@ -202,6 +244,16 @@ void *drmm_kmalloc(struct drm_device *dev, size_t size, gfp_t gfp)
 }
 EXPORT_SYMBOL(drmm_kmalloc);
 
+/**
+ * drmm_kstrdup - &drm_device managed kstrdup()
+ * @dev: DRM device
+ * @s: 0-terminated string to be duplicated
+ * @gfp: GFP allocation flags
+ *
+ * This is a &drm_device managed version of kstrdup(). The allocated memory is
+ * automatically freed on the final drm_dev_put() and works exactly like a
+ * memory allocation obtained by drmm_kmalloc().
+ */
 char *drmm_kstrdup(struct drm_device *dev, const char *s, gfp_t gfp)
 {
 	size_t size;
@@ -218,6 +270,15 @@ char *drmm_kstrdup(struct drm_device *dev, const char *s, gfp_t gfp)
 }
 EXPORT_SYMBOL_GPL(drmm_kstrdup);
 
+/**
+ * drmm_kfree - &drm_device managed kfree()
+ * @dev: DRM device
+ * @data: memory allocation to be freed
+ *
+ * This is a &drm_device managed version of kfree() which can be used to
+ * release memory allocated through drmm_kmalloc() or any of its related
+ * functions before the final drm_dev_put() of @dev.
+ */
 void drmm_kfree(struct drm_device *dev, void *data)
 {
 	struct drmres *dr_match = NULL, *dr;
diff --git a/include/drm/drm_drv.h b/include/drm/drm_drv.h
index edee40e31e4b..0fd7fc6f024e 100644
--- a/include/drm/drm_drv.h
+++ b/include/drm/drm_drv.h
@@ -266,6 +266,10 @@ struct drm_driver {
 	 *
 	 * Optional callback for destroying device data after the final
 	 * reference is released, i.e. the device is being destroyed.
+	 *
+	 * This is deprecated, clean up all memory allocations associated with a
+	 * &drm_device using drmm_add_action(), drmm_kmalloc() and related
+	 * managed resources functions.
 	 */
 	void (*release) (struct drm_device *);
 
diff --git a/include/drm/drm_managed.h b/include/drm/drm_managed.h
index 1e6291407586..af152cfb173c 100644
--- a/include/drm/drm_managed.h
+++ b/include/drm/drm_managed.h
@@ -11,6 +11,19 @@ struct drm_device;
 
 typedef void (*drmres_release_t)(struct drm_device *dev, void *res);
 
+/**
+ * drmm_add_action - add a managed release action to a &drm_device
+ * @dev: DRM device
+ * @action: function which should be called when @dev is released
+ * @data: opaque pointer, passed to @action
+ *
+ * This function adds the @release action with optional parameter @data to the
+ * list of cleanup actions for @dev. The cleanup actions will be run in reverse
+ * order in the final drm_dev_put() call for @dev.
+ *
+ * A release action can be removed before @dev is released by calling
+ * drmm_remove_action() with matching parameters for @action and @data.
+ */
 #define drmm_add_action(dev, action, data) \
 	__drmm_add_action(dev, action, data, #action)
 
@@ -18,6 +31,15 @@ int __must_check __drmm_add_action(struct drm_device *dev,
 				   drmres_release_t action,
 				   void *data, const char *name);
 
+/**
+ * drmm_add_action_or_reset - add a managed release action to a &drm_device
+ * @dev: DRM device
+ * @action: function which should be called when @dev is released
+ * @data: opaque pointer, passed to @action
+ *
+ * Similar to drmm_add_action(), with the only difference that upon failure
+ * @action is directly called for any cleanup work necessary on failures.
+ */
 #define drmm_add_action_or_reset(dev, action, data) \
 	__drmm_add_action_or_reset(dev, action, data, #action)
 
@@ -32,10 +54,33 @@ void drmm_remove_action(struct drm_device *dev,
 void drmm_add_final_kfree(struct drm_device *dev, void *parent);
 
 void *drmm_kmalloc(struct drm_device *dev, size_t size, gfp_t gfp) __malloc;
+
+/**
+ * drmm_kzalloc - &drm_device managed kzalloc()
+ * @dev: DRM device
+ * @size: size of the memory allocation
+ * @gfp: GFP allocation flags
+ *
+ * This is a &drm_device managed version of kzalloc(). The allocated memory is
+ * automatically freed on the final drm_dev_put(). Memory can also be freed
+ * before the final drm_dev_put() by calling drmm_kfree().
+ */
 static inline void *drmm_kzalloc(struct drm_device *dev, size_t size, gfp_t gfp)
 {
 	return drmm_kmalloc(dev, size, gfp | __GFP_ZERO);
 }
+
+/**
+ * drmm_kmalloc_array - &drm_device managed kmalloc_array()
+ * @dev: DRM device
+ * @n: number of array elements to allocate
+ * @size: size of array member
+ * @flags: GFP allocation flags
+ *
+ * This is a &drm_device managed version of kmalloc_array(). The allocated
+ * memory is automatically freed on the final drm_dev_put() and works exactly
+ * like a memory allocation obtained by drmm_kmalloc().
+ */
 static inline void *drmm_kmalloc_array(struct drm_device *dev,
 				       size_t n, size_t size, gfp_t flags)
 {
@@ -46,11 +91,24 @@ static inline void *drmm_kmalloc_array(struct drm_device *dev,
 
 	return drmm_kmalloc(dev, bytes, flags);
 }
+
+/**
+ * drmm_kcalloc - &drm_device managed kcalloc()
+ * @dev: DRM device
+ * @n: number of array elements to allocate
+ * @size: size of array member
+ * @flags: GFP allocation flags
+ *
+ * This is a &drm_device managed version of kcalloc(). The allocated memory is
+ * automatically freed on the final drm_dev_put() and works exactly like a
+ * memory allocation obtained by drmm_kmalloc().
+ */
 static inline void *drmm_kcalloc(struct drm_device *dev,
 				 size_t n, size_t size, gfp_t flags)
 {
 	return drmm_kmalloc_array(dev, n, size, flags | __GFP_ZERO);
 }
+
 char *drmm_kstrdup(struct drm_device *dev, const char *s, gfp_t gfp);
 
 void drmm_kfree(struct drm_device *dev, void *data);
-- 
2.24.1

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 111+ messages in thread

* Re: [PATCH 04/51] drm: Set final_kfree in drm_dev_alloc
  2020-03-02 22:25 ` [PATCH 04/51] drm: Set final_kfree in drm_dev_alloc Daniel Vetter
@ 2020-03-03  7:44   ` Gerd Hoffmann
  2020-03-07  8:06   ` Sam Ravnborg
  2020-03-11  9:09   ` Thomas Zimmermann
  2 siblings, 0 replies; 111+ messages in thread
From: Gerd Hoffmann @ 2020-03-03  7:44 UTC (permalink / raw)
  To: Daniel Vetter
  Cc: Oleksandr Andrushchenko, David Airlie,
	Intel Graphics Development, DRI Development, Thomas Zimmermann,
	xen-devel, Daniel Vetter

On Mon, Mar 02, 2020 at 11:25:44PM +0100, Daniel Vetter wrote:
> I also did a full review of all callers, and only the xen driver
> forgot to call drm_dev_put in the failure path. Fix that up too.
> 
> v2: I noticed that xen has a drm_driver.release hook, and uses
> drm_dev_alloc(). We need to remove the kfree from
> xen_drm_drv_release().
> 
> bochs also has a release hook, but leaked the drm_device ever since
> 
> commit 0a6659bdc5e8221da99eebb176fd9591435e38de
> Author: Gerd Hoffmann <kraxel@redhat.com>
> Date:   Tue Dec 17 18:04:46 2013 +0100
> 
>     drm/bochs: new driver
> 
> This patch here fixes that leak.
> 
> Same for virtio, started leaking with
> 
> commit b1df3a2b24a917f8853d43fe9683c0e360d2c33a
> Author: Gerd Hoffmann <kraxel@redhat.com>
> Date:   Tue Feb 11 14:58:04 2020 +0100
> 
>     drm/virtio: add drm_driver.release callback.

Acked-by: Gerd Hoffmann <kraxel@redhat.com>

> 
> Cc: Gerd Hoffmann <kraxel@redhat.com>
> Cc: Oleksandr Andrushchenko <oleksandr_andrushchenko@epam.com>
> Cc: xen-devel@lists.xenproject.org
> 
> Reviewed-by: Oleksandr Andrushchenko <oleksandr_andrushchenko@epam.com>
> Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
> Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
> Cc: Maxime Ripard <mripard@kernel.org>
> Cc: Thomas Zimmermann <tzimmermann@suse.de>
> Cc: David Airlie <airlied@linux.ie>
> Cc: Daniel Vetter <daniel@ffwll.ch>
> Cc: Oleksandr Andrushchenko <oleksandr_andrushchenko@epam.com>
> Cc: xen-devel@lists.xenproject.org
> ---
>  drivers/gpu/drm/drm_drv.c           | 3 +++
>  drivers/gpu/drm/xen/xen_drm_front.c | 2 +-
>  2 files changed, 4 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c
> index 153050fc926c..7b84ee8a5eb5 100644
> --- a/drivers/gpu/drm/drm_drv.c
> +++ b/drivers/gpu/drm/drm_drv.c
> @@ -39,6 +39,7 @@
>  #include <drm/drm_color_mgmt.h>
>  #include <drm/drm_drv.h>
>  #include <drm/drm_file.h>
> +#include <drm/drm_managed.h>
>  #include <drm/drm_mode_object.h>
>  #include <drm/drm_print.h>
>  
> @@ -819,6 +820,8 @@ struct drm_device *drm_dev_alloc(struct drm_driver *driver,
>  		return ERR_PTR(ret);
>  	}
>  
> +	drmm_add_final_kfree(dev, dev);
> +
>  	return dev;
>  }
>  EXPORT_SYMBOL(drm_dev_alloc);
> diff --git a/drivers/gpu/drm/xen/xen_drm_front.c b/drivers/gpu/drm/xen/xen_drm_front.c
> index 4be49c1aef51..d22b5da38935 100644
> --- a/drivers/gpu/drm/xen/xen_drm_front.c
> +++ b/drivers/gpu/drm/xen/xen_drm_front.c
> @@ -461,7 +461,6 @@ static void xen_drm_drv_release(struct drm_device *dev)
>  	drm_mode_config_cleanup(dev);
>  
>  	drm_dev_fini(dev);
> -	kfree(dev);
>  
>  	if (front_info->cfg.be_alloc)
>  		xenbus_switch_state(front_info->xb_dev,
> @@ -561,6 +560,7 @@ static int xen_drm_drv_init(struct xen_drm_front_info *front_info)
>  fail_modeset:
>  	drm_kms_helper_poll_fini(drm_dev);
>  	drm_mode_config_cleanup(drm_dev);
> +	drm_dev_put(drm_dev);
>  fail:
>  	kfree(drm_info);
>  	return ret;
> -- 
> 2.24.1
> 

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 111+ messages in thread

* Re: [PATCH 07/51] drm/qxl: Use drmm_add_final_kfree
  2020-03-02 22:25 ` [PATCH 07/51] drm/qxl: " Daniel Vetter
@ 2020-03-03  7:44   ` Gerd Hoffmann
  0 siblings, 0 replies; 111+ messages in thread
From: Gerd Hoffmann @ 2020-03-03  7:44 UTC (permalink / raw)
  To: Daniel Vetter
  Cc: Dave Airlie, Intel Graphics Development, DRI Development,
	virtualization, spice-devel, Daniel Vetter

On Mon, Mar 02, 2020 at 11:25:47PM +0100, Daniel Vetter wrote:
> With this we can drop the final kfree from the release function.

Acked-by: Gerd Hoffmann <kraxel@redhat.com>

> 
> Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
> Cc: Dave Airlie <airlied@redhat.com>
> Cc: Gerd Hoffmann <kraxel@redhat.com>
> Cc: virtualization@lists.linux-foundation.org
> Cc: spice-devel@lists.freedesktop.org
> ---
>  drivers/gpu/drm/qxl/qxl_drv.c | 2 --
>  drivers/gpu/drm/qxl/qxl_kms.c | 2 ++
>  2 files changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/gpu/drm/qxl/qxl_drv.c b/drivers/gpu/drm/qxl/qxl_drv.c
> index 4fda3f9b29f4..09102e2efabc 100644
> --- a/drivers/gpu/drm/qxl/qxl_drv.c
> +++ b/drivers/gpu/drm/qxl/qxl_drv.c
> @@ -144,8 +144,6 @@ static void qxl_drm_release(struct drm_device *dev)
>  	 */
>  	qxl_modeset_fini(qdev);
>  	qxl_device_fini(qdev);
> -	dev->dev_private = NULL;
> -	kfree(qdev);
>  }
>  
>  static void
> diff --git a/drivers/gpu/drm/qxl/qxl_kms.c b/drivers/gpu/drm/qxl/qxl_kms.c
> index 70b20ee4741a..09d7b5f6d172 100644
> --- a/drivers/gpu/drm/qxl/qxl_kms.c
> +++ b/drivers/gpu/drm/qxl/qxl_kms.c
> @@ -27,6 +27,7 @@
>  #include <linux/pci.h>
>  
>  #include <drm/drm_drv.h>
> +#include <drm/drm_managed.h>
>  #include <drm/drm_probe_helper.h>
>  
>  #include "qxl_drv.h"
> @@ -121,6 +122,7 @@ int qxl_device_init(struct qxl_device *qdev,
>  	qdev->ddev.pdev = pdev;
>  	pci_set_drvdata(pdev, &qdev->ddev);
>  	qdev->ddev.dev_private = qdev;
> +	drmm_add_final_kfree(&qdev->ddev, qdev);
>  
>  	mutex_init(&qdev->gem.mutex);
>  	mutex_init(&qdev->update_area_mutex);
> -- 
> 2.24.1
> 

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 111+ messages in thread

* Re: [PATCH 09/51] drm/cirrus: Use drmm_add_final_kfree
  2020-03-02 22:25 ` [PATCH 09/51] drm/cirrus: " Daniel Vetter
@ 2020-03-03  7:49   ` Gerd Hoffmann
  2020-03-03  8:27     ` Daniel Vetter
  0 siblings, 1 reply; 111+ messages in thread
From: Gerd Hoffmann @ 2020-03-03  7:49 UTC (permalink / raw)
  To: Daniel Vetter
  Cc: Intel Graphics Development, DRI Development, virtualization,
	Thomas Zimmermann, Dave Airlie, Daniel Vetter, Sam Ravnborg

> @@ -575,9 +574,12 @@ static int cirrus_pci_probe(struct pci_dev *pdev,
>  
>  	dev = &cirrus->dev;
>  	ret = drm_dev_init(dev, &cirrus_driver, &pdev->dev);
> -	if (ret)
> -		goto err_free_cirrus;
> +	if (ret) {
> +		kfree(cirrus);
> +		goto err_pci_release;
> +	}
>  	dev->dev_private = cirrus;
> +	drmm_add_final_kfree(dev, cirrus);

That doesn't look like an error path improvement.
With patch #30 applied it'll looks alot better though.
So maybe squash the patches?

In any case:
Acked-by: Gerd Hoffmann <kraxel@redhat.com>

cheers,
  Gerd

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 111+ messages in thread

* Re: [PATCH 27/51] drm/bochs: Remove leftover drm_atomic_helper_shutdown
  2020-03-02 22:26 ` [PATCH 27/51] drm/bochs: Remove leftover drm_atomic_helper_shutdown Daniel Vetter
@ 2020-03-03  7:49   ` Gerd Hoffmann
  0 siblings, 0 replies; 111+ messages in thread
From: Gerd Hoffmann @ 2020-03-03  7:49 UTC (permalink / raw)
  To: Daniel Vetter; +Cc: Daniel Vetter, Intel Graphics Development, DRI Development

On Mon, Mar 02, 2020 at 11:26:07PM +0100, Daniel Vetter wrote:
> Small mistake that crept into
> 
> commit 81da8c3b8d3df6f05b11300b7d17ccd1f3017fab
> Author: Gerd Hoffmann <kraxel@redhat.com>
> Date:   Tue Feb 11 14:52:18 2020 +0100
> 
>     drm/bochs: add drm_driver.release callback
> 
> where drm_atomic_helper_shutdown was left in both places. The
> ->release callback really shouldn't touch hardware.
> 
> Cc: Gerd Hoffmann <kraxel@redhat.com>
> Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>

Acked-by: Gerd Hoffmann <kraxel@redhat.com>

> ---
>  drivers/gpu/drm/bochs/bochs_kms.c | 1 -
>  1 file changed, 1 deletion(-)
> 
> diff --git a/drivers/gpu/drm/bochs/bochs_kms.c b/drivers/gpu/drm/bochs/bochs_kms.c
> index 8066d7d370d5..e8cc8156d773 100644
> --- a/drivers/gpu/drm/bochs/bochs_kms.c
> +++ b/drivers/gpu/drm/bochs/bochs_kms.c
> @@ -166,6 +166,5 @@ void bochs_kms_fini(struct bochs_device *bochs)
>  	if (!bochs->dev->mode_config.num_connector)
>  		return;
>  
> -	drm_atomic_helper_shutdown(bochs->dev);
>  	drm_mode_config_cleanup(bochs->dev);
>  }
> -- 
> 2.24.1
> 

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 111+ messages in thread

* Re: [PATCH 28/51] drm/bochs: Drop explicit drm_mode_config_cleanup
  2020-03-02 22:26 ` [PATCH 28/51] drm/bochs: Drop explicit drm_mode_config_cleanup Daniel Vetter
@ 2020-03-03  7:50   ` Gerd Hoffmann
  2020-03-06 20:14   ` Sam Ravnborg
  1 sibling, 0 replies; 111+ messages in thread
From: Gerd Hoffmann @ 2020-03-03  7:50 UTC (permalink / raw)
  To: Daniel Vetter
  Cc: Intel Graphics Development, DRI Development, virtualization,
	Laurent Pinchart, Thomas Zimmermann, Daniel Vetter, Sam Ravnborg

On Mon, Mar 02, 2020 at 11:26:08PM +0100, Daniel Vetter wrote:
> Instead rely on the automatic clean, for which we just need to check
> that drm_mode_config_init succeeded. To avoid an inversion in the
> cleanup we also have to move the dev_private allocation over to
> drmm_kzalloc.
> 
> This is made possible by a preceeding patch which added a drmm_
> cleanup action to drm_mode_config_init(), hence all we need to do to
> ensure that drm_mode_config_cleanup() is run on final drm_device
> cleanup is check the new error code for _init().

Acked-by: Gerd Hoffmann <kraxel@redhat.com>

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 111+ messages in thread

* Re: [PATCH 29/51] drm/cirrus: Drop explicit drm_mode_config_cleanup call
  2020-03-02 22:26 ` [PATCH 29/51] drm/cirrus: Drop explicit drm_mode_config_cleanup call Daniel Vetter
@ 2020-03-03  7:51   ` Gerd Hoffmann
  0 siblings, 0 replies; 111+ messages in thread
From: Gerd Hoffmann @ 2020-03-03  7:51 UTC (permalink / raw)
  To: Daniel Vetter
  Cc: Intel Graphics Development, DRI Development, virtualization,
	Laurent Pinchart, Thomas Zimmermann, Dave Airlie, Daniel Vetter,
	Sam Ravnborg

On Mon, Mar 02, 2020 at 11:26:09PM +0100, Daniel Vetter wrote:
> We can even delete the drm_driver.release hook now!
> 
> This is made possible by a preceeding patch which added a drmm_
> cleanup action to drm_mode_config_init(), hence all we need to do to
> ensure that drm_mode_config_cleanup() is run on final drm_device
> cleanup is check the new error code for _init().

Acked-by: Gerd Hoffmann <kraxel@redhat.com>

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 111+ messages in thread

* Re: [PATCH 30/51] drm/cirrus: Fully embrace devm_
  2020-03-02 22:26 ` [PATCH 30/51] drm/cirrus: Fully embrace devm_ Daniel Vetter
@ 2020-03-03  7:51   ` Gerd Hoffmann
  0 siblings, 0 replies; 111+ messages in thread
From: Gerd Hoffmann @ 2020-03-03  7:51 UTC (permalink / raw)
  To: Daniel Vetter
  Cc: Intel Graphics Development, DRI Development, virtualization,
	Thomas Zimmermann, Dave Airlie, Daniel Vetter, Emil Velikov

On Mon, Mar 02, 2020 at 11:26:10PM +0100, Daniel Vetter wrote:
> With the drm_device lifetime fun cleaned up there's nothing in the way
> anymore to use devm_ for everything hw releated. Do it, and in the
> process, throw out the entire onion unwinding.

Acked-by: Gerd Hoffmann <kraxel@redhat.com>

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 111+ messages in thread

* Re: [PATCH 50/51] drm/udl: drop drm_driver.release hook
  2020-03-02 22:26 ` [PATCH 50/51] drm/udl: drop drm_driver.release hook Daniel Vetter
@ 2020-03-03  7:57   ` Thomas Zimmermann
  0 siblings, 0 replies; 111+ messages in thread
From: Thomas Zimmermann @ 2020-03-03  7:57 UTC (permalink / raw)
  To: Daniel Vetter, DRI Development
  Cc: Sam Ravnborg, Intel Graphics Development, Emil Velikov,
	Gerd Hoffmann, Dave Airlie, Alex Deucher, Daniel Vetter,
	Thomas Gleixner, Sean Paul


[-- Attachment #1.1.1: Type: text/plain, Size: 3759 bytes --]

Hi

Am 02.03.20 um 23:26 schrieb Daniel Vetter:
> There's only two functions called from that:
> drm_kms_helper_poll_fini() and udl_free_urb_list(). Both of these are
> also called from the ubs_driver->disconnect hook, so entirely
> pointless to do the same again in the ->release hook.
> 
> Furthermore by the time we clean up the drm_driver we really shouldn't
> be touching hardware anymore, so stopping the poll worker and freeing
> the urb allocations in ->disconnect is the right thing to do.
> 
> Now disconnect still cleans things up before unregistering the driver,
> but that's a different issue.
> 
> v2: Use _fini, not _disable in unplug, motivated by discussions with
> Thomas. _disable/_enable are for suspend/resume.
> 
> Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>

Acked-by: Thomas Zimmermann <tzimmermann@suse.de>

> Cc: Dave Airlie <airlied@redhat.com>
> Cc: Sean Paul <sean@poorly.run>
> Cc: Daniel Vetter <daniel.vetter@ffwll.ch>
> Cc: Thomas Zimmermann <tzimmermann@suse.de>
> Cc: Emil Velikov <emil.l.velikov@gmail.com>
> Cc: Gerd Hoffmann <kraxel@redhat.com>
> Cc: "Noralf Trønnes" <noralf@tronnes.org>
> Cc: Sam Ravnborg <sam@ravnborg.org>
> Cc: Thomas Gleixner <tglx@linutronix.de>
> Cc: Alex Deucher <alexander.deucher@amd.com>
> ---
>  drivers/gpu/drm/udl/udl_drv.c  |  8 +-------
>  drivers/gpu/drm/udl/udl_drv.h  |  1 -
>  drivers/gpu/drm/udl/udl_main.c | 10 ----------
>  3 files changed, 1 insertion(+), 18 deletions(-)
> 
> diff --git a/drivers/gpu/drm/udl/udl_drv.c b/drivers/gpu/drm/udl/udl_drv.c
> index b447fb053e78..1ce2d865c36d 100644
> --- a/drivers/gpu/drm/udl/udl_drv.c
> +++ b/drivers/gpu/drm/udl/udl_drv.c
> @@ -34,14 +34,8 @@ static int udl_usb_resume(struct usb_interface *interface)
>  
>  DEFINE_DRM_GEM_FOPS(udl_driver_fops);
>  
> -static void udl_driver_release(struct drm_device *dev)
> -{
> -	udl_fini(dev);
> -}
> -
>  static struct drm_driver driver = {
>  	.driver_features = DRIVER_ATOMIC | DRIVER_GEM | DRIVER_MODESET,
> -	.release = udl_driver_release,
>  
>  	/* gem hooks */
>  	.gem_create_object = udl_driver_gem_create_object,
> @@ -120,7 +114,7 @@ static void udl_usb_disconnect(struct usb_interface *interface)
>  {
>  	struct drm_device *dev = usb_get_intfdata(interface);
>  
> -	drm_kms_helper_poll_disable(dev);
> +	drm_kms_helper_poll_fini(dev);
>  	udl_drop_usb(dev);
>  	drm_dev_unplug(dev);
>  	drm_dev_put(dev);
> diff --git a/drivers/gpu/drm/udl/udl_drv.h b/drivers/gpu/drm/udl/udl_drv.h
> index 1de7eb1b6aac..2642f94a63fc 100644
> --- a/drivers/gpu/drm/udl/udl_drv.h
> +++ b/drivers/gpu/drm/udl/udl_drv.h
> @@ -76,7 +76,6 @@ int udl_submit_urb(struct drm_device *dev, struct urb *urb, size_t len);
>  void udl_urb_completion(struct urb *urb);
>  
>  int udl_init(struct udl_device *udl);
> -void udl_fini(struct drm_device *dev);
>  
>  int udl_render_hline(struct drm_device *dev, int log_bpp, struct urb **urb_ptr,
>  		     const char *front, char **urb_buf_ptr,
> diff --git a/drivers/gpu/drm/udl/udl_main.c b/drivers/gpu/drm/udl/udl_main.c
> index 538718919916..f5d27f2a5654 100644
> --- a/drivers/gpu/drm/udl/udl_main.c
> +++ b/drivers/gpu/drm/udl/udl_main.c
> @@ -351,13 +351,3 @@ int udl_drop_usb(struct drm_device *dev)
>  	udl_free_urb_list(dev);
>  	return 0;
>  }
> -
> -void udl_fini(struct drm_device *dev)
> -{
> -	struct udl_device *udl = to_udl(dev);
> -
> -	drm_kms_helper_poll_fini(dev);
> -
> -	if (udl->urbs.count)
> -		udl_free_urb_list(dev);
> -}
> 

-- 
Thomas Zimmermann
Graphics Driver Developer
SUSE Software Solutions Germany GmbH
Maxfeldstr. 5, 90409 Nürnberg, Germany
(HRB 36809, AG Nürnberg)
Geschäftsführer: Felix Imendörffer


[-- Attachment #1.2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

[-- Attachment #2: Type: text/plain, Size: 160 bytes --]

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 111+ messages in thread

* Re: [PATCH 03/51] drm: add managed resources tied to drm_device
  2020-03-02 22:25 ` [PATCH 03/51] drm: add managed resources tied to drm_device Daniel Vetter
@ 2020-03-03  8:04   ` Dan Carpenter
  2020-03-03  8:25     ` Daniel Vetter
  2020-03-03  8:44   ` [PATCH] " Daniel Vetter
                     ` (2 subsequent siblings)
  3 siblings, 1 reply; 111+ messages in thread
From: Dan Carpenter @ 2020-03-03  8:04 UTC (permalink / raw)
  To: kbuild, Daniel Vetter
  Cc: kbuild-all, Rafael J. Wysocki, Daniel Vetter,
	Intel Graphics Development, DRI Development, Laurent Pinchart,
	Greg Kroah-Hartman, Daniel Vetter, Sam Ravnborg

Hi Daniel,

I love your patch! Perhaps something to improve:

url:    https://github.com/0day-ci/linux/commits/Daniel-Vetter/drm_device-managed-resources-v4/20200303-071023
base:   git://anongit.freedesktop.org/drm/drm-tip drm-tip

If you fix the issue, kindly add following tag
Reported-by: kbuild test robot <lkp@intel.com>
Reported-by: Dan Carpenter <dan.carpenter@oracle.com>

smatch warnings:
drivers/gpu/drm/drm_drv.c:843 drm_dev_release() error: dereferencing freed memory 'dev'

# https://github.com/0day-ci/linux/commit/5aba700d4c32ae5722a9931c959b13a6217a86e2
git remote add linux-review https://github.com/0day-ci/linux
git remote update linux-review
git checkout 5aba700d4c32ae5722a9931c959b13a6217a86e2
vim +/dev +843 drivers/gpu/drm/drm_drv.c

099d1c290e2ebc drivers/gpu/drm/drm_stub.c David Herrmann 2014-01-29  826  static void drm_dev_release(struct kref *ref)
0dc8fe5985e01f drivers/gpu/drm/drm_stub.c David Herrmann 2013-10-02  827  {
099d1c290e2ebc drivers/gpu/drm/drm_stub.c David Herrmann 2014-01-29  828  	struct drm_device *dev = container_of(ref, struct drm_device, ref);
8f6599da8e772f drivers/gpu/drm/drm_stub.c David Herrmann 2013-10-20  829  
f30c92576af4bb drivers/gpu/drm/drm_drv.c  Chris Wilson   2017-02-02  830  	if (dev->driver->release) {
f30c92576af4bb drivers/gpu/drm/drm_drv.c  Chris Wilson   2017-02-02  831  		dev->driver->release(dev);
f30c92576af4bb drivers/gpu/drm/drm_drv.c  Chris Wilson   2017-02-02  832  	} else {
f30c92576af4bb drivers/gpu/drm/drm_drv.c  Chris Wilson   2017-02-02  833  		drm_dev_fini(dev);
5aba700d4c32ae drivers/gpu/drm/drm_drv.c  Daniel Vetter  2020-03-02  834  	}
5aba700d4c32ae drivers/gpu/drm/drm_drv.c  Daniel Vetter  2020-03-02  835  
5aba700d4c32ae drivers/gpu/drm/drm_drv.c  Daniel Vetter  2020-03-02  836  	drm_managed_release(dev);
5aba700d4c32ae drivers/gpu/drm/drm_drv.c  Daniel Vetter  2020-03-02  837  
5aba700d4c32ae drivers/gpu/drm/drm_drv.c  Daniel Vetter  2020-03-02  838  	if (!dev->driver->release && !dev->managed.final_kfree) {
5aba700d4c32ae drivers/gpu/drm/drm_drv.c  Daniel Vetter  2020-03-02  839  		WARN_ON(!list_empty(&dev->managed.resources));
0dc8fe5985e01f drivers/gpu/drm/drm_stub.c David Herrmann 2013-10-02  840  		kfree(dev);
                                                                                        ^^^^^^^^^^
Free

0dc8fe5985e01f drivers/gpu/drm/drm_stub.c David Herrmann 2013-10-02  841  	}
5aba700d4c32ae drivers/gpu/drm/drm_drv.c  Daniel Vetter  2020-03-02  842  
5aba700d4c32ae drivers/gpu/drm/drm_drv.c  Daniel Vetter  2020-03-02 @843  	if (dev->managed.final_kfree)
                                                                                    ^^^^^
Dereference

5aba700d4c32ae drivers/gpu/drm/drm_drv.c  Daniel Vetter  2020-03-02  844  		kfree(dev->managed.final_kfree);
f30c92576af4bb drivers/gpu/drm/drm_drv.c  Chris Wilson   2017-02-02  845  }

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 111+ messages in thread

* Re: [PATCH 03/51] drm: add managed resources tied to drm_device
  2020-03-03  8:04   ` Dan Carpenter
@ 2020-03-03  8:25     ` Daniel Vetter
  0 siblings, 0 replies; 111+ messages in thread
From: Daniel Vetter @ 2020-03-03  8:25 UTC (permalink / raw)
  To: Dan Carpenter
  Cc: kbuild-all, Rafael J. Wysocki, Daniel Vetter, kbuild,
	DRI Development, Laurent Pinchart, Greg Kroah-Hartman,
	Daniel Vetter, Sam Ravnborg, Intel Graphics Development

On Tue, Mar 03, 2020 at 11:04:06AM +0300, Dan Carpenter wrote:
> Hi Daniel,
> 
> I love your patch! Perhaps something to improve:
> 
> url:    https://github.com/0day-ci/linux/commits/Daniel-Vetter/drm_device-managed-resources-v4/20200303-071023
> base:   git://anongit.freedesktop.org/drm/drm-tip drm-tip
> 
> If you fix the issue, kindly add following tag
> Reported-by: kbuild test robot <lkp@intel.com>
> Reported-by: Dan Carpenter <dan.carpenter@oracle.com>
> 
> smatch warnings:
> drivers/gpu/drm/drm_drv.c:843 drm_dev_release() error: dereferencing freed memory 'dev'
> 
> # https://github.com/0day-ci/linux/commit/5aba700d4c32ae5722a9931c959b13a6217a86e2
> git remote add linux-review https://github.com/0day-ci/linux
> git remote update linux-review
> git checkout 5aba700d4c32ae5722a9931c959b13a6217a86e2
> vim +/dev +843 drivers/gpu/drm/drm_drv.c
> 
> 099d1c290e2ebc drivers/gpu/drm/drm_stub.c David Herrmann 2014-01-29  826  static void drm_dev_release(struct kref *ref)
> 0dc8fe5985e01f drivers/gpu/drm/drm_stub.c David Herrmann 2013-10-02  827  {
> 099d1c290e2ebc drivers/gpu/drm/drm_stub.c David Herrmann 2014-01-29  828  	struct drm_device *dev = container_of(ref, struct drm_device, ref);
> 8f6599da8e772f drivers/gpu/drm/drm_stub.c David Herrmann 2013-10-20  829  
> f30c92576af4bb drivers/gpu/drm/drm_drv.c  Chris Wilson   2017-02-02  830  	if (dev->driver->release) {
> f30c92576af4bb drivers/gpu/drm/drm_drv.c  Chris Wilson   2017-02-02  831  		dev->driver->release(dev);
> f30c92576af4bb drivers/gpu/drm/drm_drv.c  Chris Wilson   2017-02-02  832  	} else {
> f30c92576af4bb drivers/gpu/drm/drm_drv.c  Chris Wilson   2017-02-02  833  		drm_dev_fini(dev);
> 5aba700d4c32ae drivers/gpu/drm/drm_drv.c  Daniel Vetter  2020-03-02  834  	}
> 5aba700d4c32ae drivers/gpu/drm/drm_drv.c  Daniel Vetter  2020-03-02  835  
> 5aba700d4c32ae drivers/gpu/drm/drm_drv.c  Daniel Vetter  2020-03-02  836  	drm_managed_release(dev);
> 5aba700d4c32ae drivers/gpu/drm/drm_drv.c  Daniel Vetter  2020-03-02  837  
> 5aba700d4c32ae drivers/gpu/drm/drm_drv.c  Daniel Vetter  2020-03-02  838  	if (!dev->driver->release && !dev->managed.final_kfree) {
> 5aba700d4c32ae drivers/gpu/drm/drm_drv.c  Daniel Vetter  2020-03-02  839  		WARN_ON(!list_empty(&dev->managed.resources));
> 0dc8fe5985e01f drivers/gpu/drm/drm_stub.c David Herrmann 2013-10-02  840  		kfree(dev);
>                                                                                         ^^^^^^^^^^
> Free
> 
> 0dc8fe5985e01f drivers/gpu/drm/drm_stub.c David Herrmann 2013-10-02  841  	}
> 5aba700d4c32ae drivers/gpu/drm/drm_drv.c  Daniel Vetter  2020-03-02  842  
> 5aba700d4c32ae drivers/gpu/drm/drm_drv.c  Daniel Vetter  2020-03-02 @843  	if (dev->managed.final_kfree)
>                                                                                     ^^^^^
> Dereference

Drat, so much for me trying to get this to bisect properly (it's interim
code and will disappear, end is correct I  think). I guess I'll try again.
-Daniel

> 
> 5aba700d4c32ae drivers/gpu/drm/drm_drv.c  Daniel Vetter  2020-03-02  844  		kfree(dev->managed.final_kfree);
> f30c92576af4bb drivers/gpu/drm/drm_drv.c  Chris Wilson   2017-02-02  845  }
> 
> ---
> 0-DAY CI Kernel Test Service, Intel Corporation
> https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org

-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 111+ messages in thread

* Re: [PATCH 09/51] drm/cirrus: Use drmm_add_final_kfree
  2020-03-03  7:49   ` Gerd Hoffmann
@ 2020-03-03  8:27     ` Daniel Vetter
  0 siblings, 0 replies; 111+ messages in thread
From: Daniel Vetter @ 2020-03-03  8:27 UTC (permalink / raw)
  To: Gerd Hoffmann
  Cc: Daniel Vetter, Intel Graphics Development, DRI Development,
	virtualization, Thomas Zimmermann, Daniel Vetter, Dave Airlie,
	Sam Ravnborg

On Tue, Mar 03, 2020 at 08:49:34AM +0100, Gerd Hoffmann wrote:
> > @@ -575,9 +574,12 @@ static int cirrus_pci_probe(struct pci_dev *pdev,
> >  
> >  	dev = &cirrus->dev;
> >  	ret = drm_dev_init(dev, &cirrus_driver, &pdev->dev);
> > -	if (ret)
> > -		goto err_free_cirrus;
> > +	if (ret) {
> > +		kfree(cirrus);
> > +		goto err_pci_release;
> > +	}
> >  	dev->dev_private = cirrus;
> > +	drmm_add_final_kfree(dev, cirrus);
> 
> That doesn't look like an error path improvement.
> With patch #30 applied it'll looks alot better though.
> So maybe squash the patches?

Breaks the patch set evolution, there's a _lot_ of dependencies in here to
make sure we never break anything interim. But yeah that's why I created
this entire series, since with just the first part it's really not any
better. I also have a pile more ideas on top, so hopefully once this lands
I can get around to them and make everything even better :-)

Cheers, Daniel

> 
> In any case:
> Acked-by: Gerd Hoffmann <kraxel@redhat.com>
> 
> cheers,
>   Gerd
> 

-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 111+ messages in thread

* [PATCH] drm: add managed resources tied to drm_device
  2020-03-02 22:25 ` [PATCH 03/51] drm: add managed resources tied to drm_device Daniel Vetter
  2020-03-03  8:04   ` Dan Carpenter
@ 2020-03-03  8:44   ` Daniel Vetter
  2020-03-06 19:38     ` Sam Ravnborg
  2020-03-11  9:07   ` [PATCH 03/51] " Thomas Zimmermann
  2020-03-11  9:14   ` Thomas Zimmermann
  3 siblings, 1 reply; 111+ messages in thread
From: Daniel Vetter @ 2020-03-03  8:44 UTC (permalink / raw)
  To: DRI Development
  Cc: Rafael J. Wysocki, Daniel Vetter, Intel Graphics Development,
	Laurent Pinchart, Greg Kroah-Hartman, Daniel Vetter,
	Sam Ravnborg, Dan Carpenter

We have lots of these. And the cleanup code tends to be of dubious
quality. The biggest wrong pattern is that developers use devm_, which
ties the release action to the underlying struct device, whereas
all the userspace visible stuff attached to a drm_device can long
outlive that one (e.g. after a hotunplug while userspace has open
files and mmap'ed buffers). Give people what they want, but with more
correctness.

Mostly copied from devres.c, with types adjusted to fit drm_device and
a few simplifications - I didn't (yet) copy over everything. Since
the types don't match code sharing looked like a hopeless endeavour.

For now it's only super simplified, no groups, you can't remove
actions (but kfree exists, we'll need that soon). Plus all specific to
drm_device ofc, including the logging. Which I didn't bother to make
compile-time optional, since none of the other drm logging is compile
time optional either.

One tricky bit here is the chicken&egg between allocating your
drm_device structure and initiliazing it with drm_dev_init. For
perfect onion unwinding we'd need to have the action to kfree the
allocation registered before drm_dev_init registers any of its own
release handlers. But drm_dev_init doesn't know where exactly the
drm_device is emebedded into the overall structure, and by the time it
returns it'll all be too late. And forcing drivers to be able clean up
everything except the one kzalloc is silly.

Work around this by having a very special final_kfree pointer. This
also avoids troubles with the list head possibly disappearing from
underneath us when we release all resources attached to the
drm_device.

v2: Do all the kerneldoc at the end, to avoid lots of fairly pointless
shuffling while getting everything into shape.

v3: Add static to add/del_dr (Neil)
Move typo fix to the right patch (Neil)

v4: Enforce contract for drmm_add_final_kfree:

Use ksize() to check that the drm_device is indeed contained somewhere
in the final kfree(). Because we need that or the entire managed
release logic blows up in a pile of use-after-frees. Motivated by a
discussion with Laurent.

v5: Review from Laurent:
- %zu instead of casting size_t
- header guards
- sorting of includes
- guarding of data assignment if we didn't allocate it for a NULL
  pointer
- delete spurious newline
- cast void* data parameter correctly in ->release call, no idea how
  this even worked before

v3: Review from Sam
- Add the kerneldoc for the managed sub-struct back in, even if it
  doesn't show up in the generated html somehow.
- Explain why __always_inline.
- Fix bisectability around the final kfree() in drm_dev_relase(). This
  is just interim code which will disappear again.
- Some whitespace polish.
- Add debug output when drmm_add_action or drmm_kmalloc fail.

v4: My bisectability fix wasn't up to par as noticed by smatch.

Cc: Dan Carpenter <dan.carpenter@oracle.com>
Cc: Sam Ravnborg <sam@ravnborg.org>
Cc: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Cc: Neil Armstrong <narmstrong@baylibre.com
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: "Rafael J. Wysocki" <rafael@kernel.org>
Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
---
 Documentation/gpu/drm-internals.rst |   6 +
 drivers/gpu/drm/Makefile            |   3 +-
 drivers/gpu/drm/drm_drv.c           |  12 +-
 drivers/gpu/drm/drm_internal.h      |   3 +
 drivers/gpu/drm/drm_managed.c       | 186 ++++++++++++++++++++++++++++
 include/drm/drm_device.h            |  15 +++
 include/drm/drm_managed.h           |  30 +++++
 include/drm/drm_print.h             |   6 +
 8 files changed, 259 insertions(+), 2 deletions(-)
 create mode 100644 drivers/gpu/drm/drm_managed.c
 create mode 100644 include/drm/drm_managed.h

diff --git a/Documentation/gpu/drm-internals.rst b/Documentation/gpu/drm-internals.rst
index a73320576ca9..a6b6145fda78 100644
--- a/Documentation/gpu/drm-internals.rst
+++ b/Documentation/gpu/drm-internals.rst
@@ -132,6 +132,12 @@ be unmapped; on many devices, the ROM address decoder is shared with
 other BARs, so leaving it mapped could cause undesired behaviour like
 hangs or memory corruption.
 
+Managed Resources
+-----------------
+
+.. kernel-doc:: drivers/gpu/drm/drm_managed.c
+   :doc: managed resources
+
 Bus-specific Device Registration and PCI Support
 ------------------------------------------------
 
diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile
index 7f72ef5e7811..183c60048307 100644
--- a/drivers/gpu/drm/Makefile
+++ b/drivers/gpu/drm/Makefile
@@ -17,7 +17,8 @@ drm-y       :=	drm_auth.o drm_cache.o \
 		drm_plane.o drm_color_mgmt.o drm_print.o \
 		drm_dumb_buffers.o drm_mode_config.o drm_vblank.o \
 		drm_syncobj.o drm_lease.o drm_writeback.o drm_client.o \
-		drm_client_modeset.o drm_atomic_uapi.o drm_hdcp.o
+		drm_client_modeset.o drm_atomic_uapi.o drm_hdcp.o \
+		drm_managed.o
 
 drm-$(CONFIG_DRM_LEGACY) += drm_legacy_misc.o drm_bufs.o drm_context.o drm_dma.o drm_scatter.o drm_lock.o
 drm-$(CONFIG_DRM_LIB_RANDOM) += lib/drm_random.o
diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c
index 9fcd6ab3c154..d36e3812bedc 100644
--- a/drivers/gpu/drm/drm_drv.c
+++ b/drivers/gpu/drm/drm_drv.c
@@ -629,6 +629,9 @@ int drm_dev_init(struct drm_device *dev,
 	dev->dev = get_device(parent);
 	dev->driver = driver;
 
+	INIT_LIST_HEAD(&dev->managed.resources);
+	spin_lock_init(&dev->managed.lock);
+
 	/* no per-device feature limits by default */
 	dev->driver_features = ~0u;
 
@@ -828,8 +831,15 @@ static void drm_dev_release(struct kref *ref)
 		dev->driver->release(dev);
 	} else {
 		drm_dev_fini(dev);
-		kfree(dev);
 	}
+
+	drm_managed_release(dev);
+
+	if (!dev->driver->release && !dev->managed.final_kfree) {
+		WARN_ON(!list_empty(&dev->managed.resources));
+		kfree(dev);
+	} else if (dev->managed.final_kfree)
+		kfree(dev->managed.final_kfree);
 }
 
 /**
diff --git a/drivers/gpu/drm/drm_internal.h b/drivers/gpu/drm/drm_internal.h
index aeec2e68d772..8c2628dfc6c7 100644
--- a/drivers/gpu/drm/drm_internal.h
+++ b/drivers/gpu/drm/drm_internal.h
@@ -89,6 +89,9 @@ void drm_prime_remove_buf_handle_locked(struct drm_prime_file_private *prime_fpr
 struct drm_minor *drm_minor_acquire(unsigned int minor_id);
 void drm_minor_release(struct drm_minor *minor);
 
+/* drm_managed.c */
+void drm_managed_release(struct drm_device *dev);
+
 /* drm_vblank.c */
 void drm_vblank_disable_and_save(struct drm_device *dev, unsigned int pipe);
 void drm_vblank_cleanup(struct drm_device *dev);
diff --git a/drivers/gpu/drm/drm_managed.c b/drivers/gpu/drm/drm_managed.c
new file mode 100644
index 000000000000..57dc79fa90af
--- /dev/null
+++ b/drivers/gpu/drm/drm_managed.c
@@ -0,0 +1,186 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2020 Intel
+ *
+ * Based on drivers/base/devres.c
+ */
+
+#include <drm/drm_managed.h>
+
+#include <linux/list.h>
+#include <linux/slab.h>
+#include <linux/spinlock.h>
+
+#include <drm/drm_device.h>
+#include <drm/drm_print.h>
+
+/**
+ * DOC: managed resources
+ *
+ * Inspired by struct &device managed resources, but tied to the lifetime of
+ * struct &drm_device, which can outlive the underlying physical device, usually
+ * when userspace has some open files and other handles to resources still open.
+ */
+struct drmres_node {
+	struct list_head	entry;
+	drmres_release_t	release;
+	const char		*name;
+	size_t			size;
+};
+
+struct drmres {
+	struct drmres_node		node;
+	/*
+	 * Some archs want to perform DMA into kmalloc caches
+	 * and need a guaranteed alignment larger than
+	 * the alignment of a 64-bit integer.
+	 * Thus we use ARCH_KMALLOC_MINALIGN here and get exactly the same
+	 * buffer alignment as if it was allocated by plain kmalloc().
+	 */
+	u8 __aligned(ARCH_KMALLOC_MINALIGN) data[];
+};
+
+void drm_managed_release(struct drm_device *dev)
+{
+	struct drmres *dr, *tmp;
+
+	drm_dbg_drmres(dev, "drmres release begin\n");
+	list_for_each_entry_safe(dr, tmp, &dev->managed.resources, node.entry) {
+		drm_dbg_drmres(dev, "REL %p %s (%zu bytes)\n",
+			       dr, dr->node.name, dr->node.size);
+
+		if (dr->node.release)
+			dr->node.release(dev, dr->node.size ? *(void **)&dr->data : NULL);
+
+		list_del(&dr->node.entry);
+		kfree(dr);
+	}
+	drm_dbg_drmres(dev, "drmres release end\n");
+}
+
+/*
+ * Always inline so that kmallc_track_caller tracks the actual interesting
+ * caller outside of drm_managed.c.
+ */
+static __always_inline struct drmres * alloc_dr(drmres_release_t release,
+						size_t size, gfp_t gfp, int nid)
+{
+	size_t tot_size;
+	struct drmres *dr;
+
+	/* We must catch any near-SIZE_MAX cases that could overflow. */
+	if (unlikely(check_add_overflow(sizeof(*dr), size, &tot_size)))
+		return NULL;
+
+	dr = kmalloc_node_track_caller(tot_size, gfp, nid);
+	if (unlikely(!dr))
+		return NULL;
+
+	memset(dr, 0, offsetof(struct drmres, data));
+
+	INIT_LIST_HEAD(&dr->node.entry);
+	dr->node.release = release;
+	dr->node.size = size;
+
+	return dr;
+}
+
+static void del_dr(struct drm_device *dev, struct drmres *dr)
+{
+	list_del_init(&dr->node.entry);
+
+	drm_dbg_drmres(dev, "DEL %p %s (%lu bytes)\n",
+		       dr, dr->node.name, (unsigned long) dr->node.size);
+}
+
+static void add_dr(struct drm_device *dev, struct drmres *dr)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&dev->managed.lock, flags);
+	list_add(&dr->node.entry, &dev->managed.resources);
+	spin_unlock_irqrestore(&dev->managed.lock, flags);
+
+	drm_dbg_drmres(dev, "ADD %p %s (%lu bytes)\n",
+		       dr, dr->node.name, (unsigned long) dr->node.size);
+}
+
+void drmm_add_final_kfree(struct drm_device *dev, void *parent)
+{
+	WARN_ON(dev->managed.final_kfree);
+	WARN_ON(dev < (struct drm_device *) parent);
+	WARN_ON(dev + 1 >= (struct drm_device *) (parent + ksize(parent)));
+	dev->managed.final_kfree = parent;
+}
+EXPORT_SYMBOL(drmm_add_final_kfree);
+
+int __drmm_add_action(struct drm_device *dev,
+		      drmres_release_t action,
+		      void *data, const char *name)
+{
+	struct drmres *dr;
+	void **void_ptr;
+
+	dr = alloc_dr(action, data ? sizeof(void*) : 0,
+		      GFP_KERNEL | __GFP_ZERO,
+		      dev_to_node(dev->dev));
+	if (!dr) {
+		drm_dbg_drmres(dev, "failed to add action %s for %p\n",
+			       name, data);
+		return -ENOMEM;
+	}
+
+	dr->node.name = name;
+	if (data) {
+		void_ptr = (void **)&dr->data;
+		*void_ptr = data;
+	}
+
+	add_dr(dev, dr);
+
+	return 0;
+}
+EXPORT_SYMBOL(__drmm_add_action);
+
+void *drmm_kmalloc(struct drm_device *dev, size_t size, gfp_t gfp)
+{
+	struct drmres *dr;
+
+	dr = alloc_dr(NULL, size, gfp, dev_to_node(dev->dev));
+	if (!dr) {
+		drm_dbg_drmres(dev, "failed to allocate %zu bytes, %u flags\n",
+			       size, gfp);
+		return NULL;
+	}
+	dr->node.name = "kmalloc";
+
+	add_dr(dev, dr);
+
+	return dr->data;
+}
+EXPORT_SYMBOL(drmm_kmalloc);
+
+void drmm_kfree(struct drm_device *dev, void *data)
+{
+	struct drmres *dr_match = NULL, *dr;
+	unsigned long flags;
+
+	if (!data)
+		return;
+
+	spin_lock_irqsave(&dev->managed.lock, flags);
+	list_for_each_entry(dr, &dev->managed.resources, node.entry) {
+		if (dr->data == data) {
+			dr_match = dr;
+			del_dr(dev, dr_match);
+			break;
+		}
+	}
+	spin_unlock_irqrestore(&dev->managed.lock, flags);
+
+	if (WARN_ON(!dr_match))
+		return;
+
+	kfree(dr_match);
+}
+EXPORT_SYMBOL(drmm_kfree);
diff --git a/include/drm/drm_device.h b/include/drm/drm_device.h
index bb60a949f416..d39132b477dd 100644
--- a/include/drm/drm_device.h
+++ b/include/drm/drm_device.h
@@ -67,6 +67,21 @@ struct drm_device {
 	/** @dev: Device structure of bus-device */
 	struct device *dev;
 
+	/**
+	 * @managed:
+	 *
+	 * Managed resources linked to the lifetime of this &drm_device as
+	 * tracked by @ref.
+	 */
+	struct {
+		/** @managed.resources: managed resources list */
+		struct list_head resources;
+		/** @managed.final_kfree: pointer for final kfree() call */
+		void *final_kfree;
+		/** @managed.lock: protects @managed.resources */
+		spinlock_t lock;
+	} managed;
+
 	/** @driver: DRM driver managing the device */
 	struct drm_driver *driver;
 
diff --git a/include/drm/drm_managed.h b/include/drm/drm_managed.h
new file mode 100644
index 000000000000..7b5df7d09b19
--- /dev/null
+++ b/include/drm/drm_managed.h
@@ -0,0 +1,30 @@
+// SPDX-License-Identifier: GPL-2.0
+
+#ifndef _DRM_MANAGED_H_
+#define _DRM_MANAGED_H_
+
+#include <linux/gfp.h>
+#include <linux/types.h>
+
+struct drm_device;
+
+typedef void (*drmres_release_t)(struct drm_device *dev, void *res);
+
+#define drmm_add_action(dev, action, data) \
+	__drmm_add_action(dev, action, data, #action)
+
+int __must_check __drmm_add_action(struct drm_device *dev,
+				   drmres_release_t action,
+				   void *data, const char *name);
+
+void drmm_add_final_kfree(struct drm_device *dev, void *parent);
+
+void *drmm_kmalloc(struct drm_device *dev, size_t size, gfp_t gfp) __malloc;
+static inline void *drmm_kzalloc(struct drm_device *dev, size_t size, gfp_t gfp)
+{
+	return drmm_kmalloc(dev, size, gfp | __GFP_ZERO);
+}
+
+void drmm_kfree(struct drm_device *dev, void *data);
+
+#endif
diff --git a/include/drm/drm_print.h b/include/drm/drm_print.h
index ca7cee8e728a..1c9417430d08 100644
--- a/include/drm/drm_print.h
+++ b/include/drm/drm_print.h
@@ -313,6 +313,10 @@ enum drm_debug_category {
 	 * @DRM_UT_DP: Used in the DP code.
 	 */
 	DRM_UT_DP		= 0x100,
+	/**
+	 * @DRM_UT_DRMRES: Used in the drm managed resources code.
+	 */
+	DRM_UT_DRMRES		= 0x200,
 };
 
 static inline bool drm_debug_enabled(enum drm_debug_category category)
@@ -442,6 +446,8 @@ void drm_dev_dbg(const struct device *dev, enum drm_debug_category category,
 	drm_dev_dbg((drm)->dev, DRM_UT_LEASE, fmt, ##__VA_ARGS__)
 #define drm_dbg_dp(drm, fmt, ...)					\
 	drm_dev_dbg((drm)->dev, DRM_UT_DP, fmt, ##__VA_ARGS__)
+#define drm_dbg_drmres(drm, fmt, ...)					\
+	drm_dev_dbg((drm)->dev, DRM_UT_DRMRES, fmt, ##__VA_ARGS__)
 
 
 /*
-- 
2.24.1

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 111+ messages in thread

* [PATCH] drm: Cleanups after drmm_add_final_kfree rollout
  2020-03-02 22:25 ` [PATCH 19/51] drm: Cleanups after drmm_add_final_kfree rollout Daniel Vetter
@ 2020-03-03  8:45   ` Daniel Vetter
  2020-03-06 20:31     ` Sam Ravnborg
  2020-03-06 20:29   ` [PATCH 19/51] " Sam Ravnborg
  2020-03-11  9:15   ` Thomas Zimmermann
  2 siblings, 1 reply; 111+ messages in thread
From: Daniel Vetter @ 2020-03-03  8:45 UTC (permalink / raw)
  To: DRI Development
  Cc: Daniel Vetter, Intel Graphics Development, Sam Ravnborg,
	Dan Carpenter, Daniel Vetter

A few things:
- Update the example driver in the documentation.
- We can drop the old kfree in drm_dev_release.
- Add a WARN_ON check in drm_dev_register to make sure everyone calls
  drmm_add_final_kfree and there's no leaks.

v2: Restore the full cleanup, I accidentally left some moved code
behind when fixing the bisectability of the series.

Cc: Sam Ravnborg <sam@ravnborg.org>
Cc: Dan Carpenter <dan.carpenter@oracle.com>
Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
---
 drivers/gpu/drm/drm_drv.c | 12 +++++-------
 1 file changed, 5 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c
index 80cfd0f14475..1ee606b4a4f9 100644
--- a/drivers/gpu/drm/drm_drv.c
+++ b/drivers/gpu/drm/drm_drv.c
@@ -297,8 +297,6 @@ void drm_minor_release(struct drm_minor *minor)
  *
  *		drm_mode_config_cleanup(drm);
  *		drm_dev_fini(drm);
- *		kfree(priv->userspace_facing);
- *		kfree(priv);
  *	}
  *
  *	static struct drm_driver driver_drm_driver = {
@@ -326,10 +324,11 @@ void drm_minor_release(struct drm_minor *minor)
  *			kfree(drm);
  *			return ret;
  *		}
+ *		drmm_add_final_kfree(drm, priv);
  *
  *		drm_mode_config_init(drm);
  *
- *		priv->userspace_facing = kzalloc(..., GFP_KERNEL);
+ *		priv->userspace_facing = drmm_kzalloc(..., GFP_KERNEL);
  *		if (!priv->userspace_facing)
  *			return -ENOMEM;
  *
@@ -838,10 +837,7 @@ static void drm_dev_release(struct kref *ref)
 
 	drm_managed_release(dev);
 
-	if (!dev->driver->release && !dev->managed.final_kfree) {
-		WARN_ON(!list_empty(&dev->managed.resources));
-		kfree(dev);
-	} else if (dev->managed.final_kfree)
+	if (dev->managed.final_kfree)
 		kfree(dev->managed.final_kfree);
 }
 
@@ -959,6 +955,8 @@ int drm_dev_register(struct drm_device *dev, unsigned long flags)
 	struct drm_driver *driver = dev->driver;
 	int ret;
 
+	WARN_ON(!dev->managed.final_kfree);
+
 	if (drm_dev_needs_global_mutex(dev))
 		mutex_lock(&drm_global_mutex);
 
-- 
2.24.1

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 111+ messages in thread

* Re: [PATCH] drm: add managed resources tied to drm_device
  2020-03-03  8:44   ` [PATCH] " Daniel Vetter
@ 2020-03-06 19:38     ` Sam Ravnborg
  0 siblings, 0 replies; 111+ messages in thread
From: Sam Ravnborg @ 2020-03-06 19:38 UTC (permalink / raw)
  To: Daniel Vetter
  Cc: Rafael J. Wysocki, Greg Kroah-Hartman,
	Intel Graphics Development, DRI Development, Laurent Pinchart,
	Daniel Vetter, Dan Carpenter

Hi Daniel.

> v2: Do all the kerneldoc at the end, to avoid lots of fairly pointless
> shuffling while getting everything into shape.
> 
> v3: Add static to add/del_dr (Neil)
> Move typo fix to the right patch (Neil)
> 
> v4: Enforce contract for drmm_add_final_kfree:
> 
> Use ksize() to check that the drm_device is indeed contained somewhere
> in the final kfree(). Because we need that or the entire managed
> release logic blows up in a pile of use-after-frees. Motivated by a
> discussion with Laurent.
> 
> v5: Review from Laurent:
> - %zu instead of casting size_t
> - header guards
> - sorting of includes
> - guarding of data assignment if we didn't allocate it for a NULL
>   pointer
> - delete spurious newline
> - cast void* data parameter correctly in ->release call, no idea how
>   this even worked before
> 
> v3: Review from Sam
> - Add the kerneldoc for the managed sub-struct back in, even if it
>   doesn't show up in the generated html somehow.
> - Explain why __always_inline.
> - Fix bisectability around the final kfree() in drm_dev_relase(). This
>   is just interim code which will disappear again.
> - Some whitespace polish.
> - Add debug output when drmm_add_action or drmm_kmalloc fail.
> 
> v4: My bisectability fix wasn't up to par as noticed by smatch.
Counting is a difficult, let's restart from v3 :-)

> 
> Cc: Dan Carpenter <dan.carpenter@oracle.com>
> Cc: Sam Ravnborg <sam@ravnborg.org>
> Cc: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
> Cc: Neil Armstrong <narmstrong@baylibre.com
> Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
> Cc: "Rafael J. Wysocki" <rafael@kernel.org>
> Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>

Looks good now.
Reviewed-by: Sam Ravnborg <sam@ravnborg.org>

> ---
>  Documentation/gpu/drm-internals.rst |   6 +
>  drivers/gpu/drm/Makefile            |   3 +-
>  drivers/gpu/drm/drm_drv.c           |  12 +-
>  drivers/gpu/drm/drm_internal.h      |   3 +
>  drivers/gpu/drm/drm_managed.c       | 186 ++++++++++++++++++++++++++++
>  include/drm/drm_device.h            |  15 +++
>  include/drm/drm_managed.h           |  30 +++++
>  include/drm/drm_print.h             |   6 +
>  8 files changed, 259 insertions(+), 2 deletions(-)
>  create mode 100644 drivers/gpu/drm/drm_managed.c
>  create mode 100644 include/drm/drm_managed.h
> 
> diff --git a/Documentation/gpu/drm-internals.rst b/Documentation/gpu/drm-internals.rst
> index a73320576ca9..a6b6145fda78 100644
> --- a/Documentation/gpu/drm-internals.rst
> +++ b/Documentation/gpu/drm-internals.rst
> @@ -132,6 +132,12 @@ be unmapped; on many devices, the ROM address decoder is shared with
>  other BARs, so leaving it mapped could cause undesired behaviour like
>  hangs or memory corruption.
>  
> +Managed Resources
> +-----------------
> +
> +.. kernel-doc:: drivers/gpu/drm/drm_managed.c
> +   :doc: managed resources
> +
>  Bus-specific Device Registration and PCI Support
>  ------------------------------------------------
>  
> diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile
> index 7f72ef5e7811..183c60048307 100644
> --- a/drivers/gpu/drm/Makefile
> +++ b/drivers/gpu/drm/Makefile
> @@ -17,7 +17,8 @@ drm-y       :=	drm_auth.o drm_cache.o \
>  		drm_plane.o drm_color_mgmt.o drm_print.o \
>  		drm_dumb_buffers.o drm_mode_config.o drm_vblank.o \
>  		drm_syncobj.o drm_lease.o drm_writeback.o drm_client.o \
> -		drm_client_modeset.o drm_atomic_uapi.o drm_hdcp.o
> +		drm_client_modeset.o drm_atomic_uapi.o drm_hdcp.o \
> +		drm_managed.o
>  
>  drm-$(CONFIG_DRM_LEGACY) += drm_legacy_misc.o drm_bufs.o drm_context.o drm_dma.o drm_scatter.o drm_lock.o
>  drm-$(CONFIG_DRM_LIB_RANDOM) += lib/drm_random.o
> diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c
> index 9fcd6ab3c154..d36e3812bedc 100644
> --- a/drivers/gpu/drm/drm_drv.c
> +++ b/drivers/gpu/drm/drm_drv.c
> @@ -629,6 +629,9 @@ int drm_dev_init(struct drm_device *dev,
>  	dev->dev = get_device(parent);
>  	dev->driver = driver;
>  
> +	INIT_LIST_HEAD(&dev->managed.resources);
> +	spin_lock_init(&dev->managed.lock);
> +
>  	/* no per-device feature limits by default */
>  	dev->driver_features = ~0u;
>  
> @@ -828,8 +831,15 @@ static void drm_dev_release(struct kref *ref)
>  		dev->driver->release(dev);
>  	} else {
>  		drm_dev_fini(dev);
> -		kfree(dev);
>  	}
> +
> +	drm_managed_release(dev);
> +
> +	if (!dev->driver->release && !dev->managed.final_kfree) {
> +		WARN_ON(!list_empty(&dev->managed.resources));
> +		kfree(dev);
> +	} else if (dev->managed.final_kfree)
> +		kfree(dev->managed.final_kfree);
>  }
>  
>  /**
> diff --git a/drivers/gpu/drm/drm_internal.h b/drivers/gpu/drm/drm_internal.h
> index aeec2e68d772..8c2628dfc6c7 100644
> --- a/drivers/gpu/drm/drm_internal.h
> +++ b/drivers/gpu/drm/drm_internal.h
> @@ -89,6 +89,9 @@ void drm_prime_remove_buf_handle_locked(struct drm_prime_file_private *prime_fpr
>  struct drm_minor *drm_minor_acquire(unsigned int minor_id);
>  void drm_minor_release(struct drm_minor *minor);
>  
> +/* drm_managed.c */
> +void drm_managed_release(struct drm_device *dev);
> +
>  /* drm_vblank.c */
>  void drm_vblank_disable_and_save(struct drm_device *dev, unsigned int pipe);
>  void drm_vblank_cleanup(struct drm_device *dev);
> diff --git a/drivers/gpu/drm/drm_managed.c b/drivers/gpu/drm/drm_managed.c
> new file mode 100644
> index 000000000000..57dc79fa90af
> --- /dev/null
> +++ b/drivers/gpu/drm/drm_managed.c
> @@ -0,0 +1,186 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Copyright (C) 2020 Intel
> + *
> + * Based on drivers/base/devres.c
> + */
> +
> +#include <drm/drm_managed.h>
> +
> +#include <linux/list.h>
> +#include <linux/slab.h>
> +#include <linux/spinlock.h>
> +
> +#include <drm/drm_device.h>
> +#include <drm/drm_print.h>
> +
> +/**
> + * DOC: managed resources
> + *
> + * Inspired by struct &device managed resources, but tied to the lifetime of
> + * struct &drm_device, which can outlive the underlying physical device, usually
> + * when userspace has some open files and other handles to resources still open.
> + */
> +struct drmres_node {
> +	struct list_head	entry;
> +	drmres_release_t	release;
> +	const char		*name;
> +	size_t			size;
> +};
> +
> +struct drmres {
> +	struct drmres_node		node;
> +	/*
> +	 * Some archs want to perform DMA into kmalloc caches
> +	 * and need a guaranteed alignment larger than
> +	 * the alignment of a 64-bit integer.
> +	 * Thus we use ARCH_KMALLOC_MINALIGN here and get exactly the same
> +	 * buffer alignment as if it was allocated by plain kmalloc().
> +	 */
> +	u8 __aligned(ARCH_KMALLOC_MINALIGN) data[];
> +};
> +
> +void drm_managed_release(struct drm_device *dev)
> +{
> +	struct drmres *dr, *tmp;
> +
> +	drm_dbg_drmres(dev, "drmres release begin\n");
> +	list_for_each_entry_safe(dr, tmp, &dev->managed.resources, node.entry) {
> +		drm_dbg_drmres(dev, "REL %p %s (%zu bytes)\n",
> +			       dr, dr->node.name, dr->node.size);
> +
> +		if (dr->node.release)
> +			dr->node.release(dev, dr->node.size ? *(void **)&dr->data : NULL);
> +
> +		list_del(&dr->node.entry);
> +		kfree(dr);
> +	}
> +	drm_dbg_drmres(dev, "drmres release end\n");
> +}
> +
> +/*
> + * Always inline so that kmallc_track_caller tracks the actual interesting
> + * caller outside of drm_managed.c.
> + */
> +static __always_inline struct drmres * alloc_dr(drmres_release_t release,
> +						size_t size, gfp_t gfp, int nid)
> +{
> +	size_t tot_size;
> +	struct drmres *dr;
> +
> +	/* We must catch any near-SIZE_MAX cases that could overflow. */
> +	if (unlikely(check_add_overflow(sizeof(*dr), size, &tot_size)))
> +		return NULL;
> +
> +	dr = kmalloc_node_track_caller(tot_size, gfp, nid);
> +	if (unlikely(!dr))
> +		return NULL;
> +
> +	memset(dr, 0, offsetof(struct drmres, data));
> +
> +	INIT_LIST_HEAD(&dr->node.entry);
> +	dr->node.release = release;
> +	dr->node.size = size;
> +
> +	return dr;
> +}
> +
> +static void del_dr(struct drm_device *dev, struct drmres *dr)
> +{
> +	list_del_init(&dr->node.entry);
> +
> +	drm_dbg_drmres(dev, "DEL %p %s (%lu bytes)\n",
> +		       dr, dr->node.name, (unsigned long) dr->node.size);
> +}
> +
> +static void add_dr(struct drm_device *dev, struct drmres *dr)
> +{
> +	unsigned long flags;
> +
> +	spin_lock_irqsave(&dev->managed.lock, flags);
> +	list_add(&dr->node.entry, &dev->managed.resources);
> +	spin_unlock_irqrestore(&dev->managed.lock, flags);
> +
> +	drm_dbg_drmres(dev, "ADD %p %s (%lu bytes)\n",
> +		       dr, dr->node.name, (unsigned long) dr->node.size);
> +}
> +
> +void drmm_add_final_kfree(struct drm_device *dev, void *parent)
> +{
> +	WARN_ON(dev->managed.final_kfree);
> +	WARN_ON(dev < (struct drm_device *) parent);
> +	WARN_ON(dev + 1 >= (struct drm_device *) (parent + ksize(parent)));
> +	dev->managed.final_kfree = parent;
> +}
> +EXPORT_SYMBOL(drmm_add_final_kfree);
> +
> +int __drmm_add_action(struct drm_device *dev,
> +		      drmres_release_t action,
> +		      void *data, const char *name)
> +{
> +	struct drmres *dr;
> +	void **void_ptr;
> +
> +	dr = alloc_dr(action, data ? sizeof(void*) : 0,
> +		      GFP_KERNEL | __GFP_ZERO,
> +		      dev_to_node(dev->dev));
> +	if (!dr) {
> +		drm_dbg_drmres(dev, "failed to add action %s for %p\n",
> +			       name, data);
> +		return -ENOMEM;
> +	}
> +
> +	dr->node.name = name;
> +	if (data) {
> +		void_ptr = (void **)&dr->data;
> +		*void_ptr = data;
> +	}
> +
> +	add_dr(dev, dr);
> +
> +	return 0;
> +}
> +EXPORT_SYMBOL(__drmm_add_action);
> +
> +void *drmm_kmalloc(struct drm_device *dev, size_t size, gfp_t gfp)
> +{
> +	struct drmres *dr;
> +
> +	dr = alloc_dr(NULL, size, gfp, dev_to_node(dev->dev));
> +	if (!dr) {
> +		drm_dbg_drmres(dev, "failed to allocate %zu bytes, %u flags\n",
> +			       size, gfp);
> +		return NULL;
> +	}
> +	dr->node.name = "kmalloc";
> +
> +	add_dr(dev, dr);
> +
> +	return dr->data;
> +}
> +EXPORT_SYMBOL(drmm_kmalloc);
> +
> +void drmm_kfree(struct drm_device *dev, void *data)
> +{
> +	struct drmres *dr_match = NULL, *dr;
> +	unsigned long flags;
> +
> +	if (!data)
> +		return;
> +
> +	spin_lock_irqsave(&dev->managed.lock, flags);
> +	list_for_each_entry(dr, &dev->managed.resources, node.entry) {
> +		if (dr->data == data) {
> +			dr_match = dr;
> +			del_dr(dev, dr_match);
> +			break;
> +		}
> +	}
> +	spin_unlock_irqrestore(&dev->managed.lock, flags);
> +
> +	if (WARN_ON(!dr_match))
> +		return;
> +
> +	kfree(dr_match);
> +}
> +EXPORT_SYMBOL(drmm_kfree);
> diff --git a/include/drm/drm_device.h b/include/drm/drm_device.h
> index bb60a949f416..d39132b477dd 100644
> --- a/include/drm/drm_device.h
> +++ b/include/drm/drm_device.h
> @@ -67,6 +67,21 @@ struct drm_device {
>  	/** @dev: Device structure of bus-device */
>  	struct device *dev;
>  
> +	/**
> +	 * @managed:
> +	 *
> +	 * Managed resources linked to the lifetime of this &drm_device as
> +	 * tracked by @ref.
> +	 */
> +	struct {
> +		/** @managed.resources: managed resources list */
> +		struct list_head resources;
> +		/** @managed.final_kfree: pointer for final kfree() call */
> +		void *final_kfree;
> +		/** @managed.lock: protects @managed.resources */
> +		spinlock_t lock;
> +	} managed;
> +
>  	/** @driver: DRM driver managing the device */
>  	struct drm_driver *driver;
>  
> diff --git a/include/drm/drm_managed.h b/include/drm/drm_managed.h
> new file mode 100644
> index 000000000000..7b5df7d09b19
> --- /dev/null
> +++ b/include/drm/drm_managed.h
> @@ -0,0 +1,30 @@
> +// SPDX-License-Identifier: GPL-2.0
> +
> +#ifndef _DRM_MANAGED_H_
> +#define _DRM_MANAGED_H_
> +
> +#include <linux/gfp.h>
> +#include <linux/types.h>
> +
> +struct drm_device;
> +
> +typedef void (*drmres_release_t)(struct drm_device *dev, void *res);
> +
> +#define drmm_add_action(dev, action, data) \
> +	__drmm_add_action(dev, action, data, #action)
> +
> +int __must_check __drmm_add_action(struct drm_device *dev,
> +				   drmres_release_t action,
> +				   void *data, const char *name);
> +
> +void drmm_add_final_kfree(struct drm_device *dev, void *parent);
> +
> +void *drmm_kmalloc(struct drm_device *dev, size_t size, gfp_t gfp) __malloc;
> +static inline void *drmm_kzalloc(struct drm_device *dev, size_t size, gfp_t gfp)
> +{
> +	return drmm_kmalloc(dev, size, gfp | __GFP_ZERO);
> +}
> +
> +void drmm_kfree(struct drm_device *dev, void *data);
> +
> +#endif
> diff --git a/include/drm/drm_print.h b/include/drm/drm_print.h
> index ca7cee8e728a..1c9417430d08 100644
> --- a/include/drm/drm_print.h
> +++ b/include/drm/drm_print.h
> @@ -313,6 +313,10 @@ enum drm_debug_category {
>  	 * @DRM_UT_DP: Used in the DP code.
>  	 */
>  	DRM_UT_DP		= 0x100,
> +	/**
> +	 * @DRM_UT_DRMRES: Used in the drm managed resources code.
> +	 */
> +	DRM_UT_DRMRES		= 0x200,
>  };
>  
>  static inline bool drm_debug_enabled(enum drm_debug_category category)
> @@ -442,6 +446,8 @@ void drm_dev_dbg(const struct device *dev, enum drm_debug_category category,
>  	drm_dev_dbg((drm)->dev, DRM_UT_LEASE, fmt, ##__VA_ARGS__)
>  #define drm_dbg_dp(drm, fmt, ...)					\
>  	drm_dev_dbg((drm)->dev, DRM_UT_DP, fmt, ##__VA_ARGS__)
> +#define drm_dbg_drmres(drm, fmt, ...)					\
> +	drm_dev_dbg((drm)->dev, DRM_UT_DRMRES, fmt, ##__VA_ARGS__)
>  
>  
>  /*
> -- 
> 2.24.1
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 111+ messages in thread

* Re: [PATCH 26/51] drm: Manage drm_mode_config_init with drmm_
  2020-03-02 22:26 ` [PATCH 26/51] drm: Manage drm_mode_config_init with drmm_ Daniel Vetter
@ 2020-03-06 20:04   ` Sam Ravnborg
  0 siblings, 0 replies; 111+ messages in thread
From: Sam Ravnborg @ 2020-03-06 20:04 UTC (permalink / raw)
  To: Daniel Vetter
  Cc: Intel Graphics Development, DRI Development, Laurent Pinchart,
	Thomas Zimmermann, Daniel Vetter

Hi Daniel.

On Mon, Mar 02, 2020 at 11:26:06PM +0100, Daniel Vetter wrote:
> drm_mode_config_cleanup is idempotent, so no harm in calling this
> twice. This allows us to gradually switch drivers over by removing
> explicit drm_mode_config_cleanup calls.
> 
> With this step it's now also possible that (at least for simple
> drivers) automatic resource cleanup can be done correctly without a
> drm_driver->release hook. Therefore allow this now in
> devm_drm_dev_init().
> 
> Also with drmm_ explicit drm_driver->release hooks are kinda not the
> best option: Drivers can always just register their current release
> hook with drmm_add_action, but even better they could split them up to
> simplify the unwinding for the driver load failure case. So deprecate
> that hook to discourage future users.
> 
> v2: Fixup the example in the kerneldoc too.
> 
> v3:
> - For paranoia, double check that minor->dev == dev in the release
>   hook, because I botched the pointer math in the drmm library.
> - Call drm_mode_config_cleanup when drmm_add_action fails, we'd be
>   missing some mutex_destroy and ida_cleanup otherwise (Laurent)
> 
> v4: Add a drmm_add_action_or_reset (like devm_ has) to encapsulate this
> pattern (Noralf).
> 
> v5: Fix oversight in the new drmm_add_action_or_reset macro (Noralf)
> 
> v4: Review from Sam:
> - drmm_mode_config_init wrapper (also suggested by Thomas)
> - improve commit message, explain better why ->relase is deprecated

The idea was to rename drm_mode_config_init() to
drmm_mode_config_init().
And then provide a wrapper for backward compatibility.
- So the kernel-doc documented function in drm_mode_config.c is the
  recommened choice
- And the wrapper in drm_mode_config.h was only for backward
  compatibility

In other words - the wrapper should be an undocumented:
static inline int drm_mode_config_init(struct drm_device *dev)
{
	return drmm_mode_config_init(dev);
}

When all users have transitioned to drmm_mode_config_init()
then the wrapper could be dropped.

With this fixed, or a good reason not to do so:

Reviewed-by: Sam Ravnborg <sam@ravnborg.org>

	Sam

> 
> Cc: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
> Cc: "Noralf Trønnes" <noralf@tronnes.org>
> Cc: Sam Ravnborg <sam@ravnborg.org>
> Cc: Thomas Zimmermann <tzimmermann@suse.de>
> Acked-by: Noralf Trønnes <noralf@tronnes.org>
> Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
> ---
>  drivers/gpu/drm/drm_drv.c         | 23 +++++++----------------
>  drivers/gpu/drm/drm_managed.c     | 14 ++++++++++++++
>  drivers/gpu/drm/drm_mode_config.c | 13 ++++++++++++-
>  include/drm/drm_managed.h         |  7 +++++++
>  include/drm/drm_mode_config.h     | 19 ++++++++++++++++++-
>  5 files changed, 58 insertions(+), 18 deletions(-)
> 
> diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c
> index c709a0ce018c..a82702d0c2fb 100644
> --- a/drivers/gpu/drm/drm_drv.c
> +++ b/drivers/gpu/drm/drm_drv.c
> @@ -98,6 +98,8 @@ static void drm_minor_alloc_release(struct drm_device *dev, void *data)
>  	struct drm_minor *minor = data;
>  	unsigned long flags;
>  
> +	WARN_ON(dev != minor->dev);
> +
>  	put_device(minor->kdev);
>  
>  	spin_lock_irqsave(&drm_minor_lock, flags);
> @@ -267,8 +269,7 @@ void drm_minor_release(struct drm_minor *minor)
>   *
>   * The following example shows a typical structure of a DRM display driver.
>   * The example focus on the probe() function and the other functions that is
> - * almost always present and serves as a demonstration of devm_drm_dev_init()
> - * usage with its accompanying drm_driver->release callback.
> + * almost always present and serves as a demonstration of devm_drm_dev_init().
>   *
>   * .. code-block:: c
>   *
> @@ -278,16 +279,8 @@ void drm_minor_release(struct drm_minor *minor)
>   *		struct clk *pclk;
>   *	};
>   *
> - *	static void driver_drm_release(struct drm_device *drm)
> - *	{
> - *		struct driver_device *priv = container_of(...);
> - *
> - *		drm_mode_config_cleanup(drm);
> - *	}
> - *
>   *	static struct drm_driver driver_drm_driver = {
>   *		[...]
> - *		.release = driver_drm_release,
>   *	};
>   *
>   *	static int driver_probe(struct platform_device *pdev)
> @@ -312,7 +305,9 @@ void drm_minor_release(struct drm_minor *minor)
>   *		}
>   *		drmm_add_final_kfree(drm, priv);
>   *
> - *		drm_mode_config_init(drm);
> + *		ret = drm_mode_config_init(drm);
> + *		if (ret)
> + *			return ret;
>   *
>   *		priv->userspace_facing = drmm_kzalloc(..., GFP_KERNEL);
>   *		if (!priv->userspace_facing)
> @@ -710,8 +705,7 @@ static void devm_drm_dev_init_release(void *data)
>   * @driver: DRM driver
>   *
>   * Managed drm_dev_init(). The DRM device initialized with this function is
> - * automatically put on driver detach using drm_dev_put(). You must supply a
> - * &drm_driver.release callback to control the finalization explicitly.
> + * automatically put on driver detach using drm_dev_put().
>   *
>   * RETURNS:
>   * 0 on success, or error code on failure.
> @@ -722,9 +716,6 @@ int devm_drm_dev_init(struct device *parent,
>  {
>  	int ret;
>  
> -	if (WARN_ON(!driver->release))
> -		return -EINVAL;
> -
>  	ret = drm_dev_init(dev, driver, parent);
>  	if (ret)
>  		return ret;
> diff --git a/drivers/gpu/drm/drm_managed.c b/drivers/gpu/drm/drm_managed.c
> index 0883615c2088..8c5f1f03c485 100644
> --- a/drivers/gpu/drm/drm_managed.c
> +++ b/drivers/gpu/drm/drm_managed.c
> @@ -142,6 +142,20 @@ int __drmm_add_action(struct drm_device *dev,
>  }
>  EXPORT_SYMBOL(__drmm_add_action);
>  
> +int __drmm_add_action_or_reset(struct drm_device *dev,
> +			       drmres_release_t action,
> +			       void *data, const char *name)
> +{
> +	int ret;
> +
> +	ret = __drmm_add_action(dev, action, data, name);
> +	if (ret)
> +		action(dev, data);
> +
> +	return ret;
> +}
> +EXPORT_SYMBOL(__drmm_add_action_or_reset);
> +
>  void drmm_remove_action(struct drm_device *dev,
>  			drmres_release_t action,
>  			void *data)
> diff --git a/drivers/gpu/drm/drm_mode_config.c b/drivers/gpu/drm/drm_mode_config.c
> index 08e6eff6a179..6f7005bc597f 100644
> --- a/drivers/gpu/drm/drm_mode_config.c
> +++ b/drivers/gpu/drm/drm_mode_config.c
> @@ -25,6 +25,7 @@
>  #include <drm/drm_drv.h>
>  #include <drm/drm_encoder.h>
>  #include <drm/drm_file.h>
> +#include <drm/drm_managed.h>
>  #include <drm/drm_mode_config.h>
>  #include <drm/drm_print.h>
>  #include <linux/dma-resv.h>
> @@ -373,6 +374,11 @@ static int drm_mode_create_standard_properties(struct drm_device *dev)
>  	return 0;
>  }
>  
> +static void drm_mode_config_init_release(struct drm_device *dev, void *ptr)
> +{
> +	drm_mode_config_cleanup(dev);
> +}
> +
>  /**
>   * drm_mode_config_init - initialize DRM mode_configuration structure
>   * @dev: DRM device
> @@ -384,8 +390,10 @@ static int drm_mode_create_standard_properties(struct drm_device *dev)
>   * problem, since this should happen single threaded at init time. It is the
>   * driver's problem to ensure this guarantee.
>   *
> + * Cleanup is automatically handled through registering drm_mode_config_cleanup
> + * with drmm_add_action().
>   */
> -void drm_mode_config_init(struct drm_device *dev)
> +int drm_mode_config_init(struct drm_device *dev)
>  {
>  	mutex_init(&dev->mode_config.mutex);
>  	drm_modeset_lock_init(&dev->mode_config.connection_mutex);
> @@ -443,6 +451,9 @@ void drm_mode_config_init(struct drm_device *dev)
>  		drm_modeset_acquire_fini(&modeset_ctx);
>  		dma_resv_fini(&resv);
>  	}
> +
> +	return drmm_add_action_or_reset(dev, drm_mode_config_init_release,
> +					NULL);
>  }
>  EXPORT_SYMBOL(drm_mode_config_init);
>  
> diff --git a/include/drm/drm_managed.h b/include/drm/drm_managed.h
> index 2b1ba2ad5582..1e6291407586 100644
> --- a/include/drm/drm_managed.h
> +++ b/include/drm/drm_managed.h
> @@ -18,6 +18,13 @@ int __must_check __drmm_add_action(struct drm_device *dev,
>  				   drmres_release_t action,
>  				   void *data, const char *name);
>  
> +#define drmm_add_action_or_reset(dev, action, data) \
> +	__drmm_add_action_or_reset(dev, action, data, #action)
> +
> +int __must_check __drmm_add_action_or_reset(struct drm_device *dev,
> +					    drmres_release_t action,
> +					    void *data, const char *name);
> +
>  void drmm_remove_action(struct drm_device *dev,
>  			drmres_release_t action,
>  			void *data);
> diff --git a/include/drm/drm_mode_config.h b/include/drm/drm_mode_config.h
> index 3bcbe30339f0..aa6288bf04df 100644
> --- a/include/drm/drm_mode_config.h
> +++ b/include/drm/drm_mode_config.h
> @@ -929,7 +929,24 @@ struct drm_mode_config {
>  	const struct drm_mode_config_helper_funcs *helper_private;
>  };
>  
> -void drm_mode_config_init(struct drm_device *dev);
> +int drm_mode_config_init(struct drm_device *dev);
> +
> +/**
> + * drmm_mode_config_init - managed DRM mode_configuration structure
> + * 	initialization
> + * @dev: DRM device
> + *
> + * This is a managed version of drm_mode_config_init(). The only difference is
> + * that this version is annotated with __must_check, to make sure that drivers
> + * can actually rely on the automatic cleanup.
> + *
> + * Returns: 0 on success, negative error value on failure.
> + */
> +static inline __must_check int drmm_mode_config_init(struct drm_device *dev)
> +{
> +	return drm_mode_config_init(dev);
> +}
> +
>  void drm_mode_config_reset(struct drm_device *dev);
>  void drm_mode_config_cleanup(struct drm_device *dev);
>  
> -- 
> 2.24.1
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 111+ messages in thread

* Re: [PATCH 28/51] drm/bochs: Drop explicit drm_mode_config_cleanup
  2020-03-02 22:26 ` [PATCH 28/51] drm/bochs: Drop explicit drm_mode_config_cleanup Daniel Vetter
  2020-03-03  7:50   ` Gerd Hoffmann
@ 2020-03-06 20:14   ` Sam Ravnborg
  1 sibling, 0 replies; 111+ messages in thread
From: Sam Ravnborg @ 2020-03-06 20:14 UTC (permalink / raw)
  To: Daniel Vetter
  Cc: Intel Graphics Development, DRI Development, virtualization,
	Gerd Hoffmann, Thomas Zimmermann, Daniel Vetter,
	Laurent Pinchart

On Mon, Mar 02, 2020 at 11:26:08PM +0100, Daniel Vetter wrote:
> Instead rely on the automatic clean, for which we just need to check
> that drm_mode_config_init succeeded. To avoid an inversion in the
> cleanup we also have to move the dev_private allocation over to
> drmm_kzalloc.
> 
> This is made possible by a preceeding patch which added a drmm_
> cleanup action to drm_mode_config_init(), hence all we need to do to
> ensure that drm_mode_config_cleanup() is run on final drm_device
> cleanup is check the new error code for _init().
> 
> v2: Explain why this cleanup is possible (Laurent).
> 
> v3: Use drmm_mode_config_init() for more clarity (Sam, Thomas)
> 
> Cc: Sam Ravnborg <sam@ravnborg.org>
> Cc: Thomas Zimmermann <tzimmermann@suse.de>
> Cc: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
> Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
> Cc: Gerd Hoffmann <kraxel@redhat.com>
> Cc: virtualization@lists.linux-foundation.org

Acked-by: Sam Ravnborg <sam@ravnborg.org>


> ---
>  drivers/gpu/drm/bochs/bochs.h     |  1 -
>  drivers/gpu/drm/bochs/bochs_drv.c |  6 ++----
>  drivers/gpu/drm/bochs/bochs_kms.c | 14 +++++---------
>  3 files changed, 7 insertions(+), 14 deletions(-)
> 
> diff --git a/drivers/gpu/drm/bochs/bochs.h b/drivers/gpu/drm/bochs/bochs.h
> index 917767173ee6..e5bd1d517a18 100644
> --- a/drivers/gpu/drm/bochs/bochs.h
> +++ b/drivers/gpu/drm/bochs/bochs.h
> @@ -92,7 +92,6 @@ void bochs_mm_fini(struct bochs_device *bochs);
>  
>  /* bochs_kms.c */
>  int bochs_kms_init(struct bochs_device *bochs);
> -void bochs_kms_fini(struct bochs_device *bochs);
>  
>  /* bochs_fbdev.c */
>  extern const struct drm_mode_config_funcs bochs_mode_funcs;
> diff --git a/drivers/gpu/drm/bochs/bochs_drv.c b/drivers/gpu/drm/bochs/bochs_drv.c
> index addb0568c1af..e18c51de1196 100644
> --- a/drivers/gpu/drm/bochs/bochs_drv.c
> +++ b/drivers/gpu/drm/bochs/bochs_drv.c
> @@ -7,6 +7,7 @@
>  
>  #include <drm/drm_drv.h>
>  #include <drm/drm_atomic_helper.h>
> +#include <drm/drm_managed.h>
>  
>  #include "bochs.h"
>  
> @@ -21,10 +22,7 @@ static void bochs_unload(struct drm_device *dev)
>  {
>  	struct bochs_device *bochs = dev->dev_private;
>  
> -	bochs_kms_fini(bochs);
>  	bochs_mm_fini(bochs);
> -	kfree(bochs);
> -	dev->dev_private = NULL;
>  }
>  
>  static int bochs_load(struct drm_device *dev)
> @@ -32,7 +30,7 @@ static int bochs_load(struct drm_device *dev)
>  	struct bochs_device *bochs;
>  	int ret;
>  
> -	bochs = kzalloc(sizeof(*bochs), GFP_KERNEL);
> +	bochs = drmm_kzalloc(dev, sizeof(*bochs), GFP_KERNEL);
>  	if (bochs == NULL)
>  		return -ENOMEM;
>  	dev->dev_private = bochs;
> diff --git a/drivers/gpu/drm/bochs/bochs_kms.c b/drivers/gpu/drm/bochs/bochs_kms.c
> index e8cc8156d773..7f4bcfad87e9 100644
> --- a/drivers/gpu/drm/bochs/bochs_kms.c
> +++ b/drivers/gpu/drm/bochs/bochs_kms.c
> @@ -134,7 +134,11 @@ const struct drm_mode_config_funcs bochs_mode_funcs = {
>  
>  int bochs_kms_init(struct bochs_device *bochs)
>  {
> -	drm_mode_config_init(bochs->dev);
> +	int ret;
> +
> +	ret = drmm_mode_config_init(bochs->dev);
> +	if (ret)
> +		return ret;
>  
>  	bochs->dev->mode_config.max_width = 8192;
>  	bochs->dev->mode_config.max_height = 8192;
> @@ -160,11 +164,3 @@ int bochs_kms_init(struct bochs_device *bochs)
>  
>  	return 0;
>  }
> -
> -void bochs_kms_fini(struct bochs_device *bochs)
> -{
> -	if (!bochs->dev->mode_config.num_connector)
> -		return;
> -
> -	drm_mode_config_cleanup(bochs->dev);
> -}
> -- 
> 2.24.1
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 111+ messages in thread

* Re: [PATCH 31/51] drm/ingenic: Drop explicit drm_mode_config_cleanup call
  2020-03-02 22:26 ` [PATCH 31/51] drm/ingenic: Drop explicit drm_mode_config_cleanup call Daniel Vetter
@ 2020-03-06 20:17   ` Sam Ravnborg
  0 siblings, 0 replies; 111+ messages in thread
From: Sam Ravnborg @ 2020-03-06 20:17 UTC (permalink / raw)
  To: Daniel Vetter
  Cc: Intel Graphics Development, DRI Development, Paul Cercueil,
	Laurent Pinchart, Thomas Zimmermann, Daniel Vetter

On Mon, Mar 02, 2020 at 11:26:11PM +0100, Daniel Vetter wrote:
> Allows us to drop the drm_driver.release callback.
> 
> This is made possible by a preceeding patch which added a drmm_
> cleanup action to drm_mode_config_init(), hence all we need to do to
> ensure that drm_mode_config_cleanup() is run on final drm_device
> cleanup is check the new error code for _init().
> 
> v2: Explain why this cleanup is possible (Laurent).
> 
> v3: Use drmm_mode_config_init() for more clarity (Sam, Thomas)
> 
> Cc: Sam Ravnborg <sam@ravnborg.org>
> Cc: Thomas Zimmermann <tzimmermann@suse.de>
> Reviewed-by: Paul Cercueil <paul@crapouillou.net> (v2)
> Cc: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
> Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
> Cc: Paul Cercueil <paul@crapouillou.net>

Acked-by: Sam Ravnborg <sam@ravnborg.org>

> ---
>  drivers/gpu/drm/ingenic/ingenic-drm.c | 11 ++++-------
>  1 file changed, 4 insertions(+), 7 deletions(-)
> 
> diff --git a/drivers/gpu/drm/ingenic/ingenic-drm.c b/drivers/gpu/drm/ingenic/ingenic-drm.c
> index 192aaa4421a3..a9bc6623b488 100644
> --- a/drivers/gpu/drm/ingenic/ingenic-drm.c
> +++ b/drivers/gpu/drm/ingenic/ingenic-drm.c
> @@ -489,11 +489,6 @@ static irqreturn_t ingenic_drm_irq_handler(int irq, void *arg)
>  	return IRQ_HANDLED;
>  }
>  
> -static void ingenic_drm_release(struct drm_device *drm)
> -{
> -	drm_mode_config_cleanup(drm);
> -}
> -
>  static int ingenic_drm_enable_vblank(struct drm_crtc *crtc)
>  {
>  	struct ingenic_drm *priv = drm_crtc_get_priv(crtc);
> @@ -537,7 +532,6 @@ static struct drm_driver ingenic_drm_driver_data = {
>  	.gem_prime_mmap		= drm_gem_cma_prime_mmap,
>  
>  	.irq_handler		= ingenic_drm_irq_handler,
> -	.release		= ingenic_drm_release,
>  };
>  
>  static const struct drm_plane_funcs ingenic_drm_primary_plane_funcs = {
> @@ -638,7 +632,10 @@ static int ingenic_drm_probe(struct platform_device *pdev)
>  	}
>  	drmm_add_final_kfree(drm, priv);
>  
> -	drm_mode_config_init(drm);
> +	ret = drmm_mode_config_init(drm);
> +	if (ret)
> +		return ret;
> +
>  	drm->mode_config.min_width = 0;
>  	drm->mode_config.min_height = 0;
>  	drm->mode_config.max_width = soc_info->max_width;
> -- 
> 2.24.1
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 111+ messages in thread

* Re: [PATCH 32/51] drm/mcde: Drop explicit drm_mode_config_cleanup call
  2020-03-02 22:26 ` [PATCH 32/51] drm/mcde: " Daniel Vetter
@ 2020-03-06 20:18   ` Sam Ravnborg
  0 siblings, 0 replies; 111+ messages in thread
From: Sam Ravnborg @ 2020-03-06 20:18 UTC (permalink / raw)
  To: Daniel Vetter
  Cc: Intel Graphics Development, DRI Development, Laurent Pinchart,
	Thomas Zimmermann, Daniel Vetter

On Mon, Mar 02, 2020 at 11:26:12PM +0100, Daniel Vetter wrote:
> Allows us to drop the drm_driver.release callback.
> 
> This is made possible by a preceeding patch which added a drmm_
> cleanup action to drm_mode_config_init(), hence all we need to do to
> ensure that drm_mode_config_cleanup() is run on final drm_device
> cleanup is check the new error code for _init().
> 
> v2: Explain why this cleanup is possible (Laurent).
> 
> v3: Use drmm_mode_config_init() for more clarity (Sam, Thomas)
> 
> Cc: Sam Ravnborg <sam@ravnborg.org>
> Cc: Thomas Zimmermann <tzimmermann@suse.de>
> Reviewed-by: Linus Walleij <linus.walleij@linaro.org> (v2)
> Cc: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
> Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
> Cc: Linus Walleij <linus.walleij@linaro.org>

Acked-by: Sam Ravnborg <sam@ravnborg.org>

> ---
>  drivers/gpu/drm/mcde/mcde_drv.c | 22 ++++++----------------
>  1 file changed, 6 insertions(+), 16 deletions(-)
> 
> diff --git a/drivers/gpu/drm/mcde/mcde_drv.c b/drivers/gpu/drm/mcde/mcde_drv.c
> index a543ebf3d541..03d2e1a00810 100644
> --- a/drivers/gpu/drm/mcde/mcde_drv.c
> +++ b/drivers/gpu/drm/mcde/mcde_drv.c
> @@ -184,13 +184,13 @@ static int mcde_modeset_init(struct drm_device *drm)
>  	ret = drm_vblank_init(drm, 1);
>  	if (ret) {
>  		dev_err(drm->dev, "failed to init vblank\n");
> -		goto out_config;
> +		return ret;
>  	}
>  
>  	ret = mcde_display_init(drm);
>  	if (ret) {
>  		dev_err(drm->dev, "failed to init display\n");
> -		goto out_config;
> +		return ret;
>  	}
>  
>  	/*
> @@ -204,7 +204,7 @@ static int mcde_modeset_init(struct drm_device *drm)
>  						    mcde->bridge);
>  	if (ret) {
>  		dev_err(drm->dev, "failed to attach display output bridge\n");
> -		goto out_config;
> +		return ret;
>  	}
>  
>  	drm_mode_config_reset(drm);
> @@ -212,17 +212,6 @@ static int mcde_modeset_init(struct drm_device *drm)
>  	drm_fbdev_generic_setup(drm, 32);
>  
>  	return 0;
> -
> -out_config:
> -	drm_mode_config_cleanup(drm);
> -	return ret;
> -}
> -
> -static void mcde_release(struct drm_device *drm)
> -{
> -	struct mcde *mcde = drm->dev_private;
> -
> -	drm_mode_config_cleanup(drm);
>  }
>  
>  DEFINE_DRM_GEM_CMA_FOPS(drm_fops);
> @@ -230,7 +219,6 @@ DEFINE_DRM_GEM_CMA_FOPS(drm_fops);
>  static struct drm_driver mcde_drm_driver = {
>  	.driver_features =
>  		DRIVER_MODESET | DRIVER_GEM | DRIVER_ATOMIC,
> -	.release = mcde_release,
>  	.lastclose = drm_fb_helper_lastclose,
>  	.ioctls = NULL,
>  	.fops = &drm_fops,
> @@ -258,7 +246,9 @@ static int mcde_drm_bind(struct device *dev)
>  	struct drm_device *drm = dev_get_drvdata(dev);
>  	int ret;
>  
> -	drm_mode_config_init(drm);
> +	ret = drmm_mode_config_init(drm);
> +	if (ret)
> +		return ret;
>  
>  	ret = component_bind_all(drm->dev, drm);
>  	if (ret) {
> -- 
> 2.24.1
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 111+ messages in thread

* Re: [PATCH 15/51] drm/repaper: Use drmm_add_final_kfree
  2020-03-02 22:25 ` [PATCH 15/51] drm/repaper: " Daniel Vetter
@ 2020-03-06 20:27   ` Sam Ravnborg
  0 siblings, 0 replies; 111+ messages in thread
From: Sam Ravnborg @ 2020-03-06 20:27 UTC (permalink / raw)
  To: Daniel Vetter; +Cc: Daniel Vetter, Intel Graphics Development, DRI Development

On Mon, Mar 02, 2020 at 11:25:55PM +0100, Daniel Vetter wrote:
> With this we can drop the final kfree from the release function.
> 
> Reviewed-by: Noralf Trønnes <noralf@tronnes.org>
> Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
> Cc: "Noralf Trønnes" <noralf@tronnes.org>

Acked-by: Sam Ravnborg <sam@ravnborg.org>

> ---
>  drivers/gpu/drm/tiny/repaper.c | 5 ++---
>  1 file changed, 2 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/gpu/drm/tiny/repaper.c b/drivers/gpu/drm/tiny/repaper.c
> index f5ebcaf7ee3a..df5654ef53ee 100644
> --- a/drivers/gpu/drm/tiny/repaper.c
> +++ b/drivers/gpu/drm/tiny/repaper.c
> @@ -31,6 +31,7 @@
>  #include <drm/drm_format_helper.h>
>  #include <drm/drm_gem_cma_helper.h>
>  #include <drm/drm_gem_framebuffer_helper.h>
> +#include <drm/drm_managed.h>
>  #include <drm/drm_modes.h>
>  #include <drm/drm_rect.h>
>  #include <drm/drm_probe_helper.h>
> @@ -910,13 +911,10 @@ static const struct drm_mode_config_funcs repaper_mode_config_funcs = {
>  
>  static void repaper_release(struct drm_device *drm)
>  {
> -	struct repaper_epd *epd = drm_to_epd(drm);
> -
>  	DRM_DEBUG_DRIVER("\n");
>  
>  	drm_mode_config_cleanup(drm);
>  	drm_dev_fini(drm);
> -	kfree(epd);
>  }
>  
>  static const uint32_t repaper_formats[] = {
> @@ -1024,6 +1022,7 @@ static int repaper_probe(struct spi_device *spi)
>  		kfree(epd);
>  		return ret;
>  	}
> +	drmm_add_final_kfree(drm, epd);
>  
>  	drm_mode_config_init(drm);
>  	drm->mode_config.funcs = &repaper_mode_config_funcs;
> -- 
> 2.24.1
> 
> _______________________________________________
> dri-devel mailing list
> dri-devel@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/dri-devel
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 111+ messages in thread

* Re: [PATCH 16/51] drm/ingenic: Use drmm_add_final_kfree
  2020-03-02 22:25 ` [PATCH 16/51] drm/ingenic: " Daniel Vetter
@ 2020-03-06 20:27   ` Sam Ravnborg
  0 siblings, 0 replies; 111+ messages in thread
From: Sam Ravnborg @ 2020-03-06 20:27 UTC (permalink / raw)
  To: Daniel Vetter
  Cc: Paul Cercueil, Daniel Vetter, Intel Graphics Development,
	DRI Development

On Mon, Mar 02, 2020 at 11:25:56PM +0100, Daniel Vetter wrote:
> With this we can drop the final kfree from the release function.
> 
> Reviewed-by: Paul Cercueil <paul@crapouillou.net>
> Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
> Cc: Paul Cercueil <paul@crapouillou.net>

Acked-by: Sam Ravnborg <sam@ravnborg.org>

> ---
>  drivers/gpu/drm/ingenic/ingenic-drm.c | 5 ++---
>  1 file changed, 2 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/gpu/drm/ingenic/ingenic-drm.c b/drivers/gpu/drm/ingenic/ingenic-drm.c
> index 9dfe7cb530e1..e2c832eb4e9a 100644
> --- a/drivers/gpu/drm/ingenic/ingenic-drm.c
> +++ b/drivers/gpu/drm/ingenic/ingenic-drm.c
> @@ -23,6 +23,7 @@
>  #include <drm/drm_fourcc.h>
>  #include <drm/drm_gem_framebuffer_helper.h>
>  #include <drm/drm_irq.h>
> +#include <drm/drm_managed.h>
>  #include <drm/drm_of.h>
>  #include <drm/drm_panel.h>
>  #include <drm/drm_plane.h>
> @@ -490,11 +491,8 @@ static irqreturn_t ingenic_drm_irq_handler(int irq, void *arg)
>  
>  static void ingenic_drm_release(struct drm_device *drm)
>  {
> -	struct ingenic_drm *priv = drm_device_get_priv(drm);
> -
>  	drm_mode_config_cleanup(drm);
>  	drm_dev_fini(drm);
> -	kfree(priv);
>  }
>  
>  static int ingenic_drm_enable_vblank(struct drm_crtc *crtc)
> @@ -639,6 +637,7 @@ static int ingenic_drm_probe(struct platform_device *pdev)
>  		kfree(priv);
>  		return ret;
>  	}
> +	drmm_add_final_kfree(drm, priv);
>  
>  	drm_mode_config_init(drm);
>  	drm->mode_config.min_width = 0;
> -- 
> 2.24.1
> 
> _______________________________________________
> dri-devel mailing list
> dri-devel@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/dri-devel
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 111+ messages in thread

* Re: [PATCH 17/51] drm/gm12u320: Use drmm_add_final_kfree
  2020-03-02 22:25 ` [PATCH 17/51] drm/gm12u320: " Daniel Vetter
@ 2020-03-06 20:27   ` Sam Ravnborg
  0 siblings, 0 replies; 111+ messages in thread
From: Sam Ravnborg @ 2020-03-06 20:27 UTC (permalink / raw)
  To: Daniel Vetter
  Cc: Daniel Vetter, Intel Graphics Development, DRI Development,
	Hans de Goede

On Mon, Mar 02, 2020 at 11:25:57PM +0100, Daniel Vetter wrote:
> With this we can drop the final kfree from the release function.
> 
> Reviewed-by: Hans de Goede <hdegoede@redhat.com>
> Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
> Cc: Hans de Goede <hdegoede@redhat.com>

Acked-by: Sam Ravnborg <sam@ravnborg.org>

> ---
>  drivers/gpu/drm/tiny/gm12u320.c | 3 ++-
>  1 file changed, 2 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/gpu/drm/tiny/gm12u320.c b/drivers/gpu/drm/tiny/gm12u320.c
> index a48173441ae0..524ca0941cf9 100644
> --- a/drivers/gpu/drm/tiny/gm12u320.c
> +++ b/drivers/gpu/drm/tiny/gm12u320.c
> @@ -19,6 +19,7 @@
>  #include <drm/drm_gem_shmem_helper.h>
>  #include <drm/drm_gem_framebuffer_helper.h>
>  #include <drm/drm_ioctl.h>
> +#include <drm/drm_managed.h>
>  #include <drm/drm_modeset_helper_vtables.h>
>  #include <drm/drm_probe_helper.h>
>  #include <drm/drm_simple_kms_helper.h>
> @@ -637,7 +638,6 @@ static void gm12u320_driver_release(struct drm_device *dev)
>  	gm12u320_usb_free(gm12u320);
>  	drm_mode_config_cleanup(dev);
>  	drm_dev_fini(dev);
> -	kfree(gm12u320);
>  }
>  
>  DEFINE_DRM_GEM_FOPS(gm12u320_fops);
> @@ -692,6 +692,7 @@ static int gm12u320_usb_probe(struct usb_interface *interface,
>  		return ret;
>  	}
>  	dev->dev_private = gm12u320;
> +	drmm_add_final_kfree(dev, gm12u320);
>  
>  	drm_mode_config_init(dev);
>  	dev->mode_config.min_width = GM12U320_USER_WIDTH;
> -- 
> 2.24.1
> 
> _______________________________________________
> dri-devel mailing list
> dri-devel@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/dri-devel
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 111+ messages in thread

* Re: [PATCH 18/51] drm/<drivers>: Use drmm_add_final_kfree
  2020-03-02 22:25 ` [PATCH 18/51] drm/<drivers>: " Daniel Vetter
@ 2020-03-06 20:28   ` Sam Ravnborg
  0 siblings, 0 replies; 111+ messages in thread
From: Sam Ravnborg @ 2020-03-06 20:28 UTC (permalink / raw)
  To: Daniel Vetter
  Cc: Intel Graphics Development, Liviu Dudau, Russell King,
	DRI Development, Hans de Goede, James (Qian) Wang, Daniel Vetter,
	Mihail Atanassov

On Mon, Mar 02, 2020 at 11:25:58PM +0100, Daniel Vetter wrote:
> These are the leftover drivers that didn't have a ->release hook that
> needed to be updated.
> 
> Acked-by: Liviu Dudau <liviu.dudau@arm.com>
> Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
> Cc: "James (Qian) Wang" <james.qian.wang@arm.com>
> Cc: Liviu Dudau <liviu.dudau@arm.com>
> Cc: Mihail Atanassov <mihail.atanassov@arm.com>
> Cc: Russell King <linux@armlinux.org.uk>
> Cc: Hans de Goede <hdegoede@redhat.com>

Acked-by: Sam Ravnborg <sam@ravnborg.org>

> ---
>  drivers/gpu/drm/arm/display/komeda/komeda_kms.c | 2 ++
>  drivers/gpu/drm/armada/armada_drv.c             | 2 ++
>  drivers/gpu/drm/vboxvideo/vbox_drv.c            | 2 ++
>  3 files changed, 6 insertions(+)
> 
> diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_kms.c b/drivers/gpu/drm/arm/display/komeda/komeda_kms.c
> index 442d4656150a..16dfd5cdb66c 100644
> --- a/drivers/gpu/drm/arm/display/komeda/komeda_kms.c
> +++ b/drivers/gpu/drm/arm/display/komeda/komeda_kms.c
> @@ -14,6 +14,7 @@
>  #include <drm/drm_gem_cma_helper.h>
>  #include <drm/drm_gem_framebuffer_helper.h>
>  #include <drm/drm_irq.h>
> +#include <drm/drm_managed.h>
>  #include <drm/drm_probe_helper.h>
>  #include <drm/drm_vblank.h>
>  
> @@ -271,6 +272,7 @@ struct komeda_kms_dev *komeda_kms_attach(struct komeda_dev *mdev)
>  	err = drm_dev_init(drm, &komeda_kms_driver, mdev->dev);
>  	if (err)
>  		goto free_kms;
> +	drmm_add_final_kfree(drm, kms);
>  
>  	drm->dev_private = mdev;
>  
> diff --git a/drivers/gpu/drm/armada/armada_drv.c b/drivers/gpu/drm/armada/armada_drv.c
> index 197dca3fc84c..dd9ed71ed942 100644
> --- a/drivers/gpu/drm/armada/armada_drv.c
> +++ b/drivers/gpu/drm/armada/armada_drv.c
> @@ -12,6 +12,7 @@
>  #include <drm/drm_atomic_helper.h>
>  #include <drm/drm_drv.h>
>  #include <drm/drm_ioctl.h>
> +#include <drm/drm_managed.h>
>  #include <drm/drm_prime.h>
>  #include <drm/drm_probe_helper.h>
>  #include <drm/drm_fb_helper.h>
> @@ -103,6 +104,7 @@ static int armada_drm_bind(struct device *dev)
>  		kfree(priv);
>  		return ret;
>  	}
> +	drmm_add_final_kfree(&priv->drm, priv);
>  
>  	/* Remove early framebuffers */
>  	ret = drm_fb_helper_remove_conflicting_framebuffers(NULL,
> diff --git a/drivers/gpu/drm/vboxvideo/vbox_drv.c b/drivers/gpu/drm/vboxvideo/vbox_drv.c
> index 8512d970a09f..13eaae7921f5 100644
> --- a/drivers/gpu/drm/vboxvideo/vbox_drv.c
> +++ b/drivers/gpu/drm/vboxvideo/vbox_drv.c
> @@ -17,6 +17,7 @@
>  #include <drm/drm_fb_helper.h>
>  #include <drm/drm_file.h>
>  #include <drm/drm_ioctl.h>
> +#include <drm/drm_managed.h>
>  
>  #include "vbox_drv.h"
>  
> @@ -54,6 +55,7 @@ static int vbox_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
>  	vbox->ddev.pdev = pdev;
>  	vbox->ddev.dev_private = vbox;
>  	pci_set_drvdata(pdev, vbox);
> +	drmm_add_final_kfree(&vbox->ddev, vbox);
>  	mutex_init(&vbox->hw_mutex);
>  
>  	ret = pci_enable_device(pdev);
> -- 
> 2.24.1
> 
> _______________________________________________
> dri-devel mailing list
> dri-devel@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/dri-devel
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 111+ messages in thread

* Re: [PATCH 19/51] drm: Cleanups after drmm_add_final_kfree rollout
  2020-03-02 22:25 ` [PATCH 19/51] drm: Cleanups after drmm_add_final_kfree rollout Daniel Vetter
  2020-03-03  8:45   ` [PATCH] " Daniel Vetter
@ 2020-03-06 20:29   ` Sam Ravnborg
  2020-03-11  9:15   ` Thomas Zimmermann
  2 siblings, 0 replies; 111+ messages in thread
From: Sam Ravnborg @ 2020-03-06 20:29 UTC (permalink / raw)
  To: Daniel Vetter; +Cc: Daniel Vetter, Intel Graphics Development, DRI Development

On Mon, Mar 02, 2020 at 11:25:59PM +0100, Daniel Vetter wrote:
> A few things:
> - Update the example driver in the documentation.
> - We can drop the old kfree in drm_dev_release.
> - Add a WARN_ON check in drm_dev_register to make sure everyone calls
>   drmm_add_final_kfree and there's no leaks.
> 
> Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>

Acked-by: Sam Ravnborg <sam@ravnborg.org>

> ---
>  drivers/gpu/drm/drm_drv.c | 7 ++++---
>  1 file changed, 4 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c
> index 7b84ee8a5eb5..1a048325f30e 100644
> --- a/drivers/gpu/drm/drm_drv.c
> +++ b/drivers/gpu/drm/drm_drv.c
> @@ -297,8 +297,6 @@ void drm_minor_release(struct drm_minor *minor)
>   *
>   *		drm_mode_config_cleanup(drm);
>   *		drm_dev_fini(drm);
> - *		kfree(priv->userspace_facing);
> - *		kfree(priv);
>   *	}
>   *
>   *	static struct drm_driver driver_drm_driver = {
> @@ -326,10 +324,11 @@ void drm_minor_release(struct drm_minor *minor)
>   *			kfree(drm);
>   *			return ret;
>   *		}
> + *		drmm_add_final_kfree(drm, priv);
>   *
>   *		drm_mode_config_init(drm);
>   *
> - *		priv->userspace_facing = kzalloc(..., GFP_KERNEL);
> + *		priv->userspace_facing = drmm_kzalloc(..., GFP_KERNEL);
>   *		if (!priv->userspace_facing)
>   *			return -ENOMEM;
>   *
> @@ -961,6 +960,8 @@ int drm_dev_register(struct drm_device *dev, unsigned long flags)
>  	struct drm_driver *driver = dev->driver;
>  	int ret;
>  
> +	WARN_ON(!dev->managed.final_kfree);
> +
>  	if (drm_dev_needs_global_mutex(dev))
>  		mutex_lock(&drm_global_mutex);
>  
> -- 
> 2.24.1
> 
> _______________________________________________
> dri-devel mailing list
> dri-devel@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/dri-devel
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 111+ messages in thread

* Re: [PATCH] drm: Cleanups after drmm_add_final_kfree rollout
  2020-03-03  8:45   ` [PATCH] " Daniel Vetter
@ 2020-03-06 20:31     ` Sam Ravnborg
  0 siblings, 0 replies; 111+ messages in thread
From: Sam Ravnborg @ 2020-03-06 20:31 UTC (permalink / raw)
  To: Daniel Vetter
  Cc: Daniel Vetter, Intel Graphics Development, Dan Carpenter,
	DRI Development

On Tue, Mar 03, 2020 at 09:45:20AM +0100, Daniel Vetter wrote:
> A few things:
> - Update the example driver in the documentation.
> - We can drop the old kfree in drm_dev_release.
> - Add a WARN_ON check in drm_dev_register to make sure everyone calls
>   drmm_add_final_kfree and there's no leaks.
> 
> v2: Restore the full cleanup, I accidentally left some moved code
> behind when fixing the bisectability of the series.

Missed that when reading first version.
Good to see this code-snippet be dropped again.
> 
> Cc: Sam Ravnborg <sam@ravnborg.org>
> Cc: Dan Carpenter <dan.carpenter@oracle.com>
> Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>

Acked-by: Sam Ravnborg <sam@ravnborg.org>


> ---
>  drivers/gpu/drm/drm_drv.c | 12 +++++-------
>  1 file changed, 5 insertions(+), 7 deletions(-)
> 
> diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c
> index 80cfd0f14475..1ee606b4a4f9 100644
> --- a/drivers/gpu/drm/drm_drv.c
> +++ b/drivers/gpu/drm/drm_drv.c
> @@ -297,8 +297,6 @@ void drm_minor_release(struct drm_minor *minor)
>   *
>   *		drm_mode_config_cleanup(drm);
>   *		drm_dev_fini(drm);
> - *		kfree(priv->userspace_facing);
> - *		kfree(priv);
>   *	}
>   *
>   *	static struct drm_driver driver_drm_driver = {
> @@ -326,10 +324,11 @@ void drm_minor_release(struct drm_minor *minor)
>   *			kfree(drm);
>   *			return ret;
>   *		}
> + *		drmm_add_final_kfree(drm, priv);
>   *
>   *		drm_mode_config_init(drm);
>   *
> - *		priv->userspace_facing = kzalloc(..., GFP_KERNEL);
> + *		priv->userspace_facing = drmm_kzalloc(..., GFP_KERNEL);
>   *		if (!priv->userspace_facing)
>   *			return -ENOMEM;
>   *
> @@ -838,10 +837,7 @@ static void drm_dev_release(struct kref *ref)
>  
>  	drm_managed_release(dev);
>  
> -	if (!dev->driver->release && !dev->managed.final_kfree) {
> -		WARN_ON(!list_empty(&dev->managed.resources));
> -		kfree(dev);
> -	} else if (dev->managed.final_kfree)
Good to see this go again.


> +	if (dev->managed.final_kfree)
>  		kfree(dev->managed.final_kfree);
>  }
>  
> @@ -959,6 +955,8 @@ int drm_dev_register(struct drm_device *dev, unsigned long flags)
>  	struct drm_driver *driver = dev->driver;
>  	int ret;
>  
> +	WARN_ON(!dev->managed.final_kfree);
> +
>  	if (drm_dev_needs_global_mutex(dev))
>  		mutex_lock(&drm_global_mutex);
>  
> -- 
> 2.24.1
> 
> _______________________________________________
> dri-devel mailing list
> dri-devel@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/dri-devel
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 111+ messages in thread

* Re: [PATCH 20/51] drm: Handle dev->unique with drmm_
  2020-03-02 22:26 ` [PATCH 20/51] drm: Handle dev->unique with drmm_ Daniel Vetter
@ 2020-03-06 20:37   ` Sam Ravnborg
  2020-03-23 10:54     ` Daniel Vetter
  2020-03-11  9:19   ` Thomas Zimmermann
  1 sibling, 1 reply; 111+ messages in thread
From: Sam Ravnborg @ 2020-03-06 20:37 UTC (permalink / raw)
  To: Daniel Vetter; +Cc: Daniel Vetter, Intel Graphics Development, DRI Development

On Mon, Mar 02, 2020 at 11:26:00PM +0100, Daniel Vetter wrote:
> We need to add a drmm_kstrdup for this, but let's start somewhere.
> 
> This is not exactly perfect onion unwinding, but it's jsut a kfree so
> doesn't really matter at all.
> 
> Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>

Reluctanlyt... But anyway
Reviewed-by: Sam Ravnborg <sam@ravnborg.org>

See below for a few comments.


> ---
>  drivers/gpu/drm/drm_drv.c     |  5 ++---
>  drivers/gpu/drm/drm_managed.c | 16 ++++++++++++++++
>  include/drm/drm_managed.h     |  1 +
>  3 files changed, 19 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c
> index 1a048325f30e..ef79c03e311c 100644
> --- a/drivers/gpu/drm/drm_drv.c
> +++ b/drivers/gpu/drm/drm_drv.c
> @@ -777,7 +777,6 @@ void drm_dev_fini(struct drm_device *dev)
>  	mutex_destroy(&dev->filelist_mutex);
>  	mutex_destroy(&dev->struct_mutex);
>  	drm_legacy_destroy_members(dev);
> -	kfree(dev->unique);
>  }
>  EXPORT_SYMBOL(drm_dev_fini);
>  
> @@ -1068,8 +1067,8 @@ EXPORT_SYMBOL(drm_dev_unregister);
>   */
>  int drm_dev_set_unique(struct drm_device *dev, const char *name)
>  {
> -	kfree(dev->unique);
> -	dev->unique = kstrdup(name, GFP_KERNEL);
> +	drmm_kfree(dev, dev->unique);
> +	dev->unique = drmm_kstrdup(dev, name, GFP_KERNEL);
>  
>  	return dev->unique ? 0 : -ENOMEM;
>  }
> diff --git a/drivers/gpu/drm/drm_managed.c b/drivers/gpu/drm/drm_managed.c
> index 57dc79fa90af..514d5bd42446 100644
> --- a/drivers/gpu/drm/drm_managed.c
> +++ b/drivers/gpu/drm/drm_managed.c
> @@ -160,6 +160,22 @@ void *drmm_kmalloc(struct drm_device *dev, size_t size, gfp_t gfp)
>  }
>  EXPORT_SYMBOL(drmm_kmalloc);
>  
> +char *drmm_kstrdup(struct drm_device *dev, const char *s, gfp_t gfp)

So we need this gfp for all users - just because i915 is special and
uses "GFP_KERNEL | __GFP_RETRY_MAYFAIL | __GFP_NOWARN" in to places -
sigh.



> +{
> +	size_t size;
> +	char *buf;
> +
> +	if (!s)
> +		return NULL;
> +
> +	size = strlen(s) + 1;
> +	buf = drmm_kmalloc(dev, size, gfp);
> +	if (buf)
> +		memcpy(buf, s, size);
> +	return buf;
> +}
> +EXPORT_SYMBOL_GPL(drmm_kstrdup);
> +
>  void drmm_kfree(struct drm_device *dev, void *data)
>  {
>  	struct drmres *dr_match = NULL, *dr;
> diff --git a/include/drm/drm_managed.h b/include/drm/drm_managed.h
> index 7b5df7d09b19..89e6fce9f689 100644
> --- a/include/drm/drm_managed.h
> +++ b/include/drm/drm_managed.h
> @@ -24,6 +24,7 @@ static inline void *drmm_kzalloc(struct drm_device *dev, size_t size, gfp_t gfp)
>  {
>  	return drmm_kmalloc(dev, size, gfp | __GFP_ZERO);
>  }
> +char *drmm_kstrdup(struct drm_device *dev, const char *s, gfp_t gfp);
Missing empty line above. But it is fixed later IIRC

>  
>  void drmm_kfree(struct drm_device *dev, void *data);
>  
> -- 
> 2.24.1
> 
> _______________________________________________
> dri-devel mailing list
> dri-devel@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/dri-devel
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 111+ messages in thread

* Re: [PATCH 04/51] drm: Set final_kfree in drm_dev_alloc
  2020-03-02 22:25 ` [PATCH 04/51] drm: Set final_kfree in drm_dev_alloc Daniel Vetter
  2020-03-03  7:44   ` Gerd Hoffmann
@ 2020-03-07  8:06   ` Sam Ravnborg
  2020-03-23 11:02     ` Daniel Vetter
  2020-03-11  9:09   ` Thomas Zimmermann
  2 siblings, 1 reply; 111+ messages in thread
From: Sam Ravnborg @ 2020-03-07  8:06 UTC (permalink / raw)
  To: Daniel Vetter
  Cc: Oleksandr Andrushchenko, David Airlie,
	Intel Graphics Development, DRI Development, Gerd Hoffmann,
	Thomas Zimmermann, Daniel Vetter, xen-devel

On Mon, Mar 02, 2020 at 11:25:44PM +0100, Daniel Vetter wrote:
> I also did a full review of all callers, and only the xen driver
> forgot to call drm_dev_put in the failure path. Fix that up too.

So ~40 callers - phew..

> 
> v2: I noticed that xen has a drm_driver.release hook, and uses
> drm_dev_alloc(). We need to remove the kfree from
> xen_drm_drv_release().
> 
> bochs also has a release hook, but leaked the drm_device ever since
> 
> commit 0a6659bdc5e8221da99eebb176fd9591435e38de
> Author: Gerd Hoffmann <kraxel@redhat.com>
> Date:   Tue Dec 17 18:04:46 2013 +0100
> 
>     drm/bochs: new driver
> 
> This patch here fixes that leak.
> 
> Same for virtio, started leaking with
> 
> commit b1df3a2b24a917f8853d43fe9683c0e360d2c33a
> Author: Gerd Hoffmann <kraxel@redhat.com>
> Date:   Tue Feb 11 14:58:04 2020 +0100
> 
>     drm/virtio: add drm_driver.release callback.
> 
> Cc: Gerd Hoffmann <kraxel@redhat.com>
> Cc: Oleksandr Andrushchenko <oleksandr_andrushchenko@epam.com>
> Cc: xen-devel@lists.xenproject.org

The above will be picked up by tools as regular Cc: lines.
But I guess it is fine.

> 
> Reviewed-by: Oleksandr Andrushchenko <oleksandr_andrushchenko@epam.com>
> Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
> Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
> Cc: Maxime Ripard <mripard@kernel.org>
> Cc: Thomas Zimmermann <tzimmermann@suse.de>
> Cc: David Airlie <airlied@linux.ie>
> Cc: Daniel Vetter <daniel@ffwll.ch>
> Cc: Oleksandr Andrushchenko <oleksandr_andrushchenko@epam.com>
> Cc: xen-devel@lists.xenproject.org

For the drivers I looked at everything looked fine.

Acked-by: Sam Ravnborg <sam@ravnborg.org>

> ---
>  drivers/gpu/drm/drm_drv.c           | 3 +++
>  drivers/gpu/drm/xen/xen_drm_front.c | 2 +-
>  2 files changed, 4 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c
> index 153050fc926c..7b84ee8a5eb5 100644
> --- a/drivers/gpu/drm/drm_drv.c
> +++ b/drivers/gpu/drm/drm_drv.c
> @@ -39,6 +39,7 @@
>  #include <drm/drm_color_mgmt.h>
>  #include <drm/drm_drv.h>
>  #include <drm/drm_file.h>
> +#include <drm/drm_managed.h>
>  #include <drm/drm_mode_object.h>
>  #include <drm/drm_print.h>
>  
> @@ -819,6 +820,8 @@ struct drm_device *drm_dev_alloc(struct drm_driver *driver,
>  		return ERR_PTR(ret);
>  	}
>  
> +	drmm_add_final_kfree(dev, dev);
> +
>  	return dev;
>  }
>  EXPORT_SYMBOL(drm_dev_alloc);
> diff --git a/drivers/gpu/drm/xen/xen_drm_front.c b/drivers/gpu/drm/xen/xen_drm_front.c
> index 4be49c1aef51..d22b5da38935 100644
> --- a/drivers/gpu/drm/xen/xen_drm_front.c
> +++ b/drivers/gpu/drm/xen/xen_drm_front.c
> @@ -461,7 +461,6 @@ static void xen_drm_drv_release(struct drm_device *dev)
>  	drm_mode_config_cleanup(dev);
>  
>  	drm_dev_fini(dev);
> -	kfree(dev);
>  
>  	if (front_info->cfg.be_alloc)
>  		xenbus_switch_state(front_info->xb_dev,
> @@ -561,6 +560,7 @@ static int xen_drm_drv_init(struct xen_drm_front_info *front_info)
>  fail_modeset:
>  	drm_kms_helper_poll_fini(drm_dev);
>  	drm_mode_config_cleanup(drm_dev);
> +	drm_dev_put(drm_dev);
>  fail:
>  	kfree(drm_info);
>  	return ret;
> -- 
> 2.24.1
> 
> _______________________________________________
> dri-devel mailing list
> dri-devel@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/dri-devel
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 111+ messages in thread

* Re: [PATCH 23/51] drm: Manage drm_gem_init with drmm_
  2020-03-02 22:26 ` [PATCH 23/51] drm: Manage drm_gem_init " Daniel Vetter
@ 2020-03-07  8:20   ` Sam Ravnborg
  0 siblings, 0 replies; 111+ messages in thread
From: Sam Ravnborg @ 2020-03-07  8:20 UTC (permalink / raw)
  To: Daniel Vetter; +Cc: Daniel Vetter, Intel Graphics Development, DRI Development

Hi Daniel.

On Mon, Mar 02, 2020 at 11:26:03PM +0100, Daniel Vetter wrote:
> We might want to look into pushing this down into drm_mm_init, but
> that would mean rolling out return codes to a pile of functions
> unfortunately. So let's leave that for now.
> 
> Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>

We are loosing this part of the destroy function:

	dev->vma_offset_manager = NULL;

But there was no code that I could find that relied on this, so this
should be OK.

Acked-by: Sam Ravnborg <sam@ravnborg.org>

> ---
>  drivers/gpu/drm/drm_drv.c      |  8 +-------
>  drivers/gpu/drm/drm_gem.c      | 21 ++++++++++-----------
>  drivers/gpu/drm/drm_internal.h |  1 -
>  3 files changed, 11 insertions(+), 19 deletions(-)
> 
> diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c
> index 29d106195ab3..9a646155dfc6 100644
> --- a/drivers/gpu/drm/drm_drv.c
> +++ b/drivers/gpu/drm/drm_drv.c
> @@ -688,13 +688,10 @@ int drm_dev_init(struct drm_device *dev,
>  
>  	ret = drm_dev_set_unique(dev, dev_name(parent));
>  	if (ret)
> -		goto err_setunique;
> +		goto err;
>  
>  	return 0;
>  
> -err_setunique:
> -	if (drm_core_check_feature(dev, DRIVER_GEM))
> -		drm_gem_destroy(dev);
>  err:
>  	drm_managed_release(dev);
>  
> @@ -756,9 +753,6 @@ EXPORT_SYMBOL(devm_drm_dev_init);
>  void drm_dev_fini(struct drm_device *dev)
>  {
>  	drm_vblank_cleanup(dev);
> -
> -	if (drm_core_check_feature(dev, DRIVER_GEM))
> -		drm_gem_destroy(dev);
>  }
>  EXPORT_SYMBOL(drm_dev_fini);
>  
> diff --git a/drivers/gpu/drm/drm_gem.c b/drivers/gpu/drm/drm_gem.c
> index 0b6e6623735e..31095e0f6b9f 100644
> --- a/drivers/gpu/drm/drm_gem.c
> +++ b/drivers/gpu/drm/drm_gem.c
> @@ -44,6 +44,7 @@
>  #include <drm/drm_drv.h>
>  #include <drm/drm_file.h>
>  #include <drm/drm_gem.h>
> +#include <drm/drm_managed.h>
>  #include <drm/drm_print.h>
>  #include <drm/drm_vma_manager.h>
>  
> @@ -77,6 +78,12 @@
>   * up at a later date, and as our interface with shmfs for memory allocation.
>   */
>  
> +static void
> +drm_gem_init_release(struct drm_device *dev, void *ptr)
> +{
> +	drm_vma_offset_manager_destroy(dev->vma_offset_manager);
> +}
> +
>  /**
>   * drm_gem_init - Initialize the GEM device fields
>   * @dev: drm_devic structure to initialize
> @@ -89,7 +96,8 @@ drm_gem_init(struct drm_device *dev)
>  	mutex_init(&dev->object_name_lock);
>  	idr_init_base(&dev->object_name_idr, 1);
>  
> -	vma_offset_manager = kzalloc(sizeof(*vma_offset_manager), GFP_KERNEL);
> +	vma_offset_manager = drmm_kzalloc(dev, sizeof(*vma_offset_manager),
> +					  GFP_KERNEL);
>  	if (!vma_offset_manager) {
>  		DRM_ERROR("out of memory\n");
>  		return -ENOMEM;
> @@ -100,16 +108,7 @@ drm_gem_init(struct drm_device *dev)
>  				    DRM_FILE_PAGE_OFFSET_START,
>  				    DRM_FILE_PAGE_OFFSET_SIZE);
>  
> -	return 0;
> -}
> -
> -void
> -drm_gem_destroy(struct drm_device *dev)
> -{
> -
> -	drm_vma_offset_manager_destroy(dev->vma_offset_manager);
> -	kfree(dev->vma_offset_manager);
> -	dev->vma_offset_manager = NULL;
> +	return drmm_add_action(dev, drm_gem_init_release, NULL);
>  }
>  
>  /**
> diff --git a/drivers/gpu/drm/drm_internal.h b/drivers/gpu/drm/drm_internal.h
> index 8c2628dfc6c7..cb09e95a795e 100644
> --- a/drivers/gpu/drm/drm_internal.h
> +++ b/drivers/gpu/drm/drm_internal.h
> @@ -144,7 +144,6 @@ void drm_sysfs_lease_event(struct drm_device *dev);
>  /* drm_gem.c */
>  struct drm_gem_object;
>  int drm_gem_init(struct drm_device *dev);
> -void drm_gem_destroy(struct drm_device *dev);
>  int drm_gem_handle_create_tail(struct drm_file *file_priv,
>  			       struct drm_gem_object *obj,
>  			       u32 *handlep);
> -- 
> 2.24.1
> 
> _______________________________________________
> dri-devel mailing list
> dri-devel@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/dri-devel
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 111+ messages in thread

* Re: [PATCH 24/51] drm: Manage drm_vblank_cleanup with drmm_
  2020-03-02 22:26 ` [PATCH 24/51] drm: Manage drm_vblank_cleanup " Daniel Vetter
@ 2020-03-07  8:28   ` Sam Ravnborg
  0 siblings, 0 replies; 111+ messages in thread
From: Sam Ravnborg @ 2020-03-07  8:28 UTC (permalink / raw)
  To: Daniel Vetter; +Cc: Daniel Vetter, Intel Graphics Development, DRI Development

On Mon, Mar 02, 2020 at 11:26:04PM +0100, Daniel Vetter wrote:
> Nothing special here, except that this is the first time that we
> automatically clean up something that's initialized with an explicit
> driver call. But the cleanup was done at the very of the release
the very what?

> sequence for all drivers, and that's still the case. At least without
> more uses of drmm_ through explicit driver calls.

This patch does not simplify things in itself.
The motivation here is to remove the drm_dev_fini()
dependencies from the drivers.

So drm_dev_fini() can be dropped in a follow-up patch.
Maybe extend the changelog a little?

> Also for this one we need drmm_kcalloc, so lets add those
> 
> v2: Sort includes (Laurent)
> 
> Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>

Acked-by: Sam Ravnborg <sam@ravnborg.org>

> ---
>  drivers/gpu/drm/drm_drv.c      |  1 -
>  drivers/gpu/drm/drm_internal.h |  1 -
>  drivers/gpu/drm/drm_vblank.c   | 31 ++++++++++++-------------------
>  include/drm/drm_managed.h      | 16 ++++++++++++++++
>  4 files changed, 28 insertions(+), 21 deletions(-)
> 
> diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c
> index 9a646155dfc6..90b6ae81d431 100644
> --- a/drivers/gpu/drm/drm_drv.c
> +++ b/drivers/gpu/drm/drm_drv.c
> @@ -752,7 +752,6 @@ EXPORT_SYMBOL(devm_drm_dev_init);
>   */
>  void drm_dev_fini(struct drm_device *dev)
>  {
> -	drm_vblank_cleanup(dev);
>  }
>  EXPORT_SYMBOL(drm_dev_fini);
>  
> diff --git a/drivers/gpu/drm/drm_internal.h b/drivers/gpu/drm/drm_internal.h
> index cb09e95a795e..e67015d07c4c 100644
> --- a/drivers/gpu/drm/drm_internal.h
> +++ b/drivers/gpu/drm/drm_internal.h
> @@ -94,7 +94,6 @@ void drm_managed_release(struct drm_device *dev);
>  
>  /* drm_vblank.c */
>  void drm_vblank_disable_and_save(struct drm_device *dev, unsigned int pipe);
> -void drm_vblank_cleanup(struct drm_device *dev);
>  
>  /* IOCTLS */
>  int drm_wait_vblank_ioctl(struct drm_device *dev, void *data,
> diff --git a/drivers/gpu/drm/drm_vblank.c b/drivers/gpu/drm/drm_vblank.c
> index 47fc4339ec7f..5a6ec8aa0873 100644
> --- a/drivers/gpu/drm/drm_vblank.c
> +++ b/drivers/gpu/drm/drm_vblank.c
> @@ -30,6 +30,7 @@
>  #include <drm/drm_crtc.h>
>  #include <drm/drm_drv.h>
>  #include <drm/drm_framebuffer.h>
> +#include <drm/drm_managed.h>
>  #include <drm/drm_modeset_helper_vtables.h>
>  #include <drm/drm_print.h>
>  #include <drm/drm_vblank.h>
> @@ -425,14 +426,10 @@ static void vblank_disable_fn(struct timer_list *t)
>  	spin_unlock_irqrestore(&dev->vbl_lock, irqflags);
>  }
>  
> -void drm_vblank_cleanup(struct drm_device *dev)
> +static void drm_vblank_init_release(struct drm_device *dev, void *ptr)
>  {
>  	unsigned int pipe;
>  
> -	/* Bail if the driver didn't call drm_vblank_init() */
> -	if (dev->num_crtcs == 0)
> -		return;
> -
>  	for (pipe = 0; pipe < dev->num_crtcs; pipe++) {
>  		struct drm_vblank_crtc *vblank = &dev->vblank[pipe];
>  
> @@ -441,10 +438,6 @@ void drm_vblank_cleanup(struct drm_device *dev)
>  
>  		del_timer_sync(&vblank->disable_timer);
>  	}
> -
> -	kfree(dev->vblank);
> -
> -	dev->num_crtcs = 0;
>  }
>  
>  /**
> @@ -453,25 +446,29 @@ void drm_vblank_cleanup(struct drm_device *dev)
>   * @num_crtcs: number of CRTCs supported by @dev
>   *
>   * This function initializes vblank support for @num_crtcs display pipelines.
> - * Cleanup is handled by the DRM core, or through calling drm_dev_fini() for
> - * drivers with a &drm_driver.release callback.
> + * Cleanup is handled automatically through a cleanup function added with
> + * drmm_add_action().
>   *
>   * Returns:
>   * Zero on success or a negative error code on failure.
>   */
>  int drm_vblank_init(struct drm_device *dev, unsigned int num_crtcs)
>  {
> -	int ret = -ENOMEM;
> +	int ret;
>  	unsigned int i;
>  
>  	spin_lock_init(&dev->vbl_lock);
>  	spin_lock_init(&dev->vblank_time_lock);
>  
> +	dev->vblank = drmm_kcalloc(dev, num_crtcs, sizeof(*dev->vblank), GFP_KERNEL);
> +	if (!dev->vblank)
> +		return -ENOMEM;
> +
>  	dev->num_crtcs = num_crtcs;
>  
> -	dev->vblank = kcalloc(num_crtcs, sizeof(*dev->vblank), GFP_KERNEL);
> -	if (!dev->vblank)
> -		goto err;
> +	ret = drmm_add_action(dev, drm_vblank_init_release, NULL);
> +	if (ret)
> +		return ret;
>  
>  	for (i = 0; i < num_crtcs; i++) {
>  		struct drm_vblank_crtc *vblank = &dev->vblank[i];
> @@ -486,10 +483,6 @@ int drm_vblank_init(struct drm_device *dev, unsigned int num_crtcs)
>  	DRM_INFO("Supports vblank timestamp caching Rev 2 (21.10.2013).\n");
>  
>  	return 0;
> -
> -err:
> -	dev->num_crtcs = 0;
> -	return ret;
>  }
>  EXPORT_SYMBOL(drm_vblank_init);
>  
> diff --git a/include/drm/drm_managed.h b/include/drm/drm_managed.h
> index 5280209dff92..2b1ba2ad5582 100644
> --- a/include/drm/drm_managed.h
> +++ b/include/drm/drm_managed.h
> @@ -4,6 +4,7 @@
>  #define _DRM_MANAGED_H_
>  
>  #include <linux/gfp.h>
> +#include <linux/overflow.h>
>  #include <linux/types.h>
>  
>  struct drm_device;
> @@ -28,6 +29,21 @@ static inline void *drmm_kzalloc(struct drm_device *dev, size_t size, gfp_t gfp)
>  {
>  	return drmm_kmalloc(dev, size, gfp | __GFP_ZERO);
>  }
> +static inline void *drmm_kmalloc_array(struct drm_device *dev,
> +				       size_t n, size_t size, gfp_t flags)
> +{
> +	size_t bytes;
> +
> +	if (unlikely(check_mul_overflow(n, size, &bytes)))
> +		return NULL;
> +
> +	return drmm_kmalloc(dev, bytes, flags);
> +}
> +static inline void *drmm_kcalloc(struct drm_device *dev,
> +				 size_t n, size_t size, gfp_t flags)
> +{
> +	return drmm_kmalloc_array(dev, n, size, flags | __GFP_ZERO);
> +}
>  char *drmm_kstrdup(struct drm_device *dev, const char *s, gfp_t gfp);
>  
>  void drmm_kfree(struct drm_device *dev, void *data);
> -- 
> 2.24.1
> 
> _______________________________________________
> dri-devel mailing list
> dri-devel@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/dri-devel
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 111+ messages in thread

* Re: [PATCH 25/51] drm: Garbage collect drm_dev_fini
  2020-03-02 22:26 ` [PATCH 25/51] drm: Garbage collect drm_dev_fini Daniel Vetter
@ 2020-03-07  8:30   ` Sam Ravnborg
  0 siblings, 0 replies; 111+ messages in thread
From: Sam Ravnborg @ 2020-03-07  8:30 UTC (permalink / raw)
  To: Daniel Vetter; +Cc: Daniel Vetter, Intel Graphics Development, DRI Development

On Mon, Mar 02, 2020 at 11:26:05PM +0100, Daniel Vetter wrote:
> It has become empty. Given the few users I figured not much point
> splitting this up.
> 
> v2: Rebase over i915 changes.
> 
> Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>

Acked-by: Sam Ravnborg <sam@ravnborg.org>

> ---
>  drivers/gpu/drm/cirrus/cirrus.c               |  1 -
>  drivers/gpu/drm/drm_drv.c                     | 23 +------------------
>  drivers/gpu/drm/drm_mipi_dbi.c                |  1 -
>  drivers/gpu/drm/i915/i915_drv.c               |  9 --------
>  .../gpu/drm/i915/selftests/mock_gem_device.c  |  2 --
>  drivers/gpu/drm/ingenic/ingenic-drm.c         |  1 -
>  drivers/gpu/drm/mcde/mcde_drv.c               |  1 -
>  drivers/gpu/drm/tidss/tidss_drv.c             |  2 --
>  drivers/gpu/drm/tiny/gm12u320.c               |  1 -
>  drivers/gpu/drm/tiny/repaper.c                |  1 -
>  drivers/gpu/drm/udl/udl_drv.c                 |  1 -
>  drivers/gpu/drm/vgem/vgem_drv.c               |  1 -
>  drivers/gpu/drm/vkms/vkms_drv.c               |  1 -
>  drivers/gpu/drm/xen/xen_drm_front.c           |  2 --
>  include/drm/drm_drv.h                         |  5 +---
>  15 files changed, 2 insertions(+), 50 deletions(-)
> 
> diff --git a/drivers/gpu/drm/cirrus/cirrus.c b/drivers/gpu/drm/cirrus/cirrus.c
> index 2232556ce34c..a9d789a56536 100644
> --- a/drivers/gpu/drm/cirrus/cirrus.c
> +++ b/drivers/gpu/drm/cirrus/cirrus.c
> @@ -529,7 +529,6 @@ static void cirrus_mode_config_init(struct cirrus_device *cirrus)
>  static void cirrus_release(struct drm_device *dev)
>  {
>  	drm_mode_config_cleanup(dev);
> -	drm_dev_fini(dev);
>  }
>  
>  DEFINE_DRM_GEM_FOPS(cirrus_fops);
> diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c
> index 90b6ae81d431..c709a0ce018c 100644
> --- a/drivers/gpu/drm/drm_drv.c
> +++ b/drivers/gpu/drm/drm_drv.c
> @@ -283,7 +283,6 @@ void drm_minor_release(struct drm_minor *minor)
>   *		struct driver_device *priv = container_of(...);
>   *
>   *		drm_mode_config_cleanup(drm);
> - *		drm_dev_fini(drm);
>   *	}
>   *
>   *	static struct drm_driver driver_drm_driver = {
> @@ -738,23 +737,6 @@ int devm_drm_dev_init(struct device *parent,
>  }
>  EXPORT_SYMBOL(devm_drm_dev_init);
>  
> -/**
> - * drm_dev_fini - Finalize a dead DRM device
> - * @dev: DRM device
> - *
> - * Finalize a dead DRM device. This is the converse to drm_dev_init() and
> - * frees up all data allocated by it. All driver private data should be
> - * finalized first. Note that this function does not free the @dev, that is
> - * left to the caller.
> - *
> - * The ref-count of @dev must be zero, and drm_dev_fini() should only be called
> - * from a &drm_driver.release callback.
> - */
> -void drm_dev_fini(struct drm_device *dev)
> -{
> -}
> -EXPORT_SYMBOL(drm_dev_fini);
> -
>  /**
>   * drm_dev_alloc - Allocate new DRM device
>   * @driver: DRM driver to allocate device for
> @@ -803,11 +785,8 @@ static void drm_dev_release(struct kref *ref)
>  {
>  	struct drm_device *dev = container_of(ref, struct drm_device, ref);
>  
> -	if (dev->driver->release) {
> +	if (dev->driver->release)
>  		dev->driver->release(dev);
> -	} else {
> -		drm_dev_fini(dev);
> -	}
>  
>  	drm_managed_release(dev);
>  
> diff --git a/drivers/gpu/drm/drm_mipi_dbi.c b/drivers/gpu/drm/drm_mipi_dbi.c
> index 069603dfcd10..a678e07508d4 100644
> --- a/drivers/gpu/drm/drm_mipi_dbi.c
> +++ b/drivers/gpu/drm/drm_mipi_dbi.c
> @@ -591,7 +591,6 @@ void mipi_dbi_release(struct drm_device *drm)
>  	DRM_DEBUG_DRIVER("\n");
>  
>  	drm_mode_config_cleanup(drm);
> -	drm_dev_fini(drm);
>  }
>  EXPORT_SYMBOL(mipi_dbi_release);
>  
> diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
> index bb14209beeed..ff24ca5df7ed 100644
> --- a/drivers/gpu/drm/i915/i915_drv.c
> +++ b/drivers/gpu/drm/i915/i915_drv.c
> @@ -911,13 +911,6 @@ i915_driver_create(struct pci_dev *pdev, const struct pci_device_id *ent)
>  	return i915;
>  }
>  
> -static void i915_driver_destroy(struct drm_i915_private *i915)
> -{
> -	struct pci_dev *pdev = i915->drm.pdev;
> -
> -	drm_dev_fini(&i915->drm);
> -}
> -
>  /**
>   * i915_driver_probe - setup chip and create an initial config
>   * @pdev: PCI device
> @@ -1020,7 +1013,6 @@ int i915_driver_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
>  	pci_disable_device(pdev);
>  out_fini:
>  	i915_probe_error(i915, "Device initialization failed (%d)\n", ret);
> -	i915_driver_destroy(i915);
>  	drm_dev_put(&i915->drm);
>  	return ret;
>  }
> @@ -1077,7 +1069,6 @@ static void i915_driver_release(struct drm_device *dev)
>  	intel_runtime_pm_driver_release(rpm);
>  
>  	i915_driver_late_release(dev_priv);
> -	i915_driver_destroy(dev_priv);
>  }
>  
>  static int i915_driver_open(struct drm_device *dev, struct drm_file *file)
> diff --git a/drivers/gpu/drm/i915/selftests/mock_gem_device.c b/drivers/gpu/drm/i915/selftests/mock_gem_device.c
> index acf889e4b993..2b4407ac26de 100644
> --- a/drivers/gpu/drm/i915/selftests/mock_gem_device.c
> +++ b/drivers/gpu/drm/i915/selftests/mock_gem_device.c
> @@ -76,7 +76,6 @@ static void mock_device_release(struct drm_device *dev)
>  
>  	drm_mode_config_cleanup(&i915->drm);
>  
> -	drm_dev_fini(&i915->drm);
>  out:
>  	put_device(&i915->drm.pdev->dev);
>  	i915->drm.pdev = NULL;
> @@ -215,7 +214,6 @@ struct drm_i915_private *mock_gem_device(void)
>  	intel_gt_driver_late_release(&i915->gt);
>  	intel_memory_regions_driver_release(i915);
>  	drm_mode_config_cleanup(&i915->drm);
> -	drm_dev_fini(&i915->drm);
>  	drm_dev_put(&i915->drm);
>  
>  	return NULL;
> diff --git a/drivers/gpu/drm/ingenic/ingenic-drm.c b/drivers/gpu/drm/ingenic/ingenic-drm.c
> index e2c832eb4e9a..192aaa4421a3 100644
> --- a/drivers/gpu/drm/ingenic/ingenic-drm.c
> +++ b/drivers/gpu/drm/ingenic/ingenic-drm.c
> @@ -492,7 +492,6 @@ static irqreturn_t ingenic_drm_irq_handler(int irq, void *arg)
>  static void ingenic_drm_release(struct drm_device *drm)
>  {
>  	drm_mode_config_cleanup(drm);
> -	drm_dev_fini(drm);
>  }
>  
>  static int ingenic_drm_enable_vblank(struct drm_crtc *crtc)
> diff --git a/drivers/gpu/drm/mcde/mcde_drv.c b/drivers/gpu/drm/mcde/mcde_drv.c
> index 7474481503a1..a543ebf3d541 100644
> --- a/drivers/gpu/drm/mcde/mcde_drv.c
> +++ b/drivers/gpu/drm/mcde/mcde_drv.c
> @@ -223,7 +223,6 @@ static void mcde_release(struct drm_device *drm)
>  	struct mcde *mcde = drm->dev_private;
>  
>  	drm_mode_config_cleanup(drm);
> -	drm_dev_fini(drm);
>  }
>  
>  DEFINE_DRM_GEM_CMA_FOPS(drm_fops);
> diff --git a/drivers/gpu/drm/tidss/tidss_drv.c b/drivers/gpu/drm/tidss/tidss_drv.c
> index 32a85628dbec..460d5e9d0cf4 100644
> --- a/drivers/gpu/drm/tidss/tidss_drv.c
> +++ b/drivers/gpu/drm/tidss/tidss_drv.c
> @@ -108,8 +108,6 @@ static void tidss_release(struct drm_device *ddev)
>  	drm_kms_helper_poll_fini(ddev);
>  
>  	tidss_modeset_cleanup(tidss);
> -
> -	drm_dev_fini(ddev);
>  }
>  
>  DEFINE_DRM_GEM_CMA_FOPS(tidss_fops);
> diff --git a/drivers/gpu/drm/tiny/gm12u320.c b/drivers/gpu/drm/tiny/gm12u320.c
> index 524ca0941cf9..3928f69bbd3d 100644
> --- a/drivers/gpu/drm/tiny/gm12u320.c
> +++ b/drivers/gpu/drm/tiny/gm12u320.c
> @@ -637,7 +637,6 @@ static void gm12u320_driver_release(struct drm_device *dev)
>  
>  	gm12u320_usb_free(gm12u320);
>  	drm_mode_config_cleanup(dev);
> -	drm_dev_fini(dev);
>  }
>  
>  DEFINE_DRM_GEM_FOPS(gm12u320_fops);
> diff --git a/drivers/gpu/drm/tiny/repaper.c b/drivers/gpu/drm/tiny/repaper.c
> index df5654ef53ee..4741ff670ec9 100644
> --- a/drivers/gpu/drm/tiny/repaper.c
> +++ b/drivers/gpu/drm/tiny/repaper.c
> @@ -914,7 +914,6 @@ static void repaper_release(struct drm_device *drm)
>  	DRM_DEBUG_DRIVER("\n");
>  
>  	drm_mode_config_cleanup(drm);
> -	drm_dev_fini(drm);
>  }
>  
>  static const uint32_t repaper_formats[] = {
> diff --git a/drivers/gpu/drm/udl/udl_drv.c b/drivers/gpu/drm/udl/udl_drv.c
> index 6a5594946096..8b78c356beb5 100644
> --- a/drivers/gpu/drm/udl/udl_drv.c
> +++ b/drivers/gpu/drm/udl/udl_drv.c
> @@ -38,7 +38,6 @@ static void udl_driver_release(struct drm_device *dev)
>  {
>  	udl_fini(dev);
>  	udl_modeset_cleanup(dev);
> -	drm_dev_fini(dev);
>  }
>  
>  static struct drm_driver driver = {
> diff --git a/drivers/gpu/drm/vgem/vgem_drv.c b/drivers/gpu/drm/vgem/vgem_drv.c
> index 7486014e9149..ec1a8ebb6f1b 100644
> --- a/drivers/gpu/drm/vgem/vgem_drv.c
> +++ b/drivers/gpu/drm/vgem/vgem_drv.c
> @@ -432,7 +432,6 @@ static void vgem_release(struct drm_device *dev)
>  	struct vgem_device *vgem = container_of(dev, typeof(*vgem), drm);
>  
>  	platform_device_unregister(vgem->platform);
> -	drm_dev_fini(&vgem->drm);
>  }
>  
>  static struct drm_driver vgem_driver = {
> diff --git a/drivers/gpu/drm/vkms/vkms_drv.c b/drivers/gpu/drm/vkms/vkms_drv.c
> index 2f35fe789343..eef85f1a0ce5 100644
> --- a/drivers/gpu/drm/vkms/vkms_drv.c
> +++ b/drivers/gpu/drm/vkms/vkms_drv.c
> @@ -64,7 +64,6 @@ static void vkms_release(struct drm_device *dev)
>  	platform_device_unregister(vkms->platform);
>  	drm_atomic_helper_shutdown(&vkms->drm);
>  	drm_mode_config_cleanup(&vkms->drm);
> -	drm_dev_fini(&vkms->drm);
>  	destroy_workqueue(vkms->output.composer_workq);
>  }
>  
> diff --git a/drivers/gpu/drm/xen/xen_drm_front.c b/drivers/gpu/drm/xen/xen_drm_front.c
> index d22b5da38935..b91d23b5f3ae 100644
> --- a/drivers/gpu/drm/xen/xen_drm_front.c
> +++ b/drivers/gpu/drm/xen/xen_drm_front.c
> @@ -460,8 +460,6 @@ static void xen_drm_drv_release(struct drm_device *dev)
>  	drm_atomic_helper_shutdown(dev);
>  	drm_mode_config_cleanup(dev);
>  
> -	drm_dev_fini(dev);
> -
>  	if (front_info->cfg.be_alloc)
>  		xenbus_switch_state(front_info->xb_dev,
>  				    XenbusStateInitialising);
> diff --git a/include/drm/drm_drv.h b/include/drm/drm_drv.h
> index cbd050419ab8..edee40e31e4b 100644
> --- a/include/drm/drm_drv.h
> +++ b/include/drm/drm_drv.h
> @@ -265,9 +265,7 @@ struct drm_driver {
>  	 * @release:
>  	 *
>  	 * Optional callback for destroying device data after the final
> -	 * reference is released, i.e. the device is being destroyed. Drivers
> -	 * using this callback are responsible for calling drm_dev_fini()
> -	 * to finalize the device and then freeing the struct themselves.
> +	 * reference is released, i.e. the device is being destroyed.
>  	 */
>  	void (*release) (struct drm_device *);
>  
> @@ -623,7 +621,6 @@ int drm_dev_init(struct drm_device *dev,
>  int devm_drm_dev_init(struct device *parent,
>  		      struct drm_device *dev,
>  		      struct drm_driver *driver);
> -void drm_dev_fini(struct drm_device *dev);
>  
>  struct drm_device *drm_dev_alloc(struct drm_driver *driver,
>  				 struct device *parent);
> -- 
> 2.24.1
> 
> _______________________________________________
> dri-devel mailing list
> dri-devel@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/dri-devel
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 111+ messages in thread

* Re: [PATCH 35/51] drm/pl111: Drop explicit drm_mode_config_cleanup call
  2020-03-02 22:26 ` [PATCH 35/51] drm/pl111: " Daniel Vetter
@ 2020-03-07  8:37   ` Sam Ravnborg
  0 siblings, 0 replies; 111+ messages in thread
From: Sam Ravnborg @ 2020-03-07  8:37 UTC (permalink / raw)
  To: Daniel Vetter
  Cc: Thomas Zimmermann, Intel Graphics Development, Laurent Pinchart,
	DRI Development, Daniel Vetter

On Mon, Mar 02, 2020 at 11:26:15PM +0100, Daniel Vetter wrote:
> It's right above the drm_dev_put().
> 
> This is made possible by a preceeding patch which added a drmm_
> cleanup action to drm_mode_config_init(), hence all we need to do to
> ensure that drm_mode_config_cleanup() is run on final drm_device
> cleanup is check the new error code for _init().
> 
> Aside: This driver gets its devm_ stuff all wrong wrt drm_device and
> anything hanging off that. Not the only one unfortunately.
> 
> v2: Explain why this cleanup is possible (Laurent).
> 
> v3: Use drmm_mode_config_init() for more clarity (Sam, Thomas)
> 
> Cc: Sam Ravnborg <sam@ravnborg.org>
> Cc: Thomas Zimmermann <tzimmermann@suse.de>
> Cc: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
> Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
> Cc: Eric Anholt <eric@anholt.net>

Acked-by: Sam Ravnborg <sam@ravnborg.org>

> ---
>  drivers/gpu/drm/pl111/pl111_drv.c | 12 ++++++------
>  1 file changed, 6 insertions(+), 6 deletions(-)
> 
> diff --git a/drivers/gpu/drm/pl111/pl111_drv.c b/drivers/gpu/drm/pl111/pl111_drv.c
> index aa8aa8d9e405..f9ca0f3edbbb 100644
> --- a/drivers/gpu/drm/pl111/pl111_drv.c
> +++ b/drivers/gpu/drm/pl111/pl111_drv.c
> @@ -90,10 +90,13 @@ static int pl111_modeset_init(struct drm_device *dev)
>  	struct drm_panel *panel = NULL;
>  	struct drm_bridge *bridge = NULL;
>  	bool defer = false;
> -	int ret = 0;
> +	int ret;
>  	int i;
>  
> -	drm_mode_config_init(dev);
> +	ret = drmm_mode_config_init(dev);
> +	if (ret)
> +		return ret;
> +
>  	mode_config = &dev->mode_config;
>  	mode_config->funcs = &mode_config_funcs;
>  	mode_config->min_width = 1;
> @@ -154,7 +157,7 @@ static int pl111_modeset_init(struct drm_device *dev)
>  						    DRM_MODE_CONNECTOR_Unknown);
>  		if (IS_ERR(bridge)) {
>  			ret = PTR_ERR(bridge);
> -			goto out_config;
> +			goto finish;
>  		}
>  	} else if (bridge) {
>  		dev_info(dev->dev, "Using non-panel bridge\n");
> @@ -197,8 +200,6 @@ static int pl111_modeset_init(struct drm_device *dev)
>  out_bridge:
>  	if (panel)
>  		drm_panel_bridge_remove(bridge);
> -out_config:
> -	drm_mode_config_cleanup(dev);
>  finish:
>  	return ret;
>  }
> @@ -343,7 +344,6 @@ static int pl111_amba_remove(struct amba_device *amba_dev)
>  	drm_dev_unregister(drm);
>  	if (priv->panel)
>  		drm_panel_bridge_remove(priv->bridge);
> -	drm_mode_config_cleanup(drm);
>  	drm_dev_put(drm);
>  	of_reserved_mem_device_release(dev);
>  
> -- 
> 2.24.1
> 
> _______________________________________________
> dri-devel mailing list
> dri-devel@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/dri-devel
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 111+ messages in thread

* Re: [PATCH 37/51] drm/rockchip: Drop explicit drm_mode_config_cleanup call
  2020-03-02 22:26 ` [PATCH 37/51] drm/rockchip: " Daniel Vetter
@ 2020-03-07  8:38   ` Sam Ravnborg
  0 siblings, 0 replies; 111+ messages in thread
From: Sam Ravnborg @ 2020-03-07  8:38 UTC (permalink / raw)
  To: Daniel Vetter
  Cc: Francesco Lavra, Intel Graphics Development, Sandy Huang,
	DRI Development, linux-rockchip, Laurent Pinchart,
	Thomas Zimmermann, Daniel Vetter, linux-arm-kernel

On Mon, Mar 02, 2020 at 11:26:17PM +0100, Daniel Vetter wrote:
> It's (almost, there's some iommu stuff without significance) right
> above the drm_dev_put().
> 
> This is made possible by a preceeding patch which added a drmm_
> cleanup action to drm_mode_config_init(), hence all we need to do to
> ensure that drm_mode_config_cleanup() is run on final drm_device
> cleanup is check the new error code for _init().
> 
> Aside: Another driver with a bit much devm_kzalloc, which should
> probably use drmm_kzalloc instead ...
> 
> v2: Explain why this cleanup is possible (Laurent).
> 
> v3: Jump out at the right label (Francesco)
> 
> v4: Try again, kbuild caught that I didn't build test this properly
> ...
> 
> v5: Use drmm_mode_config_init() for more clarity (Sam, Thomas)
> 
> Cc: Sam Ravnborg <sam@ravnborg.org>
> Cc: Thomas Zimmermann <tzimmermann@suse.de>
> Cc: Francesco Lavra <francescolavra.fl@gmail.com>
> Cc: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
> Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
> Cc: Sandy Huang <hjc@rock-chips.com>
> Cc: "Heiko Stübner" <heiko@sntech.de>
> Cc: linux-arm-kernel@lists.infradead.org
> Cc: linux-rockchip@lists.infradead.org

Acked-by: Sam Ravnborg <sam@ravnborg.org>

> ---
>  drivers/gpu/drm/rockchip/rockchip_drm_drv.c | 14 +++++---------
>  1 file changed, 5 insertions(+), 9 deletions(-)
> 
> diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_drv.c b/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
> index 20ecb1508a22..0f3eb392fe39 100644
> --- a/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
> +++ b/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
> @@ -135,14 +135,16 @@ static int rockchip_drm_bind(struct device *dev)
>  	if (ret)
>  		goto err_free;
>  
> -	drm_mode_config_init(drm_dev);
> +	ret = drmm_mode_config_init(drm_dev);
> +	if (ret)
> +		goto err_iommu_cleanup;
>  
>  	rockchip_drm_mode_config_init(drm_dev);
>  
>  	/* Try to bind all sub drivers. */
>  	ret = component_bind_all(dev, drm_dev);
>  	if (ret)
> -		goto err_mode_config_cleanup;
> +		goto err_iommu_cleanup;
>  
>  	ret = drm_vblank_init(drm_dev, drm_dev->mode_config.num_crtc);
>  	if (ret)
> @@ -173,12 +175,9 @@ static int rockchip_drm_bind(struct device *dev)
>  	rockchip_drm_fbdev_fini(drm_dev);
>  err_unbind_all:
>  	component_unbind_all(dev, drm_dev);
> -err_mode_config_cleanup:
> -	drm_mode_config_cleanup(drm_dev);
> +err_iommu_cleanup:
>  	rockchip_iommu_cleanup(drm_dev);
>  err_free:
> -	drm_dev->dev_private = NULL;
> -	dev_set_drvdata(dev, NULL);
>  	drm_dev_put(drm_dev);
>  	return ret;
>  }
> @@ -194,11 +193,8 @@ static void rockchip_drm_unbind(struct device *dev)
>  
>  	drm_atomic_helper_shutdown(drm_dev);
>  	component_unbind_all(dev, drm_dev);
> -	drm_mode_config_cleanup(drm_dev);
>  	rockchip_iommu_cleanup(drm_dev);
>  
> -	drm_dev->dev_private = NULL;
> -	dev_set_drvdata(dev, NULL);
>  	drm_dev_put(drm_dev);
>  }
>  
> -- 
> 2.24.1
> 
> _______________________________________________
> dri-devel mailing list
> dri-devel@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/dri-devel
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 111+ messages in thread

* Re: [PATCH 38/51] drm/stm: Drop explicit drm_mode_config_cleanup call
  2020-03-02 22:26 ` [PATCH 38/51] drm/stm: " Daniel Vetter
@ 2020-03-07  9:25   ` Sam Ravnborg
  0 siblings, 0 replies; 111+ messages in thread
From: Sam Ravnborg @ 2020-03-07  9:25 UTC (permalink / raw)
  To: Daniel Vetter
  Cc: Thomas Zimmermann, Intel Graphics Development, Philippe Cornu,
	DRI Development, Yannick Fertre, Laurent Pinchart,
	Maxime Coquelin, Daniel Vetter, Vincent Abriou, linux-stm32,
	linux-arm-kernel, Alexandre Torgue

On Mon, Mar 02, 2020 at 11:26:18PM +0100, Daniel Vetter wrote:
> It's right above the drm_dev_put().
> 
> This is made possible by a preceeding patch which added a drmm_
> cleanup action to drm_mode_config_init(), hence all we need to do to
> ensure that drm_mode_config_cleanup() is run on final drm_device
> cleanup is check the new error code for _init().
> 
> Aside: Another driver with a bit much devm_kzalloc, which should
> probably use drmm_kzalloc instead ...
> 
> v2: Explain why this cleanup is possible (Laurent).
> 
> v3: Use drmm_mode_config_init() for more clarity (Sam, Thomas)
> 
> Cc: Sam Ravnborg <sam@ravnborg.org>
> Cc: Thomas Zimmermann <tzimmermann@suse.de>
> Acked-by: Philippe Cornu <philippe.cornu@st.com>
> Cc: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
> Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
> Cc: Yannick Fertre <yannick.fertre@st.com>
> Cc: Philippe Cornu <philippe.cornu@st.com>
> Cc: Benjamin Gaignard <benjamin.gaignard@linaro.org>
> Cc: Vincent Abriou <vincent.abriou@st.com>
> Cc: Maxime Coquelin <mcoquelin.stm32@gmail.com>
> Cc: Alexandre Torgue <alexandre.torgue@st.com>
> Cc: linux-stm32@st-md-mailman.stormreply.com
> Cc: linux-arm-kernel@lists.infradead.org

Acked-by: Sam Ravnborg <sam@ravnborg.org>

> ---
>  drivers/gpu/drm/stm/drv.c | 10 ++++------
>  1 file changed, 4 insertions(+), 6 deletions(-)
> 
> diff --git a/drivers/gpu/drm/stm/drv.c b/drivers/gpu/drm/stm/drv.c
> index ea9fcbdc68b3..0f85dd86cafa 100644
> --- a/drivers/gpu/drm/stm/drv.c
> +++ b/drivers/gpu/drm/stm/drv.c
> @@ -88,7 +88,9 @@ static int drv_load(struct drm_device *ddev)
>  
>  	ddev->dev_private = (void *)ldev;
>  
> -	drm_mode_config_init(ddev);
> +	ret = drmm_mode_config_init(ddev);
> +	if (ret)
> +		return ret;
>  
>  	/*
>  	 * set max width and height as default value.
> @@ -103,7 +105,7 @@ static int drv_load(struct drm_device *ddev)
>  
>  	ret = ltdc_load(ddev);
>  	if (ret)
> -		goto err;
> +		return ret;
>  
>  	drm_mode_config_reset(ddev);
>  	drm_kms_helper_poll_init(ddev);
> @@ -111,9 +113,6 @@ static int drv_load(struct drm_device *ddev)
>  	platform_set_drvdata(pdev, ddev);
>  
>  	return 0;
> -err:
> -	drm_mode_config_cleanup(ddev);
> -	return ret;
>  }
>  
>  static void drv_unload(struct drm_device *ddev)
> @@ -122,7 +121,6 @@ static void drv_unload(struct drm_device *ddev)
>  
>  	drm_kms_helper_poll_fini(ddev);
>  	ltdc_unload(ddev);
> -	drm_mode_config_cleanup(ddev);
>  }
>  
>  static __maybe_unused int drv_suspend(struct device *dev)
> -- 
> 2.24.1
> 
> _______________________________________________
> dri-devel mailing list
> dri-devel@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/dri-devel
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 111+ messages in thread

* Re: [PATCH 40/51] drm/mtk: Drop explicit drm_mode_config_cleanup call
  2020-03-02 22:26 ` [PATCH 40/51] drm/mtk: " Daniel Vetter
@ 2020-03-07  9:26   ` Sam Ravnborg
  0 siblings, 0 replies; 111+ messages in thread
From: Sam Ravnborg @ 2020-03-07  9:26 UTC (permalink / raw)
  To: Daniel Vetter
  Cc: Thomas Zimmermann, Intel Graphics Development, Laurent Pinchart,
	DRI Development, Daniel Vetter

On Mon, Mar 02, 2020 at 11:26:20PM +0100, Daniel Vetter wrote:
> It's right above the drm_dev_put().
> 
> This is made possible by a preceeding patch which added a drmm_
> cleanup action to drm_mode_config_init(), hence all we need to do to
> ensure that drm_mode_config_cleanup() is run on final drm_device
> cleanup is check the new error code for _init().
> 
> Aside: Another driver with a bit much devm_kzalloc, which should
> probably use drmm_kzalloc instead ...
> 
> v2: Explain why this cleanup is possible (Laurent).
> 
> v3: Use drmm_mode_config_init() for more clarity (Sam, Thomas)
> 
> Cc: Sam Ravnborg <sam@ravnborg.org>
> Cc: Thomas Zimmermann <tzimmermann@suse.de>
> Cc: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
> Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>

Acked-by: Sam Ravnborg <sam@ravnborg.org>

> ---
>  drivers/gpu/drm/mediatek/mtk_drm_drv.c | 9 ++++-----
>  1 file changed, 4 insertions(+), 5 deletions(-)
> 
> diff --git a/drivers/gpu/drm/mediatek/mtk_drm_drv.c b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
> index 0563c6813333..2eaa9080d250 100644
> --- a/drivers/gpu/drm/mediatek/mtk_drm_drv.c
> +++ b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
> @@ -162,7 +162,9 @@ static int mtk_drm_kms_init(struct drm_device *drm)
>  	}
>  	private->mutex_dev = &pdev->dev;
>  
> -	drm_mode_config_init(drm);
> +	ret = drmm_mode_config_init(drm);
> +	if (ret)
> +		return ret;
>  
>  	drm->mode_config.min_width = 64;
>  	drm->mode_config.min_height = 64;
> @@ -179,7 +181,7 @@ static int mtk_drm_kms_init(struct drm_device *drm)
>  
>  	ret = component_bind_all(drm->dev, drm);
>  	if (ret)
> -		goto err_config_cleanup;
> +		return ret;
>  
>  	/*
>  	 * We currently support two fixed data streams, each optional,
> @@ -255,8 +257,6 @@ static int mtk_drm_kms_init(struct drm_device *drm)
>  		dma_dev->dma_parms = NULL;
>  err_component_unbind:
>  	component_unbind_all(drm->dev, drm);
> -err_config_cleanup:
> -	drm_mode_config_cleanup(drm);
>  
>  	return ret;
>  }
> @@ -272,7 +272,6 @@ static void mtk_drm_kms_deinit(struct drm_device *drm)
>  		private->dma_dev->dma_parms = NULL;
>  
>  	component_unbind_all(drm->dev, drm);
> -	drm_mode_config_cleanup(drm);
>  }
>  
>  static const struct file_operations mtk_drm_fops = {
> -- 
> 2.24.1
> 
> _______________________________________________
> dri-devel mailing list
> dri-devel@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/dri-devel
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 111+ messages in thread

* Re: [PATCH 46/51] drm/repaper: Drop explicit drm_mode_config_cleanup call
  2020-03-02 22:26 ` [PATCH 46/51] drm/repaper: Drop explicit drm_mode_config_cleanup call Daniel Vetter
@ 2020-03-07  9:31   ` Sam Ravnborg
  0 siblings, 0 replies; 111+ messages in thread
From: Sam Ravnborg @ 2020-03-07  9:31 UTC (permalink / raw)
  To: Daniel Vetter
  Cc: Thomas Zimmermann, Intel Graphics Development, Laurent Pinchart,
	DRI Development, Daniel Vetter

On Mon, Mar 02, 2020 at 11:26:26PM +0100, Daniel Vetter wrote:
> Allows us to drop the drm_driver.release callback.
> 
> This is made possible by a preceeding patch which added a drmm_
> cleanup action to drm_mode_config_init(), hence all we need to do to
> ensure that drm_mode_config_cleanup() is run on final drm_device
> cleanup is check the new error code for _init().
> 
> v2: Explain why this cleanup is possible (Laurent).
> 
> v3: Use drmm_mode_config_init() for more clarity (Sam, Thomas)
> I also noticed that I've failed to add the error checking,
> __must_check caught that.
> 
> Cc: Sam Ravnborg <sam@ravnborg.org>
> Cc: Thomas Zimmermann <tzimmermann@suse.de>
> Cc: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
> Reviewed-by: Noralf Trønnes <noralf@tronnes.org> (v2)
> Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
> Cc: "Noralf Trønnes" <noralf@tronnes.org>

Acked-by: Sam Ravnborg <sam@ravnborg.org>

> ---
>  drivers/gpu/drm/tiny/repaper.c | 12 +++---------
>  1 file changed, 3 insertions(+), 9 deletions(-)
> 
> diff --git a/drivers/gpu/drm/tiny/repaper.c b/drivers/gpu/drm/tiny/repaper.c
> index 4741ff670ec9..862c3ee6055d 100644
> --- a/drivers/gpu/drm/tiny/repaper.c
> +++ b/drivers/gpu/drm/tiny/repaper.c
> @@ -909,13 +909,6 @@ static const struct drm_mode_config_funcs repaper_mode_config_funcs = {
>  	.atomic_commit = drm_atomic_helper_commit,
>  };
>  
> -static void repaper_release(struct drm_device *drm)
> -{
> -	DRM_DEBUG_DRIVER("\n");
> -
> -	drm_mode_config_cleanup(drm);
> -}
> -
>  static const uint32_t repaper_formats[] = {
>  	DRM_FORMAT_XRGB8888,
>  };
> @@ -953,7 +946,6 @@ DEFINE_DRM_GEM_CMA_FOPS(repaper_fops);
>  static struct drm_driver repaper_driver = {
>  	.driver_features	= DRIVER_GEM | DRIVER_MODESET | DRIVER_ATOMIC,
>  	.fops			= &repaper_fops,
> -	.release		= repaper_release,
>  	DRM_GEM_CMA_VMAP_DRIVER_OPS,
>  	.name			= "repaper",
>  	.desc			= "Pervasive Displays RePaper e-ink panels",
> @@ -1023,7 +1015,9 @@ static int repaper_probe(struct spi_device *spi)
>  	}
>  	drmm_add_final_kfree(drm, epd);
>  
> -	drm_mode_config_init(drm);
> +	ret = drmm_mode_config_init(drm);
> +	if (ret)
> +		return ret;
>  	drm->mode_config.funcs = &repaper_mode_config_funcs;
>  
>  	epd->spi = spi;
> -- 
> 2.24.1
> 
> _______________________________________________
> dri-devel mailing list
> dri-devel@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/dri-devel
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 111+ messages in thread

* Re: [PATCH 51/51] drm: Add docs for managed resources
  2020-03-02 22:26 ` [PATCH 51/51] drm: Add docs for managed resources Daniel Vetter
@ 2020-03-07 10:07   ` Sam Ravnborg
  0 siblings, 0 replies; 111+ messages in thread
From: Sam Ravnborg @ 2020-03-07 10:07 UTC (permalink / raw)
  To: Daniel Vetter
  Cc: Jonathan Corbet, Greg Kroah-Hartman, Intel Graphics Development,
	linux-doc, DRI Development, Laurent Pinchart, Rafael J. Wysocki,
	Daniel Vetter

Hi Daniel.

On Mon, Mar 02, 2020 at 11:26:31PM +0100, Daniel Vetter wrote:
> All collected together to provide a consistent story in one patch,
> instead of the somewhat bumpy refactor-evolution leading to this.
> 
> Also some thoughts on what the next steps could be:
> 
> - Create a macro called devm_drm_dev_alloc() which essentially wraps
>   the kzalloc(); devm_drm_dev_init(); drmm_add_final_kfree() combo.
>   Needs to be a macro since we'll have to do some typeof trickery and
>   casting to make this fully generic for all drivers that embed struct
>   drm_device into their own thing.
> 
> - A lot of the simple drivers now have essentially just
>   drm_dev_unplug(); drm_atomic_helper_shutdown(); as their
>   $bus_driver->remove hook. We could create a devm_mode_config_reset
>   which sets drm_atomic_helper_shutdown as it's cleanup action, and a
>   devm_drm_dev_register with drm_dev_unplug as it's cleanup action,
>   and simple drivers wouldn't have a need for a ->remove function at
>   all, and we could delete them.
> 
> - For more complicated drivers we need drmm_ versions of a _lot_ more
>   things. All the userspace visible objects (crtc, plane, encoder,
>   crtc), anything else hanging of those (maybe a drmm_get_edid, at
>   least for panels and other built-in stuff).

When this patch set is landed and the dut have setteled it would
be good with a detailed todo entry including the above.
But let's land this first.

> 
> Also some more thoughts on why we're not reusing devm_ with maybe a
> fake struct device embedded into the drm_device (we can't use the
> kdev, since that's in each drm_minor).
> 
> - Code review gets extremely tricky, since every time you see a devm_
>   you need to carefully check whether the fake device (with the
>   drm_device lifetim) or the real device (with the lifetim of the
>   underlying physical device and driver binding) are used. That's not
>   going to help at all, and we have enormous amounts of drivers who
>   use devm_ where they really shouldn't. Having different types makes
>   sure the compiler type checks this for us and ensures correctness.
> 
> - The set of functions are very much non-overlapping. E.g.
>   devm_ioremap makes total sense, drmm_ioremap has the wrong lifetime,
>   since hw resources need to be cleaned out at driver unbind and wont
>   outlive that like a drm_device. Similar, but other way round for
>   drmm_connector_init (which is the only correct version, devm_ for
>   drm_connector is just buggy). Simply not having the wrong version
>   again prevents bugs.
> 
> Finally I guess this opens a huge todo for all the drivers. I'm
> semi-tempted to do a tree-wide s/devm_kzalloc/drmm_kzalloc/ since most
> likely that'll fix an enormous amount of bugs and most likely not
> cause any issues at all (aside from maybe holding onto memory slightly
> too long).
> 
> v2:
> - Doc improvements from Laurent.
> - Also add kerneldoc for the new drmm_add_action_or_reset.
> 
> Cc: Sam Ravnborg <sam@ravnborg.org>
> Cc: Jonathan Corbet <corbet@lwn.net>
> Cc: linux-doc@vger.kernel.org
> Cc: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
> Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
> Cc: "Rafael J. Wysocki" <rafael@kernel.org>
> Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>

Looks good - nice overview and good function descriptions.

Reviewed-by: Sam Ravnborg <sam@ravnborg.org>

> ---
>  Documentation/gpu/drm-internals.rst |  6 +++
>  drivers/gpu/drm/drm_drv.c           | 18 +++++++--
>  drivers/gpu/drm/drm_managed.c       | 61 +++++++++++++++++++++++++++++
>  include/drm/drm_drv.h               |  4 ++
>  include/drm/drm_managed.h           | 58 +++++++++++++++++++++++++++
>  5 files changed, 144 insertions(+), 3 deletions(-)
> 
> diff --git a/Documentation/gpu/drm-internals.rst b/Documentation/gpu/drm-internals.rst
> index a6b6145fda78..12272b168580 100644
> --- a/Documentation/gpu/drm-internals.rst
> +++ b/Documentation/gpu/drm-internals.rst
> @@ -138,6 +138,12 @@ Managed Resources
>  .. kernel-doc:: drivers/gpu/drm/drm_managed.c
>     :doc: managed resources
>  
> +.. kernel-doc:: drivers/gpu/drm/drm_managed.c
> +   :export:
> +
> +.. kernel-doc:: include/drm/drm_managed.h
> +   :internal:
> +
>  Bus-specific Device Registration and PCI Support
>  ------------------------------------------------
>  
> diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c
> index a82702d0c2fb..cd172080649c 100644
> --- a/drivers/gpu/drm/drm_drv.c
> +++ b/drivers/gpu/drm/drm_drv.c
> @@ -260,9 +260,15 @@ void drm_minor_release(struct drm_minor *minor)
>   * any other resources allocated at device initialization and drop the driver's
>   * reference to &drm_device using drm_dev_put().
>   *
> - * Note that the lifetime rules for &drm_device instance has still a lot of
> - * historical baggage. Hence use the reference counting provided by
> - * drm_dev_get() and drm_dev_put() only carefully.
> + * Note that any allocation or resource which is visible to userspace must be
> + * released only when the final drm_dev_put() is called, and not when the
> + * driver is unbound from the underlying physical struct &device. Best to use
> + * &drm_device managed resources with drmm_add_action(), drmm_kmalloc() and
> + * related functions.
> + *
> + * devres managed resources like devm_kmalloc() can only be used for resources
> + * directly related to the underlying hardware device, and only used in code
> + * paths fully protected by drm_dev_enter() and drm_dev_exit().
>   *
>   * Display driver example
>   * ~~~~~~~~~~~~~~~~~~~~~~
> @@ -606,6 +612,9 @@ static void drm_dev_init_release(struct drm_device *dev, void *res)
>   * arbitrary offset, you must supply a &drm_driver.release callback and control
>   * the finalization explicitly.
>   *
> + * Note that drivers must call drmm_add_final_kfree() after this function has
> + * completed successfully.
> + *
>   * RETURNS:
>   * 0 on success, or error code on failure.
>   */
> @@ -707,6 +716,9 @@ static void devm_drm_dev_init_release(void *data)
>   * Managed drm_dev_init(). The DRM device initialized with this function is
>   * automatically put on driver detach using drm_dev_put().
>   *
> + * Note that drivers must call drmm_add_final_kfree() after this function has
> + * completed successfully.
> + *
>   * RETURNS:
>   * 0 on success, or error code on failure.
>   */
> diff --git a/drivers/gpu/drm/drm_managed.c b/drivers/gpu/drm/drm_managed.c
> index 8c5f1f03c485..5148ef786c3b 100644
> --- a/drivers/gpu/drm/drm_managed.c
> +++ b/drivers/gpu/drm/drm_managed.c
> @@ -20,7 +20,19 @@
>   * Inspired by struct &device managed resources, but tied to the lifetime of
>   * struct &drm_device, which can outlive the underlying physical device, usually
>   * when userspace has some open files and other handles to resources still open.
> + *
> + * Release actions can be added with drmm_add_action(), memory allocations can
> + * be done directly with drmm_kmalloc() and the related functions. Everything
> + * will be released on the final drm_dev_put() in reverse order of how the
> + * release actions have been added and memory has been allocated since driver
> + * loading started with drm_dev_init().
> + *
> + * Note that release actions and managed memory can also be added and removed
> + * during the lifetime of the driver, all the functions are fully concurrent
> + * safe. But it is recommended to use managed resources only for resources that
> + * change rarely, if ever, during the lifetime of the &drm_device instance.
>   */
> +
>  struct drmres_node {
>  	struct list_head	entry;
>  	drmres_release_t	release;
> @@ -105,6 +117,18 @@ static void add_dr(struct drm_device *dev, struct drmres *dr)
>  		       dr, dr->node.name, (unsigned long) dr->node.size);
>  }
>  
> +/**
> + * drmm_add_final_kfree - add release action for the final kfree()
> + * @dev: DRM device
> + * @parent: pointer to the kmalloc allocation containing @dev
> + *
> + * Since the allocation containing the struct &drm_device must be allocated
> + * before it can be initialized with drm_dev_init() there's no way to allocate
> + * that memory with drmm_kmalloc(). To side-step this chicken-egg problem the
> + * pointer for this final kfree() must be specified by calling this function. It
> + * will be released in the final drm_dev_put() for @dev, after all other release
> + * actions installed through drmm_add_action() have been processed.
> + */
>  void drmm_add_final_kfree(struct drm_device *dev, void *parent)
>  {
>  	WARN_ON(dev->managed.final_kfree);
> @@ -156,6 +180,14 @@ int __drmm_add_action_or_reset(struct drm_device *dev,
>  }
>  EXPORT_SYMBOL(__drmm_add_action_or_reset);
>  
> +/**
> + * drmm_add_action - remove a managed release action to a &drm_device
> + * @dev: DRM device
> + * @action: release function
> + * @data: opaque pointer, passed to @action
> + *
> + * This function removes a release action added by drmm_add_action().
> + */
>  void drmm_remove_action(struct drm_device *dev,
>  			drmres_release_t action,
>  			void *data)
> @@ -184,6 +216,16 @@ void drmm_remove_action(struct drm_device *dev,
>  }
>  EXPORT_SYMBOL(drmm_remove_action);
>  
> +/**
> + * drmm_kmalloc - &drm_device managed kmalloc()
> + * @dev: DRM device
> + * @size: size of the memory allocation
> + * @gfp: GFP allocation flags
> + *
> + * This is a &drm_device managed version of kmalloc(). The allocated memory is
> + * automatically freed on the final drm_dev_put(). Memory can also be freed
> + * before the final drm_dev_put() by calling drmm_kfree().
> + */
>  void *drmm_kmalloc(struct drm_device *dev, size_t size, gfp_t gfp)
>  {
>  	struct drmres *dr;
> @@ -202,6 +244,16 @@ void *drmm_kmalloc(struct drm_device *dev, size_t size, gfp_t gfp)
>  }
>  EXPORT_SYMBOL(drmm_kmalloc);
>  
> +/**
> + * drmm_kstrdup - &drm_device managed kstrdup()
> + * @dev: DRM device
> + * @s: 0-terminated string to be duplicated
> + * @gfp: GFP allocation flags
> + *
> + * This is a &drm_device managed version of kstrdup(). The allocated memory is
> + * automatically freed on the final drm_dev_put() and works exactly like a
> + * memory allocation obtained by drmm_kmalloc().
> + */
>  char *drmm_kstrdup(struct drm_device *dev, const char *s, gfp_t gfp)
>  {
>  	size_t size;
> @@ -218,6 +270,15 @@ char *drmm_kstrdup(struct drm_device *dev, const char *s, gfp_t gfp)
>  }
>  EXPORT_SYMBOL_GPL(drmm_kstrdup);
>  
> +/**
> + * drmm_kfree - &drm_device managed kfree()
> + * @dev: DRM device
> + * @data: memory allocation to be freed
> + *
> + * This is a &drm_device managed version of kfree() which can be used to
> + * release memory allocated through drmm_kmalloc() or any of its related
> + * functions before the final drm_dev_put() of @dev.
> + */
>  void drmm_kfree(struct drm_device *dev, void *data)
>  {
>  	struct drmres *dr_match = NULL, *dr;
> diff --git a/include/drm/drm_drv.h b/include/drm/drm_drv.h
> index edee40e31e4b..0fd7fc6f024e 100644
> --- a/include/drm/drm_drv.h
> +++ b/include/drm/drm_drv.h
> @@ -266,6 +266,10 @@ struct drm_driver {
>  	 *
>  	 * Optional callback for destroying device data after the final
>  	 * reference is released, i.e. the device is being destroyed.
> +	 *
> +	 * This is deprecated, clean up all memory allocations associated with a
> +	 * &drm_device using drmm_add_action(), drmm_kmalloc() and related
> +	 * managed resources functions.
>  	 */
>  	void (*release) (struct drm_device *);
>  
> diff --git a/include/drm/drm_managed.h b/include/drm/drm_managed.h
> index 1e6291407586..af152cfb173c 100644
> --- a/include/drm/drm_managed.h
> +++ b/include/drm/drm_managed.h
> @@ -11,6 +11,19 @@ struct drm_device;
>  
>  typedef void (*drmres_release_t)(struct drm_device *dev, void *res);
>  
> +/**
> + * drmm_add_action - add a managed release action to a &drm_device
> + * @dev: DRM device
> + * @action: function which should be called when @dev is released
> + * @data: opaque pointer, passed to @action
> + *
> + * This function adds the @release action with optional parameter @data to the
> + * list of cleanup actions for @dev. The cleanup actions will be run in reverse
> + * order in the final drm_dev_put() call for @dev.
> + *
> + * A release action can be removed before @dev is released by calling
> + * drmm_remove_action() with matching parameters for @action and @data.
> + */
>  #define drmm_add_action(dev, action, data) \
>  	__drmm_add_action(dev, action, data, #action)
>  
> @@ -18,6 +31,15 @@ int __must_check __drmm_add_action(struct drm_device *dev,
>  				   drmres_release_t action,
>  				   void *data, const char *name);
>  
> +/**
> + * drmm_add_action_or_reset - add a managed release action to a &drm_device
> + * @dev: DRM device
> + * @action: function which should be called when @dev is released
> + * @data: opaque pointer, passed to @action
> + *
> + * Similar to drmm_add_action(), with the only difference that upon failure
> + * @action is directly called for any cleanup work necessary on failures.
> + */
>  #define drmm_add_action_or_reset(dev, action, data) \
>  	__drmm_add_action_or_reset(dev, action, data, #action)
>  
> @@ -32,10 +54,33 @@ void drmm_remove_action(struct drm_device *dev,
>  void drmm_add_final_kfree(struct drm_device *dev, void *parent);
>
>  void *drmm_kmalloc(struct drm_device *dev, size_t size, gfp_t gfp) __malloc;
> +
> +/**
> + * drmm_kzalloc - &drm_device managed kzalloc()
> + * @dev: DRM device
> + * @size: size of the memory allocation
> + * @gfp: GFP allocation flags
> + *
> + * This is a &drm_device managed version of kzalloc(). The allocated memory is
> + * automatically freed on the final drm_dev_put(). Memory can also be freed
> + * before the final drm_dev_put() by calling drmm_kfree().
> + */
>  static inline void *drmm_kzalloc(struct drm_device *dev, size_t size, gfp_t gfp)
>  {
>  	return drmm_kmalloc(dev, size, gfp | __GFP_ZERO);
>  }
> +
> +/**
> + * drmm_kmalloc_array - &drm_device managed kmalloc_array()
> + * @dev: DRM device
> + * @n: number of array elements to allocate
> + * @size: size of array member
> + * @flags: GFP allocation flags
> + *
> + * This is a &drm_device managed version of kmalloc_array(). The allocated
> + * memory is automatically freed on the final drm_dev_put() and works exactly
> + * like a memory allocation obtained by drmm_kmalloc().
> + */
>  static inline void *drmm_kmalloc_array(struct drm_device *dev,
>  				       size_t n, size_t size, gfp_t flags)
>  {
> @@ -46,11 +91,24 @@ static inline void *drmm_kmalloc_array(struct drm_device *dev,
>  
>  	return drmm_kmalloc(dev, bytes, flags);
>  }
> +
> +/**
> + * drmm_kcalloc - &drm_device managed kcalloc()
> + * @dev: DRM device
> + * @n: number of array elements to allocate
> + * @size: size of array member
> + * @flags: GFP allocation flags
> + *
> + * This is a &drm_device managed version of kcalloc(). The allocated memory is
> + * automatically freed on the final drm_dev_put() and works exactly like a
> + * memory allocation obtained by drmm_kmalloc().
> + */
>  static inline void *drmm_kcalloc(struct drm_device *dev,
>  				 size_t n, size_t size, gfp_t flags)
>  {
>  	return drmm_kmalloc_array(dev, n, size, flags | __GFP_ZERO);
>  }
> +
>  char *drmm_kstrdup(struct drm_device *dev, const char *s, gfp_t gfp);
>
>  void drmm_kfree(struct drm_device *dev, void *data);
> -- 
> 2.24.1
> 
> _______________________________________________
> dri-devel mailing list
> dri-devel@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/dri-devel
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 111+ messages in thread

* Re: [PATCH 03/51] drm: add managed resources tied to drm_device
  2020-03-02 22:25 ` [PATCH 03/51] drm: add managed resources tied to drm_device Daniel Vetter
  2020-03-03  8:04   ` Dan Carpenter
  2020-03-03  8:44   ` [PATCH] " Daniel Vetter
@ 2020-03-11  9:07   ` Thomas Zimmermann
  2020-03-11  9:47     ` Thomas Zimmermann
  2020-03-16  8:45     ` Daniel Vetter
  2020-03-11  9:14   ` Thomas Zimmermann
  3 siblings, 2 replies; 111+ messages in thread
From: Thomas Zimmermann @ 2020-03-11  9:07 UTC (permalink / raw)
  To: Daniel Vetter, DRI Development
  Cc: Rafael J. Wysocki, Greg Kroah-Hartman,
	Intel Graphics Development, Laurent Pinchart, Daniel Vetter,
	Sam Ravnborg


[-- Attachment #1.1.1: Type: text/plain, Size: 16739 bytes --]

Hi Daniel

Am 02.03.20 um 23:25 schrieb Daniel Vetter:
> We have lots of these. And the cleanup code tends to be of dubious
> quality. The biggest wrong pattern is that developers use devm_, which
> ties the release action to the underlying struct device, whereas
> all the userspace visible stuff attached to a drm_device can long
> outlive that one (e.g. after a hotunplug while userspace has open
> files and mmap'ed buffers). Give people what they want, but with more
> correctness.
> 
> Mostly copied from devres.c, with types adjusted to fit drm_device and
> a few simplifications - I didn't (yet) copy over everything. Since
> the types don't match code sharing looked like a hopeless endeavour.
> 
> For now it's only super simplified, no groups, you can't remove
> actions (but kfree exists, we'll need that soon). Plus all specific to
> drm_device ofc, including the logging. Which I didn't bother to make
> compile-time optional, since none of the other drm logging is compile
> time optional either.
> 
> One tricky bit here is the chicken&egg between allocating your
> drm_device structure and initiliazing it with drm_dev_init. For
> perfect onion unwinding we'd need to have the action to kfree the
> allocation registered before drm_dev_init registers any of its own
> release handlers. But drm_dev_init doesn't know where exactly the
> drm_device is emebedded into the overall structure, and by the time it
> returns it'll all be too late. And forcing drivers to be able clean up
> everything except the one kzalloc is silly.
> 
> Work around this by having a very special final_kfree pointer. This
> also avoids troubles with the list head possibly disappearing from
> underneath us when we release all resources attached to the
> drm_device.
> 
> v2: Do all the kerneldoc at the end, to avoid lots of fairly pointless
> shuffling while getting everything into shape.
> 
> v3: Add static to add/del_dr (Neil)
> Move typo fix to the right patch (Neil)
> 
> v4: Enforce contract for drmm_add_final_kfree:
> 
> Use ksize() to check that the drm_device is indeed contained somewhere
> in the final kfree(). Because we need that or the entire managed
> release logic blows up in a pile of use-after-frees. Motivated by a
> discussion with Laurent.
> 
> v5: Review from Laurent:
> - %zu instead of casting size_t
> - header guards
> - sorting of includes
> - guarding of data assignment if we didn't allocate it for a NULL
>   pointer
> - delete spurious newline
> - cast void* data parameter correctly in ->release call, no idea how
>   this even worked before
> 
> v3: Review from Sam
> - Add the kerneldoc for the managed sub-struct back in, even if it
>   doesn't show up in the generated html somehow.
> - Explain why __always_inline.
> - Fix bisectability around the final kfree() in drm_dev_relase(). This
>   is just interim code which will disappear again.
> - Some whitespace polish.
> - Add debug output when drmm_add_action or drmm_kmalloc fail.
> 
> Cc: Sam Ravnborg <sam@ravnborg.org>
> Cc: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
> Cc: Neil Armstrong <narmstrong@baylibre.com
> Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
> Cc: "Rafael J. Wysocki" <rafael@kernel.org>
> Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
> ---
>  Documentation/gpu/drm-internals.rst |   6 +
>  drivers/gpu/drm/Makefile            |   3 +-
>  drivers/gpu/drm/drm_drv.c           |  12 ++
>  drivers/gpu/drm/drm_internal.h      |   3 +
>  drivers/gpu/drm/drm_managed.c       | 186 ++++++++++++++++++++++++++++
>  include/drm/drm_device.h            |  15 +++
>  include/drm/drm_managed.h           |  30 +++++
>  include/drm/drm_print.h             |   6 +
>  8 files changed, 260 insertions(+), 1 deletion(-)
>  create mode 100644 drivers/gpu/drm/drm_managed.c
>  create mode 100644 include/drm/drm_managed.h
> 
> diff --git a/Documentation/gpu/drm-internals.rst b/Documentation/gpu/drm-internals.rst
> index a73320576ca9..a6b6145fda78 100644
> --- a/Documentation/gpu/drm-internals.rst
> +++ b/Documentation/gpu/drm-internals.rst
> @@ -132,6 +132,12 @@ be unmapped; on many devices, the ROM address decoder is shared with
>  other BARs, so leaving it mapped could cause undesired behaviour like
>  hangs or memory corruption.
>  
> +Managed Resources
> +-----------------
> +
> +.. kernel-doc:: drivers/gpu/drm/drm_managed.c
> +   :doc: managed resources
> +
>  Bus-specific Device Registration and PCI Support
>  ------------------------------------------------
>  
> diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile
> index 7f72ef5e7811..183c60048307 100644
> --- a/drivers/gpu/drm/Makefile
> +++ b/drivers/gpu/drm/Makefile
> @@ -17,7 +17,8 @@ drm-y       :=	drm_auth.o drm_cache.o \
>  		drm_plane.o drm_color_mgmt.o drm_print.o \
>  		drm_dumb_buffers.o drm_mode_config.o drm_vblank.o \
>  		drm_syncobj.o drm_lease.o drm_writeback.o drm_client.o \
> -		drm_client_modeset.o drm_atomic_uapi.o drm_hdcp.o
> +		drm_client_modeset.o drm_atomic_uapi.o drm_hdcp.o \
> +		drm_managed.o
>  
>  drm-$(CONFIG_DRM_LEGACY) += drm_legacy_misc.o drm_bufs.o drm_context.o drm_dma.o drm_scatter.o drm_lock.o
>  drm-$(CONFIG_DRM_LIB_RANDOM) += lib/drm_random.o
> diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c
> index 9fcd6ab3c154..153050fc926c 100644
> --- a/drivers/gpu/drm/drm_drv.c
> +++ b/drivers/gpu/drm/drm_drv.c
> @@ -629,6 +629,9 @@ int drm_dev_init(struct drm_device *dev,
>  	dev->dev = get_device(parent);
>  	dev->driver = driver;
>  
> +	INIT_LIST_HEAD(&dev->managed.resources);
> +	spin_lock_init(&dev->managed.lock);
> +
>  	/* no per-device feature limits by default */
>  	dev->driver_features = ~0u;
>  
> @@ -828,8 +831,17 @@ static void drm_dev_release(struct kref *ref)
>  		dev->driver->release(dev);
>  	} else {
>  		drm_dev_fini(dev);
> +	}
> +
> +	drm_managed_release(dev);
> +
> +	if (!dev->driver->release && !dev->managed.final_kfree) {
> +		WARN_ON(!list_empty(&dev->managed.resources));
>  		kfree(dev);
>  	}
> +
> +	if (dev->managed.final_kfree)
> +		kfree(dev->managed.final_kfree);
>  }
>  
>  /**
> diff --git a/drivers/gpu/drm/drm_internal.h b/drivers/gpu/drm/drm_internal.h
> index aeec2e68d772..8c2628dfc6c7 100644
> --- a/drivers/gpu/drm/drm_internal.h
> +++ b/drivers/gpu/drm/drm_internal.h
> @@ -89,6 +89,9 @@ void drm_prime_remove_buf_handle_locked(struct drm_prime_file_private *prime_fpr
>  struct drm_minor *drm_minor_acquire(unsigned int minor_id);
>  void drm_minor_release(struct drm_minor *minor);
>  
> +/* drm_managed.c */
> +void drm_managed_release(struct drm_device *dev);
> +
>  /* drm_vblank.c */
>  void drm_vblank_disable_and_save(struct drm_device *dev, unsigned int pipe);
>  void drm_vblank_cleanup(struct drm_device *dev);
> diff --git a/drivers/gpu/drm/drm_managed.c b/drivers/gpu/drm/drm_managed.c
> new file mode 100644
> index 000000000000..57dc79fa90af
> --- /dev/null
> +++ b/drivers/gpu/drm/drm_managed.c
> @@ -0,0 +1,186 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Copyright (C) 2020 Intel
> + *
> + * Based on drivers/base/devres.c
> + */
> +
> +#include <drm/drm_managed.h>
> +
> +#include <linux/list.h>
> +#include <linux/slab.h>
> +#include <linux/spinlock.h>
> +
> +#include <drm/drm_device.h>
> +#include <drm/drm_print.h>
> +
> +/**
> + * DOC: managed resources
> + *
> + * Inspired by struct &device managed resources, but tied to the lifetime of
> + * struct &drm_device, which can outlive the underlying physical device, usually
> + * when userspace has some open files and other handles to resources still open.
> + */
> +struct drmres_node {
> +	struct list_head	entry;
> +	drmres_release_t	release;
> +	const char		*name;
> +	size_t			size;
> +};

At a later point, we could have debugfs for instances of this data
structure. There's already a name field.

> +
> +struct drmres {
> +	struct drmres_node		node;
> +	/*
> +	 * Some archs want to perform DMA into kmalloc caches
> +	 * and need a guaranteed alignment larger than
> +	 * the alignment of a 64-bit integer.
> +	 * Thus we use ARCH_KMALLOC_MINALIGN here and get exactly the same
> +	 * buffer alignment as if it was allocated by plain kmalloc().
> +	 */
> +	u8 __aligned(ARCH_KMALLOC_MINALIGN) data[];
> +};
> +
> +void drm_managed_release(struct drm_device *dev)
> +{
> +	struct drmres *dr, *tmp;
> +
> +	drm_dbg_drmres(dev, "drmres release begin\n");
> +	list_for_each_entry_safe(dr, tmp, &dev->managed.resources, node.entry) {
> +		drm_dbg_drmres(dev, "REL %p %s (%zu bytes)\n",
> +			       dr, dr->node.name, dr->node.size);
> +
> +		if (dr->node.release)
> +			dr->node.release(dev, dr->node.size ? *(void **)&dr->data : NULL);
> +
> +		list_del(&dr->node.entry);
> +		kfree(dr);
> +	}
> +	drm_dbg_drmres(dev, "drmres release end\n");
> +}
> +
> +/*
> + * Always inline so that kmallc_track_caller tracks the actual interesting

'kmalloc_node_track_caller'

> + * caller outside of drm_managed.c.
> + */
> +static __always_inline struct drmres * alloc_dr(drmres_release_t release,
> +						size_t size, gfp_t gfp, int nid)
> +{
> +	size_t tot_size;
> +	struct drmres *dr;
> +
> +	/* We must catch any near-SIZE_MAX cases that could overflow. */
> +	if (unlikely(check_add_overflow(sizeof(*dr), size, &tot_size)))
> +		return NULL;
> +
> +	dr = kmalloc_node_track_caller(tot_size, gfp, nid);
> +	if (unlikely(!dr))
> +		return NULL;
> +
> +	memset(dr, 0, offsetof(struct drmres, data));
> +
> +	INIT_LIST_HEAD(&dr->node.entry);
> +	dr->node.release = release;
> +	dr->node.size = size;
> +
> +	return dr;
> +}
> +
> +static void del_dr(struct drm_device *dev, struct drmres *dr)
> +{
> +	list_del_init(&dr->node.entry);
> +
> +	drm_dbg_drmres(dev, "DEL %p %s (%lu bytes)\n",
> +		       dr, dr->node.name, (unsigned long) dr->node.size);
> +}
> +
> +static void add_dr(struct drm_device *dev, struct drmres *dr)
> +{
> +	unsigned long flags;
> +
> +	spin_lock_irqsave(&dev->managed.lock, flags);
> +	list_add(&dr->node.entry, &dev->managed.resources);
> +	spin_unlock_irqrestore(&dev->managed.lock, flags);
> +
> +	drm_dbg_drmres(dev, "ADD %p %s (%lu bytes)\n",
> +		       dr, dr->node.name, (unsigned long) dr->node.size);

If the insert code blows up, it might be helpful to have this message in
the log already. So should this message be located before the code for
inserting the entry?

> +}
> +
> +void drmm_add_final_kfree(struct drm_device *dev, void *parent)

Can you come up with better names? 'final_kfree' sounds like a function
pointer to an implementation of kfree() and 'parent' sounds like the
parent device in a device hierarchy.

I suggest to rename 'parent' to 'container' and 'final_kfree'
'drmm_container'. The function's name could be drmm_dev_set_container().

> +{
> +	WARN_ON(dev->managed.final_kfree);
> +	WARN_ON(dev < (struct drm_device *) parent);
> +	WARN_ON(dev + 1 >= (struct drm_device *) (parent + ksize(parent)));
> +	dev->managed.final_kfree = parent;
> +}
> +EXPORT_SYMBOL(drmm_add_final_kfree);
> +
> +int __drmm_add_action(struct drm_device *dev,
> +		      drmres_release_t action,
> +		      void *data, const char *name)

Is there a reason to pass in 'void* data' instead of 'void** datap'? The
latter would communicate what this parameter is for and not need void_ptr.

In any case, there seems to be no interface to remove an added action
(e.g., __drmm_remove_action()). Please see my comment on drmm_kfree() below.

And more generally, do we really need __drmm_add_action() in it's
current form? I'd change it to __drmm_kmalloc(), which is drmm_kmalloc()
plus optional release-action and name parameters. And drm_kmalloc()
would be a simple wrapper in the header file, just like drmm_kcalloc().

> +{
> +	struct drmres *dr;
> +	void **void_ptr;
> +
> +	dr = alloc_dr(action, data ? sizeof(void*) : 0,
> +		      GFP_KERNEL | __GFP_ZERO,
> +		      dev_to_node(dev->dev));
> +	if (!dr) {
> +		drm_dbg_drmres(dev, "failed to add action %s for %p\n",
> +			       name, data);
> +		return -ENOMEM;
> +	}
> +
> +	dr->node.name = name;
> +	if (data) {
> +		void_ptr = (void **)&dr->data;
> +		*void_ptr = data;
> +	}
> +
> +	add_dr(dev, dr);
> +
> +	return 0;
> +}
> +EXPORT_SYMBOL(__drmm_add_action);
> +
> +void *drmm_kmalloc(struct drm_device *dev, size_t size, gfp_t gfp)
> +{
> +	struct drmres *dr;
> +
> +	dr = alloc_dr(NULL, size, gfp, dev_to_node(dev->dev));
> +	if (!dr) {
> +		drm_dbg_drmres(dev, "failed to allocate %zu bytes, %u flags\n",
> +			       size, gfp);
> +		return NULL;
> +	}
> +	dr->node.name = "kmalloc";
> +
> +	add_dr(dev, dr);
> +
> +	return dr->data;
> +}
> +EXPORT_SYMBOL(drmm_kmalloc);
> +
> +void drmm_kfree(struct drm_device *dev, void *data)

I suggest to wrap this function around an implementatian that calls the
optional release action. drmm_kfree() would become a trivial wrapper in
the header file.

Best regards
Thomas

> +{
> +	struct drmres *dr_match = NULL, *dr;
> +	unsigned long flags;
> +
> +	if (!data)
> +		return;
> +
> +	spin_lock_irqsave(&dev->managed.lock, flags);
> +	list_for_each_entry(dr, &dev->managed.resources, node.entry) {
> +		if (dr->data == data) {
> +			dr_match = dr;
> +			del_dr(dev, dr_match);
> +			break;
> +		}
> +	}
> +	spin_unlock_irqrestore(&dev->managed.lock, flags);
> +
> +	if (WARN_ON(!dr_match))
> +		return;
> +
> +	kfree(dr_match);
> +}
> +EXPORT_SYMBOL(drmm_kfree);
> diff --git a/include/drm/drm_device.h b/include/drm/drm_device.h
> index bb60a949f416..d39132b477dd 100644
> --- a/include/drm/drm_device.h
> +++ b/include/drm/drm_device.h
> @@ -67,6 +67,21 @@ struct drm_device {
>  	/** @dev: Device structure of bus-device */
>  	struct device *dev;
>  
> +	/**
> +	 * @managed:
> +	 *
> +	 * Managed resources linked to the lifetime of this &drm_device as
> +	 * tracked by @ref.
> +	 */
> +	struct {
> +		/** @managed.resources: managed resources list */
> +		struct list_head resources;
> +		/** @managed.final_kfree: pointer for final kfree() call */
> +		void *final_kfree;
> +		/** @managed.lock: protects @managed.resources */
> +		spinlock_t lock;
> +	} managed;
> +
>  	/** @driver: DRM driver managing the device */
>  	struct drm_driver *driver;
>  
> diff --git a/include/drm/drm_managed.h b/include/drm/drm_managed.h
> new file mode 100644
> index 000000000000..7b5df7d09b19
> --- /dev/null
> +++ b/include/drm/drm_managed.h
> @@ -0,0 +1,30 @@
> +// SPDX-License-Identifier: GPL-2.0
> +
> +#ifndef _DRM_MANAGED_H_
> +#define _DRM_MANAGED_H_
> +
> +#include <linux/gfp.h>
> +#include <linux/types.h>
> +
> +struct drm_device;
> +
> +typedef void (*drmres_release_t)(struct drm_device *dev, void *res);
> +
> +#define drmm_add_action(dev, action, data) \
> +	__drmm_add_action(dev, action, data, #action)
> +
> +int __must_check __drmm_add_action(struct drm_device *dev,
> +				   drmres_release_t action,
> +				   void *data, const char *name);
> +
> +void drmm_add_final_kfree(struct drm_device *dev, void *parent);
> +
> +void *drmm_kmalloc(struct drm_device *dev, size_t size, gfp_t gfp) __malloc;
> +static inline void *drmm_kzalloc(struct drm_device *dev, size_t size, gfp_t gfp)
> +{
> +	return drmm_kmalloc(dev, size, gfp | __GFP_ZERO);
> +}
> +
> +void drmm_kfree(struct drm_device *dev, void *data);
> +
> +#endif
> diff --git a/include/drm/drm_print.h b/include/drm/drm_print.h
> index ca7cee8e728a..1c9417430d08 100644
> --- a/include/drm/drm_print.h
> +++ b/include/drm/drm_print.h
> @@ -313,6 +313,10 @@ enum drm_debug_category {
>  	 * @DRM_UT_DP: Used in the DP code.
>  	 */
>  	DRM_UT_DP		= 0x100,
> +	/**
> +	 * @DRM_UT_DRMRES: Used in the drm managed resources code.
> +	 */
> +	DRM_UT_DRMRES		= 0x200,
>  };
>  
>  static inline bool drm_debug_enabled(enum drm_debug_category category)
> @@ -442,6 +446,8 @@ void drm_dev_dbg(const struct device *dev, enum drm_debug_category category,
>  	drm_dev_dbg((drm)->dev, DRM_UT_LEASE, fmt, ##__VA_ARGS__)
>  #define drm_dbg_dp(drm, fmt, ...)					\
>  	drm_dev_dbg((drm)->dev, DRM_UT_DP, fmt, ##__VA_ARGS__)
> +#define drm_dbg_drmres(drm, fmt, ...)					\
> +	drm_dev_dbg((drm)->dev, DRM_UT_DRMRES, fmt, ##__VA_ARGS__)
>  
>  
>  /*
> 

-- 
Thomas Zimmermann
Graphics Driver Developer
SUSE Software Solutions Germany GmbH
Maxfeldstr. 5, 90409 Nürnberg, Germany
(HRB 36809, AG Nürnberg)
Geschäftsführer: Felix Imendörffer


[-- Attachment #1.2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

[-- Attachment #2: Type: text/plain, Size: 160 bytes --]

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 111+ messages in thread

* Re: [PATCH 04/51] drm: Set final_kfree in drm_dev_alloc
  2020-03-02 22:25 ` [PATCH 04/51] drm: Set final_kfree in drm_dev_alloc Daniel Vetter
  2020-03-03  7:44   ` Gerd Hoffmann
  2020-03-07  8:06   ` Sam Ravnborg
@ 2020-03-11  9:09   ` Thomas Zimmermann
  2 siblings, 0 replies; 111+ messages in thread
From: Thomas Zimmermann @ 2020-03-11  9:09 UTC (permalink / raw)
  To: Daniel Vetter, DRI Development
  Cc: Oleksandr Andrushchenko, David Airlie,
	Intel Graphics Development, Gerd Hoffmann, Daniel Vetter,
	xen-devel


[-- Attachment #1.1.1: Type: text/plain, Size: 3260 bytes --]



Am 02.03.20 um 23:25 schrieb Daniel Vetter:
> I also did a full review of all callers, and only the xen driver
> forgot to call drm_dev_put in the failure path. Fix that up too.
> 
> v2: I noticed that xen has a drm_driver.release hook, and uses
> drm_dev_alloc(). We need to remove the kfree from
> xen_drm_drv_release().
> 
> bochs also has a release hook, but leaked the drm_device ever since
> 
> commit 0a6659bdc5e8221da99eebb176fd9591435e38de
> Author: Gerd Hoffmann <kraxel@redhat.com>
> Date:   Tue Dec 17 18:04:46 2013 +0100
> 
>     drm/bochs: new driver
> 
> This patch here fixes that leak.
> 
> Same for virtio, started leaking with
> 
> commit b1df3a2b24a917f8853d43fe9683c0e360d2c33a
> Author: Gerd Hoffmann <kraxel@redhat.com>
> Date:   Tue Feb 11 14:58:04 2020 +0100
> 
>     drm/virtio: add drm_driver.release callback.
> 
> Cc: Gerd Hoffmann <kraxel@redhat.com>
> Cc: Oleksandr Andrushchenko <oleksandr_andrushchenko@epam.com>
> Cc: xen-devel@lists.xenproject.org
> 
> Reviewed-by: Oleksandr Andrushchenko <oleksandr_andrushchenko@epam.com>
> Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>

Acked-by: Thomas Zimmermann <tzimmermann@suse.de>

> Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
> Cc: Maxime Ripard <mripard@kernel.org>
> Cc: Thomas Zimmermann <tzimmermann@suse.de>
> Cc: David Airlie <airlied@linux.ie>
> Cc: Daniel Vetter <daniel@ffwll.ch>
> Cc: Oleksandr Andrushchenko <oleksandr_andrushchenko@epam.com>
> Cc: xen-devel@lists.xenproject.org
> ---
>  drivers/gpu/drm/drm_drv.c           | 3 +++
>  drivers/gpu/drm/xen/xen_drm_front.c | 2 +-
>  2 files changed, 4 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c
> index 153050fc926c..7b84ee8a5eb5 100644
> --- a/drivers/gpu/drm/drm_drv.c
> +++ b/drivers/gpu/drm/drm_drv.c
> @@ -39,6 +39,7 @@
>  #include <drm/drm_color_mgmt.h>
>  #include <drm/drm_drv.h>
>  #include <drm/drm_file.h>
> +#include <drm/drm_managed.h>
>  #include <drm/drm_mode_object.h>
>  #include <drm/drm_print.h>
>  
> @@ -819,6 +820,8 @@ struct drm_device *drm_dev_alloc(struct drm_driver *driver,
>  		return ERR_PTR(ret);
>  	}
>  
> +	drmm_add_final_kfree(dev, dev);
> +
>  	return dev;
>  }
>  EXPORT_SYMBOL(drm_dev_alloc);
> diff --git a/drivers/gpu/drm/xen/xen_drm_front.c b/drivers/gpu/drm/xen/xen_drm_front.c
> index 4be49c1aef51..d22b5da38935 100644
> --- a/drivers/gpu/drm/xen/xen_drm_front.c
> +++ b/drivers/gpu/drm/xen/xen_drm_front.c
> @@ -461,7 +461,6 @@ static void xen_drm_drv_release(struct drm_device *dev)
>  	drm_mode_config_cleanup(dev);
>  
>  	drm_dev_fini(dev);
> -	kfree(dev);
>  
>  	if (front_info->cfg.be_alloc)
>  		xenbus_switch_state(front_info->xb_dev,
> @@ -561,6 +560,7 @@ static int xen_drm_drv_init(struct xen_drm_front_info *front_info)
>  fail_modeset:
>  	drm_kms_helper_poll_fini(drm_dev);
>  	drm_mode_config_cleanup(drm_dev);
> +	drm_dev_put(drm_dev);
>  fail:
>  	kfree(drm_info);
>  	return ret;
> 

-- 
Thomas Zimmermann
Graphics Driver Developer
SUSE Software Solutions Germany GmbH
Maxfeldstr. 5, 90409 Nürnberg, Germany
(HRB 36809, AG Nürnberg)
Geschäftsführer: Felix Imendörffer


[-- Attachment #1.2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

[-- Attachment #2: Type: text/plain, Size: 160 bytes --]

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 111+ messages in thread

* Re: [PATCH 06/51] drm/udl: Use drmm_add_final_kfree
  2020-03-02 22:25 ` [PATCH 06/51] drm/udl: Use drmm_add_final_kfree Daniel Vetter
@ 2020-03-11  9:10   ` Thomas Zimmermann
  0 siblings, 0 replies; 111+ messages in thread
From: Thomas Zimmermann @ 2020-03-11  9:10 UTC (permalink / raw)
  To: Daniel Vetter, DRI Development
  Cc: Sam Ravnborg, Intel Graphics Development, Emil Velikov,
	Laurent Pinchart, Dave Airlie, Daniel Vetter, Thomas Gleixner,
	Sean Paul


[-- Attachment #1.1.1: Type: text/plain, Size: 2252 bytes --]



Am 02.03.20 um 23:25 schrieb Daniel Vetter:
> With this we can drop the final kfree from the release function.
> 
> v2: We need drm_dev_put to unroll the driver creation (once
> drm_dev_init and drmm_add_final_kfree suceeded), otherwise
> the drmm_ magic doesn't happen.
> 
> v3: Actually squash in the fixup (Laurent).
> 
> Acked-by: Sam Ravnborg <sam@ravnborg.org>
> Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>

Acked-by: Thomas Zimmermann <tzimmermann@suse.de>

> Cc: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
> Cc: Dave Airlie <airlied@redhat.com>
> Cc: Sean Paul <sean@poorly.run>
> Cc: Thomas Zimmermann <tzimmermann@suse.de>
> Cc: Emil Velikov <emil.l.velikov@gmail.com>
> Cc: Daniel Vetter <daniel.vetter@ffwll.ch>
> Cc: "Noralf Trønnes" <noralf@tronnes.org>
> Cc: Thomas Gleixner <tglx@linutronix.de>
> Cc: Sam Ravnborg <sam@ravnborg.org>
> ---
>  drivers/gpu/drm/udl/udl_drv.c | 6 +++---
>  1 file changed, 3 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/gpu/drm/udl/udl_drv.c b/drivers/gpu/drm/udl/udl_drv.c
> index e6c1cd77d4d4..6a5594946096 100644
> --- a/drivers/gpu/drm/udl/udl_drv.c
> +++ b/drivers/gpu/drm/udl/udl_drv.c
> @@ -10,6 +10,7 @@
>  #include <drm/drm_fb_helper.h>
>  #include <drm/drm_file.h>
>  #include <drm/drm_gem_shmem_helper.h>
> +#include <drm/drm_managed.h>
>  #include <drm/drm_ioctl.h>
>  #include <drm/drm_probe_helper.h>
>  #include <drm/drm_print.h>
> @@ -38,7 +39,6 @@ static void udl_driver_release(struct drm_device *dev)
>  	udl_fini(dev);
>  	udl_modeset_cleanup(dev);
>  	drm_dev_fini(dev);
> -	kfree(dev);
>  }
>  
>  static struct drm_driver driver = {
> @@ -77,11 +77,11 @@ static struct udl_device *udl_driver_create(struct usb_interface *interface)
>  
>  	udl->udev = udev;
>  	udl->drm.dev_private = udl;
> +	drmm_add_final_kfree(&udl->drm, udl);
>  
>  	r = udl_init(udl);
>  	if (r) {
> -		drm_dev_fini(&udl->drm);
> -		kfree(udl);
> +		drm_dev_put(&udl->drm);
>  		return ERR_PTR(r);
>  	}
>  
> 

-- 
Thomas Zimmermann
Graphics Driver Developer
SUSE Software Solutions Germany GmbH
Maxfeldstr. 5, 90409 Nürnberg, Germany
(HRB 36809, AG Nürnberg)
Geschäftsführer: Felix Imendörffer


[-- Attachment #1.2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

[-- Attachment #2: Type: text/plain, Size: 160 bytes --]

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 111+ messages in thread

* Re: [PATCH 03/51] drm: add managed resources tied to drm_device
  2020-03-02 22:25 ` [PATCH 03/51] drm: add managed resources tied to drm_device Daniel Vetter
                     ` (2 preceding siblings ...)
  2020-03-11  9:07   ` [PATCH 03/51] " Thomas Zimmermann
@ 2020-03-11  9:14   ` Thomas Zimmermann
  2020-03-16  8:50     ` Daniel Vetter
  3 siblings, 1 reply; 111+ messages in thread
From: Thomas Zimmermann @ 2020-03-11  9:14 UTC (permalink / raw)
  To: Daniel Vetter, DRI Development
  Cc: Rafael J. Wysocki, Greg Kroah-Hartman,
	Intel Graphics Development, Laurent Pinchart, Daniel Vetter,
	Sam Ravnborg


[-- Attachment #1.1.1: Type: text/plain, Size: 4900 bytes --]



Am 02.03.20 um 23:25 schrieb Daniel Vetter:
<...>
> +
> +int __drmm_add_action(struct drm_device *dev,
> +		      drmres_release_t action,
> +		      void *data, const char *name)
> +{
> +	struct drmres *dr;
> +	void **void_ptr;
> +
> +	dr = alloc_dr(action, data ? sizeof(void*) : 0,
> +		      GFP_KERNEL | __GFP_ZERO,
> +		      dev_to_node(dev->dev));
> +	if (!dr) {
> +		drm_dbg_drmres(dev, "failed to add action %s for %p\n",
> +			       name, data);
> +		return -ENOMEM;
> +	}
> +
> +	dr->node.name = name;

Maybe do a kstrdup_const() on name and later a kfree_const() during
release. Just in case someone decides to allocate 'name' dynamically.

> +	if (data) {
> +		void_ptr = (void **)&dr->data;
> +		*void_ptr = data;
> +	}
> +
> +	add_dr(dev, dr);
> +
> +	return 0;
> +}
> +EXPORT_SYMBOL(__drmm_add_action);
> +
> +void *drmm_kmalloc(struct drm_device *dev, size_t size, gfp_t gfp)
> +{
> +	struct drmres *dr;
> +
> +	dr = alloc_dr(NULL, size, gfp, dev_to_node(dev->dev));
> +	if (!dr) {
> +		drm_dbg_drmres(dev, "failed to allocate %zu bytes, %u flags\n",
> +			       size, gfp);
> +		return NULL;
> +	}
> +	dr->node.name = "kmalloc";
> +
> +	add_dr(dev, dr);
> +
> +	return dr->data;
> +}
> +EXPORT_SYMBOL(drmm_kmalloc);
> +
> +void drmm_kfree(struct drm_device *dev, void *data)
> +{
> +	struct drmres *dr_match = NULL, *dr;
> +	unsigned long flags;
> +
> +	if (!data)
> +		return;
> +
> +	spin_lock_irqsave(&dev->managed.lock, flags);
> +	list_for_each_entry(dr, &dev->managed.resources, node.entry) {
> +		if (dr->data == data) {
> +			dr_match = dr;
> +			del_dr(dev, dr_match);
> +			break;
> +		}
> +	}
> +	spin_unlock_irqrestore(&dev->managed.lock, flags);
> +
> +	if (WARN_ON(!dr_match))
> +		return;
> +
> +	kfree(dr_match);
> +}
> +EXPORT_SYMBOL(drmm_kfree);
> diff --git a/include/drm/drm_device.h b/include/drm/drm_device.h
> index bb60a949f416..d39132b477dd 100644
> --- a/include/drm/drm_device.h
> +++ b/include/drm/drm_device.h
> @@ -67,6 +67,21 @@ struct drm_device {
>  	/** @dev: Device structure of bus-device */
>  	struct device *dev;
>  
> +	/**
> +	 * @managed:
> +	 *
> +	 * Managed resources linked to the lifetime of this &drm_device as
> +	 * tracked by @ref.
> +	 */
> +	struct {
> +		/** @managed.resources: managed resources list */
> +		struct list_head resources;
> +		/** @managed.final_kfree: pointer for final kfree() call */
> +		void *final_kfree;
> +		/** @managed.lock: protects @managed.resources */
> +		spinlock_t lock;
> +	} managed;
> +
>  	/** @driver: DRM driver managing the device */
>  	struct drm_driver *driver;
>  
> diff --git a/include/drm/drm_managed.h b/include/drm/drm_managed.h
> new file mode 100644
> index 000000000000..7b5df7d09b19
> --- /dev/null
> +++ b/include/drm/drm_managed.h
> @@ -0,0 +1,30 @@
> +// SPDX-License-Identifier: GPL-2.0
> +
> +#ifndef _DRM_MANAGED_H_
> +#define _DRM_MANAGED_H_
> +
> +#include <linux/gfp.h>
> +#include <linux/types.h>
> +
> +struct drm_device;
> +
> +typedef void (*drmres_release_t)(struct drm_device *dev, void *res);
> +
> +#define drmm_add_action(dev, action, data) \
> +	__drmm_add_action(dev, action, data, #action)
> +
> +int __must_check __drmm_add_action(struct drm_device *dev,
> +				   drmres_release_t action,
> +				   void *data, const char *name);
> +
> +void drmm_add_final_kfree(struct drm_device *dev, void *parent);
> +
> +void *drmm_kmalloc(struct drm_device *dev, size_t size, gfp_t gfp) __malloc;
> +static inline void *drmm_kzalloc(struct drm_device *dev, size_t size, gfp_t gfp)
> +{
> +	return drmm_kmalloc(dev, size, gfp | __GFP_ZERO);
> +}
> +
> +void drmm_kfree(struct drm_device *dev, void *data);
> +
> +#endif
> diff --git a/include/drm/drm_print.h b/include/drm/drm_print.h
> index ca7cee8e728a..1c9417430d08 100644
> --- a/include/drm/drm_print.h
> +++ b/include/drm/drm_print.h
> @@ -313,6 +313,10 @@ enum drm_debug_category {
>  	 * @DRM_UT_DP: Used in the DP code.
>  	 */
>  	DRM_UT_DP		= 0x100,
> +	/**
> +	 * @DRM_UT_DRMRES: Used in the drm managed resources code.
> +	 */
> +	DRM_UT_DRMRES		= 0x200,
>  };
>  
>  static inline bool drm_debug_enabled(enum drm_debug_category category)
> @@ -442,6 +446,8 @@ void drm_dev_dbg(const struct device *dev, enum drm_debug_category category,
>  	drm_dev_dbg((drm)->dev, DRM_UT_LEASE, fmt, ##__VA_ARGS__)
>  #define drm_dbg_dp(drm, fmt, ...)					\
>  	drm_dev_dbg((drm)->dev, DRM_UT_DP, fmt, ##__VA_ARGS__)
> +#define drm_dbg_drmres(drm, fmt, ...)					\
> +	drm_dev_dbg((drm)->dev, DRM_UT_DRMRES, fmt, ##__VA_ARGS__)
>  
>  
>  /*
> 

-- 
Thomas Zimmermann
Graphics Driver Developer
SUSE Software Solutions Germany GmbH
Maxfeldstr. 5, 90409 Nürnberg, Germany
(HRB 36809, AG Nürnberg)
Geschäftsführer: Felix Imendörffer


[-- Attachment #1.2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

[-- Attachment #2: Type: text/plain, Size: 160 bytes --]

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 111+ messages in thread

* Re: [PATCH 19/51] drm: Cleanups after drmm_add_final_kfree rollout
  2020-03-02 22:25 ` [PATCH 19/51] drm: Cleanups after drmm_add_final_kfree rollout Daniel Vetter
  2020-03-03  8:45   ` [PATCH] " Daniel Vetter
  2020-03-06 20:29   ` [PATCH 19/51] " Sam Ravnborg
@ 2020-03-11  9:15   ` Thomas Zimmermann
  2 siblings, 0 replies; 111+ messages in thread
From: Thomas Zimmermann @ 2020-03-11  9:15 UTC (permalink / raw)
  To: Daniel Vetter, DRI Development; +Cc: Daniel Vetter, Intel Graphics Development


[-- Attachment #1.1.1: Type: text/plain, Size: 1864 bytes --]



Am 02.03.20 um 23:25 schrieb Daniel Vetter:
> A few things:
> - Update the example driver in the documentation.
> - We can drop the old kfree in drm_dev_release.
> - Add a WARN_ON check in drm_dev_register to make sure everyone calls
>   drmm_add_final_kfree and there's no leaks.
> 
> Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>

Acked-by: Thomas Zimmermann <tzimmermann@suse.de>

> ---
>  drivers/gpu/drm/drm_drv.c | 7 ++++---
>  1 file changed, 4 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c
> index 7b84ee8a5eb5..1a048325f30e 100644
> --- a/drivers/gpu/drm/drm_drv.c
> +++ b/drivers/gpu/drm/drm_drv.c
> @@ -297,8 +297,6 @@ void drm_minor_release(struct drm_minor *minor)
>   *
>   *		drm_mode_config_cleanup(drm);
>   *		drm_dev_fini(drm);
> - *		kfree(priv->userspace_facing);
> - *		kfree(priv);
>   *	}
>   *
>   *	static struct drm_driver driver_drm_driver = {
> @@ -326,10 +324,11 @@ void drm_minor_release(struct drm_minor *minor)
>   *			kfree(drm);
>   *			return ret;
>   *		}
> + *		drmm_add_final_kfree(drm, priv);
>   *
>   *		drm_mode_config_init(drm);
>   *
> - *		priv->userspace_facing = kzalloc(..., GFP_KERNEL);
> + *		priv->userspace_facing = drmm_kzalloc(..., GFP_KERNEL);
>   *		if (!priv->userspace_facing)
>   *			return -ENOMEM;
>   *
> @@ -961,6 +960,8 @@ int drm_dev_register(struct drm_device *dev, unsigned long flags)
>  	struct drm_driver *driver = dev->driver;
>  	int ret;
>  
> +	WARN_ON(!dev->managed.final_kfree);
> +
>  	if (drm_dev_needs_global_mutex(dev))
>  		mutex_lock(&drm_global_mutex);
>  
> 

-- 
Thomas Zimmermann
Graphics Driver Developer
SUSE Software Solutions Germany GmbH
Maxfeldstr. 5, 90409 Nürnberg, Germany
(HRB 36809, AG Nürnberg)
Geschäftsführer: Felix Imendörffer


[-- Attachment #1.2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

[-- Attachment #2: Type: text/plain, Size: 160 bytes --]

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 111+ messages in thread

* Re: [PATCH 20/51] drm: Handle dev->unique with drmm_
  2020-03-02 22:26 ` [PATCH 20/51] drm: Handle dev->unique with drmm_ Daniel Vetter
  2020-03-06 20:37   ` Sam Ravnborg
@ 2020-03-11  9:19   ` Thomas Zimmermann
  1 sibling, 0 replies; 111+ messages in thread
From: Thomas Zimmermann @ 2020-03-11  9:19 UTC (permalink / raw)
  To: Daniel Vetter, DRI Development; +Cc: Daniel Vetter, Intel Graphics Development


[-- Attachment #1.1.1: Type: text/plain, Size: 2810 bytes --]



Am 02.03.20 um 23:26 schrieb Daniel Vetter:
> We need to add a drmm_kstrdup for this, but let's start somewhere.
> 
> This is not exactly perfect onion unwinding, but it's jsut a kfree so
> doesn't really matter at all.
> 
> Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>

Acked-by: Thomas Zimmermann <tzimmermann@suse.de>

> ---
>  drivers/gpu/drm/drm_drv.c     |  5 ++---
>  drivers/gpu/drm/drm_managed.c | 16 ++++++++++++++++
>  include/drm/drm_managed.h     |  1 +
>  3 files changed, 19 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c
> index 1a048325f30e..ef79c03e311c 100644
> --- a/drivers/gpu/drm/drm_drv.c
> +++ b/drivers/gpu/drm/drm_drv.c
> @@ -777,7 +777,6 @@ void drm_dev_fini(struct drm_device *dev)
>  	mutex_destroy(&dev->filelist_mutex);
>  	mutex_destroy(&dev->struct_mutex);
>  	drm_legacy_destroy_members(dev);
> -	kfree(dev->unique);
>  }
>  EXPORT_SYMBOL(drm_dev_fini);
>  
> @@ -1068,8 +1067,8 @@ EXPORT_SYMBOL(drm_dev_unregister);
>   */
>  int drm_dev_set_unique(struct drm_device *dev, const char *name)
>  {
> -	kfree(dev->unique);
> -	dev->unique = kstrdup(name, GFP_KERNEL);
> +	drmm_kfree(dev, dev->unique);
> +	dev->unique = drmm_kstrdup(dev, name, GFP_KERNEL);
>  
>  	return dev->unique ? 0 : -ENOMEM;
>  }
> diff --git a/drivers/gpu/drm/drm_managed.c b/drivers/gpu/drm/drm_managed.c
> index 57dc79fa90af..514d5bd42446 100644
> --- a/drivers/gpu/drm/drm_managed.c
> +++ b/drivers/gpu/drm/drm_managed.c
> @@ -160,6 +160,22 @@ void *drmm_kmalloc(struct drm_device *dev, size_t size, gfp_t gfp)
>  }
>  EXPORT_SYMBOL(drmm_kmalloc);
>  
> +char *drmm_kstrdup(struct drm_device *dev, const char *s, gfp_t gfp)
> +{
> +	size_t size;
> +	char *buf;
> +
> +	if (!s)
> +		return NULL;
> +
> +	size = strlen(s) + 1;
> +	buf = drmm_kmalloc(dev, size, gfp);
> +	if (buf)
> +		memcpy(buf, s, size);
> +	return buf;
> +}
> +EXPORT_SYMBOL_GPL(drmm_kstrdup);
> +
>  void drmm_kfree(struct drm_device *dev, void *data)
>  {
>  	struct drmres *dr_match = NULL, *dr;
> diff --git a/include/drm/drm_managed.h b/include/drm/drm_managed.h
> index 7b5df7d09b19..89e6fce9f689 100644
> --- a/include/drm/drm_managed.h
> +++ b/include/drm/drm_managed.h
> @@ -24,6 +24,7 @@ static inline void *drmm_kzalloc(struct drm_device *dev, size_t size, gfp_t gfp)
>  {
>  	return drmm_kmalloc(dev, size, gfp | __GFP_ZERO);
>  }
> +char *drmm_kstrdup(struct drm_device *dev, const char *s, gfp_t gfp);
>  
>  void drmm_kfree(struct drm_device *dev, void *data);
>  
> 

-- 
Thomas Zimmermann
Graphics Driver Developer
SUSE Software Solutions Germany GmbH
Maxfeldstr. 5, 90409 Nürnberg, Germany
(HRB 36809, AG Nürnberg)
Geschäftsführer: Felix Imendörffer


[-- Attachment #1.2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

[-- Attachment #2: Type: text/plain, Size: 160 bytes --]

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 111+ messages in thread

* Re: [PATCH 21/51] drm: Use drmm_ for drm_dev_init cleanup
  2020-03-02 22:26 ` [PATCH 21/51] drm: Use drmm_ for drm_dev_init cleanup Daniel Vetter
@ 2020-03-11  9:39   ` Thomas Zimmermann
  2020-03-16  9:02     ` Daniel Vetter
  0 siblings, 1 reply; 111+ messages in thread
From: Thomas Zimmermann @ 2020-03-11  9:39 UTC (permalink / raw)
  To: Daniel Vetter, DRI Development; +Cc: Daniel Vetter, Intel Graphics Development


[-- Attachment #1.1.1: Type: text/plain, Size: 4620 bytes --]

Hi

Am 02.03.20 um 23:26 schrieb Daniel Vetter:
> Well for the simple stuff at least, vblank, gem and minor cleanup I
> want to further split up as a demonstration.
> 
> v2: We need to clear drm_device->dev otherwise the debug drm printing
> after our cleanup hook (e.g. in drm_manged_release) will chase
> released memory and result in a use-after-free. Not really pretty, but
> oh well.
> 
> Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
> ---
>  drivers/gpu/drm/drm_drv.c | 48 ++++++++++++++++++++-------------------
>  1 file changed, 25 insertions(+), 23 deletions(-)
> 
> diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c
> index ef79c03e311c..23e5b0e7e041 100644
> --- a/drivers/gpu/drm/drm_drv.c
> +++ b/drivers/gpu/drm/drm_drv.c
> @@ -580,6 +580,23 @@ static void drm_fs_inode_free(struct inode *inode)
>   *    used.
>   */
>  
> +static void drm_dev_init_release(struct drm_device *dev, void *res)
> +{
> +	drm_legacy_ctxbitmap_cleanup(dev);
> +	drm_legacy_remove_map_hash(dev);
> +	drm_fs_inode_free(dev->anon_inode);
> +
> +	put_device(dev->dev);
> +	/* Prevent use-after-free in drm_managed_release when debugging is
> +	 * enabled. Slightly awkward, but can't really be helped. */
> +	dev->dev = NULL;
> +	mutex_destroy(&dev->master_mutex);
> +	mutex_destroy(&dev->clientlist_mutex);
> +	mutex_destroy(&dev->filelist_mutex);
> +	mutex_destroy(&dev->struct_mutex);
> +	drm_legacy_destroy_members(dev);
> +}
> +
>  /**
>   * drm_dev_init - Initialise new DRM device
>   * @dev: DRM device
> @@ -647,11 +664,15 @@ int drm_dev_init(struct drm_device *dev,
>  	mutex_init(&dev->clientlist_mutex);
>  	mutex_init(&dev->master_mutex);
>  
> +	ret = drmm_add_action(dev, drm_dev_init_release, NULL);
> +	if (ret)
> +		return ret;
> +

Is this code supposed to stay for the long term? As devices are
allocated dynamically, I can imagine that there will be a call that
allocates the memory and, at the same time, sets drm_dev_init_release()
as the release callback.

The question is also released to patch 3, where I proposed to rename
__drm_add_action() to __drmm_kzalloc().

>  	dev->anon_inode = drm_fs_inode_new();
>  	if (IS_ERR(dev->anon_inode)) {
>  		ret = PTR_ERR(dev->anon_inode);
>  		DRM_ERROR("Cannot allocate anonymous inode: %d\n", ret);
> -		goto err_free;
> +		goto err;
>  	}
>  
>  	if (drm_core_check_feature(dev, DRIVER_RENDER)) {
> @@ -688,19 +709,12 @@ int drm_dev_init(struct drm_device *dev,
>  	if (drm_core_check_feature(dev, DRIVER_GEM))
>  		drm_gem_destroy(dev);
>  err_ctxbitmap:
> -	drm_legacy_ctxbitmap_cleanup(dev);
> -	drm_legacy_remove_map_hash(dev);
>  err_minors:
>  	drm_minor_free(dev, DRM_MINOR_PRIMARY);
>  	drm_minor_free(dev, DRM_MINOR_RENDER);
> -	drm_fs_inode_free(dev->anon_inode);
> -err_free:
> -	put_device(dev->dev);
> -	mutex_destroy(&dev->master_mutex);
> -	mutex_destroy(&dev->clientlist_mutex);
> -	mutex_destroy(&dev->filelist_mutex);
> -	mutex_destroy(&dev->struct_mutex);
> -	drm_legacy_destroy_members(dev);
> +err:
> +	drm_managed_release(dev);
> +

Here's more of a general observation than a comment on the actual patch:

One odd thing about the overall interface is that there's no way of
updating the release callback afterwards. In an OOP language, such as
C++, an error within the constructor would rollback the performed
actions and return without calling the destructor. Destructors only run
for fully constructed objects.

In our case, the equivalent is to run the init function and set
drm_dev_init_release() as the final step. The init's rollback-code would
have to stay, obviously.

Best regards
Thomas

>  	return ret;
>  }
>  EXPORT_SYMBOL(drm_dev_init);
> @@ -763,20 +777,8 @@ void drm_dev_fini(struct drm_device *dev)
>  	if (drm_core_check_feature(dev, DRIVER_GEM))
>  		drm_gem_destroy(dev);
>  
> -	drm_legacy_ctxbitmap_cleanup(dev);
> -	drm_legacy_remove_map_hash(dev);
> -	drm_fs_inode_free(dev->anon_inode);
> -
>  	drm_minor_free(dev, DRM_MINOR_PRIMARY);
>  	drm_minor_free(dev, DRM_MINOR_RENDER);
> -
> -	put_device(dev->dev);
> -
> -	mutex_destroy(&dev->master_mutex);
> -	mutex_destroy(&dev->clientlist_mutex);
> -	mutex_destroy(&dev->filelist_mutex);
> -	mutex_destroy(&dev->struct_mutex);
> -	drm_legacy_destroy_members(dev);
>  }
>  EXPORT_SYMBOL(drm_dev_fini);
>  
> 

-- 
Thomas Zimmermann
Graphics Driver Developer
SUSE Software Solutions Germany GmbH
Maxfeldstr. 5, 90409 Nürnberg, Germany
(HRB 36809, AG Nürnberg)
Geschäftsführer: Felix Imendörffer


[-- Attachment #1.2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

[-- Attachment #2: Type: text/plain, Size: 160 bytes --]

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 111+ messages in thread

* Re: [PATCH 03/51] drm: add managed resources tied to drm_device
  2020-03-11  9:07   ` [PATCH 03/51] " Thomas Zimmermann
@ 2020-03-11  9:47     ` Thomas Zimmermann
  2020-03-16  8:45     ` Daniel Vetter
  1 sibling, 0 replies; 111+ messages in thread
From: Thomas Zimmermann @ 2020-03-11  9:47 UTC (permalink / raw)
  To: Daniel Vetter, DRI Development
  Cc: Rafael J. Wysocki, Greg Kroah-Hartman,
	Intel Graphics Development, Laurent Pinchart, Daniel Vetter,
	Sam Ravnborg


[-- Attachment #1.1.1: Type: text/plain, Size: 17698 bytes --]



Am 11.03.20 um 10:07 schrieb Thomas Zimmermann:
> Hi Daniel
> 
> Am 02.03.20 um 23:25 schrieb Daniel Vetter:
>> We have lots of these. And the cleanup code tends to be of dubious
>> quality. The biggest wrong pattern is that developers use devm_, which
>> ties the release action to the underlying struct device, whereas
>> all the userspace visible stuff attached to a drm_device can long
>> outlive that one (e.g. after a hotunplug while userspace has open
>> files and mmap'ed buffers). Give people what they want, but with more
>> correctness.
>>
>> Mostly copied from devres.c, with types adjusted to fit drm_device and
>> a few simplifications - I didn't (yet) copy over everything. Since
>> the types don't match code sharing looked like a hopeless endeavour.
>>
>> For now it's only super simplified, no groups, you can't remove
>> actions (but kfree exists, we'll need that soon). Plus all specific to
>> drm_device ofc, including the logging. Which I didn't bother to make
>> compile-time optional, since none of the other drm logging is compile
>> time optional either.
>>
>> One tricky bit here is the chicken&egg between allocating your
>> drm_device structure and initiliazing it with drm_dev_init. For
>> perfect onion unwinding we'd need to have the action to kfree the
>> allocation registered before drm_dev_init registers any of its own
>> release handlers. But drm_dev_init doesn't know where exactly the
>> drm_device is emebedded into the overall structure, and by the time it
>> returns it'll all be too late. And forcing drivers to be able clean up
>> everything except the one kzalloc is silly.
>>
>> Work around this by having a very special final_kfree pointer. This
>> also avoids troubles with the list head possibly disappearing from
>> underneath us when we release all resources attached to the
>> drm_device.
>>
>> v2: Do all the kerneldoc at the end, to avoid lots of fairly pointless
>> shuffling while getting everything into shape.
>>
>> v3: Add static to add/del_dr (Neil)
>> Move typo fix to the right patch (Neil)
>>
>> v4: Enforce contract for drmm_add_final_kfree:
>>
>> Use ksize() to check that the drm_device is indeed contained somewhere
>> in the final kfree(). Because we need that or the entire managed
>> release logic blows up in a pile of use-after-frees. Motivated by a
>> discussion with Laurent.
>>
>> v5: Review from Laurent:
>> - %zu instead of casting size_t
>> - header guards
>> - sorting of includes
>> - guarding of data assignment if we didn't allocate it for a NULL
>>   pointer
>> - delete spurious newline
>> - cast void* data parameter correctly in ->release call, no idea how
>>   this even worked before
>>
>> v3: Review from Sam
>> - Add the kerneldoc for the managed sub-struct back in, even if it
>>   doesn't show up in the generated html somehow.
>> - Explain why __always_inline.
>> - Fix bisectability around the final kfree() in drm_dev_relase(). This
>>   is just interim code which will disappear again.
>> - Some whitespace polish.
>> - Add debug output when drmm_add_action or drmm_kmalloc fail.
>>
>> Cc: Sam Ravnborg <sam@ravnborg.org>
>> Cc: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
>> Cc: Neil Armstrong <narmstrong@baylibre.com
>> Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
>> Cc: "Rafael J. Wysocki" <rafael@kernel.org>
>> Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
>> ---
>>  Documentation/gpu/drm-internals.rst |   6 +
>>  drivers/gpu/drm/Makefile            |   3 +-
>>  drivers/gpu/drm/drm_drv.c           |  12 ++
>>  drivers/gpu/drm/drm_internal.h      |   3 +
>>  drivers/gpu/drm/drm_managed.c       | 186 ++++++++++++++++++++++++++++
>>  include/drm/drm_device.h            |  15 +++
>>  include/drm/drm_managed.h           |  30 +++++
>>  include/drm/drm_print.h             |   6 +
>>  8 files changed, 260 insertions(+), 1 deletion(-)
>>  create mode 100644 drivers/gpu/drm/drm_managed.c
>>  create mode 100644 include/drm/drm_managed.h
>>
>> diff --git a/Documentation/gpu/drm-internals.rst b/Documentation/gpu/drm-internals.rst
>> index a73320576ca9..a6b6145fda78 100644
>> --- a/Documentation/gpu/drm-internals.rst
>> +++ b/Documentation/gpu/drm-internals.rst
>> @@ -132,6 +132,12 @@ be unmapped; on many devices, the ROM address decoder is shared with
>>  other BARs, so leaving it mapped could cause undesired behaviour like
>>  hangs or memory corruption.
>>  
>> +Managed Resources
>> +-----------------
>> +
>> +.. kernel-doc:: drivers/gpu/drm/drm_managed.c
>> +   :doc: managed resources
>> +
>>  Bus-specific Device Registration and PCI Support
>>  ------------------------------------------------
>>  
>> diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile
>> index 7f72ef5e7811..183c60048307 100644
>> --- a/drivers/gpu/drm/Makefile
>> +++ b/drivers/gpu/drm/Makefile
>> @@ -17,7 +17,8 @@ drm-y       :=	drm_auth.o drm_cache.o \
>>  		drm_plane.o drm_color_mgmt.o drm_print.o \
>>  		drm_dumb_buffers.o drm_mode_config.o drm_vblank.o \
>>  		drm_syncobj.o drm_lease.o drm_writeback.o drm_client.o \
>> -		drm_client_modeset.o drm_atomic_uapi.o drm_hdcp.o
>> +		drm_client_modeset.o drm_atomic_uapi.o drm_hdcp.o \
>> +		drm_managed.o
>>  
>>  drm-$(CONFIG_DRM_LEGACY) += drm_legacy_misc.o drm_bufs.o drm_context.o drm_dma.o drm_scatter.o drm_lock.o
>>  drm-$(CONFIG_DRM_LIB_RANDOM) += lib/drm_random.o
>> diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c
>> index 9fcd6ab3c154..153050fc926c 100644
>> --- a/drivers/gpu/drm/drm_drv.c
>> +++ b/drivers/gpu/drm/drm_drv.c
>> @@ -629,6 +629,9 @@ int drm_dev_init(struct drm_device *dev,
>>  	dev->dev = get_device(parent);
>>  	dev->driver = driver;
>>  
>> +	INIT_LIST_HEAD(&dev->managed.resources);
>> +	spin_lock_init(&dev->managed.lock);
>> +
>>  	/* no per-device feature limits by default */
>>  	dev->driver_features = ~0u;
>>  
>> @@ -828,8 +831,17 @@ static void drm_dev_release(struct kref *ref)
>>  		dev->driver->release(dev);
>>  	} else {
>>  		drm_dev_fini(dev);
>> +	}
>> +
>> +	drm_managed_release(dev);
>> +
>> +	if (!dev->driver->release && !dev->managed.final_kfree) {
>> +		WARN_ON(!list_empty(&dev->managed.resources));
>>  		kfree(dev);
>>  	}
>> +
>> +	if (dev->managed.final_kfree)
>> +		kfree(dev->managed.final_kfree);
>>  }
>>  
>>  /**
>> diff --git a/drivers/gpu/drm/drm_internal.h b/drivers/gpu/drm/drm_internal.h
>> index aeec2e68d772..8c2628dfc6c7 100644
>> --- a/drivers/gpu/drm/drm_internal.h
>> +++ b/drivers/gpu/drm/drm_internal.h
>> @@ -89,6 +89,9 @@ void drm_prime_remove_buf_handle_locked(struct drm_prime_file_private *prime_fpr
>>  struct drm_minor *drm_minor_acquire(unsigned int minor_id);
>>  void drm_minor_release(struct drm_minor *minor);
>>  
>> +/* drm_managed.c */
>> +void drm_managed_release(struct drm_device *dev);
>> +
>>  /* drm_vblank.c */
>>  void drm_vblank_disable_and_save(struct drm_device *dev, unsigned int pipe);
>>  void drm_vblank_cleanup(struct drm_device *dev);
>> diff --git a/drivers/gpu/drm/drm_managed.c b/drivers/gpu/drm/drm_managed.c
>> new file mode 100644
>> index 000000000000..57dc79fa90af
>> --- /dev/null
>> +++ b/drivers/gpu/drm/drm_managed.c
>> @@ -0,0 +1,186 @@
>> +// SPDX-License-Identifier: GPL-2.0
>> +/*
>> + * Copyright (C) 2020 Intel
>> + *
>> + * Based on drivers/base/devres.c
>> + */
>> +
>> +#include <drm/drm_managed.h>
>> +
>> +#include <linux/list.h>
>> +#include <linux/slab.h>
>> +#include <linux/spinlock.h>
>> +
>> +#include <drm/drm_device.h>
>> +#include <drm/drm_print.h>
>> +
>> +/**
>> + * DOC: managed resources
>> + *
>> + * Inspired by struct &device managed resources, but tied to the lifetime of
>> + * struct &drm_device, which can outlive the underlying physical device, usually
>> + * when userspace has some open files and other handles to resources still open.
>> + */
>> +struct drmres_node {
>> +	struct list_head	entry;
>> +	drmres_release_t	release;
>> +	const char		*name;
>> +	size_t			size;
>> +};
> 
> At a later point, we could have debugfs for instances of this data
> structure. There's already a name field.
> 
>> +
>> +struct drmres {
>> +	struct drmres_node		node;
>> +	/*
>> +	 * Some archs want to perform DMA into kmalloc caches
>> +	 * and need a guaranteed alignment larger than
>> +	 * the alignment of a 64-bit integer.
>> +	 * Thus we use ARCH_KMALLOC_MINALIGN here and get exactly the same
>> +	 * buffer alignment as if it was allocated by plain kmalloc().
>> +	 */
>> +	u8 __aligned(ARCH_KMALLOC_MINALIGN) data[];
>> +};
>> +
>> +void drm_managed_release(struct drm_device *dev)
>> +{
>> +	struct drmres *dr, *tmp;
>> +
>> +	drm_dbg_drmres(dev, "drmres release begin\n");
>> +	list_for_each_entry_safe(dr, tmp, &dev->managed.resources, node.entry) {
>> +		drm_dbg_drmres(dev, "REL %p %s (%zu bytes)\n",
>> +			       dr, dr->node.name, dr->node.size);
>> +
>> +		if (dr->node.release)
>> +			dr->node.release(dev, dr->node.size ? *(void **)&dr->data : NULL);
>> +
>> +		list_del(&dr->node.entry);
>> +		kfree(dr);
>> +	}
>> +	drm_dbg_drmres(dev, "drmres release end\n");
>> +}
>> +
>> +/*
>> + * Always inline so that kmallc_track_caller tracks the actual interesting
> 
> 'kmalloc_node_track_caller'
> 
>> + * caller outside of drm_managed.c.
>> + */
>> +static __always_inline struct drmres * alloc_dr(drmres_release_t release,
>> +						size_t size, gfp_t gfp, int nid)
>> +{
>> +	size_t tot_size;
>> +	struct drmres *dr;
>> +
>> +	/* We must catch any near-SIZE_MAX cases that could overflow. */
>> +	if (unlikely(check_add_overflow(sizeof(*dr), size, &tot_size)))
>> +		return NULL;
>> +
>> +	dr = kmalloc_node_track_caller(tot_size, gfp, nid);
>> +	if (unlikely(!dr))
>> +		return NULL;
>> +
>> +	memset(dr, 0, offsetof(struct drmres, data));
>> +
>> +	INIT_LIST_HEAD(&dr->node.entry);
>> +	dr->node.release = release;
>> +	dr->node.size = size;
>> +
>> +	return dr;
>> +}
>> +
>> +static void del_dr(struct drm_device *dev, struct drmres *dr)
>> +{
>> +	list_del_init(&dr->node.entry);
>> +
>> +	drm_dbg_drmres(dev, "DEL %p %s (%lu bytes)\n",
>> +		       dr, dr->node.name, (unsigned long) dr->node.size);
>> +}
>> +
>> +static void add_dr(struct drm_device *dev, struct drmres *dr)
>> +{
>> +	unsigned long flags;
>> +
>> +	spin_lock_irqsave(&dev->managed.lock, flags);
>> +	list_add(&dr->node.entry, &dev->managed.resources);
>> +	spin_unlock_irqrestore(&dev->managed.lock, flags);
>> +
>> +	drm_dbg_drmres(dev, "ADD %p %s (%lu bytes)\n",
>> +		       dr, dr->node.name, (unsigned long) dr->node.size);
> 
> If the insert code blows up, it might be helpful to have this message in
> the log already. So should this message be located before the code for
> inserting the entry?
> 
>> +}
>> +
>> +void drmm_add_final_kfree(struct drm_device *dev, void *parent)
> 
> Can you come up with better names? 'final_kfree' sounds like a function
> pointer to an implementation of kfree() and 'parent' sounds like the
> parent device in a device hierarchy.
> 
> I suggest to rename 'parent' to 'container' and 'final_kfree'
> 'drmm_container'. The function's name could be drmm_dev_set_container().
> 
>> +{
>> +	WARN_ON(dev->managed.final_kfree);
>> +	WARN_ON(dev < (struct drm_device *) parent);
>> +	WARN_ON(dev + 1 >= (struct drm_device *) (parent + ksize(parent)));
>> +	dev->managed.final_kfree = parent;
>> +}
>> +EXPORT_SYMBOL(drmm_add_final_kfree);
>> +
>> +int __drmm_add_action(struct drm_device *dev,
>> +		      drmres_release_t action,
>> +		      void *data, const char *name)
> 
> Is there a reason to pass in 'void* data' instead of 'void** datap'? The
> latter would communicate what this parameter is for and not need void_ptr.
> 
> In any case, there seems to be no interface to remove an added action
> (e.g., __drmm_remove_action()). Please see my comment on drmm_kfree() below.

Ah, I just saw this was added in patch 22.

And patch 22 made me think that the interface name must clearly
communicate whether the function invokes the release callback or not.

Best regards
Thomas

> 
> And more generally, do we really need __drmm_add_action() in it's
> current form? I'd change it to __drmm_kmalloc(), which is drmm_kmalloc()
> plus optional release-action and name parameters. And drm_kmalloc()
> would be a simple wrapper in the header file, just like drmm_kcalloc().
> 
>> +{
>> +	struct drmres *dr;
>> +	void **void_ptr;
>> +
>> +	dr = alloc_dr(action, data ? sizeof(void*) : 0,
>> +		      GFP_KERNEL | __GFP_ZERO,
>> +		      dev_to_node(dev->dev));
>> +	if (!dr) {
>> +		drm_dbg_drmres(dev, "failed to add action %s for %p\n",
>> +			       name, data);
>> +		return -ENOMEM;
>> +	}
>> +
>> +	dr->node.name = name;
>> +	if (data) {
>> +		void_ptr = (void **)&dr->data;
>> +		*void_ptr = data;
>> +	}
>> +
>> +	add_dr(dev, dr);
>> +
>> +	return 0;
>> +}
>> +EXPORT_SYMBOL(__drmm_add_action);
>> +
>> +void *drmm_kmalloc(struct drm_device *dev, size_t size, gfp_t gfp)
>> +{
>> +	struct drmres *dr;
>> +
>> +	dr = alloc_dr(NULL, size, gfp, dev_to_node(dev->dev));
>> +	if (!dr) {
>> +		drm_dbg_drmres(dev, "failed to allocate %zu bytes, %u flags\n",
>> +			       size, gfp);
>> +		return NULL;
>> +	}
>> +	dr->node.name = "kmalloc";
>> +
>> +	add_dr(dev, dr);
>> +
>> +	return dr->data;
>> +}
>> +EXPORT_SYMBOL(drmm_kmalloc);
>> +
>> +void drmm_kfree(struct drm_device *dev, void *data)
> 
> I suggest to wrap this function around an implementatian that calls the
> optional release action. drmm_kfree() would become a trivial wrapper in
> the header file.
> 
> Best regards
> Thomas
> 
>> +{
>> +	struct drmres *dr_match = NULL, *dr;
>> +	unsigned long flags;
>> +
>> +	if (!data)
>> +		return;
>> +
>> +	spin_lock_irqsave(&dev->managed.lock, flags);
>> +	list_for_each_entry(dr, &dev->managed.resources, node.entry) {
>> +		if (dr->data == data) {
>> +			dr_match = dr;
>> +			del_dr(dev, dr_match);
>> +			break;
>> +		}
>> +	}
>> +	spin_unlock_irqrestore(&dev->managed.lock, flags);
>> +
>> +	if (WARN_ON(!dr_match))
>> +		return;
>> +
>> +	kfree(dr_match);
>> +}
>> +EXPORT_SYMBOL(drmm_kfree);
>> diff --git a/include/drm/drm_device.h b/include/drm/drm_device.h
>> index bb60a949f416..d39132b477dd 100644
>> --- a/include/drm/drm_device.h
>> +++ b/include/drm/drm_device.h
>> @@ -67,6 +67,21 @@ struct drm_device {
>>  	/** @dev: Device structure of bus-device */
>>  	struct device *dev;
>>  
>> +	/**
>> +	 * @managed:
>> +	 *
>> +	 * Managed resources linked to the lifetime of this &drm_device as
>> +	 * tracked by @ref.
>> +	 */
>> +	struct {
>> +		/** @managed.resources: managed resources list */
>> +		struct list_head resources;
>> +		/** @managed.final_kfree: pointer for final kfree() call */
>> +		void *final_kfree;
>> +		/** @managed.lock: protects @managed.resources */
>> +		spinlock_t lock;
>> +	} managed;
>> +
>>  	/** @driver: DRM driver managing the device */
>>  	struct drm_driver *driver;
>>  
>> diff --git a/include/drm/drm_managed.h b/include/drm/drm_managed.h
>> new file mode 100644
>> index 000000000000..7b5df7d09b19
>> --- /dev/null
>> +++ b/include/drm/drm_managed.h
>> @@ -0,0 +1,30 @@
>> +// SPDX-License-Identifier: GPL-2.0
>> +
>> +#ifndef _DRM_MANAGED_H_
>> +#define _DRM_MANAGED_H_
>> +
>> +#include <linux/gfp.h>
>> +#include <linux/types.h>
>> +
>> +struct drm_device;
>> +
>> +typedef void (*drmres_release_t)(struct drm_device *dev, void *res);
>> +
>> +#define drmm_add_action(dev, action, data) \
>> +	__drmm_add_action(dev, action, data, #action)
>> +
>> +int __must_check __drmm_add_action(struct drm_device *dev,
>> +				   drmres_release_t action,
>> +				   void *data, const char *name);
>> +
>> +void drmm_add_final_kfree(struct drm_device *dev, void *parent);
>> +
>> +void *drmm_kmalloc(struct drm_device *dev, size_t size, gfp_t gfp) __malloc;
>> +static inline void *drmm_kzalloc(struct drm_device *dev, size_t size, gfp_t gfp)
>> +{
>> +	return drmm_kmalloc(dev, size, gfp | __GFP_ZERO);
>> +}
>> +
>> +void drmm_kfree(struct drm_device *dev, void *data);
>> +
>> +#endif
>> diff --git a/include/drm/drm_print.h b/include/drm/drm_print.h
>> index ca7cee8e728a..1c9417430d08 100644
>> --- a/include/drm/drm_print.h
>> +++ b/include/drm/drm_print.h
>> @@ -313,6 +313,10 @@ enum drm_debug_category {
>>  	 * @DRM_UT_DP: Used in the DP code.
>>  	 */
>>  	DRM_UT_DP		= 0x100,
>> +	/**
>> +	 * @DRM_UT_DRMRES: Used in the drm managed resources code.
>> +	 */
>> +	DRM_UT_DRMRES		= 0x200,
>>  };
>>  
>>  static inline bool drm_debug_enabled(enum drm_debug_category category)
>> @@ -442,6 +446,8 @@ void drm_dev_dbg(const struct device *dev, enum drm_debug_category category,
>>  	drm_dev_dbg((drm)->dev, DRM_UT_LEASE, fmt, ##__VA_ARGS__)
>>  #define drm_dbg_dp(drm, fmt, ...)					\
>>  	drm_dev_dbg((drm)->dev, DRM_UT_DP, fmt, ##__VA_ARGS__)
>> +#define drm_dbg_drmres(drm, fmt, ...)					\
>> +	drm_dev_dbg((drm)->dev, DRM_UT_DRMRES, fmt, ##__VA_ARGS__)
>>  
>>  
>>  /*
>>
> 
> 
> _______________________________________________
> dri-devel mailing list
> dri-devel@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/dri-devel
> 

-- 
Thomas Zimmermann
Graphics Driver Developer
SUSE Software Solutions Germany GmbH
Maxfeldstr. 5, 90409 Nürnberg, Germany
(HRB 36809, AG Nürnberg)
Geschäftsführer: Felix Imendörffer


[-- Attachment #1.2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

[-- Attachment #2: Type: text/plain, Size: 160 bytes --]

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 111+ messages in thread

* Re: [PATCH 22/51] drm: manage drm_minor cleanup with drmm_
  2020-03-02 22:26 ` [PATCH 22/51] drm: manage drm_minor cleanup with drmm_ Daniel Vetter
@ 2020-03-11  9:59   ` Thomas Zimmermann
  2020-03-16  9:07     ` Daniel Vetter
  0 siblings, 1 reply; 111+ messages in thread
From: Thomas Zimmermann @ 2020-03-11  9:59 UTC (permalink / raw)
  To: Daniel Vetter, DRI Development
  Cc: Daniel Vetter, Intel Graphics Development, Laurent Pinchart


[-- Attachment #1.1.1: Type: text/plain, Size: 7256 bytes --]

Hi

Am 02.03.20 um 23:26 schrieb Daniel Vetter:
> The cleanup here is somewhat tricky, since we can't tell apart the
> allocated minor index from 0. So register a cleanup action first, and
> if the index allocation fails, unregister that cleanup action again to
> avoid bad mistakes.
> 
> The kdev for the minor already handles NULL, so no problem there.
> 
> Hence add drmm_remove_action() to the drm_managed library.
> 
> v2: Make pointer math around void ** consistent with what Laurent
> suggested.
> 
> Cc: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
> Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
> ---
>  drivers/gpu/drm/drm_drv.c     | 74 +++++++++++++----------------------
>  drivers/gpu/drm/drm_managed.c | 28 +++++++++++++
>  include/drm/drm_managed.h     |  4 ++
>  3 files changed, 59 insertions(+), 47 deletions(-)
> 
> diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c
> index 23e5b0e7e041..29d106195ab3 100644
> --- a/drivers/gpu/drm/drm_drv.c
> +++ b/drivers/gpu/drm/drm_drv.c
> @@ -93,19 +93,35 @@ static struct drm_minor **drm_minor_get_slot(struct drm_device *dev,
>  	}
>  }
>  
> +static void drm_minor_alloc_release(struct drm_device *dev, void *data)
> +{
> +	struct drm_minor *minor = data;
> +	unsigned long flags;
> +
> +	put_device(minor->kdev);
> +
> +	spin_lock_irqsave(&drm_minor_lock, flags);
> +	idr_remove(&drm_minors_idr, minor->index);
> +	spin_unlock_irqrestore(&drm_minor_lock, flags);
> +}
> +
>  static int drm_minor_alloc(struct drm_device *dev, unsigned int type)
>  {
>  	struct drm_minor *minor;
>  	unsigned long flags;
>  	int r;
>  
> -	minor = kzalloc(sizeof(*minor), GFP_KERNEL);
> +	minor = drmm_kzalloc(dev, sizeof(*minor), GFP_KERNEL);
>  	if (!minor)
>  		return -ENOMEM;
>  
>  	minor->type = type;
>  	minor->dev = dev;
>  
> +	r = drmm_add_action(dev, drm_minor_alloc_release, minor);
> +	if (r)
> +		return r;
> +
>  	idr_preload(GFP_KERNEL);
>  	spin_lock_irqsave(&drm_minor_lock, flags);
>  	r = idr_alloc(&drm_minors_idr,
> @@ -116,47 +132,18 @@ static int drm_minor_alloc(struct drm_device *dev, unsigned int type)
>  	spin_unlock_irqrestore(&drm_minor_lock, flags);
>  	idr_preload_end();
>  
> -	if (r < 0)
> -		goto err_free;
> +	if (r < 0) {
> +		drmm_remove_action(dev, drm_minor_alloc_release, minor);
> +		return r;
> +	}
>  
>  	minor->index = r;
> -
>  	minor->kdev = drm_sysfs_minor_alloc(minor);
> -	if (IS_ERR(minor->kdev)) {
> -		r = PTR_ERR(minor->kdev);
> -		goto err_index;
> -	}
> +	if (IS_ERR(minor->kdev))
> +		return PTR_ERR(minor->kdev);
>  
>  	*drm_minor_get_slot(dev, type) = minor;
>  	return 0;
> -
> -err_index:
> -	spin_lock_irqsave(&drm_minor_lock, flags);
> -	idr_remove(&drm_minors_idr, minor->index);
> -	spin_unlock_irqrestore(&drm_minor_lock, flags);
> -err_free:
> -	kfree(minor);
> -	return r;
> -}

TBH, I think you're reducing code quality by removing the rollback code
from init functions, just for the sake of it.

Specifically in this case here, you saved a few lines of code, but the
overall flow is way more complicated to follow. That's typically a
reliably source of bugs. This call to drmm_remove_action() just makes it
worse.

Rather, see my remark on OOP destruction in patch 21. For now, I'd focus
on the device cleanup and leave init functions as they are.

Best regards
Thomas

> -
> -static void drm_minor_free(struct drm_device *dev, unsigned int type)
> -{
> -	struct drm_minor **slot, *minor;
> -	unsigned long flags;
> -
> -	slot = drm_minor_get_slot(dev, type);
> -	minor = *slot;
> -	if (!minor)
> -		return;
> -
> -	put_device(minor->kdev);
> -
> -	spin_lock_irqsave(&drm_minor_lock, flags);
> -	idr_remove(&drm_minors_idr, minor->index);
> -	spin_unlock_irqrestore(&drm_minor_lock, flags);
> -
> -	kfree(minor);
> -	*slot = NULL;
>  }
>  
>  static int drm_minor_register(struct drm_device *dev, unsigned int type)
> @@ -678,16 +665,16 @@ int drm_dev_init(struct drm_device *dev,
>  	if (drm_core_check_feature(dev, DRIVER_RENDER)) {
>  		ret = drm_minor_alloc(dev, DRM_MINOR_RENDER);
>  		if (ret)
> -			goto err_minors;
> +			goto err;
>  	}
>  
>  	ret = drm_minor_alloc(dev, DRM_MINOR_PRIMARY);
>  	if (ret)
> -		goto err_minors;
> +		goto err;
>  
>  	ret = drm_legacy_create_map_hash(dev);
>  	if (ret)
> -		goto err_minors;
> +		goto err;
>  
>  	drm_legacy_ctxbitmap_init(dev);
>  
> @@ -695,7 +682,7 @@ int drm_dev_init(struct drm_device *dev,
>  		ret = drm_gem_init(dev);
>  		if (ret) {
>  			DRM_ERROR("Cannot initialize graphics execution manager (GEM)\n");
> -			goto err_ctxbitmap;
> +			goto err;
>  		}
>  	}
>  
> @@ -708,10 +695,6 @@ int drm_dev_init(struct drm_device *dev,
>  err_setunique:
>  	if (drm_core_check_feature(dev, DRIVER_GEM))
>  		drm_gem_destroy(dev);
> -err_ctxbitmap:
> -err_minors:
> -	drm_minor_free(dev, DRM_MINOR_PRIMARY);
> -	drm_minor_free(dev, DRM_MINOR_RENDER);
>  err:
>  	drm_managed_release(dev);
>  
> @@ -776,9 +759,6 @@ void drm_dev_fini(struct drm_device *dev)
>  
>  	if (drm_core_check_feature(dev, DRIVER_GEM))
>  		drm_gem_destroy(dev);
> -
> -	drm_minor_free(dev, DRM_MINOR_PRIMARY);
> -	drm_minor_free(dev, DRM_MINOR_RENDER);
>  }
>  EXPORT_SYMBOL(drm_dev_fini);
>  
> diff --git a/drivers/gpu/drm/drm_managed.c b/drivers/gpu/drm/drm_managed.c
> index 514d5bd42446..0883615c2088 100644
> --- a/drivers/gpu/drm/drm_managed.c
> +++ b/drivers/gpu/drm/drm_managed.c
> @@ -142,6 +142,34 @@ int __drmm_add_action(struct drm_device *dev,
>  }
>  EXPORT_SYMBOL(__drmm_add_action);
>  
> +void drmm_remove_action(struct drm_device *dev,
> +			drmres_release_t action,
> +			void *data)
> +{
> +	struct drmres *dr = NULL, *tmp;
> +	unsigned long flags;
> +
> +	if (!data)
> +		return;
> +
> +	spin_lock_irqsave(&dev->managed.lock, flags);
> +	list_for_each_entry(tmp, &dev->managed.resources, node.entry) {
> +		if (tmp->node.release == action &&
> +		    *(void **)&tmp->data == data) {
> +			dr = tmp;
> +			del_dr(dev, dr);
> +			break;
> +		}
> +	}
> +	spin_unlock_irqrestore(&dev->managed.lock, flags);
> +
> +	if (WARN_ON(!dr))
> +		return;
> +
> +	kfree(dr);
> +}
> +EXPORT_SYMBOL(drmm_remove_action);
> +
>  void *drmm_kmalloc(struct drm_device *dev, size_t size, gfp_t gfp)
>  {
>  	struct drmres *dr;
> diff --git a/include/drm/drm_managed.h b/include/drm/drm_managed.h
> index 89e6fce9f689..5280209dff92 100644
> --- a/include/drm/drm_managed.h
> +++ b/include/drm/drm_managed.h
> @@ -17,6 +17,10 @@ int __must_check __drmm_add_action(struct drm_device *dev,
>  				   drmres_release_t action,
>  				   void *data, const char *name);
>  
> +void drmm_remove_action(struct drm_device *dev,
> +			drmres_release_t action,
> +			void *data);
> +
>  void drmm_add_final_kfree(struct drm_device *dev, void *parent);
>  
>  void *drmm_kmalloc(struct drm_device *dev, size_t size, gfp_t gfp) __malloc;
> 

-- 
Thomas Zimmermann
Graphics Driver Developer
SUSE Software Solutions Germany GmbH
Maxfeldstr. 5, 90409 Nürnberg, Germany
(HRB 36809, AG Nürnberg)
Geschäftsführer: Felix Imendörffer


[-- Attachment #1.2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

[-- Attachment #2: Type: text/plain, Size: 160 bytes --]

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 111+ messages in thread

* Re: [PATCH 03/51] drm: add managed resources tied to drm_device
  2020-03-11  9:07   ` [PATCH 03/51] " Thomas Zimmermann
  2020-03-11  9:47     ` Thomas Zimmermann
@ 2020-03-16  8:45     ` Daniel Vetter
  1 sibling, 0 replies; 111+ messages in thread
From: Daniel Vetter @ 2020-03-16  8:45 UTC (permalink / raw)
  To: Thomas Zimmermann
  Cc: Rafael J. Wysocki, Daniel Vetter, Intel Graphics Development,
	DRI Development, Laurent Pinchart, Greg Kroah-Hartman,
	Daniel Vetter, Sam Ravnborg

On Wed, Mar 11, 2020 at 10:07:13AM +0100, Thomas Zimmermann wrote:
> Hi Daniel
> 
> Am 02.03.20 um 23:25 schrieb Daniel Vetter:
> > We have lots of these. And the cleanup code tends to be of dubious
> > quality. The biggest wrong pattern is that developers use devm_, which
> > ties the release action to the underlying struct device, whereas
> > all the userspace visible stuff attached to a drm_device can long
> > outlive that one (e.g. after a hotunplug while userspace has open
> > files and mmap'ed buffers). Give people what they want, but with more
> > correctness.
> > 
> > Mostly copied from devres.c, with types adjusted to fit drm_device and
> > a few simplifications - I didn't (yet) copy over everything. Since
> > the types don't match code sharing looked like a hopeless endeavour.
> > 
> > For now it's only super simplified, no groups, you can't remove
> > actions (but kfree exists, we'll need that soon). Plus all specific to
> > drm_device ofc, including the logging. Which I didn't bother to make
> > compile-time optional, since none of the other drm logging is compile
> > time optional either.
> > 
> > One tricky bit here is the chicken&egg between allocating your
> > drm_device structure and initiliazing it with drm_dev_init. For
> > perfect onion unwinding we'd need to have the action to kfree the
> > allocation registered before drm_dev_init registers any of its own
> > release handlers. But drm_dev_init doesn't know where exactly the
> > drm_device is emebedded into the overall structure, and by the time it
> > returns it'll all be too late. And forcing drivers to be able clean up
> > everything except the one kzalloc is silly.
> > 
> > Work around this by having a very special final_kfree pointer. This
> > also avoids troubles with the list head possibly disappearing from
> > underneath us when we release all resources attached to the
> > drm_device.
> > 
> > v2: Do all the kerneldoc at the end, to avoid lots of fairly pointless
> > shuffling while getting everything into shape.
> > 
> > v3: Add static to add/del_dr (Neil)
> > Move typo fix to the right patch (Neil)
> > 
> > v4: Enforce contract for drmm_add_final_kfree:
> > 
> > Use ksize() to check that the drm_device is indeed contained somewhere
> > in the final kfree(). Because we need that or the entire managed
> > release logic blows up in a pile of use-after-frees. Motivated by a
> > discussion with Laurent.
> > 
> > v5: Review from Laurent:
> > - %zu instead of casting size_t
> > - header guards
> > - sorting of includes
> > - guarding of data assignment if we didn't allocate it for a NULL
> >   pointer
> > - delete spurious newline
> > - cast void* data parameter correctly in ->release call, no idea how
> >   this even worked before
> > 
> > v3: Review from Sam
> > - Add the kerneldoc for the managed sub-struct back in, even if it
> >   doesn't show up in the generated html somehow.
> > - Explain why __always_inline.
> > - Fix bisectability around the final kfree() in drm_dev_relase(). This
> >   is just interim code which will disappear again.
> > - Some whitespace polish.
> > - Add debug output when drmm_add_action or drmm_kmalloc fail.
> > 
> > Cc: Sam Ravnborg <sam@ravnborg.org>
> > Cc: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
> > Cc: Neil Armstrong <narmstrong@baylibre.com
> > Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
> > Cc: "Rafael J. Wysocki" <rafael@kernel.org>
> > Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
> > ---
> >  Documentation/gpu/drm-internals.rst |   6 +
> >  drivers/gpu/drm/Makefile            |   3 +-
> >  drivers/gpu/drm/drm_drv.c           |  12 ++
> >  drivers/gpu/drm/drm_internal.h      |   3 +
> >  drivers/gpu/drm/drm_managed.c       | 186 ++++++++++++++++++++++++++++
> >  include/drm/drm_device.h            |  15 +++
> >  include/drm/drm_managed.h           |  30 +++++
> >  include/drm/drm_print.h             |   6 +
> >  8 files changed, 260 insertions(+), 1 deletion(-)
> >  create mode 100644 drivers/gpu/drm/drm_managed.c
> >  create mode 100644 include/drm/drm_managed.h
> > 
> > diff --git a/Documentation/gpu/drm-internals.rst b/Documentation/gpu/drm-internals.rst
> > index a73320576ca9..a6b6145fda78 100644
> > --- a/Documentation/gpu/drm-internals.rst
> > +++ b/Documentation/gpu/drm-internals.rst
> > @@ -132,6 +132,12 @@ be unmapped; on many devices, the ROM address decoder is shared with
> >  other BARs, so leaving it mapped could cause undesired behaviour like
> >  hangs or memory corruption.
> >  
> > +Managed Resources
> > +-----------------
> > +
> > +.. kernel-doc:: drivers/gpu/drm/drm_managed.c
> > +   :doc: managed resources
> > +
> >  Bus-specific Device Registration and PCI Support
> >  ------------------------------------------------
> >  
> > diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile
> > index 7f72ef5e7811..183c60048307 100644
> > --- a/drivers/gpu/drm/Makefile
> > +++ b/drivers/gpu/drm/Makefile
> > @@ -17,7 +17,8 @@ drm-y       :=	drm_auth.o drm_cache.o \
> >  		drm_plane.o drm_color_mgmt.o drm_print.o \
> >  		drm_dumb_buffers.o drm_mode_config.o drm_vblank.o \
> >  		drm_syncobj.o drm_lease.o drm_writeback.o drm_client.o \
> > -		drm_client_modeset.o drm_atomic_uapi.o drm_hdcp.o
> > +		drm_client_modeset.o drm_atomic_uapi.o drm_hdcp.o \
> > +		drm_managed.o
> >  
> >  drm-$(CONFIG_DRM_LEGACY) += drm_legacy_misc.o drm_bufs.o drm_context.o drm_dma.o drm_scatter.o drm_lock.o
> >  drm-$(CONFIG_DRM_LIB_RANDOM) += lib/drm_random.o
> > diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c
> > index 9fcd6ab3c154..153050fc926c 100644
> > --- a/drivers/gpu/drm/drm_drv.c
> > +++ b/drivers/gpu/drm/drm_drv.c
> > @@ -629,6 +629,9 @@ int drm_dev_init(struct drm_device *dev,
> >  	dev->dev = get_device(parent);
> >  	dev->driver = driver;
> >  
> > +	INIT_LIST_HEAD(&dev->managed.resources);
> > +	spin_lock_init(&dev->managed.lock);
> > +
> >  	/* no per-device feature limits by default */
> >  	dev->driver_features = ~0u;
> >  
> > @@ -828,8 +831,17 @@ static void drm_dev_release(struct kref *ref)
> >  		dev->driver->release(dev);
> >  	} else {
> >  		drm_dev_fini(dev);
> > +	}
> > +
> > +	drm_managed_release(dev);
> > +
> > +	if (!dev->driver->release && !dev->managed.final_kfree) {
> > +		WARN_ON(!list_empty(&dev->managed.resources));
> >  		kfree(dev);
> >  	}
> > +
> > +	if (dev->managed.final_kfree)
> > +		kfree(dev->managed.final_kfree);
> >  }
> >  
> >  /**
> > diff --git a/drivers/gpu/drm/drm_internal.h b/drivers/gpu/drm/drm_internal.h
> > index aeec2e68d772..8c2628dfc6c7 100644
> > --- a/drivers/gpu/drm/drm_internal.h
> > +++ b/drivers/gpu/drm/drm_internal.h
> > @@ -89,6 +89,9 @@ void drm_prime_remove_buf_handle_locked(struct drm_prime_file_private *prime_fpr
> >  struct drm_minor *drm_minor_acquire(unsigned int minor_id);
> >  void drm_minor_release(struct drm_minor *minor);
> >  
> > +/* drm_managed.c */
> > +void drm_managed_release(struct drm_device *dev);
> > +
> >  /* drm_vblank.c */
> >  void drm_vblank_disable_and_save(struct drm_device *dev, unsigned int pipe);
> >  void drm_vblank_cleanup(struct drm_device *dev);
> > diff --git a/drivers/gpu/drm/drm_managed.c b/drivers/gpu/drm/drm_managed.c
> > new file mode 100644
> > index 000000000000..57dc79fa90af
> > --- /dev/null
> > +++ b/drivers/gpu/drm/drm_managed.c
> > @@ -0,0 +1,186 @@
> > +// SPDX-License-Identifier: GPL-2.0
> > +/*
> > + * Copyright (C) 2020 Intel
> > + *
> > + * Based on drivers/base/devres.c
> > + */
> > +
> > +#include <drm/drm_managed.h>
> > +
> > +#include <linux/list.h>
> > +#include <linux/slab.h>
> > +#include <linux/spinlock.h>
> > +
> > +#include <drm/drm_device.h>
> > +#include <drm/drm_print.h>
> > +
> > +/**
> > + * DOC: managed resources
> > + *
> > + * Inspired by struct &device managed resources, but tied to the lifetime of
> > + * struct &drm_device, which can outlive the underlying physical device, usually
> > + * when userspace has some open files and other handles to resources still open.
> > + */
> > +struct drmres_node {
> > +	struct list_head	entry;
> > +	drmres_release_t	release;
> > +	const char		*name;
> > +	size_t			size;
> > +};
> 
> At a later point, we could have debugfs for instances of this data
> structure. There's already a name field.
> 
> > +
> > +struct drmres {
> > +	struct drmres_node		node;
> > +	/*
> > +	 * Some archs want to perform DMA into kmalloc caches
> > +	 * and need a guaranteed alignment larger than
> > +	 * the alignment of a 64-bit integer.
> > +	 * Thus we use ARCH_KMALLOC_MINALIGN here and get exactly the same
> > +	 * buffer alignment as if it was allocated by plain kmalloc().
> > +	 */
> > +	u8 __aligned(ARCH_KMALLOC_MINALIGN) data[];
> > +};
> > +
> > +void drm_managed_release(struct drm_device *dev)
> > +{
> > +	struct drmres *dr, *tmp;
> > +
> > +	drm_dbg_drmres(dev, "drmres release begin\n");
> > +	list_for_each_entry_safe(dr, tmp, &dev->managed.resources, node.entry) {
> > +		drm_dbg_drmres(dev, "REL %p %s (%zu bytes)\n",
> > +			       dr, dr->node.name, dr->node.size);
> > +
> > +		if (dr->node.release)
> > +			dr->node.release(dev, dr->node.size ? *(void **)&dr->data : NULL);
> > +
> > +		list_del(&dr->node.entry);
> > +		kfree(dr);
> > +	}
> > +	drm_dbg_drmres(dev, "drmres release end\n");
> > +}
> > +
> > +/*
> > + * Always inline so that kmallc_track_caller tracks the actual interesting
> 
> 'kmalloc_node_track_caller'

Yeah I dropped the _node for shortern naming, most people don't use
kmalloc_node, but just plain kmalloc. But I just spotted that I have a
spelling issue in that too :-)

> > + * caller outside of drm_managed.c.
> > + */
> > +static __always_inline struct drmres * alloc_dr(drmres_release_t release,
> > +						size_t size, gfp_t gfp, int nid)
> > +{
> > +	size_t tot_size;
> > +	struct drmres *dr;
> > +
> > +	/* We must catch any near-SIZE_MAX cases that could overflow. */
> > +	if (unlikely(check_add_overflow(sizeof(*dr), size, &tot_size)))
> > +		return NULL;
> > +
> > +	dr = kmalloc_node_track_caller(tot_size, gfp, nid);
> > +	if (unlikely(!dr))
> > +		return NULL;
> > +
> > +	memset(dr, 0, offsetof(struct drmres, data));
> > +
> > +	INIT_LIST_HEAD(&dr->node.entry);
> > +	dr->node.release = release;
> > +	dr->node.size = size;
> > +
> > +	return dr;
> > +}
> > +
> > +static void del_dr(struct drm_device *dev, struct drmres *dr)
> > +{
> > +	list_del_init(&dr->node.entry);
> > +
> > +	drm_dbg_drmres(dev, "DEL %p %s (%lu bytes)\n",
> > +		       dr, dr->node.name, (unsigned long) dr->node.size);
> > +}
> > +
> > +static void add_dr(struct drm_device *dev, struct drmres *dr)
> > +{
> > +	unsigned long flags;
> > +
> > +	spin_lock_irqsave(&dev->managed.lock, flags);
> > +	list_add(&dr->node.entry, &dev->managed.resources);
> > +	spin_unlock_irqrestore(&dev->managed.lock, flags);
> > +
> > +	drm_dbg_drmres(dev, "ADD %p %s (%lu bytes)\n",
> > +		       dr, dr->node.name, (unsigned long) dr->node.size);
> 
> If the insert code blows up, it might be helpful to have this message in
> the log already. So should this message be located before the code for
> inserting the entry?

If list_add blows up we have bigger problems imo :-) I think I'll just
leave this wherever it is.

> 
> > +}
> > +
> > +void drmm_add_final_kfree(struct drm_device *dev, void *parent)
> 
> Can you come up with better names? 'final_kfree' sounds like a function
> pointer to an implementation of kfree() and 'parent' sounds like the
> parent device in a device hierarchy.
> 
> I suggest to rename 'parent' to 'container' and 'final_kfree'
> 'drmm_container'. The function's name could be drmm_dev_set_container().

s/parent/container is really good. For the other I want more votes since
it's going to be a pile of churn, and I'm not massively sold on your
naming ...

> > +{
> > +	WARN_ON(dev->managed.final_kfree);
> > +	WARN_ON(dev < (struct drm_device *) parent);
> > +	WARN_ON(dev + 1 >= (struct drm_device *) (parent + ksize(parent)));
> > +	dev->managed.final_kfree = parent;
> > +}
> > +EXPORT_SYMBOL(drmm_add_final_kfree);
> > +
> > +int __drmm_add_action(struct drm_device *dev,
> > +		      drmres_release_t action,
> > +		      void *data, const char *name)
> 
> Is there a reason to pass in 'void* data' instead of 'void** datap'? The
> latter would communicate what this parameter is for and not need void_ptr.

I don't get why you'd want to convert this into void**. The argument for
the release function is a void*, not a void**. That's also what external
callers pass in here. void** would be utterly confusing and actually hide
the void_ptr trickery we need I think (since it then happens automatically
as part of argument conversion hidden in the function call).

> In any case, there seems to be no interface to remove an added action
> (e.g., __drmm_remove_action()). Please see my comment on drmm_kfree() below.

Not yet needed, I'm building this up as we go. A later patch actually adds
it, plus the even neater add_action_or_reset.

> And more generally, do we really need __drmm_add_action() in it's
> current form? I'd change it to __drmm_kmalloc(), which is drmm_kmalloc()
> plus optional release-action and name parameters. And drm_kmalloc()
> would be a simple wrapper in the header file, just like drmm_kcalloc().

Uh we kinda have that, with the lower-level alloc_dr/add_dr functions.
__drmm_add_action _is_ the wrapper (and definitely too big for header
file static include stuff). We could go overboard with forced code
sharing, but I think the current code is actually a bit easier to read.

> > +{
> > +	struct drmres *dr;
> > +	void **void_ptr;
> > +
> > +	dr = alloc_dr(action, data ? sizeof(void*) : 0,
> > +		      GFP_KERNEL | __GFP_ZERO,
> > +		      dev_to_node(dev->dev));
> > +	if (!dr) {
> > +		drm_dbg_drmres(dev, "failed to add action %s for %p\n",
> > +			       name, data);
> > +		return -ENOMEM;
> > +	}
> > +
> > +	dr->node.name = name;
> > +	if (data) {
> > +		void_ptr = (void **)&dr->data;
> > +		*void_ptr = data;
> > +	}
> > +
> > +	add_dr(dev, dr);
> > +
> > +	return 0;
> > +}
> > +EXPORT_SYMBOL(__drmm_add_action);
> > +
> > +void *drmm_kmalloc(struct drm_device *dev, size_t size, gfp_t gfp)
> > +{
> > +	struct drmres *dr;
> > +
> > +	dr = alloc_dr(NULL, size, gfp, dev_to_node(dev->dev));
> > +	if (!dr) {
> > +		drm_dbg_drmres(dev, "failed to allocate %zu bytes, %u flags\n",
> > +			       size, gfp);
> > +		return NULL;
> > +	}
> > +	dr->node.name = "kmalloc";
> > +
> > +	add_dr(dev, dr);
> > +
> > +	return dr->data;
> > +}
> > +EXPORT_SYMBOL(drmm_kmalloc);
> > +
> > +void drmm_kfree(struct drm_device *dev, void *data)
> 
> I suggest to wrap this function around an implementatian that calls the
> optional release action. drmm_kfree() would become a trivial wrapper in
> the header file.

C isn't that good at meta-programing. You'd need to pass in a special
match function, with opaque match parameters, and then you can do generic
removal. It's real ugly, imo 2 copies of a simple loop to find what you
need and delete it is much better.
-Daniel


> Best regards
> Thomas
> 
> > +{
> > +	struct drmres *dr_match = NULL, *dr;
> > +	unsigned long flags;
> > +
> > +	if (!data)
> > +		return;
> > +
> > +	spin_lock_irqsave(&dev->managed.lock, flags);
> > +	list_for_each_entry(dr, &dev->managed.resources, node.entry) {
> > +		if (dr->data == data) {
> > +			dr_match = dr;
> > +			del_dr(dev, dr_match);
> > +			break;
> > +		}
> > +	}
> > +	spin_unlock_irqrestore(&dev->managed.lock, flags);
> > +
> > +	if (WARN_ON(!dr_match))
> > +		return;
> > +
> > +	kfree(dr_match);
> > +}
> > +EXPORT_SYMBOL(drmm_kfree);
> > diff --git a/include/drm/drm_device.h b/include/drm/drm_device.h
> > index bb60a949f416..d39132b477dd 100644
> > --- a/include/drm/drm_device.h
> > +++ b/include/drm/drm_device.h
> > @@ -67,6 +67,21 @@ struct drm_device {
> >  	/** @dev: Device structure of bus-device */
> >  	struct device *dev;
> >  
> > +	/**
> > +	 * @managed:
> > +	 *
> > +	 * Managed resources linked to the lifetime of this &drm_device as
> > +	 * tracked by @ref.
> > +	 */
> > +	struct {
> > +		/** @managed.resources: managed resources list */
> > +		struct list_head resources;
> > +		/** @managed.final_kfree: pointer for final kfree() call */
> > +		void *final_kfree;
> > +		/** @managed.lock: protects @managed.resources */
> > +		spinlock_t lock;
> > +	} managed;
> > +
> >  	/** @driver: DRM driver managing the device */
> >  	struct drm_driver *driver;
> >  
> > diff --git a/include/drm/drm_managed.h b/include/drm/drm_managed.h
> > new file mode 100644
> > index 000000000000..7b5df7d09b19
> > --- /dev/null
> > +++ b/include/drm/drm_managed.h
> > @@ -0,0 +1,30 @@
> > +// SPDX-License-Identifier: GPL-2.0
> > +
> > +#ifndef _DRM_MANAGED_H_
> > +#define _DRM_MANAGED_H_
> > +
> > +#include <linux/gfp.h>
> > +#include <linux/types.h>
> > +
> > +struct drm_device;
> > +
> > +typedef void (*drmres_release_t)(struct drm_device *dev, void *res);
> > +
> > +#define drmm_add_action(dev, action, data) \
> > +	__drmm_add_action(dev, action, data, #action)
> > +
> > +int __must_check __drmm_add_action(struct drm_device *dev,
> > +				   drmres_release_t action,
> > +				   void *data, const char *name);
> > +
> > +void drmm_add_final_kfree(struct drm_device *dev, void *parent);
> > +
> > +void *drmm_kmalloc(struct drm_device *dev, size_t size, gfp_t gfp) __malloc;
> > +static inline void *drmm_kzalloc(struct drm_device *dev, size_t size, gfp_t gfp)
> > +{
> > +	return drmm_kmalloc(dev, size, gfp | __GFP_ZERO);
> > +}
> > +
> > +void drmm_kfree(struct drm_device *dev, void *data);
> > +
> > +#endif
> > diff --git a/include/drm/drm_print.h b/include/drm/drm_print.h
> > index ca7cee8e728a..1c9417430d08 100644
> > --- a/include/drm/drm_print.h
> > +++ b/include/drm/drm_print.h
> > @@ -313,6 +313,10 @@ enum drm_debug_category {
> >  	 * @DRM_UT_DP: Used in the DP code.
> >  	 */
> >  	DRM_UT_DP		= 0x100,
> > +	/**
> > +	 * @DRM_UT_DRMRES: Used in the drm managed resources code.
> > +	 */
> > +	DRM_UT_DRMRES		= 0x200,
> >  };
> >  
> >  static inline bool drm_debug_enabled(enum drm_debug_category category)
> > @@ -442,6 +446,8 @@ void drm_dev_dbg(const struct device *dev, enum drm_debug_category category,
> >  	drm_dev_dbg((drm)->dev, DRM_UT_LEASE, fmt, ##__VA_ARGS__)
> >  #define drm_dbg_dp(drm, fmt, ...)					\
> >  	drm_dev_dbg((drm)->dev, DRM_UT_DP, fmt, ##__VA_ARGS__)
> > +#define drm_dbg_drmres(drm, fmt, ...)					\
> > +	drm_dev_dbg((drm)->dev, DRM_UT_DRMRES, fmt, ##__VA_ARGS__)
> >  
> >  
> >  /*
> > 
> 
> -- 
> Thomas Zimmermann
> Graphics Driver Developer
> SUSE Software Solutions Germany GmbH
> Maxfeldstr. 5, 90409 Nürnberg, Germany
> (HRB 36809, AG Nürnberg)
> Geschäftsführer: Felix Imendörffer
> 




-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 111+ messages in thread

* Re: [PATCH 03/51] drm: add managed resources tied to drm_device
  2020-03-11  9:14   ` Thomas Zimmermann
@ 2020-03-16  8:50     ` Daniel Vetter
  0 siblings, 0 replies; 111+ messages in thread
From: Daniel Vetter @ 2020-03-16  8:50 UTC (permalink / raw)
  To: Thomas Zimmermann
  Cc: Rafael J. Wysocki, Daniel Vetter, Intel Graphics Development,
	DRI Development, Laurent Pinchart, Greg Kroah-Hartman,
	Daniel Vetter, Sam Ravnborg

On Wed, Mar 11, 2020 at 10:14:03AM +0100, Thomas Zimmermann wrote:
> 
> 
> Am 02.03.20 um 23:25 schrieb Daniel Vetter:
> <...>
> > +
> > +int __drmm_add_action(struct drm_device *dev,
> > +		      drmres_release_t action,
> > +		      void *data, const char *name)
> > +{
> > +	struct drmres *dr;
> > +	void **void_ptr;
> > +
> > +	dr = alloc_dr(action, data ? sizeof(void*) : 0,
> > +		      GFP_KERNEL | __GFP_ZERO,
> > +		      dev_to_node(dev->dev));
> > +	if (!dr) {
> > +		drm_dbg_drmres(dev, "failed to add action %s for %p\n",
> > +			       name, data);
> > +		return -ENOMEM;
> > +	}
> > +
> > +	dr->node.name = name;
> 
> Maybe do a kstrdup_const() on name and later a kfree_const() during
> release. Just in case someone decides to allocate 'name' dynamically.

Makes sense, but a bit of churn since I need a free_dr() helper now :-)
-Daniel

> 
> > +	if (data) {
> > +		void_ptr = (void **)&dr->data;
> > +		*void_ptr = data;
> > +	}
> > +
> > +	add_dr(dev, dr);
> > +
> > +	return 0;
> > +}
> > +EXPORT_SYMBOL(__drmm_add_action);
> > +
> > +void *drmm_kmalloc(struct drm_device *dev, size_t size, gfp_t gfp)
> > +{
> > +	struct drmres *dr;
> > +
> > +	dr = alloc_dr(NULL, size, gfp, dev_to_node(dev->dev));
> > +	if (!dr) {
> > +		drm_dbg_drmres(dev, "failed to allocate %zu bytes, %u flags\n",
> > +			       size, gfp);
> > +		return NULL;
> > +	}
> > +	dr->node.name = "kmalloc";
> > +
> > +	add_dr(dev, dr);
> > +
> > +	return dr->data;
> > +}
> > +EXPORT_SYMBOL(drmm_kmalloc);
> > +
> > +void drmm_kfree(struct drm_device *dev, void *data)
> > +{
> > +	struct drmres *dr_match = NULL, *dr;
> > +	unsigned long flags;
> > +
> > +	if (!data)
> > +		return;
> > +
> > +	spin_lock_irqsave(&dev->managed.lock, flags);
> > +	list_for_each_entry(dr, &dev->managed.resources, node.entry) {
> > +		if (dr->data == data) {
> > +			dr_match = dr;
> > +			del_dr(dev, dr_match);
> > +			break;
> > +		}
> > +	}
> > +	spin_unlock_irqrestore(&dev->managed.lock, flags);
> > +
> > +	if (WARN_ON(!dr_match))
> > +		return;
> > +
> > +	kfree(dr_match);
> > +}
> > +EXPORT_SYMBOL(drmm_kfree);
> > diff --git a/include/drm/drm_device.h b/include/drm/drm_device.h
> > index bb60a949f416..d39132b477dd 100644
> > --- a/include/drm/drm_device.h
> > +++ b/include/drm/drm_device.h
> > @@ -67,6 +67,21 @@ struct drm_device {
> >  	/** @dev: Device structure of bus-device */
> >  	struct device *dev;
> >  
> > +	/**
> > +	 * @managed:
> > +	 *
> > +	 * Managed resources linked to the lifetime of this &drm_device as
> > +	 * tracked by @ref.
> > +	 */
> > +	struct {
> > +		/** @managed.resources: managed resources list */
> > +		struct list_head resources;
> > +		/** @managed.final_kfree: pointer for final kfree() call */
> > +		void *final_kfree;
> > +		/** @managed.lock: protects @managed.resources */
> > +		spinlock_t lock;
> > +	} managed;
> > +
> >  	/** @driver: DRM driver managing the device */
> >  	struct drm_driver *driver;
> >  
> > diff --git a/include/drm/drm_managed.h b/include/drm/drm_managed.h
> > new file mode 100644
> > index 000000000000..7b5df7d09b19
> > --- /dev/null
> > +++ b/include/drm/drm_managed.h
> > @@ -0,0 +1,30 @@
> > +// SPDX-License-Identifier: GPL-2.0
> > +
> > +#ifndef _DRM_MANAGED_H_
> > +#define _DRM_MANAGED_H_
> > +
> > +#include <linux/gfp.h>
> > +#include <linux/types.h>
> > +
> > +struct drm_device;
> > +
> > +typedef void (*drmres_release_t)(struct drm_device *dev, void *res);
> > +
> > +#define drmm_add_action(dev, action, data) \
> > +	__drmm_add_action(dev, action, data, #action)
> > +
> > +int __must_check __drmm_add_action(struct drm_device *dev,
> > +				   drmres_release_t action,
> > +				   void *data, const char *name);
> > +
> > +void drmm_add_final_kfree(struct drm_device *dev, void *parent);
> > +
> > +void *drmm_kmalloc(struct drm_device *dev, size_t size, gfp_t gfp) __malloc;
> > +static inline void *drmm_kzalloc(struct drm_device *dev, size_t size, gfp_t gfp)
> > +{
> > +	return drmm_kmalloc(dev, size, gfp | __GFP_ZERO);
> > +}
> > +
> > +void drmm_kfree(struct drm_device *dev, void *data);
> > +
> > +#endif
> > diff --git a/include/drm/drm_print.h b/include/drm/drm_print.h
> > index ca7cee8e728a..1c9417430d08 100644
> > --- a/include/drm/drm_print.h
> > +++ b/include/drm/drm_print.h
> > @@ -313,6 +313,10 @@ enum drm_debug_category {
> >  	 * @DRM_UT_DP: Used in the DP code.
> >  	 */
> >  	DRM_UT_DP		= 0x100,
> > +	/**
> > +	 * @DRM_UT_DRMRES: Used in the drm managed resources code.
> > +	 */
> > +	DRM_UT_DRMRES		= 0x200,
> >  };
> >  
> >  static inline bool drm_debug_enabled(enum drm_debug_category category)
> > @@ -442,6 +446,8 @@ void drm_dev_dbg(const struct device *dev, enum drm_debug_category category,
> >  	drm_dev_dbg((drm)->dev, DRM_UT_LEASE, fmt, ##__VA_ARGS__)
> >  #define drm_dbg_dp(drm, fmt, ...)					\
> >  	drm_dev_dbg((drm)->dev, DRM_UT_DP, fmt, ##__VA_ARGS__)
> > +#define drm_dbg_drmres(drm, fmt, ...)					\
> > +	drm_dev_dbg((drm)->dev, DRM_UT_DRMRES, fmt, ##__VA_ARGS__)
> >  
> >  
> >  /*
> > 
> 
> -- 
> Thomas Zimmermann
> Graphics Driver Developer
> SUSE Software Solutions Germany GmbH
> Maxfeldstr. 5, 90409 Nürnberg, Germany
> (HRB 36809, AG Nürnberg)
> Geschäftsführer: Felix Imendörffer
> 




-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 111+ messages in thread

* Re: [PATCH 21/51] drm: Use drmm_ for drm_dev_init cleanup
  2020-03-11  9:39   ` Thomas Zimmermann
@ 2020-03-16  9:02     ` Daniel Vetter
  0 siblings, 0 replies; 111+ messages in thread
From: Daniel Vetter @ 2020-03-16  9:02 UTC (permalink / raw)
  To: Thomas Zimmermann
  Cc: Daniel Vetter, Intel Graphics Development, DRI Development,
	Daniel Vetter

On Wed, Mar 11, 2020 at 10:39:13AM +0100, Thomas Zimmermann wrote:
> Hi
> 
> Am 02.03.20 um 23:26 schrieb Daniel Vetter:
> > Well for the simple stuff at least, vblank, gem and minor cleanup I
> > want to further split up as a demonstration.
> > 
> > v2: We need to clear drm_device->dev otherwise the debug drm printing
> > after our cleanup hook (e.g. in drm_manged_release) will chase
> > released memory and result in a use-after-free. Not really pretty, but
> > oh well.
> > 
> > Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
> > ---
> >  drivers/gpu/drm/drm_drv.c | 48 ++++++++++++++++++++-------------------
> >  1 file changed, 25 insertions(+), 23 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c
> > index ef79c03e311c..23e5b0e7e041 100644
> > --- a/drivers/gpu/drm/drm_drv.c
> > +++ b/drivers/gpu/drm/drm_drv.c
> > @@ -580,6 +580,23 @@ static void drm_fs_inode_free(struct inode *inode)
> >   *    used.
> >   */
> >  
> > +static void drm_dev_init_release(struct drm_device *dev, void *res)
> > +{
> > +	drm_legacy_ctxbitmap_cleanup(dev);
> > +	drm_legacy_remove_map_hash(dev);
> > +	drm_fs_inode_free(dev->anon_inode);
> > +
> > +	put_device(dev->dev);
> > +	/* Prevent use-after-free in drm_managed_release when debugging is
> > +	 * enabled. Slightly awkward, but can't really be helped. */
> > +	dev->dev = NULL;
> > +	mutex_destroy(&dev->master_mutex);
> > +	mutex_destroy(&dev->clientlist_mutex);
> > +	mutex_destroy(&dev->filelist_mutex);
> > +	mutex_destroy(&dev->struct_mutex);
> > +	drm_legacy_destroy_members(dev);
> > +}
> > +
> >  /**
> >   * drm_dev_init - Initialise new DRM device
> >   * @dev: DRM device
> > @@ -647,11 +664,15 @@ int drm_dev_init(struct drm_device *dev,
> >  	mutex_init(&dev->clientlist_mutex);
> >  	mutex_init(&dev->master_mutex);
> >  
> > +	ret = drmm_add_action(dev, drm_dev_init_release, NULL);
> > +	if (ret)
> > +		return ret;
> > +
> 
> Is this code supposed to stay for the long term? As devices are
> allocated dynamically, I can imagine that there will be a call that
> allocates the memory and, at the same time, sets drm_dev_init_release()
> as the release callback.

There's a chicken-egg situation here. The plan is to fix this with a
devm_drm_dev_alloc() macro, which we discussed quite a bit in earlier
versions. It's just that the patch series is already big as-is, hence this
is postponed to the next round.

> The question is also released to patch 3, where I proposed to rename
> __drm_add_action() to __drmm_kzalloc().
> 
> >  	dev->anon_inode = drm_fs_inode_new();
> >  	if (IS_ERR(dev->anon_inode)) {
> >  		ret = PTR_ERR(dev->anon_inode);
> >  		DRM_ERROR("Cannot allocate anonymous inode: %d\n", ret);
> > -		goto err_free;
> > +		goto err;
> >  	}
> >  
> >  	if (drm_core_check_feature(dev, DRIVER_RENDER)) {
> > @@ -688,19 +709,12 @@ int drm_dev_init(struct drm_device *dev,
> >  	if (drm_core_check_feature(dev, DRIVER_GEM))
> >  		drm_gem_destroy(dev);
> >  err_ctxbitmap:
> > -	drm_legacy_ctxbitmap_cleanup(dev);
> > -	drm_legacy_remove_map_hash(dev);
> >  err_minors:
> >  	drm_minor_free(dev, DRM_MINOR_PRIMARY);
> >  	drm_minor_free(dev, DRM_MINOR_RENDER);
> > -	drm_fs_inode_free(dev->anon_inode);
> > -err_free:
> > -	put_device(dev->dev);
> > -	mutex_destroy(&dev->master_mutex);
> > -	mutex_destroy(&dev->clientlist_mutex);
> > -	mutex_destroy(&dev->filelist_mutex);
> > -	mutex_destroy(&dev->struct_mutex);
> > -	drm_legacy_destroy_members(dev);
> > +err:
> > +	drm_managed_release(dev);
> > +
> 
> Here's more of a general observation than a comment on the actual patch:
> 
> One odd thing about the overall interface is that there's no way of
> updating the release callback afterwards. In an OOP language, such as
> C++, an error within the constructor would rollback the performed
> actions and return without calling the destructor. Destructors only run
> for fully constructed objects.
> 
> In our case, the equivalent is to run the init function and set
> drm_dev_init_release() as the final step. The init's rollback-code would
> have to stay, obviously.

See the various drivers later on in the series, the init rollback
completely disappears once we're done here. If this wouldn't Just Work for
both final destruction and init rollback there's really no point. There's
a few ugly corner-cases with getting this boot-strapped though.
-Daniel

> 
> Best regards
> Thomas
> 
> >  	return ret;
> >  }
> >  EXPORT_SYMBOL(drm_dev_init);
> > @@ -763,20 +777,8 @@ void drm_dev_fini(struct drm_device *dev)
> >  	if (drm_core_check_feature(dev, DRIVER_GEM))
> >  		drm_gem_destroy(dev);
> >  
> > -	drm_legacy_ctxbitmap_cleanup(dev);
> > -	drm_legacy_remove_map_hash(dev);
> > -	drm_fs_inode_free(dev->anon_inode);
> > -
> >  	drm_minor_free(dev, DRM_MINOR_PRIMARY);
> >  	drm_minor_free(dev, DRM_MINOR_RENDER);
> > -
> > -	put_device(dev->dev);
> > -
> > -	mutex_destroy(&dev->master_mutex);
> > -	mutex_destroy(&dev->clientlist_mutex);
> > -	mutex_destroy(&dev->filelist_mutex);
> > -	mutex_destroy(&dev->struct_mutex);
> > -	drm_legacy_destroy_members(dev);
> >  }
> >  EXPORT_SYMBOL(drm_dev_fini);
> >  
> > 
> 
> -- 
> Thomas Zimmermann
> Graphics Driver Developer
> SUSE Software Solutions Germany GmbH
> Maxfeldstr. 5, 90409 Nürnberg, Germany
> (HRB 36809, AG Nürnberg)
> Geschäftsführer: Felix Imendörffer
> 




-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 111+ messages in thread

* Re: [PATCH 22/51] drm: manage drm_minor cleanup with drmm_
  2020-03-11  9:59   ` Thomas Zimmermann
@ 2020-03-16  9:07     ` Daniel Vetter
  0 siblings, 0 replies; 111+ messages in thread
From: Daniel Vetter @ 2020-03-16  9:07 UTC (permalink / raw)
  To: Thomas Zimmermann
  Cc: Daniel Vetter, Intel Graphics Development, Laurent Pinchart,
	DRI Development, Daniel Vetter

On Wed, Mar 11, 2020 at 10:59:10AM +0100, Thomas Zimmermann wrote:
> Hi
> 
> Am 02.03.20 um 23:26 schrieb Daniel Vetter:
> > The cleanup here is somewhat tricky, since we can't tell apart the
> > allocated minor index from 0. So register a cleanup action first, and
> > if the index allocation fails, unregister that cleanup action again to
> > avoid bad mistakes.
> > 
> > The kdev for the minor already handles NULL, so no problem there.
> > 
> > Hence add drmm_remove_action() to the drm_managed library.
> > 
> > v2: Make pointer math around void ** consistent with what Laurent
> > suggested.
> > 
> > Cc: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
> > Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
> > ---
> >  drivers/gpu/drm/drm_drv.c     | 74 +++++++++++++----------------------
> >  drivers/gpu/drm/drm_managed.c | 28 +++++++++++++
> >  include/drm/drm_managed.h     |  4 ++
> >  3 files changed, 59 insertions(+), 47 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c
> > index 23e5b0e7e041..29d106195ab3 100644
> > --- a/drivers/gpu/drm/drm_drv.c
> > +++ b/drivers/gpu/drm/drm_drv.c
> > @@ -93,19 +93,35 @@ static struct drm_minor **drm_minor_get_slot(struct drm_device *dev,
> >  	}
> >  }
> >  
> > +static void drm_minor_alloc_release(struct drm_device *dev, void *data)
> > +{
> > +	struct drm_minor *minor = data;
> > +	unsigned long flags;
> > +
> > +	put_device(minor->kdev);
> > +
> > +	spin_lock_irqsave(&drm_minor_lock, flags);
> > +	idr_remove(&drm_minors_idr, minor->index);
> > +	spin_unlock_irqrestore(&drm_minor_lock, flags);
> > +}
> > +
> >  static int drm_minor_alloc(struct drm_device *dev, unsigned int type)
> >  {
> >  	struct drm_minor *minor;
> >  	unsigned long flags;
> >  	int r;
> >  
> > -	minor = kzalloc(sizeof(*minor), GFP_KERNEL);
> > +	minor = drmm_kzalloc(dev, sizeof(*minor), GFP_KERNEL);
> >  	if (!minor)
> >  		return -ENOMEM;
> >  
> >  	minor->type = type;
> >  	minor->dev = dev;
> >  
> > +	r = drmm_add_action(dev, drm_minor_alloc_release, minor);
> > +	if (r)
> > +		return r;
> > +
> >  	idr_preload(GFP_KERNEL);
> >  	spin_lock_irqsave(&drm_minor_lock, flags);
> >  	r = idr_alloc(&drm_minors_idr,
> > @@ -116,47 +132,18 @@ static int drm_minor_alloc(struct drm_device *dev, unsigned int type)
> >  	spin_unlock_irqrestore(&drm_minor_lock, flags);
> >  	idr_preload_end();
> >  
> > -	if (r < 0)
> > -		goto err_free;
> > +	if (r < 0) {
> > +		drmm_remove_action(dev, drm_minor_alloc_release, minor);
> > +		return r;
> > +	}
> >  
> >  	minor->index = r;
> > -
> >  	minor->kdev = drm_sysfs_minor_alloc(minor);
> > -	if (IS_ERR(minor->kdev)) {
> > -		r = PTR_ERR(minor->kdev);
> > -		goto err_index;
> > -	}
> > +	if (IS_ERR(minor->kdev))
> > +		return PTR_ERR(minor->kdev);
> >  
> >  	*drm_minor_get_slot(dev, type) = minor;
> >  	return 0;
> > -
> > -err_index:
> > -	spin_lock_irqsave(&drm_minor_lock, flags);
> > -	idr_remove(&drm_minors_idr, minor->index);
> > -	spin_unlock_irqrestore(&drm_minor_lock, flags);
> > -err_free:
> > -	kfree(minor);
> > -	return r;
> > -}
> 
> TBH, I think you're reducing code quality by removing the rollback code
> from init functions, just for the sake of it.
> 
> Specifically in this case here, you saved a few lines of code, but the
> overall flow is way more complicated to follow. That's typically a
> reliably source of bugs. This call to drmm_remove_action() just makes it
> worse.
> 
> Rather, see my remark on OOP destruction in patch 21. For now, I'd focus
> on the device cleanup and leave init functions as they are.

Ah, I can simplify this with add_action_or_reset. This removes the only
user of drmm_remove_action, which I think is actually a good thing :-)
-Daniel

> 
> Best regards
> Thomas
> 
> > -
> > -static void drm_minor_free(struct drm_device *dev, unsigned int type)
> > -{
> > -	struct drm_minor **slot, *minor;
> > -	unsigned long flags;
> > -
> > -	slot = drm_minor_get_slot(dev, type);
> > -	minor = *slot;
> > -	if (!minor)
> > -		return;
> > -
> > -	put_device(minor->kdev);
> > -
> > -	spin_lock_irqsave(&drm_minor_lock, flags);
> > -	idr_remove(&drm_minors_idr, minor->index);
> > -	spin_unlock_irqrestore(&drm_minor_lock, flags);
> > -
> > -	kfree(minor);
> > -	*slot = NULL;
> >  }
> >  
> >  static int drm_minor_register(struct drm_device *dev, unsigned int type)
> > @@ -678,16 +665,16 @@ int drm_dev_init(struct drm_device *dev,
> >  	if (drm_core_check_feature(dev, DRIVER_RENDER)) {
> >  		ret = drm_minor_alloc(dev, DRM_MINOR_RENDER);
> >  		if (ret)
> > -			goto err_minors;
> > +			goto err;
> >  	}
> >  
> >  	ret = drm_minor_alloc(dev, DRM_MINOR_PRIMARY);
> >  	if (ret)
> > -		goto err_minors;
> > +		goto err;
> >  
> >  	ret = drm_legacy_create_map_hash(dev);
> >  	if (ret)
> > -		goto err_minors;
> > +		goto err;
> >  
> >  	drm_legacy_ctxbitmap_init(dev);
> >  
> > @@ -695,7 +682,7 @@ int drm_dev_init(struct drm_device *dev,
> >  		ret = drm_gem_init(dev);
> >  		if (ret) {
> >  			DRM_ERROR("Cannot initialize graphics execution manager (GEM)\n");
> > -			goto err_ctxbitmap;
> > +			goto err;
> >  		}
> >  	}
> >  
> > @@ -708,10 +695,6 @@ int drm_dev_init(struct drm_device *dev,
> >  err_setunique:
> >  	if (drm_core_check_feature(dev, DRIVER_GEM))
> >  		drm_gem_destroy(dev);
> > -err_ctxbitmap:
> > -err_minors:
> > -	drm_minor_free(dev, DRM_MINOR_PRIMARY);
> > -	drm_minor_free(dev, DRM_MINOR_RENDER);
> >  err:
> >  	drm_managed_release(dev);
> >  
> > @@ -776,9 +759,6 @@ void drm_dev_fini(struct drm_device *dev)
> >  
> >  	if (drm_core_check_feature(dev, DRIVER_GEM))
> >  		drm_gem_destroy(dev);
> > -
> > -	drm_minor_free(dev, DRM_MINOR_PRIMARY);
> > -	drm_minor_free(dev, DRM_MINOR_RENDER);
> >  }
> >  EXPORT_SYMBOL(drm_dev_fini);
> >  
> > diff --git a/drivers/gpu/drm/drm_managed.c b/drivers/gpu/drm/drm_managed.c
> > index 514d5bd42446..0883615c2088 100644
> > --- a/drivers/gpu/drm/drm_managed.c
> > +++ b/drivers/gpu/drm/drm_managed.c
> > @@ -142,6 +142,34 @@ int __drmm_add_action(struct drm_device *dev,
> >  }
> >  EXPORT_SYMBOL(__drmm_add_action);
> >  
> > +void drmm_remove_action(struct drm_device *dev,
> > +			drmres_release_t action,
> > +			void *data)
> > +{
> > +	struct drmres *dr = NULL, *tmp;
> > +	unsigned long flags;
> > +
> > +	if (!data)
> > +		return;
> > +
> > +	spin_lock_irqsave(&dev->managed.lock, flags);
> > +	list_for_each_entry(tmp, &dev->managed.resources, node.entry) {
> > +		if (tmp->node.release == action &&
> > +		    *(void **)&tmp->data == data) {
> > +			dr = tmp;
> > +			del_dr(dev, dr);
> > +			break;
> > +		}
> > +	}
> > +	spin_unlock_irqrestore(&dev->managed.lock, flags);
> > +
> > +	if (WARN_ON(!dr))
> > +		return;
> > +
> > +	kfree(dr);
> > +}
> > +EXPORT_SYMBOL(drmm_remove_action);
> > +
> >  void *drmm_kmalloc(struct drm_device *dev, size_t size, gfp_t gfp)
> >  {
> >  	struct drmres *dr;
> > diff --git a/include/drm/drm_managed.h b/include/drm/drm_managed.h
> > index 89e6fce9f689..5280209dff92 100644
> > --- a/include/drm/drm_managed.h
> > +++ b/include/drm/drm_managed.h
> > @@ -17,6 +17,10 @@ int __must_check __drmm_add_action(struct drm_device *dev,
> >  				   drmres_release_t action,
> >  				   void *data, const char *name);
> >  
> > +void drmm_remove_action(struct drm_device *dev,
> > +			drmres_release_t action,
> > +			void *data);
> > +
> >  void drmm_add_final_kfree(struct drm_device *dev, void *parent);
> >  
> >  void *drmm_kmalloc(struct drm_device *dev, size_t size, gfp_t gfp) __malloc;
> > 
> 
> -- 
> Thomas Zimmermann
> Graphics Driver Developer
> SUSE Software Solutions Germany GmbH
> Maxfeldstr. 5, 90409 Nürnberg, Germany
> (HRB 36809, AG Nürnberg)
> Geschäftsführer: Felix Imendörffer
> 




-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 111+ messages in thread

* Re: [PATCH 20/51] drm: Handle dev->unique with drmm_
  2020-03-06 20:37   ` Sam Ravnborg
@ 2020-03-23 10:54     ` Daniel Vetter
  0 siblings, 0 replies; 111+ messages in thread
From: Daniel Vetter @ 2020-03-23 10:54 UTC (permalink / raw)
  To: Sam Ravnborg
  Cc: Daniel Vetter, Intel Graphics Development, DRI Development,
	Daniel Vetter

On Fri, Mar 06, 2020 at 09:37:10PM +0100, Sam Ravnborg wrote:
> On Mon, Mar 02, 2020 at 11:26:00PM +0100, Daniel Vetter wrote:
> > We need to add a drmm_kstrdup for this, but let's start somewhere.
> > 
> > This is not exactly perfect onion unwinding, but it's jsut a kfree so
> > doesn't really matter at all.
> > 
> > Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
> 
> Reluctanlyt... But anyway
> Reviewed-by: Sam Ravnborg <sam@ravnborg.org>
> 
> See below for a few comments.
> 
> 
> > ---
> >  drivers/gpu/drm/drm_drv.c     |  5 ++---
> >  drivers/gpu/drm/drm_managed.c | 16 ++++++++++++++++
> >  include/drm/drm_managed.h     |  1 +
> >  3 files changed, 19 insertions(+), 3 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c
> > index 1a048325f30e..ef79c03e311c 100644
> > --- a/drivers/gpu/drm/drm_drv.c
> > +++ b/drivers/gpu/drm/drm_drv.c
> > @@ -777,7 +777,6 @@ void drm_dev_fini(struct drm_device *dev)
> >  	mutex_destroy(&dev->filelist_mutex);
> >  	mutex_destroy(&dev->struct_mutex);
> >  	drm_legacy_destroy_members(dev);
> > -	kfree(dev->unique);
> >  }
> >  EXPORT_SYMBOL(drm_dev_fini);
> >  
> > @@ -1068,8 +1067,8 @@ EXPORT_SYMBOL(drm_dev_unregister);
> >   */
> >  int drm_dev_set_unique(struct drm_device *dev, const char *name)
> >  {
> > -	kfree(dev->unique);
> > -	dev->unique = kstrdup(name, GFP_KERNEL);
> > +	drmm_kfree(dev, dev->unique);
> > +	dev->unique = drmm_kstrdup(dev, name, GFP_KERNEL);
> >  
> >  	return dev->unique ? 0 : -ENOMEM;
> >  }
> > diff --git a/drivers/gpu/drm/drm_managed.c b/drivers/gpu/drm/drm_managed.c
> > index 57dc79fa90af..514d5bd42446 100644
> > --- a/drivers/gpu/drm/drm_managed.c
> > +++ b/drivers/gpu/drm/drm_managed.c
> > @@ -160,6 +160,22 @@ void *drmm_kmalloc(struct drm_device *dev, size_t size, gfp_t gfp)
> >  }
> >  EXPORT_SYMBOL(drmm_kmalloc);
> >  
> > +char *drmm_kstrdup(struct drm_device *dev, const char *s, gfp_t gfp)
> 
> So we need this gfp for all users - just because i915 is special and
> uses "GFP_KERNEL | __GFP_RETRY_MAYFAIL | __GFP_NOWARN" in to places -
> sigh.

Nope, that's not the reason. That NOWARN is not in a driver load path, so
won't ever get converted to drmm_.

Sole reason for adding gfp_flags is consisteny with everything else -
devm_ also has them (and I'd question anyone who does stuff like
GFP_ATOMIC in their driver load path). I guess you can make a case that
some memory allocation functions shouldn't have a gfp_flags parameter
because the only thing you can use that for is create bugs (everyone
should set GFP_KERNEL, maybe with the GFP_ZERO flag set on top). But not
really what I'm aiming for in this series :-)

Hope that explains why I'm sticking with this here.
-Daniel

> 
> 
> 
> > +{
> > +	size_t size;
> > +	char *buf;
> > +
> > +	if (!s)
> > +		return NULL;
> > +
> > +	size = strlen(s) + 1;
> > +	buf = drmm_kmalloc(dev, size, gfp);
> > +	if (buf)
> > +		memcpy(buf, s, size);
> > +	return buf;
> > +}
> > +EXPORT_SYMBOL_GPL(drmm_kstrdup);
> > +
> >  void drmm_kfree(struct drm_device *dev, void *data)
> >  {
> >  	struct drmres *dr_match = NULL, *dr;
> > diff --git a/include/drm/drm_managed.h b/include/drm/drm_managed.h
> > index 7b5df7d09b19..89e6fce9f689 100644
> > --- a/include/drm/drm_managed.h
> > +++ b/include/drm/drm_managed.h
> > @@ -24,6 +24,7 @@ static inline void *drmm_kzalloc(struct drm_device *dev, size_t size, gfp_t gfp)
> >  {
> >  	return drmm_kmalloc(dev, size, gfp | __GFP_ZERO);
> >  }
> > +char *drmm_kstrdup(struct drm_device *dev, const char *s, gfp_t gfp);
> Missing empty line above. But it is fixed later IIRC
> 
> >  
> >  void drmm_kfree(struct drm_device *dev, void *data);
> >  
> > -- 
> > 2.24.1
> > 
> > _______________________________________________
> > dri-devel mailing list
> > dri-devel@lists.freedesktop.org
> > https://lists.freedesktop.org/mailman/listinfo/dri-devel

-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 111+ messages in thread

* Re: [PATCH 04/51] drm: Set final_kfree in drm_dev_alloc
  2020-03-07  8:06   ` Sam Ravnborg
@ 2020-03-23 11:02     ` Daniel Vetter
  0 siblings, 0 replies; 111+ messages in thread
From: Daniel Vetter @ 2020-03-23 11:02 UTC (permalink / raw)
  To: Sam Ravnborg
  Cc: Oleksandr Andrushchenko, David Airlie, Daniel Vetter,
	Intel Graphics Development, DRI Development, Gerd Hoffmann,
	Thomas Zimmermann, Daniel Vetter, xen-devel

On Sat, Mar 07, 2020 at 09:06:08AM +0100, Sam Ravnborg wrote:
> On Mon, Mar 02, 2020 at 11:25:44PM +0100, Daniel Vetter wrote:
> > I also did a full review of all callers, and only the xen driver
> > forgot to call drm_dev_put in the failure path. Fix that up too.
> 
> So ~40 callers - phew..
> 
> > 
> > v2: I noticed that xen has a drm_driver.release hook, and uses
> > drm_dev_alloc(). We need to remove the kfree from
> > xen_drm_drv_release().
> > 
> > bochs also has a release hook, but leaked the drm_device ever since
> > 
> > commit 0a6659bdc5e8221da99eebb176fd9591435e38de
> > Author: Gerd Hoffmann <kraxel@redhat.com>
> > Date:   Tue Dec 17 18:04:46 2013 +0100
> > 
> >     drm/bochs: new driver
> > 
> > This patch here fixes that leak.
> > 
> > Same for virtio, started leaking with
> > 
> > commit b1df3a2b24a917f8853d43fe9683c0e360d2c33a
> > Author: Gerd Hoffmann <kraxel@redhat.com>
> > Date:   Tue Feb 11 14:58:04 2020 +0100
> > 
> >     drm/virtio: add drm_driver.release callback.
> > 
> > Cc: Gerd Hoffmann <kraxel@redhat.com>
> > Cc: Oleksandr Andrushchenko <oleksandr_andrushchenko@epam.com>
> > Cc: xen-devel@lists.xenproject.org
> 
> The above will be picked up by tools as regular Cc: lines.
> But I guess it is fine.

That was the idea, I've deleted the spurious blank line to make this less
confusing.
-Daniel

> 
> > 
> > Reviewed-by: Oleksandr Andrushchenko <oleksandr_andrushchenko@epam.com>
> > Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
> > Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
> > Cc: Maxime Ripard <mripard@kernel.org>
> > Cc: Thomas Zimmermann <tzimmermann@suse.de>
> > Cc: David Airlie <airlied@linux.ie>
> > Cc: Daniel Vetter <daniel@ffwll.ch>
> > Cc: Oleksandr Andrushchenko <oleksandr_andrushchenko@epam.com>
> > Cc: xen-devel@lists.xenproject.org
> 
> For the drivers I looked at everything looked fine.
> 
> Acked-by: Sam Ravnborg <sam@ravnborg.org>
> 
> > ---
> >  drivers/gpu/drm/drm_drv.c           | 3 +++
> >  drivers/gpu/drm/xen/xen_drm_front.c | 2 +-
> >  2 files changed, 4 insertions(+), 1 deletion(-)
> > 
> > diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c
> > index 153050fc926c..7b84ee8a5eb5 100644
> > --- a/drivers/gpu/drm/drm_drv.c
> > +++ b/drivers/gpu/drm/drm_drv.c
> > @@ -39,6 +39,7 @@
> >  #include <drm/drm_color_mgmt.h>
> >  #include <drm/drm_drv.h>
> >  #include <drm/drm_file.h>
> > +#include <drm/drm_managed.h>
> >  #include <drm/drm_mode_object.h>
> >  #include <drm/drm_print.h>
> >  
> > @@ -819,6 +820,8 @@ struct drm_device *drm_dev_alloc(struct drm_driver *driver,
> >  		return ERR_PTR(ret);
> >  	}
> >  
> > +	drmm_add_final_kfree(dev, dev);
> > +
> >  	return dev;
> >  }
> >  EXPORT_SYMBOL(drm_dev_alloc);
> > diff --git a/drivers/gpu/drm/xen/xen_drm_front.c b/drivers/gpu/drm/xen/xen_drm_front.c
> > index 4be49c1aef51..d22b5da38935 100644
> > --- a/drivers/gpu/drm/xen/xen_drm_front.c
> > +++ b/drivers/gpu/drm/xen/xen_drm_front.c
> > @@ -461,7 +461,6 @@ static void xen_drm_drv_release(struct drm_device *dev)
> >  	drm_mode_config_cleanup(dev);
> >  
> >  	drm_dev_fini(dev);
> > -	kfree(dev);
> >  
> >  	if (front_info->cfg.be_alloc)
> >  		xenbus_switch_state(front_info->xb_dev,
> > @@ -561,6 +560,7 @@ static int xen_drm_drv_init(struct xen_drm_front_info *front_info)
> >  fail_modeset:
> >  	drm_kms_helper_poll_fini(drm_dev);
> >  	drm_mode_config_cleanup(drm_dev);
> > +	drm_dev_put(drm_dev);
> >  fail:
> >  	kfree(drm_info);
> >  	return ret;
> > -- 
> > 2.24.1
> > 
> > _______________________________________________
> > dri-devel mailing list
> > dri-devel@lists.freedesktop.org
> > https://lists.freedesktop.org/mailman/listinfo/dri-devel

-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 111+ messages in thread

* [PATCH 50/51] drm/udl: drop drm_driver.release hook
  2020-03-23 14:48 [PATCH 00/51] drm_device managed resources, v5 Daniel Vetter
@ 2020-03-23 14:49 ` Daniel Vetter
  0 siblings, 0 replies; 111+ messages in thread
From: Daniel Vetter @ 2020-03-23 14:49 UTC (permalink / raw)
  To: DRI Development
  Cc: Sam Ravnborg, Daniel Vetter, Intel Graphics Development,
	Emil Velikov, Gerd Hoffmann, Thomas Zimmermann, Daniel Vetter,
	Alex Deucher, Dave Airlie, Thomas Gleixner, Sean Paul

There's only two functions called from that:
drm_kms_helper_poll_fini() and udl_free_urb_list(). Both of these are
also called from the ubs_driver->disconnect hook, so entirely
pointless to do the same again in the ->release hook.

Furthermore by the time we clean up the drm_driver we really shouldn't
be touching hardware anymore, so stopping the poll worker and freeing
the urb allocations in ->disconnect is the right thing to do.

Now disconnect still cleans things up before unregistering the driver,
but that's a different issue.

v2: Use _fini, not _disable in unplug, motivated by discussions with
Thomas. _disable/_enable are for suspend/resume.

Acked-by: Thomas Zimmermann <tzimmermann@suse.de>
Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
Cc: Dave Airlie <airlied@redhat.com>
Cc: Sean Paul <sean@poorly.run>
Cc: Daniel Vetter <daniel.vetter@ffwll.ch>
Cc: Thomas Zimmermann <tzimmermann@suse.de>
Cc: Emil Velikov <emil.l.velikov@gmail.com>
Cc: Gerd Hoffmann <kraxel@redhat.com>
Cc: "Noralf Trønnes" <noralf@tronnes.org>
Cc: Sam Ravnborg <sam@ravnborg.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Alex Deucher <alexander.deucher@amd.com>
---
 drivers/gpu/drm/udl/udl_drv.c  |  8 +-------
 drivers/gpu/drm/udl/udl_drv.h  |  1 -
 drivers/gpu/drm/udl/udl_main.c | 10 ----------
 3 files changed, 1 insertion(+), 18 deletions(-)

diff --git a/drivers/gpu/drm/udl/udl_drv.c b/drivers/gpu/drm/udl/udl_drv.c
index b447fb053e78..1ce2d865c36d 100644
--- a/drivers/gpu/drm/udl/udl_drv.c
+++ b/drivers/gpu/drm/udl/udl_drv.c
@@ -34,14 +34,8 @@ static int udl_usb_resume(struct usb_interface *interface)
 
 DEFINE_DRM_GEM_FOPS(udl_driver_fops);
 
-static void udl_driver_release(struct drm_device *dev)
-{
-	udl_fini(dev);
-}
-
 static struct drm_driver driver = {
 	.driver_features = DRIVER_ATOMIC | DRIVER_GEM | DRIVER_MODESET,
-	.release = udl_driver_release,
 
 	/* gem hooks */
 	.gem_create_object = udl_driver_gem_create_object,
@@ -120,7 +114,7 @@ static void udl_usb_disconnect(struct usb_interface *interface)
 {
 	struct drm_device *dev = usb_get_intfdata(interface);
 
-	drm_kms_helper_poll_disable(dev);
+	drm_kms_helper_poll_fini(dev);
 	udl_drop_usb(dev);
 	drm_dev_unplug(dev);
 	drm_dev_put(dev);
diff --git a/drivers/gpu/drm/udl/udl_drv.h b/drivers/gpu/drm/udl/udl_drv.h
index 1de7eb1b6aac..2642f94a63fc 100644
--- a/drivers/gpu/drm/udl/udl_drv.h
+++ b/drivers/gpu/drm/udl/udl_drv.h
@@ -76,7 +76,6 @@ int udl_submit_urb(struct drm_device *dev, struct urb *urb, size_t len);
 void udl_urb_completion(struct urb *urb);
 
 int udl_init(struct udl_device *udl);
-void udl_fini(struct drm_device *dev);
 
 int udl_render_hline(struct drm_device *dev, int log_bpp, struct urb **urb_ptr,
 		     const char *front, char **urb_buf_ptr,
diff --git a/drivers/gpu/drm/udl/udl_main.c b/drivers/gpu/drm/udl/udl_main.c
index 538718919916..f5d27f2a5654 100644
--- a/drivers/gpu/drm/udl/udl_main.c
+++ b/drivers/gpu/drm/udl/udl_main.c
@@ -351,13 +351,3 @@ int udl_drop_usb(struct drm_device *dev)
 	udl_free_urb_list(dev);
 	return 0;
 }
-
-void udl_fini(struct drm_device *dev)
-{
-	struct udl_device *udl = to_udl(dev);
-
-	drm_kms_helper_poll_fini(dev);
-
-	if (udl->urbs.count)
-		udl_free_urb_list(dev);
-}
-- 
2.25.1

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 111+ messages in thread

* Re: [PATCH 50/51] drm/udl: drop drm_driver.release hook
  2020-03-02  8:14           ` Thomas Zimmermann
@ 2020-03-02  9:01             ` Daniel Vetter
  0 siblings, 0 replies; 111+ messages in thread
From: Daniel Vetter @ 2020-03-02  9:01 UTC (permalink / raw)
  To: Thomas Zimmermann
  Cc: Sean Paul, Intel Graphics Development, Emil Velikov,
	Marco Felsch, DRI Development, Gerd Hoffmann, Daniel Vetter,
	Alex Deucher, Dave Airlie, Thomas Gleixner, Sam Ravnborg

On Mon, Mar 2, 2020 at 9:14 AM Thomas Zimmermann <tzimmermann@suse.de> wrote:
>
> Hi Daniel
>
> Am 28.02.20 um 18:43 schrieb Daniel Vetter:
> > On Fri, Feb 28, 2020 at 12:46 PM Thomas Zimmermann <tzimmermann@suse.de> wrote:
> >>
> >> Hi
> >>
> >> Am 28.02.20 um 09:40 schrieb Daniel Vetter:
> >>> On Fri, Feb 28, 2020 at 8:44 AM Thomas Zimmermann <tzimmermann@suse.de> wrote:
> >>>>
> >>>> Hi Daniel
> >>>>
> >>>> Am 27.02.20 um 19:15 schrieb Daniel Vetter:
> >>>>> There's only two functions called from that:
> >>>>> drm_kms_helper_poll_fini() and udl_free_urb_list(). Both of these are
> >>>>> also called from the ubs_driver->disconnect hook, so entirely
> >>>>> pointless to do the same again in the ->release hook.
> >>>>
> >>>> The disconnect hook calls drm_kms_helper_poll_disable() instead if
> >>>> _fini(). They are the same, except that _disable() does not clear
> >>>> dev->mode_config.poll_enabled to false. Is this OK?
> >>>
> >>> oops, I overlooked that. But yeah for driver shutdown it's the same
> >>> really, we're not going to re-enable. _disable is meant for suspend so
> >>> youc an re-enable again on resume.
> >>>
> >>> I'll augment the commit message on the next round to clarify that.
> >>
> >> Well, we have a managed API. It could support
> >> drmm_kms_helper_poll_init(). :)
> >
> > You're ahead of the game here, but yes that's the plan. And a lot
> > more. Ideally I really want to get rid of both bus_driver->remove and
> > drm_driver->release callbacks for all drivers.
> >
> > Also, for polling you actually want devm_kms_poll_init, since polling
> > should be stopped at unplug/remove time. Not at drm_driver release
> > time :-)
>
> Quite honestly, if you're not adding devm_kms_poll_init() now, why even
> bother removing the _fini() call from release()? It hasn't been a
> problem so far and it won't become one. Doing a half-baked change now
> results in a potential WTF moment for other developers.
>
> Rather clean up release() when you add the managed devm_kms_poll_init()
> and have a nice, clear patch.

So the thing is, you need to stop your poll worker in ->unplug, not
->release. That's the part I'm fixing here (plus stopping it twice is
overkill). I'm not seeing any connection to making the ->unplug part
here automatic, that was just a future idea. But this patch series
here is all about ->release stuff. I guess I can do a respin and
change the one in ->unplug from _disable to _fini, which would be
clearer.

But not doing this patch here just because we want to clean things up
even more doesn't make sense to me.
-Daniel

> Best regards
> Thomas
>
>
> > -Daniel
> >
> >>
> >> Best regards
> >> Thomas
> >>
> >>> -Daniel
> >>>
> >>>
> >>>> Best regards
> >>>> Thomas
> >>>>
> >>>>>
> >>>>> Furthermore by the time we clean up the drm_driver we really shouldn't
> >>>>> be touching hardware anymore, so stopping the poll worker and freeing
> >>>>> the urb allocations in ->disconnect is the right thing to do.
> >>>>>
> >>>>> Now disconnect still cleans things up before unregistering the driver,
> >>>>> but that's a different issue.
> >>>>>
> >>>>> Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
> >>>>> Cc: Dave Airlie <airlied@redhat.com>
> >>>>> Cc: Sean Paul <sean@poorly.run>
> >>>>> Cc: Daniel Vetter <daniel.vetter@ffwll.ch>
> >>>>> Cc: Thomas Zimmermann <tzimmermann@suse.de>
> >>>>> Cc: Emil Velikov <emil.l.velikov@gmail.com>
> >>>>> Cc: Gerd Hoffmann <kraxel@redhat.com>
> >>>>> Cc: "Noralf Trønnes" <noralf@tronnes.org>
> >>>>> Cc: Sam Ravnborg <sam@ravnborg.org>
> >>>>> Cc: Thomas Gleixner <tglx@linutronix.de>
> >>>>> Cc: Alex Deucher <alexander.deucher@amd.com>
> >>>>> ---
> >>>>>  drivers/gpu/drm/udl/udl_drv.c  |  6 ------
> >>>>>  drivers/gpu/drm/udl/udl_drv.h  |  1 -
> >>>>>  drivers/gpu/drm/udl/udl_main.c | 10 ----------
> >>>>>  3 files changed, 17 deletions(-)
> >>>>>
> >>>>> diff --git a/drivers/gpu/drm/udl/udl_drv.c b/drivers/gpu/drm/udl/udl_drv.c
> >>>>> index b447fb053e78..7f140898df3e 100644
> >>>>> --- a/drivers/gpu/drm/udl/udl_drv.c
> >>>>> +++ b/drivers/gpu/drm/udl/udl_drv.c
> >>>>> @@ -34,14 +34,8 @@ static int udl_usb_resume(struct usb_interface *interface)
> >>>>>
> >>>>>  DEFINE_DRM_GEM_FOPS(udl_driver_fops);
> >>>>>
> >>>>> -static void udl_driver_release(struct drm_device *dev)
> >>>>> -{
> >>>>> -     udl_fini(dev);
> >>>>> -}
> >>>>> -
> >>>>>  static struct drm_driver driver = {
> >>>>>       .driver_features = DRIVER_ATOMIC | DRIVER_GEM | DRIVER_MODESET,
> >>>>> -     .release = udl_driver_release,
> >>>>>
> >>>>>       /* gem hooks */
> >>>>>       .gem_create_object = udl_driver_gem_create_object,
> >>>>> diff --git a/drivers/gpu/drm/udl/udl_drv.h b/drivers/gpu/drm/udl/udl_drv.h
> >>>>> index 1de7eb1b6aac..2642f94a63fc 100644
> >>>>> --- a/drivers/gpu/drm/udl/udl_drv.h
> >>>>> +++ b/drivers/gpu/drm/udl/udl_drv.h
> >>>>> @@ -76,7 +76,6 @@ int udl_submit_urb(struct drm_device *dev, struct urb *urb, size_t len);
> >>>>>  void udl_urb_completion(struct urb *urb);
> >>>>>
> >>>>>  int udl_init(struct udl_device *udl);
> >>>>> -void udl_fini(struct drm_device *dev);
> >>>>>
> >>>>>  int udl_render_hline(struct drm_device *dev, int log_bpp, struct urb **urb_ptr,
> >>>>>                    const char *front, char **urb_buf_ptr,
> >>>>> diff --git a/drivers/gpu/drm/udl/udl_main.c b/drivers/gpu/drm/udl/udl_main.c
> >>>>> index 538718919916..f5d27f2a5654 100644
> >>>>> --- a/drivers/gpu/drm/udl/udl_main.c
> >>>>> +++ b/drivers/gpu/drm/udl/udl_main.c
> >>>>> @@ -351,13 +351,3 @@ int udl_drop_usb(struct drm_device *dev)
> >>>>>       udl_free_urb_list(dev);
> >>>>>       return 0;
> >>>>>  }
> >>>>> -
> >>>>> -void udl_fini(struct drm_device *dev)
> >>>>> -{
> >>>>> -     struct udl_device *udl = to_udl(dev);
> >>>>> -
> >>>>> -     drm_kms_helper_poll_fini(dev);
> >>>>> -
> >>>>> -     if (udl->urbs.count)
> >>>>> -             udl_free_urb_list(dev);
> >>>>> -}
> >>>>>
> >>>>
> >>>> --
> >>>> Thomas Zimmermann
> >>>> Graphics Driver Developer
> >>>> SUSE Software Solutions Germany GmbH
> >>>> Maxfeldstr. 5, 90409 Nürnberg, Germany
> >>>> (HRB 36809, AG Nürnberg)
> >>>> Geschäftsführer: Felix Imendörffer
> >>>>
> >>>
> >>>
> >>
> >> --
> >> Thomas Zimmermann
> >> Graphics Driver Developer
> >> SUSE Software Solutions Germany GmbH
> >> Maxfeldstr. 5, 90409 Nürnberg, Germany
> >> (HRB 36809, AG Nürnberg)
> >> Geschäftsführer: Felix Imendörffer
> >>
> >
> >
>
> --
> Thomas Zimmermann
> Graphics Driver Developer
> SUSE Software Solutions Germany GmbH
> Maxfeldstr. 5, 90409 Nürnberg, Germany
> (HRB 36809, AG Nürnberg)
> Geschäftsführer: Felix Imendörffer
>


-- 
Daniel Vetter
Software Engineer, Intel Corporation
+41 (0) 79 365 57 48 - http://blog.ffwll.ch
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 111+ messages in thread

* Re: [PATCH 50/51] drm/udl: drop drm_driver.release hook
  2020-02-28 17:43         ` Daniel Vetter
@ 2020-03-02  8:14           ` Thomas Zimmermann
  2020-03-02  9:01             ` Daniel Vetter
  0 siblings, 1 reply; 111+ messages in thread
From: Thomas Zimmermann @ 2020-03-02  8:14 UTC (permalink / raw)
  To: Daniel Vetter
  Cc: Sean Paul, Intel Graphics Development, Emil Velikov,
	Marco Felsch, DRI Development, Gerd Hoffmann, Daniel Vetter,
	Alex Deucher, Dave Airlie, Thomas Gleixner, Sam Ravnborg


[-- Attachment #1.1.1: Type: text/plain, Size: 5856 bytes --]

Hi Daniel

Am 28.02.20 um 18:43 schrieb Daniel Vetter:
> On Fri, Feb 28, 2020 at 12:46 PM Thomas Zimmermann <tzimmermann@suse.de> wrote:
>>
>> Hi
>>
>> Am 28.02.20 um 09:40 schrieb Daniel Vetter:
>>> On Fri, Feb 28, 2020 at 8:44 AM Thomas Zimmermann <tzimmermann@suse.de> wrote:
>>>>
>>>> Hi Daniel
>>>>
>>>> Am 27.02.20 um 19:15 schrieb Daniel Vetter:
>>>>> There's only two functions called from that:
>>>>> drm_kms_helper_poll_fini() and udl_free_urb_list(). Both of these are
>>>>> also called from the ubs_driver->disconnect hook, so entirely
>>>>> pointless to do the same again in the ->release hook.
>>>>
>>>> The disconnect hook calls drm_kms_helper_poll_disable() instead if
>>>> _fini(). They are the same, except that _disable() does not clear
>>>> dev->mode_config.poll_enabled to false. Is this OK?
>>>
>>> oops, I overlooked that. But yeah for driver shutdown it's the same
>>> really, we're not going to re-enable. _disable is meant for suspend so
>>> youc an re-enable again on resume.
>>>
>>> I'll augment the commit message on the next round to clarify that.
>>
>> Well, we have a managed API. It could support
>> drmm_kms_helper_poll_init(). :)
> 
> You're ahead of the game here, but yes that's the plan. And a lot
> more. Ideally I really want to get rid of both bus_driver->remove and
> drm_driver->release callbacks for all drivers.
> 
> Also, for polling you actually want devm_kms_poll_init, since polling
> should be stopped at unplug/remove time. Not at drm_driver release
> time :-)

Quite honestly, if you're not adding devm_kms_poll_init() now, why even
bother removing the _fini() call from release()? It hasn't been a
problem so far and it won't become one. Doing a half-baked change now
results in a potential WTF moment for other developers.

Rather clean up release() when you add the managed devm_kms_poll_init()
and have a nice, clear patch.

Best regards
Thomas


> -Daniel
> 
>>
>> Best regards
>> Thomas
>>
>>> -Daniel
>>>
>>>
>>>> Best regards
>>>> Thomas
>>>>
>>>>>
>>>>> Furthermore by the time we clean up the drm_driver we really shouldn't
>>>>> be touching hardware anymore, so stopping the poll worker and freeing
>>>>> the urb allocations in ->disconnect is the right thing to do.
>>>>>
>>>>> Now disconnect still cleans things up before unregistering the driver,
>>>>> but that's a different issue.
>>>>>
>>>>> Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
>>>>> Cc: Dave Airlie <airlied@redhat.com>
>>>>> Cc: Sean Paul <sean@poorly.run>
>>>>> Cc: Daniel Vetter <daniel.vetter@ffwll.ch>
>>>>> Cc: Thomas Zimmermann <tzimmermann@suse.de>
>>>>> Cc: Emil Velikov <emil.l.velikov@gmail.com>
>>>>> Cc: Gerd Hoffmann <kraxel@redhat.com>
>>>>> Cc: "Noralf Trønnes" <noralf@tronnes.org>
>>>>> Cc: Sam Ravnborg <sam@ravnborg.org>
>>>>> Cc: Thomas Gleixner <tglx@linutronix.de>
>>>>> Cc: Alex Deucher <alexander.deucher@amd.com>
>>>>> ---
>>>>>  drivers/gpu/drm/udl/udl_drv.c  |  6 ------
>>>>>  drivers/gpu/drm/udl/udl_drv.h  |  1 -
>>>>>  drivers/gpu/drm/udl/udl_main.c | 10 ----------
>>>>>  3 files changed, 17 deletions(-)
>>>>>
>>>>> diff --git a/drivers/gpu/drm/udl/udl_drv.c b/drivers/gpu/drm/udl/udl_drv.c
>>>>> index b447fb053e78..7f140898df3e 100644
>>>>> --- a/drivers/gpu/drm/udl/udl_drv.c
>>>>> +++ b/drivers/gpu/drm/udl/udl_drv.c
>>>>> @@ -34,14 +34,8 @@ static int udl_usb_resume(struct usb_interface *interface)
>>>>>
>>>>>  DEFINE_DRM_GEM_FOPS(udl_driver_fops);
>>>>>
>>>>> -static void udl_driver_release(struct drm_device *dev)
>>>>> -{
>>>>> -     udl_fini(dev);
>>>>> -}
>>>>> -
>>>>>  static struct drm_driver driver = {
>>>>>       .driver_features = DRIVER_ATOMIC | DRIVER_GEM | DRIVER_MODESET,
>>>>> -     .release = udl_driver_release,
>>>>>
>>>>>       /* gem hooks */
>>>>>       .gem_create_object = udl_driver_gem_create_object,
>>>>> diff --git a/drivers/gpu/drm/udl/udl_drv.h b/drivers/gpu/drm/udl/udl_drv.h
>>>>> index 1de7eb1b6aac..2642f94a63fc 100644
>>>>> --- a/drivers/gpu/drm/udl/udl_drv.h
>>>>> +++ b/drivers/gpu/drm/udl/udl_drv.h
>>>>> @@ -76,7 +76,6 @@ int udl_submit_urb(struct drm_device *dev, struct urb *urb, size_t len);
>>>>>  void udl_urb_completion(struct urb *urb);
>>>>>
>>>>>  int udl_init(struct udl_device *udl);
>>>>> -void udl_fini(struct drm_device *dev);
>>>>>
>>>>>  int udl_render_hline(struct drm_device *dev, int log_bpp, struct urb **urb_ptr,
>>>>>                    const char *front, char **urb_buf_ptr,
>>>>> diff --git a/drivers/gpu/drm/udl/udl_main.c b/drivers/gpu/drm/udl/udl_main.c
>>>>> index 538718919916..f5d27f2a5654 100644
>>>>> --- a/drivers/gpu/drm/udl/udl_main.c
>>>>> +++ b/drivers/gpu/drm/udl/udl_main.c
>>>>> @@ -351,13 +351,3 @@ int udl_drop_usb(struct drm_device *dev)
>>>>>       udl_free_urb_list(dev);
>>>>>       return 0;
>>>>>  }
>>>>> -
>>>>> -void udl_fini(struct drm_device *dev)
>>>>> -{
>>>>> -     struct udl_device *udl = to_udl(dev);
>>>>> -
>>>>> -     drm_kms_helper_poll_fini(dev);
>>>>> -
>>>>> -     if (udl->urbs.count)
>>>>> -             udl_free_urb_list(dev);
>>>>> -}
>>>>>
>>>>
>>>> --
>>>> Thomas Zimmermann
>>>> Graphics Driver Developer
>>>> SUSE Software Solutions Germany GmbH
>>>> Maxfeldstr. 5, 90409 Nürnberg, Germany
>>>> (HRB 36809, AG Nürnberg)
>>>> Geschäftsführer: Felix Imendörffer
>>>>
>>>
>>>
>>
>> --
>> Thomas Zimmermann
>> Graphics Driver Developer
>> SUSE Software Solutions Germany GmbH
>> Maxfeldstr. 5, 90409 Nürnberg, Germany
>> (HRB 36809, AG Nürnberg)
>> Geschäftsführer: Felix Imendörffer
>>
> 
> 

-- 
Thomas Zimmermann
Graphics Driver Developer
SUSE Software Solutions Germany GmbH
Maxfeldstr. 5, 90409 Nürnberg, Germany
(HRB 36809, AG Nürnberg)
Geschäftsführer: Felix Imendörffer


[-- Attachment #1.2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

[-- Attachment #2: Type: text/plain, Size: 160 bytes --]

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 111+ messages in thread

* Re: [PATCH 50/51] drm/udl: drop drm_driver.release hook
  2020-02-28 11:46       ` Thomas Zimmermann
@ 2020-02-28 17:43         ` Daniel Vetter
  2020-03-02  8:14           ` Thomas Zimmermann
  0 siblings, 1 reply; 111+ messages in thread
From: Daniel Vetter @ 2020-02-28 17:43 UTC (permalink / raw)
  To: Thomas Zimmermann
  Cc: Sean Paul, Intel Graphics Development, Emil Velikov,
	Marco Felsch, DRI Development, Gerd Hoffmann, Daniel Vetter,
	Alex Deucher, Dave Airlie, Thomas Gleixner, Sam Ravnborg

On Fri, Feb 28, 2020 at 12:46 PM Thomas Zimmermann <tzimmermann@suse.de> wrote:
>
> Hi
>
> Am 28.02.20 um 09:40 schrieb Daniel Vetter:
> > On Fri, Feb 28, 2020 at 8:44 AM Thomas Zimmermann <tzimmermann@suse.de> wrote:
> >>
> >> Hi Daniel
> >>
> >> Am 27.02.20 um 19:15 schrieb Daniel Vetter:
> >>> There's only two functions called from that:
> >>> drm_kms_helper_poll_fini() and udl_free_urb_list(). Both of these are
> >>> also called from the ubs_driver->disconnect hook, so entirely
> >>> pointless to do the same again in the ->release hook.
> >>
> >> The disconnect hook calls drm_kms_helper_poll_disable() instead if
> >> _fini(). They are the same, except that _disable() does not clear
> >> dev->mode_config.poll_enabled to false. Is this OK?
> >
> > oops, I overlooked that. But yeah for driver shutdown it's the same
> > really, we're not going to re-enable. _disable is meant for suspend so
> > youc an re-enable again on resume.
> >
> > I'll augment the commit message on the next round to clarify that.
>
> Well, we have a managed API. It could support
> drmm_kms_helper_poll_init(). :)

You're ahead of the game here, but yes that's the plan. And a lot
more. Ideally I really want to get rid of both bus_driver->remove and
drm_driver->release callbacks for all drivers.

Also, for polling you actually want devm_kms_poll_init, since polling
should be stopped at unplug/remove time. Not at drm_driver release
time :-)
-Daniel

>
> Best regards
> Thomas
>
> > -Daniel
> >
> >
> >> Best regards
> >> Thomas
> >>
> >>>
> >>> Furthermore by the time we clean up the drm_driver we really shouldn't
> >>> be touching hardware anymore, so stopping the poll worker and freeing
> >>> the urb allocations in ->disconnect is the right thing to do.
> >>>
> >>> Now disconnect still cleans things up before unregistering the driver,
> >>> but that's a different issue.
> >>>
> >>> Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
> >>> Cc: Dave Airlie <airlied@redhat.com>
> >>> Cc: Sean Paul <sean@poorly.run>
> >>> Cc: Daniel Vetter <daniel.vetter@ffwll.ch>
> >>> Cc: Thomas Zimmermann <tzimmermann@suse.de>
> >>> Cc: Emil Velikov <emil.l.velikov@gmail.com>
> >>> Cc: Gerd Hoffmann <kraxel@redhat.com>
> >>> Cc: "Noralf Trønnes" <noralf@tronnes.org>
> >>> Cc: Sam Ravnborg <sam@ravnborg.org>
> >>> Cc: Thomas Gleixner <tglx@linutronix.de>
> >>> Cc: Alex Deucher <alexander.deucher@amd.com>
> >>> ---
> >>>  drivers/gpu/drm/udl/udl_drv.c  |  6 ------
> >>>  drivers/gpu/drm/udl/udl_drv.h  |  1 -
> >>>  drivers/gpu/drm/udl/udl_main.c | 10 ----------
> >>>  3 files changed, 17 deletions(-)
> >>>
> >>> diff --git a/drivers/gpu/drm/udl/udl_drv.c b/drivers/gpu/drm/udl/udl_drv.c
> >>> index b447fb053e78..7f140898df3e 100644
> >>> --- a/drivers/gpu/drm/udl/udl_drv.c
> >>> +++ b/drivers/gpu/drm/udl/udl_drv.c
> >>> @@ -34,14 +34,8 @@ static int udl_usb_resume(struct usb_interface *interface)
> >>>
> >>>  DEFINE_DRM_GEM_FOPS(udl_driver_fops);
> >>>
> >>> -static void udl_driver_release(struct drm_device *dev)
> >>> -{
> >>> -     udl_fini(dev);
> >>> -}
> >>> -
> >>>  static struct drm_driver driver = {
> >>>       .driver_features = DRIVER_ATOMIC | DRIVER_GEM | DRIVER_MODESET,
> >>> -     .release = udl_driver_release,
> >>>
> >>>       /* gem hooks */
> >>>       .gem_create_object = udl_driver_gem_create_object,
> >>> diff --git a/drivers/gpu/drm/udl/udl_drv.h b/drivers/gpu/drm/udl/udl_drv.h
> >>> index 1de7eb1b6aac..2642f94a63fc 100644
> >>> --- a/drivers/gpu/drm/udl/udl_drv.h
> >>> +++ b/drivers/gpu/drm/udl/udl_drv.h
> >>> @@ -76,7 +76,6 @@ int udl_submit_urb(struct drm_device *dev, struct urb *urb, size_t len);
> >>>  void udl_urb_completion(struct urb *urb);
> >>>
> >>>  int udl_init(struct udl_device *udl);
> >>> -void udl_fini(struct drm_device *dev);
> >>>
> >>>  int udl_render_hline(struct drm_device *dev, int log_bpp, struct urb **urb_ptr,
> >>>                    const char *front, char **urb_buf_ptr,
> >>> diff --git a/drivers/gpu/drm/udl/udl_main.c b/drivers/gpu/drm/udl/udl_main.c
> >>> index 538718919916..f5d27f2a5654 100644
> >>> --- a/drivers/gpu/drm/udl/udl_main.c
> >>> +++ b/drivers/gpu/drm/udl/udl_main.c
> >>> @@ -351,13 +351,3 @@ int udl_drop_usb(struct drm_device *dev)
> >>>       udl_free_urb_list(dev);
> >>>       return 0;
> >>>  }
> >>> -
> >>> -void udl_fini(struct drm_device *dev)
> >>> -{
> >>> -     struct udl_device *udl = to_udl(dev);
> >>> -
> >>> -     drm_kms_helper_poll_fini(dev);
> >>> -
> >>> -     if (udl->urbs.count)
> >>> -             udl_free_urb_list(dev);
> >>> -}
> >>>
> >>
> >> --
> >> Thomas Zimmermann
> >> Graphics Driver Developer
> >> SUSE Software Solutions Germany GmbH
> >> Maxfeldstr. 5, 90409 Nürnberg, Germany
> >> (HRB 36809, AG Nürnberg)
> >> Geschäftsführer: Felix Imendörffer
> >>
> >
> >
>
> --
> Thomas Zimmermann
> Graphics Driver Developer
> SUSE Software Solutions Germany GmbH
> Maxfeldstr. 5, 90409 Nürnberg, Germany
> (HRB 36809, AG Nürnberg)
> Geschäftsführer: Felix Imendörffer
>


-- 
Daniel Vetter
Software Engineer, Intel Corporation
+41 (0) 79 365 57 48 - http://blog.ffwll.ch
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 111+ messages in thread

* Re: [PATCH 50/51] drm/udl: drop drm_driver.release hook
  2020-02-28  8:40     ` Daniel Vetter
@ 2020-02-28 11:46       ` Thomas Zimmermann
  2020-02-28 17:43         ` Daniel Vetter
  0 siblings, 1 reply; 111+ messages in thread
From: Thomas Zimmermann @ 2020-02-28 11:46 UTC (permalink / raw)
  To: Daniel Vetter
  Cc: Sean Paul, Intel Graphics Development, Emil Velikov,
	Marco Felsch, DRI Development, Gerd Hoffmann, Daniel Vetter,
	Alex Deucher, Dave Airlie, Thomas Gleixner, Sam Ravnborg


[-- Attachment #1.1.1: Type: text/plain, Size: 4463 bytes --]

Hi

Am 28.02.20 um 09:40 schrieb Daniel Vetter:
> On Fri, Feb 28, 2020 at 8:44 AM Thomas Zimmermann <tzimmermann@suse.de> wrote:
>>
>> Hi Daniel
>>
>> Am 27.02.20 um 19:15 schrieb Daniel Vetter:
>>> There's only two functions called from that:
>>> drm_kms_helper_poll_fini() and udl_free_urb_list(). Both of these are
>>> also called from the ubs_driver->disconnect hook, so entirely
>>> pointless to do the same again in the ->release hook.
>>
>> The disconnect hook calls drm_kms_helper_poll_disable() instead if
>> _fini(). They are the same, except that _disable() does not clear
>> dev->mode_config.poll_enabled to false. Is this OK?
> 
> oops, I overlooked that. But yeah for driver shutdown it's the same
> really, we're not going to re-enable. _disable is meant for suspend so
> youc an re-enable again on resume.
> 
> I'll augment the commit message on the next round to clarify that.

Well, we have a managed API. It could support
drmm_kms_helper_poll_init(). :)

Best regards
Thomas

> -Daniel
> 
> 
>> Best regards
>> Thomas
>>
>>>
>>> Furthermore by the time we clean up the drm_driver we really shouldn't
>>> be touching hardware anymore, so stopping the poll worker and freeing
>>> the urb allocations in ->disconnect is the right thing to do.
>>>
>>> Now disconnect still cleans things up before unregistering the driver,
>>> but that's a different issue.
>>>
>>> Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
>>> Cc: Dave Airlie <airlied@redhat.com>
>>> Cc: Sean Paul <sean@poorly.run>
>>> Cc: Daniel Vetter <daniel.vetter@ffwll.ch>
>>> Cc: Thomas Zimmermann <tzimmermann@suse.de>
>>> Cc: Emil Velikov <emil.l.velikov@gmail.com>
>>> Cc: Gerd Hoffmann <kraxel@redhat.com>
>>> Cc: "Noralf Trønnes" <noralf@tronnes.org>
>>> Cc: Sam Ravnborg <sam@ravnborg.org>
>>> Cc: Thomas Gleixner <tglx@linutronix.de>
>>> Cc: Alex Deucher <alexander.deucher@amd.com>
>>> ---
>>>  drivers/gpu/drm/udl/udl_drv.c  |  6 ------
>>>  drivers/gpu/drm/udl/udl_drv.h  |  1 -
>>>  drivers/gpu/drm/udl/udl_main.c | 10 ----------
>>>  3 files changed, 17 deletions(-)
>>>
>>> diff --git a/drivers/gpu/drm/udl/udl_drv.c b/drivers/gpu/drm/udl/udl_drv.c
>>> index b447fb053e78..7f140898df3e 100644
>>> --- a/drivers/gpu/drm/udl/udl_drv.c
>>> +++ b/drivers/gpu/drm/udl/udl_drv.c
>>> @@ -34,14 +34,8 @@ static int udl_usb_resume(struct usb_interface *interface)
>>>
>>>  DEFINE_DRM_GEM_FOPS(udl_driver_fops);
>>>
>>> -static void udl_driver_release(struct drm_device *dev)
>>> -{
>>> -     udl_fini(dev);
>>> -}
>>> -
>>>  static struct drm_driver driver = {
>>>       .driver_features = DRIVER_ATOMIC | DRIVER_GEM | DRIVER_MODESET,
>>> -     .release = udl_driver_release,
>>>
>>>       /* gem hooks */
>>>       .gem_create_object = udl_driver_gem_create_object,
>>> diff --git a/drivers/gpu/drm/udl/udl_drv.h b/drivers/gpu/drm/udl/udl_drv.h
>>> index 1de7eb1b6aac..2642f94a63fc 100644
>>> --- a/drivers/gpu/drm/udl/udl_drv.h
>>> +++ b/drivers/gpu/drm/udl/udl_drv.h
>>> @@ -76,7 +76,6 @@ int udl_submit_urb(struct drm_device *dev, struct urb *urb, size_t len);
>>>  void udl_urb_completion(struct urb *urb);
>>>
>>>  int udl_init(struct udl_device *udl);
>>> -void udl_fini(struct drm_device *dev);
>>>
>>>  int udl_render_hline(struct drm_device *dev, int log_bpp, struct urb **urb_ptr,
>>>                    const char *front, char **urb_buf_ptr,
>>> diff --git a/drivers/gpu/drm/udl/udl_main.c b/drivers/gpu/drm/udl/udl_main.c
>>> index 538718919916..f5d27f2a5654 100644
>>> --- a/drivers/gpu/drm/udl/udl_main.c
>>> +++ b/drivers/gpu/drm/udl/udl_main.c
>>> @@ -351,13 +351,3 @@ int udl_drop_usb(struct drm_device *dev)
>>>       udl_free_urb_list(dev);
>>>       return 0;
>>>  }
>>> -
>>> -void udl_fini(struct drm_device *dev)
>>> -{
>>> -     struct udl_device *udl = to_udl(dev);
>>> -
>>> -     drm_kms_helper_poll_fini(dev);
>>> -
>>> -     if (udl->urbs.count)
>>> -             udl_free_urb_list(dev);
>>> -}
>>>
>>
>> --
>> Thomas Zimmermann
>> Graphics Driver Developer
>> SUSE Software Solutions Germany GmbH
>> Maxfeldstr. 5, 90409 Nürnberg, Germany
>> (HRB 36809, AG Nürnberg)
>> Geschäftsführer: Felix Imendörffer
>>
> 
> 

-- 
Thomas Zimmermann
Graphics Driver Developer
SUSE Software Solutions Germany GmbH
Maxfeldstr. 5, 90409 Nürnberg, Germany
(HRB 36809, AG Nürnberg)
Geschäftsführer: Felix Imendörffer


[-- Attachment #1.2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

[-- Attachment #2: Type: text/plain, Size: 160 bytes --]

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 111+ messages in thread

* Re: [PATCH 50/51] drm/udl: drop drm_driver.release hook
  2020-02-28  7:43   ` Thomas Zimmermann
@ 2020-02-28  8:40     ` Daniel Vetter
  2020-02-28 11:46       ` Thomas Zimmermann
  0 siblings, 1 reply; 111+ messages in thread
From: Daniel Vetter @ 2020-02-28  8:40 UTC (permalink / raw)
  To: Thomas Zimmermann
  Cc: Sam Ravnborg, Intel Graphics Development, Emil Velikov,
	Marco Felsch, DRI Development, Gerd Hoffmann, Dave Airlie,
	Alex Deucher, Daniel Vetter, Thomas Gleixner, Sean Paul

On Fri, Feb 28, 2020 at 8:44 AM Thomas Zimmermann <tzimmermann@suse.de> wrote:
>
> Hi Daniel
>
> Am 27.02.20 um 19:15 schrieb Daniel Vetter:
> > There's only two functions called from that:
> > drm_kms_helper_poll_fini() and udl_free_urb_list(). Both of these are
> > also called from the ubs_driver->disconnect hook, so entirely
> > pointless to do the same again in the ->release hook.
>
> The disconnect hook calls drm_kms_helper_poll_disable() instead if
> _fini(). They are the same, except that _disable() does not clear
> dev->mode_config.poll_enabled to false. Is this OK?

oops, I overlooked that. But yeah for driver shutdown it's the same
really, we're not going to re-enable. _disable is meant for suspend so
youc an re-enable again on resume.

I'll augment the commit message on the next round to clarify that.
-Daniel


> Best regards
> Thomas
>
> >
> > Furthermore by the time we clean up the drm_driver we really shouldn't
> > be touching hardware anymore, so stopping the poll worker and freeing
> > the urb allocations in ->disconnect is the right thing to do.
> >
> > Now disconnect still cleans things up before unregistering the driver,
> > but that's a different issue.
> >
> > Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
> > Cc: Dave Airlie <airlied@redhat.com>
> > Cc: Sean Paul <sean@poorly.run>
> > Cc: Daniel Vetter <daniel.vetter@ffwll.ch>
> > Cc: Thomas Zimmermann <tzimmermann@suse.de>
> > Cc: Emil Velikov <emil.l.velikov@gmail.com>
> > Cc: Gerd Hoffmann <kraxel@redhat.com>
> > Cc: "Noralf Trønnes" <noralf@tronnes.org>
> > Cc: Sam Ravnborg <sam@ravnborg.org>
> > Cc: Thomas Gleixner <tglx@linutronix.de>
> > Cc: Alex Deucher <alexander.deucher@amd.com>
> > ---
> >  drivers/gpu/drm/udl/udl_drv.c  |  6 ------
> >  drivers/gpu/drm/udl/udl_drv.h  |  1 -
> >  drivers/gpu/drm/udl/udl_main.c | 10 ----------
> >  3 files changed, 17 deletions(-)
> >
> > diff --git a/drivers/gpu/drm/udl/udl_drv.c b/drivers/gpu/drm/udl/udl_drv.c
> > index b447fb053e78..7f140898df3e 100644
> > --- a/drivers/gpu/drm/udl/udl_drv.c
> > +++ b/drivers/gpu/drm/udl/udl_drv.c
> > @@ -34,14 +34,8 @@ static int udl_usb_resume(struct usb_interface *interface)
> >
> >  DEFINE_DRM_GEM_FOPS(udl_driver_fops);
> >
> > -static void udl_driver_release(struct drm_device *dev)
> > -{
> > -     udl_fini(dev);
> > -}
> > -
> >  static struct drm_driver driver = {
> >       .driver_features = DRIVER_ATOMIC | DRIVER_GEM | DRIVER_MODESET,
> > -     .release = udl_driver_release,
> >
> >       /* gem hooks */
> >       .gem_create_object = udl_driver_gem_create_object,
> > diff --git a/drivers/gpu/drm/udl/udl_drv.h b/drivers/gpu/drm/udl/udl_drv.h
> > index 1de7eb1b6aac..2642f94a63fc 100644
> > --- a/drivers/gpu/drm/udl/udl_drv.h
> > +++ b/drivers/gpu/drm/udl/udl_drv.h
> > @@ -76,7 +76,6 @@ int udl_submit_urb(struct drm_device *dev, struct urb *urb, size_t len);
> >  void udl_urb_completion(struct urb *urb);
> >
> >  int udl_init(struct udl_device *udl);
> > -void udl_fini(struct drm_device *dev);
> >
> >  int udl_render_hline(struct drm_device *dev, int log_bpp, struct urb **urb_ptr,
> >                    const char *front, char **urb_buf_ptr,
> > diff --git a/drivers/gpu/drm/udl/udl_main.c b/drivers/gpu/drm/udl/udl_main.c
> > index 538718919916..f5d27f2a5654 100644
> > --- a/drivers/gpu/drm/udl/udl_main.c
> > +++ b/drivers/gpu/drm/udl/udl_main.c
> > @@ -351,13 +351,3 @@ int udl_drop_usb(struct drm_device *dev)
> >       udl_free_urb_list(dev);
> >       return 0;
> >  }
> > -
> > -void udl_fini(struct drm_device *dev)
> > -{
> > -     struct udl_device *udl = to_udl(dev);
> > -
> > -     drm_kms_helper_poll_fini(dev);
> > -
> > -     if (udl->urbs.count)
> > -             udl_free_urb_list(dev);
> > -}
> >
>
> --
> Thomas Zimmermann
> Graphics Driver Developer
> SUSE Software Solutions Germany GmbH
> Maxfeldstr. 5, 90409 Nürnberg, Germany
> (HRB 36809, AG Nürnberg)
> Geschäftsführer: Felix Imendörffer
>


-- 
Daniel Vetter
Software Engineer, Intel Corporation
+41 (0) 79 365 57 48 - http://blog.ffwll.ch
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 111+ messages in thread

* Re: [PATCH 50/51] drm/udl: drop drm_driver.release hook
  2020-02-27 18:15 ` [PATCH 50/51] drm/udl: drop drm_driver.release hook Daniel Vetter
@ 2020-02-28  7:43   ` Thomas Zimmermann
  2020-02-28  8:40     ` Daniel Vetter
  0 siblings, 1 reply; 111+ messages in thread
From: Thomas Zimmermann @ 2020-02-28  7:43 UTC (permalink / raw)
  To: Daniel Vetter, DRI Development
  Cc: Sam Ravnborg, Intel Graphics Development, Emil Velikov, m.felsch,
	Gerd Hoffmann, Dave Airlie, Alex Deucher, Daniel Vetter,
	Thomas Gleixner, Sean Paul


[-- Attachment #1.1.1: Type: text/plain, Size: 3476 bytes --]

Hi Daniel

Am 27.02.20 um 19:15 schrieb Daniel Vetter:
> There's only two functions called from that:
> drm_kms_helper_poll_fini() and udl_free_urb_list(). Both of these are
> also called from the ubs_driver->disconnect hook, so entirely
> pointless to do the same again in the ->release hook.

The disconnect hook calls drm_kms_helper_poll_disable() instead if
_fini(). They are the same, except that _disable() does not clear
dev->mode_config.poll_enabled to false. Is this OK?

Best regards
Thomas

> 
> Furthermore by the time we clean up the drm_driver we really shouldn't
> be touching hardware anymore, so stopping the poll worker and freeing
> the urb allocations in ->disconnect is the right thing to do.
> 
> Now disconnect still cleans things up before unregistering the driver,
> but that's a different issue.
> 
> Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
> Cc: Dave Airlie <airlied@redhat.com>
> Cc: Sean Paul <sean@poorly.run>
> Cc: Daniel Vetter <daniel.vetter@ffwll.ch>
> Cc: Thomas Zimmermann <tzimmermann@suse.de>
> Cc: Emil Velikov <emil.l.velikov@gmail.com>
> Cc: Gerd Hoffmann <kraxel@redhat.com>
> Cc: "Noralf Trønnes" <noralf@tronnes.org>
> Cc: Sam Ravnborg <sam@ravnborg.org>
> Cc: Thomas Gleixner <tglx@linutronix.de>
> Cc: Alex Deucher <alexander.deucher@amd.com>
> ---
>  drivers/gpu/drm/udl/udl_drv.c  |  6 ------
>  drivers/gpu/drm/udl/udl_drv.h  |  1 -
>  drivers/gpu/drm/udl/udl_main.c | 10 ----------
>  3 files changed, 17 deletions(-)
> 
> diff --git a/drivers/gpu/drm/udl/udl_drv.c b/drivers/gpu/drm/udl/udl_drv.c
> index b447fb053e78..7f140898df3e 100644
> --- a/drivers/gpu/drm/udl/udl_drv.c
> +++ b/drivers/gpu/drm/udl/udl_drv.c
> @@ -34,14 +34,8 @@ static int udl_usb_resume(struct usb_interface *interface)
>  
>  DEFINE_DRM_GEM_FOPS(udl_driver_fops);
>  
> -static void udl_driver_release(struct drm_device *dev)
> -{
> -	udl_fini(dev);
> -}
> -
>  static struct drm_driver driver = {
>  	.driver_features = DRIVER_ATOMIC | DRIVER_GEM | DRIVER_MODESET,
> -	.release = udl_driver_release,
>  
>  	/* gem hooks */
>  	.gem_create_object = udl_driver_gem_create_object,
> diff --git a/drivers/gpu/drm/udl/udl_drv.h b/drivers/gpu/drm/udl/udl_drv.h
> index 1de7eb1b6aac..2642f94a63fc 100644
> --- a/drivers/gpu/drm/udl/udl_drv.h
> +++ b/drivers/gpu/drm/udl/udl_drv.h
> @@ -76,7 +76,6 @@ int udl_submit_urb(struct drm_device *dev, struct urb *urb, size_t len);
>  void udl_urb_completion(struct urb *urb);
>  
>  int udl_init(struct udl_device *udl);
> -void udl_fini(struct drm_device *dev);
>  
>  int udl_render_hline(struct drm_device *dev, int log_bpp, struct urb **urb_ptr,
>  		     const char *front, char **urb_buf_ptr,
> diff --git a/drivers/gpu/drm/udl/udl_main.c b/drivers/gpu/drm/udl/udl_main.c
> index 538718919916..f5d27f2a5654 100644
> --- a/drivers/gpu/drm/udl/udl_main.c
> +++ b/drivers/gpu/drm/udl/udl_main.c
> @@ -351,13 +351,3 @@ int udl_drop_usb(struct drm_device *dev)
>  	udl_free_urb_list(dev);
>  	return 0;
>  }
> -
> -void udl_fini(struct drm_device *dev)
> -{
> -	struct udl_device *udl = to_udl(dev);
> -
> -	drm_kms_helper_poll_fini(dev);
> -
> -	if (udl->urbs.count)
> -		udl_free_urb_list(dev);
> -}
> 

-- 
Thomas Zimmermann
Graphics Driver Developer
SUSE Software Solutions Germany GmbH
Maxfeldstr. 5, 90409 Nürnberg, Germany
(HRB 36809, AG Nürnberg)
Geschäftsführer: Felix Imendörffer


[-- Attachment #1.2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

[-- Attachment #2: Type: text/plain, Size: 160 bytes --]

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 111+ messages in thread

* [PATCH 50/51] drm/udl: drop drm_driver.release hook
  2020-02-27 18:14 [PATCH 00/51] drm managed resources, v3 Daniel Vetter
@ 2020-02-27 18:15 ` Daniel Vetter
  2020-02-28  7:43   ` Thomas Zimmermann
  0 siblings, 1 reply; 111+ messages in thread
From: Daniel Vetter @ 2020-02-27 18:15 UTC (permalink / raw)
  To: DRI Development
  Cc: Sam Ravnborg, Daniel Vetter, Intel Graphics Development,
	Emil Velikov, m.felsch, Gerd Hoffmann, Thomas Zimmermann,
	Dave Airlie, Alex Deucher, Daniel Vetter, Thomas Gleixner,
	Sean Paul

There's only two functions called from that:
drm_kms_helper_poll_fini() and udl_free_urb_list(). Both of these are
also called from the ubs_driver->disconnect hook, so entirely
pointless to do the same again in the ->release hook.

Furthermore by the time we clean up the drm_driver we really shouldn't
be touching hardware anymore, so stopping the poll worker and freeing
the urb allocations in ->disconnect is the right thing to do.

Now disconnect still cleans things up before unregistering the driver,
but that's a different issue.

Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
Cc: Dave Airlie <airlied@redhat.com>
Cc: Sean Paul <sean@poorly.run>
Cc: Daniel Vetter <daniel.vetter@ffwll.ch>
Cc: Thomas Zimmermann <tzimmermann@suse.de>
Cc: Emil Velikov <emil.l.velikov@gmail.com>
Cc: Gerd Hoffmann <kraxel@redhat.com>
Cc: "Noralf Trønnes" <noralf@tronnes.org>
Cc: Sam Ravnborg <sam@ravnborg.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Alex Deucher <alexander.deucher@amd.com>
---
 drivers/gpu/drm/udl/udl_drv.c  |  6 ------
 drivers/gpu/drm/udl/udl_drv.h  |  1 -
 drivers/gpu/drm/udl/udl_main.c | 10 ----------
 3 files changed, 17 deletions(-)

diff --git a/drivers/gpu/drm/udl/udl_drv.c b/drivers/gpu/drm/udl/udl_drv.c
index b447fb053e78..7f140898df3e 100644
--- a/drivers/gpu/drm/udl/udl_drv.c
+++ b/drivers/gpu/drm/udl/udl_drv.c
@@ -34,14 +34,8 @@ static int udl_usb_resume(struct usb_interface *interface)
 
 DEFINE_DRM_GEM_FOPS(udl_driver_fops);
 
-static void udl_driver_release(struct drm_device *dev)
-{
-	udl_fini(dev);
-}
-
 static struct drm_driver driver = {
 	.driver_features = DRIVER_ATOMIC | DRIVER_GEM | DRIVER_MODESET,
-	.release = udl_driver_release,
 
 	/* gem hooks */
 	.gem_create_object = udl_driver_gem_create_object,
diff --git a/drivers/gpu/drm/udl/udl_drv.h b/drivers/gpu/drm/udl/udl_drv.h
index 1de7eb1b6aac..2642f94a63fc 100644
--- a/drivers/gpu/drm/udl/udl_drv.h
+++ b/drivers/gpu/drm/udl/udl_drv.h
@@ -76,7 +76,6 @@ int udl_submit_urb(struct drm_device *dev, struct urb *urb, size_t len);
 void udl_urb_completion(struct urb *urb);
 
 int udl_init(struct udl_device *udl);
-void udl_fini(struct drm_device *dev);
 
 int udl_render_hline(struct drm_device *dev, int log_bpp, struct urb **urb_ptr,
 		     const char *front, char **urb_buf_ptr,
diff --git a/drivers/gpu/drm/udl/udl_main.c b/drivers/gpu/drm/udl/udl_main.c
index 538718919916..f5d27f2a5654 100644
--- a/drivers/gpu/drm/udl/udl_main.c
+++ b/drivers/gpu/drm/udl/udl_main.c
@@ -351,13 +351,3 @@ int udl_drop_usb(struct drm_device *dev)
 	udl_free_urb_list(dev);
 	return 0;
 }
-
-void udl_fini(struct drm_device *dev)
-{
-	struct udl_device *udl = to_udl(dev);
-
-	drm_kms_helper_poll_fini(dev);
-
-	if (udl->urbs.count)
-		udl_free_urb_list(dev);
-}
-- 
2.24.1

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 111+ messages in thread

* [PATCH 50/51] drm/udl: drop drm_driver.release hook
  2020-02-21 21:02 [PATCH 00/51] drm managed resources, v2 Daniel Vetter
@ 2020-02-21 21:03 ` Daniel Vetter
  0 siblings, 0 replies; 111+ messages in thread
From: Daniel Vetter @ 2020-02-21 21:03 UTC (permalink / raw)
  To: DRI Development
  Cc: Sam Ravnborg, Daniel Vetter, Intel Graphics Development,
	Emil Velikov, Gerd Hoffmann, Thomas Zimmermann, Daniel Vetter,
	Alex Deucher, Dave Airlie, Thomas Gleixner, Sean Paul

There's only two functions called from that:
drm_kms_helper_poll_fini() and udl_free_urb_list(). Both of these are
also called from the ubs_driver->disconnect hook, so entirely
pointless to do the same again in the ->release hook.

Furthermore by the time we clean up the drm_driver we really shouldn't
be touching hardware anymore, so stopping the poll worker and freeing
the urb allocations in ->disconnect is the right thing to do.

Now disconnect still cleans things up before unregistering the driver,
but that's a different issue.

Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
Cc: Dave Airlie <airlied@redhat.com>
Cc: Sean Paul <sean@poorly.run>
Cc: Daniel Vetter <daniel.vetter@ffwll.ch>
Cc: Thomas Zimmermann <tzimmermann@suse.de>
Cc: Emil Velikov <emil.l.velikov@gmail.com>
Cc: Gerd Hoffmann <kraxel@redhat.com>
Cc: "Noralf Trønnes" <noralf@tronnes.org>
Cc: Sam Ravnborg <sam@ravnborg.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Alex Deucher <alexander.deucher@amd.com>
---
 drivers/gpu/drm/udl/udl_drv.c  |  6 ------
 drivers/gpu/drm/udl/udl_drv.h  |  1 -
 drivers/gpu/drm/udl/udl_main.c | 10 ----------
 3 files changed, 17 deletions(-)

diff --git a/drivers/gpu/drm/udl/udl_drv.c b/drivers/gpu/drm/udl/udl_drv.c
index b447fb053e78..7f140898df3e 100644
--- a/drivers/gpu/drm/udl/udl_drv.c
+++ b/drivers/gpu/drm/udl/udl_drv.c
@@ -34,14 +34,8 @@ static int udl_usb_resume(struct usb_interface *interface)
 
 DEFINE_DRM_GEM_FOPS(udl_driver_fops);
 
-static void udl_driver_release(struct drm_device *dev)
-{
-	udl_fini(dev);
-}
-
 static struct drm_driver driver = {
 	.driver_features = DRIVER_ATOMIC | DRIVER_GEM | DRIVER_MODESET,
-	.release = udl_driver_release,
 
 	/* gem hooks */
 	.gem_create_object = udl_driver_gem_create_object,
diff --git a/drivers/gpu/drm/udl/udl_drv.h b/drivers/gpu/drm/udl/udl_drv.h
index 1de7eb1b6aac..2642f94a63fc 100644
--- a/drivers/gpu/drm/udl/udl_drv.h
+++ b/drivers/gpu/drm/udl/udl_drv.h
@@ -76,7 +76,6 @@ int udl_submit_urb(struct drm_device *dev, struct urb *urb, size_t len);
 void udl_urb_completion(struct urb *urb);
 
 int udl_init(struct udl_device *udl);
-void udl_fini(struct drm_device *dev);
 
 int udl_render_hline(struct drm_device *dev, int log_bpp, struct urb **urb_ptr,
 		     const char *front, char **urb_buf_ptr,
diff --git a/drivers/gpu/drm/udl/udl_main.c b/drivers/gpu/drm/udl/udl_main.c
index 538718919916..f5d27f2a5654 100644
--- a/drivers/gpu/drm/udl/udl_main.c
+++ b/drivers/gpu/drm/udl/udl_main.c
@@ -351,13 +351,3 @@ int udl_drop_usb(struct drm_device *dev)
 	udl_free_urb_list(dev);
 	return 0;
 }
-
-void udl_fini(struct drm_device *dev)
-{
-	struct udl_device *udl = to_udl(dev);
-
-	drm_kms_helper_poll_fini(dev);
-
-	if (udl->urbs.count)
-		udl_free_urb_list(dev);
-}
-- 
2.24.1

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 111+ messages in thread

end of thread, other threads:[~2020-03-23 14:52 UTC | newest]

Thread overview: 111+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-03-02 22:25 [PATCH 00/51] drm_device managed resources, v4 Daniel Vetter
2020-03-02 22:25 ` [PATCH 01/51] mm/sl[uo]b: export __kmalloc_track(_node)_caller Daniel Vetter
2020-03-02 22:25 ` [PATCH 02/51] drm/i915: Don't clear drvdata in ->release Daniel Vetter
2020-03-02 22:25 ` [PATCH 03/51] drm: add managed resources tied to drm_device Daniel Vetter
2020-03-03  8:04   ` Dan Carpenter
2020-03-03  8:25     ` Daniel Vetter
2020-03-03  8:44   ` [PATCH] " Daniel Vetter
2020-03-06 19:38     ` Sam Ravnborg
2020-03-11  9:07   ` [PATCH 03/51] " Thomas Zimmermann
2020-03-11  9:47     ` Thomas Zimmermann
2020-03-16  8:45     ` Daniel Vetter
2020-03-11  9:14   ` Thomas Zimmermann
2020-03-16  8:50     ` Daniel Vetter
2020-03-02 22:25 ` [PATCH 04/51] drm: Set final_kfree in drm_dev_alloc Daniel Vetter
2020-03-03  7:44   ` Gerd Hoffmann
2020-03-07  8:06   ` Sam Ravnborg
2020-03-23 11:02     ` Daniel Vetter
2020-03-11  9:09   ` Thomas Zimmermann
2020-03-02 22:25 ` [PATCH 05/51] drm/mipi_dbi: Use drmm_add_final_kfree in all drivers Daniel Vetter
2020-03-02 22:25 ` [PATCH 06/51] drm/udl: Use drmm_add_final_kfree Daniel Vetter
2020-03-11  9:10   ` Thomas Zimmermann
2020-03-02 22:25 ` [PATCH 07/51] drm/qxl: " Daniel Vetter
2020-03-03  7:44   ` Gerd Hoffmann
2020-03-02 22:25 ` [PATCH 08/51] drm/i915: " Daniel Vetter
2020-03-02 22:25 ` [PATCH 09/51] drm/cirrus: " Daniel Vetter
2020-03-03  7:49   ` Gerd Hoffmann
2020-03-03  8:27     ` Daniel Vetter
2020-03-02 22:25 ` [PATCH 10/51] drm/v3d: " Daniel Vetter
2020-03-02 22:25 ` [PATCH 11/51] drm/tidss: " Daniel Vetter
2020-03-02 22:25 ` [PATCH 12/51] drm/mcde: " Daniel Vetter
2020-03-02 22:25 ` [PATCH 13/51] drm/vgem: " Daniel Vetter
2020-03-02 22:25 ` [PATCH 14/51] drm/vkms: " Daniel Vetter
2020-03-02 22:25 ` [PATCH 15/51] drm/repaper: " Daniel Vetter
2020-03-06 20:27   ` Sam Ravnborg
2020-03-02 22:25 ` [PATCH 16/51] drm/ingenic: " Daniel Vetter
2020-03-06 20:27   ` Sam Ravnborg
2020-03-02 22:25 ` [PATCH 17/51] drm/gm12u320: " Daniel Vetter
2020-03-06 20:27   ` Sam Ravnborg
2020-03-02 22:25 ` [PATCH 18/51] drm/<drivers>: " Daniel Vetter
2020-03-06 20:28   ` Sam Ravnborg
2020-03-02 22:25 ` [PATCH 19/51] drm: Cleanups after drmm_add_final_kfree rollout Daniel Vetter
2020-03-03  8:45   ` [PATCH] " Daniel Vetter
2020-03-06 20:31     ` Sam Ravnborg
2020-03-06 20:29   ` [PATCH 19/51] " Sam Ravnborg
2020-03-11  9:15   ` Thomas Zimmermann
2020-03-02 22:26 ` [PATCH 20/51] drm: Handle dev->unique with drmm_ Daniel Vetter
2020-03-06 20:37   ` Sam Ravnborg
2020-03-23 10:54     ` Daniel Vetter
2020-03-11  9:19   ` Thomas Zimmermann
2020-03-02 22:26 ` [PATCH 21/51] drm: Use drmm_ for drm_dev_init cleanup Daniel Vetter
2020-03-11  9:39   ` Thomas Zimmermann
2020-03-16  9:02     ` Daniel Vetter
2020-03-02 22:26 ` [PATCH 22/51] drm: manage drm_minor cleanup with drmm_ Daniel Vetter
2020-03-11  9:59   ` Thomas Zimmermann
2020-03-16  9:07     ` Daniel Vetter
2020-03-02 22:26 ` [PATCH 23/51] drm: Manage drm_gem_init " Daniel Vetter
2020-03-07  8:20   ` Sam Ravnborg
2020-03-02 22:26 ` [PATCH 24/51] drm: Manage drm_vblank_cleanup " Daniel Vetter
2020-03-07  8:28   ` Sam Ravnborg
2020-03-02 22:26 ` [PATCH 25/51] drm: Garbage collect drm_dev_fini Daniel Vetter
2020-03-07  8:30   ` Sam Ravnborg
2020-03-02 22:26 ` [PATCH 26/51] drm: Manage drm_mode_config_init with drmm_ Daniel Vetter
2020-03-06 20:04   ` Sam Ravnborg
2020-03-02 22:26 ` [PATCH 27/51] drm/bochs: Remove leftover drm_atomic_helper_shutdown Daniel Vetter
2020-03-03  7:49   ` Gerd Hoffmann
2020-03-02 22:26 ` [PATCH 28/51] drm/bochs: Drop explicit drm_mode_config_cleanup Daniel Vetter
2020-03-03  7:50   ` Gerd Hoffmann
2020-03-06 20:14   ` Sam Ravnborg
2020-03-02 22:26 ` [PATCH 29/51] drm/cirrus: Drop explicit drm_mode_config_cleanup call Daniel Vetter
2020-03-03  7:51   ` Gerd Hoffmann
2020-03-02 22:26 ` [PATCH 30/51] drm/cirrus: Fully embrace devm_ Daniel Vetter
2020-03-03  7:51   ` Gerd Hoffmann
2020-03-02 22:26 ` [PATCH 31/51] drm/ingenic: Drop explicit drm_mode_config_cleanup call Daniel Vetter
2020-03-06 20:17   ` Sam Ravnborg
2020-03-02 22:26 ` [PATCH 32/51] drm/mcde: " Daniel Vetter
2020-03-06 20:18   ` Sam Ravnborg
2020-03-02 22:26 ` [PATCH 33/51] drm/mcde: More devm_drm_dev_init Daniel Vetter
2020-03-02 22:26 ` [PATCH 34/51] drm/meson: Drop explicit drm_mode_config_cleanup call Daniel Vetter
2020-03-02 22:26 ` [PATCH 35/51] drm/pl111: " Daniel Vetter
2020-03-07  8:37   ` Sam Ravnborg
2020-03-02 22:26 ` [PATCH 36/51] drm/rcar-du: " Daniel Vetter
2020-03-02 22:26 ` [PATCH 37/51] drm/rockchip: " Daniel Vetter
2020-03-07  8:38   ` Sam Ravnborg
2020-03-02 22:26 ` [PATCH 38/51] drm/stm: " Daniel Vetter
2020-03-07  9:25   ` Sam Ravnborg
2020-03-02 22:26 ` [PATCH 39/51] drm/shmob: " Daniel Vetter
2020-03-02 22:26 ` [PATCH 40/51] drm/mtk: " Daniel Vetter
2020-03-07  9:26   ` Sam Ravnborg
2020-03-02 22:26 ` [PATCH 41/51] drm/tidss: " Daniel Vetter
2020-03-02 22:26 ` [PATCH 42/51] drm/gm12u320: More drmm_ Daniel Vetter
2020-03-02 22:26 ` [PATCH 43/51] drm/gm12u320: Use devm_drm_dev_init Daniel Vetter
2020-03-02 22:26 ` [PATCH 44/51] drm/gm12u320: Use helpers for shutdown/suspend/resume Daniel Vetter
2020-03-02 22:26 ` [PATCH 45/51] drm/gm12u320: Simplify upload work Daniel Vetter
2020-03-02 22:26 ` [PATCH 46/51] drm/repaper: Drop explicit drm_mode_config_cleanup call Daniel Vetter
2020-03-07  9:31   ` Sam Ravnborg
2020-03-02 22:26 ` [PATCH 47/51] drm/mipi-dbi: Move drm_mode_config_init into mipi library Daniel Vetter
2020-03-02 22:26 ` [PATCH 48/51] drm/mipi-dbi: Drop explicit drm_mode_config_cleanup call Daniel Vetter
2020-03-02 22:26 ` [PATCH 49/51] drm/udl: " Daniel Vetter
2020-03-02 22:26 ` [PATCH 50/51] drm/udl: drop drm_driver.release hook Daniel Vetter
2020-03-03  7:57   ` Thomas Zimmermann
2020-03-02 22:26 ` [PATCH 51/51] drm: Add docs for managed resources Daniel Vetter
2020-03-07 10:07   ` Sam Ravnborg
  -- strict thread matches above, loose matches on Subject: below --
2020-03-23 14:48 [PATCH 00/51] drm_device managed resources, v5 Daniel Vetter
2020-03-23 14:49 ` [PATCH 50/51] drm/udl: drop drm_driver.release hook Daniel Vetter
2020-02-27 18:14 [PATCH 00/51] drm managed resources, v3 Daniel Vetter
2020-02-27 18:15 ` [PATCH 50/51] drm/udl: drop drm_driver.release hook Daniel Vetter
2020-02-28  7:43   ` Thomas Zimmermann
2020-02-28  8:40     ` Daniel Vetter
2020-02-28 11:46       ` Thomas Zimmermann
2020-02-28 17:43         ` Daniel Vetter
2020-03-02  8:14           ` Thomas Zimmermann
2020-03-02  9:01             ` Daniel Vetter
2020-02-21 21:02 [PATCH 00/51] drm managed resources, v2 Daniel Vetter
2020-02-21 21:03 ` [PATCH 50/51] drm/udl: drop drm_driver.release hook Daniel Vetter

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).