All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 00/52] drm_device managed resources
@ 2020-02-19 10:20 ` Daniel Vetter
  0 siblings, 0 replies; 310+ messages in thread
From: Daniel Vetter @ 2020-02-19 10:20 UTC (permalink / raw)
  To: DRI Development; +Cc: Daniel Vetter, Intel Graphics Development

Hi all,

So I finally bit the bullet and started a little framework for managed
resources tied to the drm_device lifetime, instead of the lifetime of the
underlying physical device. Because I've seen one patch too many that just
totally got this wrong.

Yes it's huge, but I think this is what we minimally need to show an
actual improvement, and at least a glimpse of the road ahead.

For reading the patch series I think it'd be best to start at the very
end, which contains the documentation for the entire thing. I've assembled
that at the end since a few of the intermediate states are a bit gross,
but necessary to get there with full bisectability.

Once you know where things will go, start at the front (the two very first
patches are just trivial prep that got in the way).

There's three major phases:

- Handling the final kfree of the structure containing the drm_device

- Converting drm_dev_fini to the managed resource framework

- Converting drm_mode_config_cleanup to the managed resource framework.

The last patch's commit message also contains a bit a todo about what next
possible steps could be.

Review (primarily on the big picture at least at first) but also testing
for all the drivers I'm touching very much appreciated.

Cheers, Daniel

Daniel Vetter (52):
  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/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/inigenic: 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                     | 217 ++++++--------
 drivers/gpu/drm/drm_gem.c                     |  21 +-
 drivers/gpu/drm/drm_internal.h                |   5 +-
 drivers/gpu/drm/drm_managed.c                 | 278 ++++++++++++++++++
 drivers/gpu/drm/drm_mipi_dbi.c                |  24 +-
 drivers/gpu/drm/drm_mode_config.c             |  12 +-
 drivers/gpu/drm/drm_vblank.c                  |  31 +-
 drivers/gpu/drm/i915/i915_drv.c               |  21 +-
 drivers/gpu/drm/i915/i915_drv.h               |   3 +
 .../gpu/drm/i915/selftests/mock_gem_device.c  |  20 +-
 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   |  10 +-
 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               | 225 ++++++--------
 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                |  14 +-
 drivers/gpu/drm/tiny/st7586.c                 |   5 +-
 drivers/gpu/drm/tiny/st7735r.c                |   5 +-
 drivers/gpu/drm/udl/udl_drv.c                 |  14 +-
 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                      |  12 +
 include/drm/drm_drv.h                         |   9 +-
 include/drm/drm_managed.h                     |  93 ++++++
 include/drm/drm_mipi_dbi.h                    |   1 -
 include/drm/drm_mode_config.h                 |   2 +-
 include/drm/drm_print.h                       |   6 +
 mm/slob.c                                     |   2 +
 mm/slub.c                                     |   2 +
 60 files changed, 816 insertions(+), 602 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] 310+ messages in thread

* [Intel-gfx] [PATCH 00/52] drm_device managed resources
@ 2020-02-19 10:20 ` Daniel Vetter
  0 siblings, 0 replies; 310+ messages in thread
From: Daniel Vetter @ 2020-02-19 10:20 UTC (permalink / raw)
  To: DRI Development; +Cc: Daniel Vetter, Intel Graphics Development

Hi all,

So I finally bit the bullet and started a little framework for managed
resources tied to the drm_device lifetime, instead of the lifetime of the
underlying physical device. Because I've seen one patch too many that just
totally got this wrong.

Yes it's huge, but I think this is what we minimally need to show an
actual improvement, and at least a glimpse of the road ahead.

For reading the patch series I think it'd be best to start at the very
end, which contains the documentation for the entire thing. I've assembled
that at the end since a few of the intermediate states are a bit gross,
but necessary to get there with full bisectability.

Once you know where things will go, start at the front (the two very first
patches are just trivial prep that got in the way).

There's three major phases:

- Handling the final kfree of the structure containing the drm_device

- Converting drm_dev_fini to the managed resource framework

- Converting drm_mode_config_cleanup to the managed resource framework.

The last patch's commit message also contains a bit a todo about what next
possible steps could be.

Review (primarily on the big picture at least at first) but also testing
for all the drivers I'm touching very much appreciated.

Cheers, Daniel

Daniel Vetter (52):
  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/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/inigenic: 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                     | 217 ++++++--------
 drivers/gpu/drm/drm_gem.c                     |  21 +-
 drivers/gpu/drm/drm_internal.h                |   5 +-
 drivers/gpu/drm/drm_managed.c                 | 278 ++++++++++++++++++
 drivers/gpu/drm/drm_mipi_dbi.c                |  24 +-
 drivers/gpu/drm/drm_mode_config.c             |  12 +-
 drivers/gpu/drm/drm_vblank.c                  |  31 +-
 drivers/gpu/drm/i915/i915_drv.c               |  21 +-
 drivers/gpu/drm/i915/i915_drv.h               |   3 +
 .../gpu/drm/i915/selftests/mock_gem_device.c  |  20 +-
 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   |  10 +-
 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               | 225 ++++++--------
 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                |  14 +-
 drivers/gpu/drm/tiny/st7586.c                 |   5 +-
 drivers/gpu/drm/tiny/st7735r.c                |   5 +-
 drivers/gpu/drm/udl/udl_drv.c                 |  14 +-
 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                      |  12 +
 include/drm/drm_drv.h                         |   9 +-
 include/drm/drm_managed.h                     |  93 ++++++
 include/drm/drm_mipi_dbi.h                    |   1 -
 include/drm/drm_mode_config.h                 |   2 +-
 include/drm/drm_print.h                       |   6 +
 mm/slob.c                                     |   2 +
 mm/slub.c                                     |   2 +
 60 files changed, 816 insertions(+), 602 deletions(-)
 create mode 100644 drivers/gpu/drm/drm_managed.c
 create mode 100644 include/drm/drm_managed.h

-- 
2.24.1

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* [PATCH 01/52] mm/sl[uo]b: export __kmalloc_track(_node)_caller
  2020-02-19 10:20 ` [Intel-gfx] " Daniel Vetter
  (?)
@ 2020-02-19 10:20   ` Daniel Vetter
  -1 siblings, 0 replies; 310+ messages in thread
From: Daniel Vetter @ 2020-02-19 10:20 UTC (permalink / raw)
  To: DRI Development
  Cc: Intel Graphics Development, Daniel Vetter, Daniel Vetter,
	Christoph Lameter, Pekka Enberg, David Rientjes, Joonsoo Kim,
	Andrew Morton, linux-mm

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.

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
--
Ack for merging through drm trees very much appreciated.

Thanks, 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



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

* [PATCH 01/52] mm/sl[uo]b: export __kmalloc_track(_node)_caller
@ 2020-02-19 10:20   ` Daniel Vetter
  0 siblings, 0 replies; 310+ messages in thread
From: Daniel Vetter @ 2020-02-19 10:20 UTC (permalink / raw)
  To: DRI Development
  Cc: Andrew Morton, Daniel Vetter, Intel Graphics Development,
	Pekka Enberg, linux-mm, David Rientjes, Daniel Vetter,
	Christoph Lameter, Joonsoo Kim

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.

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
--
Ack for merging through drm trees very much appreciated.

Thanks, 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] 310+ messages in thread

* [Intel-gfx] [PATCH 01/52] mm/sl[uo]b: export __kmalloc_track(_node)_caller
@ 2020-02-19 10:20   ` Daniel Vetter
  0 siblings, 0 replies; 310+ messages in thread
From: Daniel Vetter @ 2020-02-19 10:20 UTC (permalink / raw)
  To: DRI Development
  Cc: Andrew Morton, Daniel Vetter, Intel Graphics Development,
	Pekka Enberg, linux-mm, David Rientjes, Daniel Vetter,
	Christoph Lameter, Joonsoo Kim

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.

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
--
Ack for merging through drm trees very much appreciated.

Thanks, 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

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* [PATCH 02/52] drm/i915: Don't clear drvdata in ->release
  2020-02-19 10:20 ` [Intel-gfx] " Daniel Vetter
@ 2020-02-19 10:20   ` Daniel Vetter
  -1 siblings, 0 replies; 310+ messages in thread
From: Daniel Vetter @ 2020-02-19 10:20 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.

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 f7a1c33697b7..050e4d7c6723 100644
--- a/drivers/gpu/drm/i915/i915_drv.c
+++ b/drivers/gpu/drm/i915/i915_drv.c
@@ -1383,9 +1383,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] 310+ messages in thread

* [Intel-gfx] [PATCH 02/52] drm/i915: Don't clear drvdata in ->release
@ 2020-02-19 10:20   ` Daniel Vetter
  0 siblings, 0 replies; 310+ messages in thread
From: Daniel Vetter @ 2020-02-19 10:20 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.

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 f7a1c33697b7..050e4d7c6723 100644
--- a/drivers/gpu/drm/i915/i915_drv.c
+++ b/drivers/gpu/drm/i915/i915_drv.c
@@ -1383,9 +1383,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

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* [PATCH 03/52] drm: add managed resources tied to drm_device
  2020-02-19 10:20 ` [Intel-gfx] " Daniel Vetter
@ 2020-02-19 10:20   ` Daniel Vetter
  -1 siblings, 0 replies; 310+ messages in thread
From: Daniel Vetter @ 2020-02-19 10:20 UTC (permalink / raw)
  To: DRI Development
  Cc: Daniel Vetter, Daniel Vetter, Intel Graphics Development,
	Rafael J. Wysocki, Greg Kroah-Hartman

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.

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           |  13 ++-
 drivers/gpu/drm/drm_internal.h      |   3 +
 drivers/gpu/drm/drm_managed.c       | 173 ++++++++++++++++++++++++++++
 include/drm/drm_device.h            |  12 ++
 include/drm/drm_managed.h           |  25 ++++
 include/drm/drm_print.h             |   6 +
 8 files changed, 239 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 ca0ca775d37f..53d8fa170143 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..3e5627d6eba6 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,16 @@ static void drm_dev_release(struct kref *ref)
 		dev->driver->release(dev);
 	} else {
 		drm_dev_fini(dev);
-		kfree(dev);
+		if (!dev->managed.final_kfree) {
+			WARN_ON(!list_empty(&dev->managed.resources));
+			kfree(dev);
+		}
 	}
+
+	drm_managed_release(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..ee7c7253af61
--- /dev/null
+++ b/drivers/gpu/drm/drm_managed.c
@@ -0,0 +1,173 @@
+// 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 sturct &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 (%lu bytes)\n",
+			       dr, dr->node.name, (unsigned long) dr->node.size);
+
+		if (dr->node.release)
+			dr->node.release(dev, dr->node.size ? dr->data : NULL);
+
+		list_del(&dr->node.entry);
+		kfree(dr);
+	}
+	drm_dbg_drmres(dev, "drmres release end\n");
+}
+
+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;
+}
+
+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);
+}
+
+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);
+	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)
+		return -ENOMEM;
+	dr->node.name = name;
+	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)
+		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 = 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->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_kfree);
diff --git a/include/drm/drm_device.h b/include/drm/drm_device.h
index bb60a949f416..2790c9ed614e 100644
--- a/include/drm/drm_device.h
+++ b/include/drm/drm_device.h
@@ -67,6 +67,18 @@ 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 {
+		struct list_head resources;
+		void *final_kfree;
+		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..75f2c8932c69
--- /dev/null
+++ b/include/drm/drm_managed.h
@@ -0,0 +1,25 @@
+// SPDX-License-Identifier: GPL-2.0
+
+#include <linux/types.h>
+#include <linux/gfp.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);
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] 310+ messages in thread

* [Intel-gfx] [PATCH 03/52] drm: add managed resources tied to drm_device
@ 2020-02-19 10:20   ` Daniel Vetter
  0 siblings, 0 replies; 310+ messages in thread
From: Daniel Vetter @ 2020-02-19 10:20 UTC (permalink / raw)
  To: DRI Development
  Cc: Daniel Vetter, Daniel Vetter, Intel Graphics Development,
	Rafael J. Wysocki, Greg Kroah-Hartman

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.

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           |  13 ++-
 drivers/gpu/drm/drm_internal.h      |   3 +
 drivers/gpu/drm/drm_managed.c       | 173 ++++++++++++++++++++++++++++
 include/drm/drm_device.h            |  12 ++
 include/drm/drm_managed.h           |  25 ++++
 include/drm/drm_print.h             |   6 +
 8 files changed, 239 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 ca0ca775d37f..53d8fa170143 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..3e5627d6eba6 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,16 @@ static void drm_dev_release(struct kref *ref)
 		dev->driver->release(dev);
 	} else {
 		drm_dev_fini(dev);
-		kfree(dev);
+		if (!dev->managed.final_kfree) {
+			WARN_ON(!list_empty(&dev->managed.resources));
+			kfree(dev);
+		}
 	}
+
+	drm_managed_release(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..ee7c7253af61
--- /dev/null
+++ b/drivers/gpu/drm/drm_managed.c
@@ -0,0 +1,173 @@
+// 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 sturct &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 (%lu bytes)\n",
+			       dr, dr->node.name, (unsigned long) dr->node.size);
+
+		if (dr->node.release)
+			dr->node.release(dev, dr->node.size ? dr->data : NULL);
+
+		list_del(&dr->node.entry);
+		kfree(dr);
+	}
+	drm_dbg_drmres(dev, "drmres release end\n");
+}
+
+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;
+}
+
+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);
+}
+
+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);
+	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)
+		return -ENOMEM;
+	dr->node.name = name;
+	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)
+		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 = 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->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_kfree);
diff --git a/include/drm/drm_device.h b/include/drm/drm_device.h
index bb60a949f416..2790c9ed614e 100644
--- a/include/drm/drm_device.h
+++ b/include/drm/drm_device.h
@@ -67,6 +67,18 @@ 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 {
+		struct list_head resources;
+		void *final_kfree;
+		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..75f2c8932c69
--- /dev/null
+++ b/include/drm/drm_managed.h
@@ -0,0 +1,25 @@
+// SPDX-License-Identifier: GPL-2.0
+
+#include <linux/types.h>
+#include <linux/gfp.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);
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

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* [PATCH 04/52] drm: Set final_kfree in drm_dev_alloc
  2020-02-19 10:20 ` [Intel-gfx] " Daniel Vetter
  (?)
@ 2020-02-19 10:20   ` Daniel Vetter
  -1 siblings, 0 replies; 310+ messages in thread
From: Daniel Vetter @ 2020-02-19 10:20 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

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 3e5627d6eba6..9e62e28bbc62 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] 310+ messages in thread

* [Intel-gfx] [PATCH 04/52] drm: Set final_kfree in drm_dev_alloc
@ 2020-02-19 10:20   ` Daniel Vetter
  0 siblings, 0 replies; 310+ messages in thread
From: Daniel Vetter @ 2020-02-19 10:20 UTC (permalink / raw)
  To: DRI Development
  Cc: Oleksandr Andrushchenko, David Airlie, Daniel Vetter,
	Intel Graphics Development, Maxime Ripard, 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

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 3e5627d6eba6..9e62e28bbc62 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

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* [Xen-devel] [PATCH 04/52] drm: Set final_kfree in drm_dev_alloc
@ 2020-02-19 10:20   ` Daniel Vetter
  0 siblings, 0 replies; 310+ messages in thread
From: Daniel Vetter @ 2020-02-19 10:20 UTC (permalink / raw)
  To: DRI Development
  Cc: Daniel Vetter, Oleksandr Andrushchenko, David Airlie,
	Daniel Vetter, Intel Graphics Development, Maarten Lankhorst,
	Maxime Ripard, 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

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 3e5627d6eba6..9e62e28bbc62 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


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

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

* [PATCH 05/52] drm/mipi_dbi: Use drmm_add_final_kfree in all drivers
  2020-02-19 10:20 ` [Intel-gfx] " Daniel Vetter
@ 2020-02-19 10:20   ` Daniel Vetter
  -1 siblings, 0 replies; 310+ messages in thread
From: Daniel Vetter @ 2020-02-19 10:20 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).

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] 310+ messages in thread

* [Intel-gfx] [PATCH 05/52] drm/mipi_dbi: Use drmm_add_final_kfree in all drivers
@ 2020-02-19 10:20   ` Daniel Vetter
  0 siblings, 0 replies; 310+ messages in thread
From: Daniel Vetter @ 2020-02-19 10:20 UTC (permalink / raw)
  To: DRI Development
  Cc: David Airlie, Daniel Vetter, Intel Graphics Development,
	Maxime Ripard, Eric Anholt, Noralf Trønnes,
	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).

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

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* [PATCH 06/52] drm/udl: Use drmm_add_final_kfree
  2020-02-19 10:20 ` [Intel-gfx] " Daniel Vetter
@ 2020-02-19 10:20   ` Daniel Vetter
  -1 siblings, 0 replies; 310+ messages in thread
From: Daniel Vetter @ 2020-02-19 10:20 UTC (permalink / raw)
  To: DRI Development
  Cc: Sam Ravnborg, Daniel Vetter, Intel Graphics Development,
	Emil Velikov, Thomas Zimmermann, Daniel Vetter, Dave Airlie,
	Thomas Gleixner, Sean Paul

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: 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 | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/udl/udl_drv.c b/drivers/gpu/drm/udl/udl_drv.c
index e6c1cd77d4d4..d5b89711ab1e 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,6 +77,7 @@ 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) {
-- 
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] 310+ messages in thread

* [Intel-gfx] [PATCH 06/52] drm/udl: Use drmm_add_final_kfree
@ 2020-02-19 10:20   ` Daniel Vetter
  0 siblings, 0 replies; 310+ messages in thread
From: Daniel Vetter @ 2020-02-19 10:20 UTC (permalink / raw)
  To: DRI Development
  Cc: Sam Ravnborg, Daniel Vetter, Intel Graphics Development,
	Noralf Trønnes, Thomas Zimmermann, Daniel Vetter,
	Dave Airlie, Thomas Gleixner

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: 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 | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/udl/udl_drv.c b/drivers/gpu/drm/udl/udl_drv.c
index e6c1cd77d4d4..d5b89711ab1e 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,6 +77,7 @@ 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) {
-- 
2.24.1

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* [PATCH 07/52] drm/udl: Use drmm_add_final_kfree
  2020-02-19 10:20 ` [Intel-gfx] " Daniel Vetter
@ 2020-02-19 10:20   ` Daniel Vetter
  -1 siblings, 0 replies; 310+ messages in thread
From: Daniel Vetter @ 2020-02-19 10:20 UTC (permalink / raw)
  To: DRI Development
  Cc: Sam Ravnborg, Daniel Vetter, Intel Graphics Development,
	Emil Velikov, Thomas Zimmermann, Daniel Vetter, Dave Airlie,
	Thomas Gleixner, Sean Paul

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.

Signed-off-by: Daniel Vetter <daniel.vetter@intel.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 | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/udl/udl_drv.c b/drivers/gpu/drm/udl/udl_drv.c
index d5b89711ab1e..6a5594946096 100644
--- a/drivers/gpu/drm/udl/udl_drv.c
+++ b/drivers/gpu/drm/udl/udl_drv.c
@@ -81,8 +81,7 @@ static struct udl_device *udl_driver_create(struct usb_interface *interface)
 
 	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] 310+ messages in thread

* [Intel-gfx] [PATCH 07/52] drm/udl: Use drmm_add_final_kfree
@ 2020-02-19 10:20   ` Daniel Vetter
  0 siblings, 0 replies; 310+ messages in thread
From: Daniel Vetter @ 2020-02-19 10:20 UTC (permalink / raw)
  To: DRI Development
  Cc: Sam Ravnborg, Daniel Vetter, Intel Graphics Development,
	Noralf Trønnes, Thomas Zimmermann, Daniel Vetter,
	Dave Airlie, Thomas Gleixner

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.

Signed-off-by: Daniel Vetter <daniel.vetter@intel.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 | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/udl/udl_drv.c b/drivers/gpu/drm/udl/udl_drv.c
index d5b89711ab1e..6a5594946096 100644
--- a/drivers/gpu/drm/udl/udl_drv.c
+++ b/drivers/gpu/drm/udl/udl_drv.c
@@ -81,8 +81,7 @@ static struct udl_device *udl_driver_create(struct usb_interface *interface)
 
 	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

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* [PATCH 08/52] drm/qxl: Use drmm_add_final_kfree
  2020-02-19 10:20 ` [Intel-gfx] " Daniel Vetter
  (?)
@ 2020-02-19 10:20   ` Daniel Vetter
  -1 siblings, 0 replies; 310+ messages in thread
From: Daniel Vetter @ 2020-02-19 10:20 UTC (permalink / raw)
  To: DRI Development
  Cc: spice-devel, Daniel Vetter, Intel Graphics Development,
	virtualization, 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

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

* [PATCH 08/52] drm/qxl: Use drmm_add_final_kfree
@ 2020-02-19 10:20   ` Daniel Vetter
  0 siblings, 0 replies; 310+ messages in thread
From: Daniel Vetter @ 2020-02-19 10:20 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] 310+ messages in thread

* [Intel-gfx] [PATCH 08/52] drm/qxl: Use drmm_add_final_kfree
@ 2020-02-19 10:20   ` Daniel Vetter
  0 siblings, 0 replies; 310+ messages in thread
From: Daniel Vetter @ 2020-02-19 10:20 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

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* [PATCH 09/52] drm/i915: Use drmm_add_final_kfree
  2020-02-19 10:20 ` [Intel-gfx] " Daniel Vetter
@ 2020-02-19 10:20   ` Daniel Vetter
  -1 siblings, 0 replies; 310+ messages in thread
From: Daniel Vetter @ 2020-02-19 10:20 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.

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                |  9 ++++++++-
 drivers/gpu/drm/i915/i915_drv.h                |  3 +++
 .../gpu/drm/i915/selftests/mock_gem_device.c   | 18 +++++++++++++++++-
 3 files changed, 28 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
index 050e4d7c6723..61d874b61cb3 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 <drm/i915_drm.h>
 
@@ -1363,6 +1364,7 @@ i915_driver_create(struct pci_dev *pdev, const struct pci_device_id *ent)
 	}
 
 	i915->drm.dev_private = i915;
+	drmm_add_final_kfree(&i915->drm, i915);
 
 	i915->drm.pdev = pdev;
 	pci_set_drvdata(pdev, i915);
@@ -1382,7 +1384,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);
 }
 
 /**
@@ -1458,6 +1459,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_hw:
@@ -1474,6 +1477,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;
 }
 
@@ -1516,6 +1520,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 3330b538d379..6e984fd7ae77 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 3b8986983afc..9b06d5ec889a 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)
+		return;
+
 	mock_device_flush(i915);
 	intel_gt_driver_remove(&i915->gt);
 
@@ -114,9 +119,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;
+	i915 = kzalloc(sizeof(*i915), GFP_KERNEL);
+	if (!i915) {
+		kfree(pdev);
+		goto err;
+	}
 
 	device_initialize(&pdev->dev);
 	pdev->class = PCI_BASE_CLASS_DISPLAY << 16;
@@ -141,10 +151,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);
+		kfree(i915);
+
 		goto put_device;
 	}
 	i915->drm.pdev = pdev;
 	i915->drm.dev_private = i915;
+	drmm_add_final_kfree(&i915->drm, i915);
 
 	intel_runtime_pm_init_early(&i915->runtime_pm);
 
@@ -189,6 +202,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:
@@ -200,6 +215,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);
+	drm_dev_put(&i915->drm);
 put_device:
 	put_device(&pdev->dev);
 err:
-- 
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] 310+ messages in thread

* [Intel-gfx] [PATCH 09/52] drm/i915: Use drmm_add_final_kfree
@ 2020-02-19 10:20   ` Daniel Vetter
  0 siblings, 0 replies; 310+ messages in thread
From: Daniel Vetter @ 2020-02-19 10:20 UTC (permalink / raw)
  To: DRI Development
  Cc: Daniel Vetter, Intel Graphics Development, Matthew Auld, 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.

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                |  9 ++++++++-
 drivers/gpu/drm/i915/i915_drv.h                |  3 +++
 .../gpu/drm/i915/selftests/mock_gem_device.c   | 18 +++++++++++++++++-
 3 files changed, 28 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
index 050e4d7c6723..61d874b61cb3 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 <drm/i915_drm.h>
 
@@ -1363,6 +1364,7 @@ i915_driver_create(struct pci_dev *pdev, const struct pci_device_id *ent)
 	}
 
 	i915->drm.dev_private = i915;
+	drmm_add_final_kfree(&i915->drm, i915);
 
 	i915->drm.pdev = pdev;
 	pci_set_drvdata(pdev, i915);
@@ -1382,7 +1384,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);
 }
 
 /**
@@ -1458,6 +1459,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_hw:
@@ -1474,6 +1477,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;
 }
 
@@ -1516,6 +1520,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 3330b538d379..6e984fd7ae77 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 3b8986983afc..9b06d5ec889a 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)
+		return;
+
 	mock_device_flush(i915);
 	intel_gt_driver_remove(&i915->gt);
 
@@ -114,9 +119,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;
+	i915 = kzalloc(sizeof(*i915), GFP_KERNEL);
+	if (!i915) {
+		kfree(pdev);
+		goto err;
+	}
 
 	device_initialize(&pdev->dev);
 	pdev->class = PCI_BASE_CLASS_DISPLAY << 16;
@@ -141,10 +151,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);
+		kfree(i915);
+
 		goto put_device;
 	}
 	i915->drm.pdev = pdev;
 	i915->drm.dev_private = i915;
+	drmm_add_final_kfree(&i915->drm, i915);
 
 	intel_runtime_pm_init_early(&i915->runtime_pm);
 
@@ -189,6 +202,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:
@@ -200,6 +215,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);
+	drm_dev_put(&i915->drm);
 put_device:
 	put_device(&pdev->dev);
 err:
-- 
2.24.1

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* [PATCH 10/52] drm/cirrus: Use drmm_add_final_kfree
  2020-02-19 10:20 ` [Intel-gfx] " Daniel Vetter
  (?)
@ 2020-02-19 10:20   ` Daniel Vetter
  -1 siblings, 0 replies; 310+ messages in thread
From: Daniel Vetter @ 2020-02-19 10:20 UTC (permalink / raw)
  To: DRI Development
  Cc: Daniel Vetter, Intel Graphics Development, virtualization,
	Noralf Trønnes, Thomas Zimmermann, Daniel Vetter,
	Dave Airlie, Sam Ravnborg, Linus Walleij

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.

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

_______________________________________________
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization

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

* [PATCH 10/52] drm/cirrus: Use drmm_add_final_kfree
@ 2020-02-19 10:20   ` Daniel Vetter
  0 siblings, 0 replies; 310+ messages in thread
From: Daniel Vetter @ 2020-02-19 10:20 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.

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] 310+ messages in thread

* [Intel-gfx] [PATCH 10/52] drm/cirrus: Use drmm_add_final_kfree
@ 2020-02-19 10:20   ` Daniel Vetter
  0 siblings, 0 replies; 310+ messages in thread
From: Daniel Vetter @ 2020-02-19 10:20 UTC (permalink / raw)
  To: DRI Development
  Cc: Daniel Vetter, Intel Graphics Development, virtualization,
	Noralf Trønnes, Gerd Hoffmann, Thomas Zimmermann,
	Daniel Vetter, Dave Airlie, Sam Ravnborg, Linus Walleij

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.

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

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* [PATCH 11/52] drm/v3d: Use drmm_add_final_kfree
  2020-02-19 10:20 ` [Intel-gfx] " Daniel Vetter
@ 2020-02-19 10:20   ` Daniel Vetter
  -1 siblings, 0 replies; 310+ messages in thread
From: Daniel Vetter @ 2020-02-19 10:20 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.

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.

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] 310+ messages in thread

* [Intel-gfx] [PATCH 11/52] drm/v3d: Use drmm_add_final_kfree
@ 2020-02-19 10:20   ` Daniel Vetter
  0 siblings, 0 replies; 310+ messages in thread
From: Daniel Vetter @ 2020-02-19 10:20 UTC (permalink / raw)
  To: DRI Development
  Cc: Eric Anholt, Daniel Vetter, Intel Graphics Development, Daniel Vetter

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.

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

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* [PATCH 12/52] drm/tidss: Use drmm_add_final_kfree
  2020-02-19 10:20 ` [Intel-gfx] " Daniel Vetter
@ 2020-02-19 10:20   ` Daniel Vetter
  -1 siblings, 0 replies; 310+ messages in thread
From: Daniel Vetter @ 2020-02-19 10:20 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.

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] 310+ messages in thread

* [Intel-gfx] [PATCH 12/52] drm/tidss: Use drmm_add_final_kfree
@ 2020-02-19 10:20   ` Daniel Vetter
  0 siblings, 0 replies; 310+ messages in thread
From: Daniel Vetter @ 2020-02-19 10:20 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.

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

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* [PATCH 13/52] drm/mcde: Use drmm_add_final_kfree
  2020-02-19 10:20 ` [Intel-gfx] " Daniel Vetter
@ 2020-02-19 10:20   ` Daniel Vetter
  -1 siblings, 0 replies; 310+ messages in thread
From: Daniel Vetter @ 2020-02-19 10:20 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.

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] 310+ messages in thread

* [Intel-gfx] [PATCH 13/52] drm/mcde: Use drmm_add_final_kfree
@ 2020-02-19 10:20   ` Daniel Vetter
  0 siblings, 0 replies; 310+ messages in thread
From: Daniel Vetter @ 2020-02-19 10:20 UTC (permalink / raw)
  To: DRI Development
  Cc: Daniel Vetter, Intel Graphics Development, Linus Walleij, Daniel Vetter

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

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

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* [PATCH 14/52] drm/vgem: Use drmm_add_final_kfree
  2020-02-19 10:20 ` [Intel-gfx] " Daniel Vetter
@ 2020-02-19 10:20   ` Daniel Vetter
  -1 siblings, 0 replies; 310+ messages in thread
From: Daniel Vetter @ 2020-02-19 10:20 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.

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] 310+ messages in thread

* [Intel-gfx] [PATCH 14/52] drm/vgem: Use drmm_add_final_kfree
@ 2020-02-19 10:20   ` Daniel Vetter
  0 siblings, 0 replies; 310+ messages in thread
From: Daniel Vetter @ 2020-02-19 10:20 UTC (permalink / raw)
  To: DRI Development
  Cc: Rob Clark, Daniel Vetter, Intel Graphics Development,
	Eric Anholt, 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.

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

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* [PATCH 15/52] drm/vkms: Use drmm_add_final_kfree
  2020-02-19 10:20 ` [Intel-gfx] " Daniel Vetter
@ 2020-02-19 10:20   ` Daniel Vetter
  -1 siblings, 0 replies; 310+ messages in thread
From: Daniel Vetter @ 2020-02-19 10:20 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.

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] 310+ messages in thread

* [Intel-gfx] [PATCH 15/52] drm/vkms: Use drmm_add_final_kfree
@ 2020-02-19 10:20   ` Daniel Vetter
  0 siblings, 0 replies; 310+ messages in thread
From: Daniel Vetter @ 2020-02-19 10:20 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.

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

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* [PATCH 16/52] drm/repaper: Use drmm_add_final_kfree
  2020-02-19 10:20 ` [Intel-gfx] " Daniel Vetter
@ 2020-02-19 10:20   ` Daniel Vetter
  -1 siblings, 0 replies; 310+ messages in thread
From: Daniel Vetter @ 2020-02-19 10:20 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.

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] 310+ messages in thread

* [Intel-gfx] [PATCH 16/52] drm/repaper: Use drmm_add_final_kfree
@ 2020-02-19 10:20   ` Daniel Vetter
  0 siblings, 0 replies; 310+ messages in thread
From: Daniel Vetter @ 2020-02-19 10:20 UTC (permalink / raw)
  To: DRI Development
  Cc: Daniel Vetter, Intel Graphics Development, Noralf Trønnes,
	Daniel Vetter

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

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

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* [PATCH 17/52] drm/inigenic: Use drmm_add_final_kfree
  2020-02-19 10:20 ` [Intel-gfx] " Daniel Vetter
@ 2020-02-19 10:20   ` Daniel Vetter
  -1 siblings, 0 replies; 310+ messages in thread
From: Daniel Vetter @ 2020-02-19 10:20 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.

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 6d47ef7b148c..12b14aed05cd 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] 310+ messages in thread

* [Intel-gfx] [PATCH 17/52] drm/inigenic: Use drmm_add_final_kfree
@ 2020-02-19 10:20   ` Daniel Vetter
  0 siblings, 0 replies; 310+ messages in thread
From: Daniel Vetter @ 2020-02-19 10:20 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.

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 6d47ef7b148c..12b14aed05cd 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

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* [PATCH 18/52] drm/gm12u320: Use drmm_add_final_kfree
  2020-02-19 10:20 ` [Intel-gfx] " Daniel Vetter
@ 2020-02-19 10:20   ` Daniel Vetter
  -1 siblings, 0 replies; 310+ messages in thread
From: Daniel Vetter @ 2020-02-19 10:20 UTC (permalink / raw)
  To: DRI Development
  Cc: Daniel Vetter, Intel Graphics Development, Hans de Goede, Daniel Vetter

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

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] 310+ messages in thread

* [Intel-gfx] [PATCH 18/52] drm/gm12u320: Use drmm_add_final_kfree
@ 2020-02-19 10:20   ` Daniel Vetter
  0 siblings, 0 replies; 310+ messages in thread
From: Daniel Vetter @ 2020-02-19 10:20 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.

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

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* [PATCH 19/52] drm/<drivers>: Use drmm_add_final_kfree
  2020-02-19 10:20 ` [Intel-gfx] " Daniel Vetter
@ 2020-02-19 10:20   ` Daniel Vetter
  -1 siblings, 0 replies; 310+ messages in thread
From: Daniel Vetter @ 2020-02-19 10:20 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.

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] 310+ messages in thread

* [Intel-gfx] [PATCH 19/52] drm/<drivers>: Use drmm_add_final_kfree
@ 2020-02-19 10:20   ` Daniel Vetter
  0 siblings, 0 replies; 310+ messages in thread
From: Daniel Vetter @ 2020-02-19 10:20 UTC (permalink / raw)
  To: DRI Development
  Cc: Daniel Vetter, Intel Graphics Development, Russell King,
	James (Qian) Wang, Daniel Vetter, Mihail Atanassov

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

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

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* [PATCH 20/52] drm: Cleanups after drmm_add_final_kfree rollout
  2020-02-19 10:20 ` [Intel-gfx] " Daniel Vetter
@ 2020-02-19 10:20   ` Daniel Vetter
  -1 siblings, 0 replies; 310+ messages in thread
From: Daniel Vetter @ 2020-02-19 10:20 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 | 11 ++++-------
 1 file changed, 4 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c
index 9e62e28bbc62..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;
  *
@@ -834,10 +833,6 @@ static void drm_dev_release(struct kref *ref)
 		dev->driver->release(dev);
 	} else {
 		drm_dev_fini(dev);
-		if (!dev->managed.final_kfree) {
-			WARN_ON(!list_empty(&dev->managed.resources));
-			kfree(dev);
-		}
 	}
 
 	drm_managed_release(dev);
@@ -960,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] 310+ messages in thread

* [Intel-gfx] [PATCH 20/52] drm: Cleanups after drmm_add_final_kfree rollout
@ 2020-02-19 10:20   ` Daniel Vetter
  0 siblings, 0 replies; 310+ messages in thread
From: Daniel Vetter @ 2020-02-19 10:20 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 | 11 ++++-------
 1 file changed, 4 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c
index 9e62e28bbc62..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;
  *
@@ -834,10 +833,6 @@ static void drm_dev_release(struct kref *ref)
 		dev->driver->release(dev);
 	} else {
 		drm_dev_fini(dev);
-		if (!dev->managed.final_kfree) {
-			WARN_ON(!list_empty(&dev->managed.resources));
-			kfree(dev);
-		}
 	}
 
 	drm_managed_release(dev);
@@ -960,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

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* [PATCH 21/52] drm: Handle dev->unique with drmm_
  2020-02-19 10:20 ` [Intel-gfx] " Daniel Vetter
@ 2020-02-19 10:20   ` Daniel Vetter
  -1 siblings, 0 replies; 310+ messages in thread
From: Daniel Vetter @ 2020-02-19 10:20 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 1ee606b4a4f9..782fd5d6f8b2 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);
 
@@ -1063,8 +1062,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 ee7c7253af61..d8a484e19830 100644
--- a/drivers/gpu/drm/drm_managed.c
+++ b/drivers/gpu/drm/drm_managed.c
@@ -147,6 +147,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 = NULL, *tmp;
diff --git a/include/drm/drm_managed.h b/include/drm/drm_managed.h
index 75f2c8932c69..240edd395e88 100644
--- a/include/drm/drm_managed.h
+++ b/include/drm/drm_managed.h
@@ -21,5 +21,6 @@ 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] 310+ messages in thread

* [Intel-gfx] [PATCH 21/52] drm: Handle dev->unique with drmm_
@ 2020-02-19 10:20   ` Daniel Vetter
  0 siblings, 0 replies; 310+ messages in thread
From: Daniel Vetter @ 2020-02-19 10:20 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 1ee606b4a4f9..782fd5d6f8b2 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);
 
@@ -1063,8 +1062,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 ee7c7253af61..d8a484e19830 100644
--- a/drivers/gpu/drm/drm_managed.c
+++ b/drivers/gpu/drm/drm_managed.c
@@ -147,6 +147,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 = NULL, *tmp;
diff --git a/include/drm/drm_managed.h b/include/drm/drm_managed.h
index 75f2c8932c69..240edd395e88 100644
--- a/include/drm/drm_managed.h
+++ b/include/drm/drm_managed.h
@@ -21,5 +21,6 @@ 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

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* [PATCH 22/52] drm: Use drmm_ for drm_dev_init cleanup
  2020-02-19 10:20 ` [Intel-gfx] " Daniel Vetter
@ 2020-02-19 10:20   ` Daniel Vetter
  -1 siblings, 0 replies; 310+ messages in thread
From: Daniel Vetter @ 2020-02-19 10:20 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 782fd5d6f8b2..1f7ab88d9435 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] 310+ messages in thread

* [Intel-gfx] [PATCH 22/52] drm: Use drmm_ for drm_dev_init cleanup
@ 2020-02-19 10:20   ` Daniel Vetter
  0 siblings, 0 replies; 310+ messages in thread
From: Daniel Vetter @ 2020-02-19 10:20 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 782fd5d6f8b2..1f7ab88d9435 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

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* [PATCH 23/52] drm: manage drm_minor cleanup with drmm_
  2020-02-19 10:20 ` [Intel-gfx] " Daniel Vetter
@ 2020-02-19 10:20   ` Daniel Vetter
  -1 siblings, 0 replies; 310+ messages in thread
From: Daniel Vetter @ 2020-02-19 10:20 UTC (permalink / raw)
  To: DRI Development; +Cc: Daniel Vetter, Intel Graphics Development, 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.

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 1f7ab88d9435..03a1fb377830 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 d8a484e19830..fb44fe65c2cd 100644
--- a/drivers/gpu/drm/drm_managed.c
+++ b/drivers/gpu/drm/drm_managed.c
@@ -132,6 +132,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 240edd395e88..df30f9355902 100644
--- a/include/drm/drm_managed.h
+++ b/include/drm/drm_managed.h
@@ -14,6 +14,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] 310+ messages in thread

* [Intel-gfx] [PATCH 23/52] drm: manage drm_minor cleanup with drmm_
@ 2020-02-19 10:20   ` Daniel Vetter
  0 siblings, 0 replies; 310+ messages in thread
From: Daniel Vetter @ 2020-02-19 10:20 UTC (permalink / raw)
  To: DRI Development; +Cc: Daniel Vetter, Intel Graphics Development, 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.

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 1f7ab88d9435..03a1fb377830 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 d8a484e19830..fb44fe65c2cd 100644
--- a/drivers/gpu/drm/drm_managed.c
+++ b/drivers/gpu/drm/drm_managed.c
@@ -132,6 +132,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 240edd395e88..df30f9355902 100644
--- a/include/drm/drm_managed.h
+++ b/include/drm/drm_managed.h
@@ -14,6 +14,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

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* [PATCH 24/52] drm: Manage drm_gem_init with drmm_
  2020-02-19 10:20 ` [Intel-gfx] " Daniel Vetter
@ 2020-02-19 10:20   ` Daniel Vetter
  -1 siblings, 0 replies; 310+ messages in thread
From: Daniel Vetter @ 2020-02-19 10:20 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 03a1fb377830..7b3df1188da9 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] 310+ messages in thread

* [Intel-gfx] [PATCH 24/52] drm: Manage drm_gem_init with drmm_
@ 2020-02-19 10:20   ` Daniel Vetter
  0 siblings, 0 replies; 310+ messages in thread
From: Daniel Vetter @ 2020-02-19 10:20 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 03a1fb377830..7b3df1188da9 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

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* [PATCH 25/52] drm: Manage drm_vblank_cleanup with drmm_
  2020-02-19 10:20 ` [Intel-gfx] " Daniel Vetter
@ 2020-02-19 10:20   ` Daniel Vetter
  -1 siblings, 0 replies; 310+ messages in thread
From: Daniel Vetter @ 2020-02-19 10:20 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

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 7b3df1188da9..b8db2cc4a19b 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 df30f9355902..573cadca4b3d 100644
--- a/include/drm/drm_managed.h
+++ b/include/drm/drm_managed.h
@@ -2,6 +2,7 @@
 
 #include <linux/types.h>
 #include <linux/gfp.h>
+#include <linux/overflow.h>
 
 struct drm_device;
 
@@ -25,6 +26,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] 310+ messages in thread

* [Intel-gfx] [PATCH 25/52] drm: Manage drm_vblank_cleanup with drmm_
@ 2020-02-19 10:20   ` Daniel Vetter
  0 siblings, 0 replies; 310+ messages in thread
From: Daniel Vetter @ 2020-02-19 10:20 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

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 7b3df1188da9..b8db2cc4a19b 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 df30f9355902..573cadca4b3d 100644
--- a/include/drm/drm_managed.h
+++ b/include/drm/drm_managed.h
@@ -2,6 +2,7 @@
 
 #include <linux/types.h>
 #include <linux/gfp.h>
+#include <linux/overflow.h>
 
 struct drm_device;
 
@@ -25,6 +26,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

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* [PATCH 26/52] drm: Garbage collect drm_dev_fini
  2020-02-19 10:20 ` [Intel-gfx] " Daniel Vetter
@ 2020-02-19 10:20   ` Daniel Vetter
  -1 siblings, 0 replies; 310+ messages in thread
From: Daniel Vetter @ 2020-02-19 10:20 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.

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 b8db2cc4a19b..3cf40864d4a6 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 61d874b61cb3..1db3cc761741 100644
--- a/drivers/gpu/drm/i915/i915_drv.c
+++ b/drivers/gpu/drm/i915/i915_drv.c
@@ -1379,13 +1379,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
@@ -1476,7 +1469,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;
 }
@@ -1536,7 +1528,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 9b06d5ec889a..00683af97a94 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);
 	put_device(&i915->drm.pdev->dev);
 }
 
@@ -214,7 +213,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);
 put_device:
 	put_device(&pdev->dev);
diff --git a/drivers/gpu/drm/ingenic/ingenic-drm.c b/drivers/gpu/drm/ingenic/ingenic-drm.c
index 12b14aed05cd..06c195af714e 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] 310+ messages in thread

* [Intel-gfx] [PATCH 26/52] drm: Garbage collect drm_dev_fini
@ 2020-02-19 10:20   ` Daniel Vetter
  0 siblings, 0 replies; 310+ messages in thread
From: Daniel Vetter @ 2020-02-19 10:20 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.

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 b8db2cc4a19b..3cf40864d4a6 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 61d874b61cb3..1db3cc761741 100644
--- a/drivers/gpu/drm/i915/i915_drv.c
+++ b/drivers/gpu/drm/i915/i915_drv.c
@@ -1379,13 +1379,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
@@ -1476,7 +1469,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;
 }
@@ -1536,7 +1528,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 9b06d5ec889a..00683af97a94 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);
 	put_device(&i915->drm.pdev->dev);
 }
 
@@ -214,7 +213,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);
 put_device:
 	put_device(&pdev->dev);
diff --git a/drivers/gpu/drm/ingenic/ingenic-drm.c b/drivers/gpu/drm/ingenic/ingenic-drm.c
index 12b14aed05cd..06c195af714e 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

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* [PATCH 27/52] drm: Manage drm_mode_config_init with drmm_
  2020-02-19 10:20 ` [Intel-gfx] " Daniel Vetter
@ 2020-02-19 10:20   ` Daniel Vetter
  -1 siblings, 0 replies; 310+ messages in thread
From: Daniel Vetter @ 2020-02-19 10:20 UTC (permalink / raw)
  To: DRI Development
  Cc: Daniel Vetter, Intel Graphics Development, 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 not 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, so deprecate that hook to discourage future users.

v2: Fixup the example in the kerneldoc too.

Cc: "Noralf Trønnes" <noralf@tronnes.org>
Cc: Sam Ravnborg <sam@ravnborg.org>
Cc: Thomas Zimmermann <tzimmermann@suse.de>
Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
---
 drivers/gpu/drm/drm_drv.c         | 21 +++++----------------
 drivers/gpu/drm/drm_mode_config.c | 12 +++++++++++-
 include/drm/drm_mode_config.h     |  2 +-
 3 files changed, 17 insertions(+), 18 deletions(-)

diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c
index 3cf40864d4a6..428c569aaaf1 100644
--- a/drivers/gpu/drm/drm_drv.c
+++ b/drivers/gpu/drm/drm_drv.c
@@ -267,8 +267,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 +277,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 +303,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 +703,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 +714,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_mode_config.c b/drivers/gpu/drm/drm_mode_config.c
index 08e6eff6a179..957db1edba0c 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,8 @@ void drm_mode_config_init(struct drm_device *dev)
 		drm_modeset_acquire_fini(&modeset_ctx);
 		dma_resv_fini(&resv);
 	}
+
+	return drmm_add_action(dev, drm_mode_config_init_release, NULL);
 }
 EXPORT_SYMBOL(drm_mode_config_init);
 
diff --git a/include/drm/drm_mode_config.h b/include/drm/drm_mode_config.h
index 3bcbe30339f0..160a3e4b51c3 100644
--- a/include/drm/drm_mode_config.h
+++ b/include/drm/drm_mode_config.h
@@ -929,7 +929,7 @@ 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);
 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] 310+ messages in thread

* [Intel-gfx] [PATCH 27/52] drm: Manage drm_mode_config_init with drmm_
@ 2020-02-19 10:20   ` Daniel Vetter
  0 siblings, 0 replies; 310+ messages in thread
From: Daniel Vetter @ 2020-02-19 10:20 UTC (permalink / raw)
  To: DRI Development
  Cc: Daniel Vetter, Intel Graphics Development, Noralf Trønnes,
	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 not 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, so deprecate that hook to discourage future users.

v2: Fixup the example in the kerneldoc too.

Cc: "Noralf Trønnes" <noralf@tronnes.org>
Cc: Sam Ravnborg <sam@ravnborg.org>
Cc: Thomas Zimmermann <tzimmermann@suse.de>
Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
---
 drivers/gpu/drm/drm_drv.c         | 21 +++++----------------
 drivers/gpu/drm/drm_mode_config.c | 12 +++++++++++-
 include/drm/drm_mode_config.h     |  2 +-
 3 files changed, 17 insertions(+), 18 deletions(-)

diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c
index 3cf40864d4a6..428c569aaaf1 100644
--- a/drivers/gpu/drm/drm_drv.c
+++ b/drivers/gpu/drm/drm_drv.c
@@ -267,8 +267,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 +277,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 +303,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 +703,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 +714,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_mode_config.c b/drivers/gpu/drm/drm_mode_config.c
index 08e6eff6a179..957db1edba0c 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,8 @@ void drm_mode_config_init(struct drm_device *dev)
 		drm_modeset_acquire_fini(&modeset_ctx);
 		dma_resv_fini(&resv);
 	}
+
+	return drmm_add_action(dev, drm_mode_config_init_release, NULL);
 }
 EXPORT_SYMBOL(drm_mode_config_init);
 
diff --git a/include/drm/drm_mode_config.h b/include/drm/drm_mode_config.h
index 3bcbe30339f0..160a3e4b51c3 100644
--- a/include/drm/drm_mode_config.h
+++ b/include/drm/drm_mode_config.h
@@ -929,7 +929,7 @@ 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);
 void drm_mode_config_reset(struct drm_device *dev);
 void drm_mode_config_cleanup(struct drm_device *dev);
 
-- 
2.24.1

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* [PATCH 28/52] drm/bochs: Remove leftover drm_atomic_helper_shutdown
  2020-02-19 10:20 ` [Intel-gfx] " Daniel Vetter
@ 2020-02-19 10:20   ` Daniel Vetter
  -1 siblings, 0 replies; 310+ messages in thread
From: Daniel Vetter @ 2020-02-19 10:20 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] 310+ messages in thread

* [Intel-gfx] [PATCH 28/52] drm/bochs: Remove leftover drm_atomic_helper_shutdown
@ 2020-02-19 10:20   ` Daniel Vetter
  0 siblings, 0 replies; 310+ messages in thread
From: Daniel Vetter @ 2020-02-19 10:20 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

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* [PATCH 29/52] drm/bochs: Drop explicit drm_mode_config_cleanup
  2020-02-19 10:20 ` [Intel-gfx] " Daniel Vetter
  (?)
@ 2020-02-19 10:20   ` Daniel Vetter
  -1 siblings, 0 replies; 310+ messages in thread
From: Daniel Vetter @ 2020-02-19 10:20 UTC (permalink / raw)
  To: DRI Development
  Cc: Daniel Vetter, Intel Graphics Development, virtualization,
	Gerd Hoffmann, Daniel Vetter

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.

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..8285c03a6a95 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 = drm_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

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

* [PATCH 29/52] drm/bochs: Drop explicit drm_mode_config_cleanup
@ 2020-02-19 10:20   ` Daniel Vetter
  0 siblings, 0 replies; 310+ messages in thread
From: Daniel Vetter @ 2020-02-19 10:20 UTC (permalink / raw)
  To: DRI Development
  Cc: Daniel Vetter, Intel Graphics Development, virtualization,
	Gerd Hoffmann, Daniel Vetter

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.

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..8285c03a6a95 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 = drm_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] 310+ messages in thread

* [Intel-gfx] [PATCH 29/52] drm/bochs: Drop explicit drm_mode_config_cleanup
@ 2020-02-19 10:20   ` Daniel Vetter
  0 siblings, 0 replies; 310+ messages in thread
From: Daniel Vetter @ 2020-02-19 10:20 UTC (permalink / raw)
  To: DRI Development
  Cc: Daniel Vetter, Intel Graphics Development, virtualization,
	Gerd Hoffmann, Daniel Vetter

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.

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..8285c03a6a95 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 = drm_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

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* [PATCH 30/52] drm/cirrus: Drop explicit drm_mode_config_cleanup call
  2020-02-19 10:20 ` [Intel-gfx] " Daniel Vetter
  (?)
@ 2020-02-19 10:21   ` Daniel Vetter
  -1 siblings, 0 replies; 310+ messages in thread
From: Daniel Vetter @ 2020-02-19 10:21 UTC (permalink / raw)
  To: DRI Development
  Cc: Daniel Vetter, Intel Graphics Development, virtualization,
	Noralf Trønnes, Thomas Zimmermann, Daniel Vetter,
	Dave Airlie, Sam Ravnborg

We can even delete the drm_driver.release hook now!

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..6ac0286810ec 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 = drm_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

_______________________________________________
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization

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

* [PATCH 30/52] drm/cirrus: Drop explicit drm_mode_config_cleanup call
@ 2020-02-19 10:21   ` Daniel Vetter
  0 siblings, 0 replies; 310+ messages in thread
From: Daniel Vetter @ 2020-02-19 10:21 UTC (permalink / raw)
  To: DRI Development
  Cc: Daniel Vetter, Intel Graphics Development, virtualization,
	Gerd Hoffmann, Thomas Zimmermann, Daniel Vetter, Dave Airlie,
	Sam Ravnborg

We can even delete the drm_driver.release hook now!

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..6ac0286810ec 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 = drm_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] 310+ messages in thread

* [Intel-gfx] [PATCH 30/52] drm/cirrus: Drop explicit drm_mode_config_cleanup call
@ 2020-02-19 10:21   ` Daniel Vetter
  0 siblings, 0 replies; 310+ messages in thread
From: Daniel Vetter @ 2020-02-19 10:21 UTC (permalink / raw)
  To: DRI Development
  Cc: Daniel Vetter, Intel Graphics Development, virtualization,
	Noralf Trønnes, Gerd Hoffmann, Thomas Zimmermann,
	Daniel Vetter, Dave Airlie, Sam Ravnborg

We can even delete the drm_driver.release hook now!

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..6ac0286810ec 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 = drm_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

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* [PATCH 31/52] drm/cirrus: Fully embrace devm_
  2020-02-19 10:20 ` [Intel-gfx] " Daniel Vetter
  (?)
@ 2020-02-19 10:21   ` Daniel Vetter
  -1 siblings, 0 replies; 310+ messages in thread
From: Daniel Vetter @ 2020-02-19 10:21 UTC (permalink / raw)
  To: DRI Development
  Cc: Daniel Vetter, Intel Graphics Development, virtualization,
	Noralf Trønnes, 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 6ac0286810ec..1b78a2f88f69 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

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* [PATCH 31/52] drm/cirrus: Fully embrace devm_
@ 2020-02-19 10:21   ` Daniel Vetter
  0 siblings, 0 replies; 310+ messages in thread
From: Daniel Vetter @ 2020-02-19 10:21 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 6ac0286810ec..1b78a2f88f69 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] 310+ messages in thread

* [Intel-gfx] [PATCH 31/52] drm/cirrus: Fully embrace devm_
@ 2020-02-19 10:21   ` Daniel Vetter
  0 siblings, 0 replies; 310+ messages in thread
From: Daniel Vetter @ 2020-02-19 10:21 UTC (permalink / raw)
  To: DRI Development
  Cc: Daniel Vetter, Intel Graphics Development, virtualization,
	Noralf Trønnes, 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 6ac0286810ec..1b78a2f88f69 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

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* [PATCH 32/52] drm/ingenic: Drop explicit drm_mode_config_cleanup call
  2020-02-19 10:20 ` [Intel-gfx] " Daniel Vetter
@ 2020-02-19 10:21   ` Daniel Vetter
  -1 siblings, 0 replies; 310+ messages in thread
From: Daniel Vetter @ 2020-02-19 10:21 UTC (permalink / raw)
  To: DRI Development
  Cc: Paul Cercueil, Daniel Vetter, Intel Graphics Development, Daniel Vetter

Allows us to drop the drm_driver.release callback.

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 06c195af714e..587369f6c0d7 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 = drm_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] 310+ messages in thread

* [Intel-gfx] [PATCH 32/52] drm/ingenic: Drop explicit drm_mode_config_cleanup call
@ 2020-02-19 10:21   ` Daniel Vetter
  0 siblings, 0 replies; 310+ messages in thread
From: Daniel Vetter @ 2020-02-19 10:21 UTC (permalink / raw)
  To: DRI Development
  Cc: Paul Cercueil, Daniel Vetter, Intel Graphics Development, Daniel Vetter

Allows us to drop the drm_driver.release callback.

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 06c195af714e..587369f6c0d7 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 = drm_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

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* [PATCH 33/52] drm/mcde: Drop explicit drm_mode_config_cleanup call
  2020-02-19 10:20 ` [Intel-gfx] " Daniel Vetter
@ 2020-02-19 10:21   ` Daniel Vetter
  -1 siblings, 0 replies; 310+ messages in thread
From: Daniel Vetter @ 2020-02-19 10:21 UTC (permalink / raw)
  To: DRI Development; +Cc: Daniel Vetter, Intel Graphics Development, Daniel Vetter

Allows us to drop the drm_driver.release callback.

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..b8ca99995e51 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 = drm_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] 310+ messages in thread

* [Intel-gfx] [PATCH 33/52] drm/mcde: Drop explicit drm_mode_config_cleanup call
@ 2020-02-19 10:21   ` Daniel Vetter
  0 siblings, 0 replies; 310+ messages in thread
From: Daniel Vetter @ 2020-02-19 10:21 UTC (permalink / raw)
  To: DRI Development
  Cc: Daniel Vetter, Intel Graphics Development, Linus Walleij, Daniel Vetter

Allows us to drop the drm_driver.release callback.

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..b8ca99995e51 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 = drm_mode_config_init(drm);
+	if (ret)
+		return ret;
 
 	ret = component_bind_all(drm->dev, drm);
 	if (ret) {
-- 
2.24.1

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* [PATCH 34/52] drm/mcde: More devm_drm_dev_init
  2020-02-19 10:20 ` [Intel-gfx] " Daniel Vetter
@ 2020-02-19 10:21   ` Daniel Vetter
  -1 siblings, 0 replies; 310+ messages in thread
From: Daniel Vetter @ 2020-02-19 10:21 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.

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 b8ca99995e51..3e92a44397cf 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] 310+ messages in thread

* [Intel-gfx] [PATCH 34/52] drm/mcde: More devm_drm_dev_init
@ 2020-02-19 10:21   ` Daniel Vetter
  0 siblings, 0 replies; 310+ messages in thread
From: Daniel Vetter @ 2020-02-19 10:21 UTC (permalink / raw)
  To: DRI Development
  Cc: Daniel Vetter, Intel Graphics Development, Linus Walleij, 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.

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 b8ca99995e51..3e92a44397cf 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

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* [PATCH 35/52] drm/meson: Drop explicit drm_mode_config_cleanup call
  2020-02-19 10:20 ` [Intel-gfx] " Daniel Vetter
  (?)
  (?)
@ 2020-02-19 10:21   ` Daniel Vetter
  -1 siblings, 0 replies; 310+ messages in thread
From: Daniel Vetter @ 2020-02-19 10:21 UTC (permalink / raw)
  To: DRI Development
  Cc: Neil Armstrong, Daniel Vetter, Daniel Vetter,
	Intel Graphics Development, Kevin Hilman, linux-amlogic,
	linux-arm-kernel

It's right above the drm_dev_put().

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

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..ae94d14ab7bc 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 = drm_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


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* [PATCH 35/52] drm/meson: Drop explicit drm_mode_config_cleanup call
@ 2020-02-19 10:21   ` Daniel Vetter
  0 siblings, 0 replies; 310+ messages in thread
From: Daniel Vetter @ 2020-02-19 10:21 UTC (permalink / raw)
  To: DRI Development
  Cc: Neil Armstrong, Daniel Vetter, Daniel Vetter,
	Intel Graphics Development, Kevin Hilman, linux-amlogic,
	linux-arm-kernel

It's right above the drm_dev_put().

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

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..ae94d14ab7bc 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 = drm_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] 310+ messages in thread

* [Intel-gfx] [PATCH 35/52] drm/meson: Drop explicit drm_mode_config_cleanup call
@ 2020-02-19 10:21   ` Daniel Vetter
  0 siblings, 0 replies; 310+ messages in thread
From: Daniel Vetter @ 2020-02-19 10:21 UTC (permalink / raw)
  To: DRI Development
  Cc: Neil Armstrong, Daniel Vetter, Daniel Vetter,
	Intel Graphics Development, Kevin Hilman, linux-amlogic,
	linux-arm-kernel

It's right above the drm_dev_put().

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

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..ae94d14ab7bc 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 = drm_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

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* [PATCH 35/52] drm/meson: Drop explicit drm_mode_config_cleanup call
@ 2020-02-19 10:21   ` Daniel Vetter
  0 siblings, 0 replies; 310+ messages in thread
From: Daniel Vetter @ 2020-02-19 10:21 UTC (permalink / raw)
  To: DRI Development
  Cc: Neil Armstrong, Daniel Vetter, Daniel Vetter,
	Intel Graphics Development, Kevin Hilman, linux-amlogic,
	linux-arm-kernel

It's right above the drm_dev_put().

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

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..ae94d14ab7bc 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 = drm_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


_______________________________________________
linux-amlogic mailing list
linux-amlogic@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-amlogic

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

* [PATCH 36/52] drm/pl111: Drop explicit drm_mode_config_cleanup call
  2020-02-19 10:20 ` [Intel-gfx] " Daniel Vetter
@ 2020-02-19 10:21   ` Daniel Vetter
  -1 siblings, 0 replies; 310+ messages in thread
From: Daniel Vetter @ 2020-02-19 10:21 UTC (permalink / raw)
  To: DRI Development; +Cc: Daniel Vetter, Intel Graphics Development, Daniel Vetter

It's right above the drm_dev_put().

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

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..87b9b32c90a8 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 = drm_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] 310+ messages in thread

* [Intel-gfx] [PATCH 36/52] drm/pl111: Drop explicit drm_mode_config_cleanup call
@ 2020-02-19 10:21   ` Daniel Vetter
  0 siblings, 0 replies; 310+ messages in thread
From: Daniel Vetter @ 2020-02-19 10:21 UTC (permalink / raw)
  To: DRI Development
  Cc: Eric Anholt, Daniel Vetter, Intel Graphics Development, Daniel Vetter

It's right above the drm_dev_put().

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

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..87b9b32c90a8 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 = drm_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

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* [PATCH 37/52] drm/rcar-du: Drop explicit drm_mode_config_cleanup call
  2020-02-19 10:20 ` [Intel-gfx] " Daniel Vetter
  (?)
@ 2020-02-19 10:21   ` Daniel Vetter
  -1 siblings, 0 replies; 310+ messages in thread
From: Daniel Vetter @ 2020-02-19 10:21 UTC (permalink / raw)
  To: DRI Development
  Cc: Intel Graphics Development, Daniel Vetter, Daniel Vetter,
	Laurent Pinchart, Kieran Bingham, linux-renesas-soc

It's right above the drm_dev_put().

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

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..dcdc1580b511 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 = drm_mode_config_init(dev);
+	if (ret)
+		return ret;
 
 	dev->mode_config.min_width = 0;
 	dev->mode_config.min_height = 0;
-- 
2.24.1


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

* [PATCH 37/52] drm/rcar-du: Drop explicit drm_mode_config_cleanup call
@ 2020-02-19 10:21   ` Daniel Vetter
  0 siblings, 0 replies; 310+ messages in thread
From: Daniel Vetter @ 2020-02-19 10:21 UTC (permalink / raw)
  To: DRI Development
  Cc: Daniel Vetter, Intel Graphics Development, linux-renesas-soc,
	Kieran Bingham, Laurent Pinchart, Daniel Vetter

It's right above the drm_dev_put().

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

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..dcdc1580b511 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 = drm_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] 310+ messages in thread

* [Intel-gfx] [PATCH 37/52] drm/rcar-du: Drop explicit drm_mode_config_cleanup call
@ 2020-02-19 10:21   ` Daniel Vetter
  0 siblings, 0 replies; 310+ messages in thread
From: Daniel Vetter @ 2020-02-19 10:21 UTC (permalink / raw)
  To: DRI Development
  Cc: Daniel Vetter, Intel Graphics Development, linux-renesas-soc,
	Kieran Bingham, Laurent Pinchart, Daniel Vetter

It's right above the drm_dev_put().

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

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..dcdc1580b511 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 = drm_mode_config_init(dev);
+	if (ret)
+		return ret;
 
 	dev->mode_config.min_width = 0;
 	dev->mode_config.min_height = 0;
-- 
2.24.1

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* [PATCH 38/52] drm/rockchip: Drop explicit drm_mode_config_cleanup call
  2020-02-19 10:20 ` [Intel-gfx] " Daniel Vetter
  (?)
  (?)
@ 2020-02-19 10:21     ` Daniel Vetter
  -1 siblings, 0 replies; 310+ messages in thread
From: Daniel Vetter @ 2020-02-19 10:21 UTC (permalink / raw)
  To: DRI Development
  Cc: Heiko Stübner, Daniel Vetter, Intel Graphics Development,
	Sandy Huang, linux-rockchip-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	Daniel Vetter, linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r

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

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

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 | 10 +++-------
 1 file changed, 3 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_drv.c b/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
index 20ecb1508a22..d0eba21eebc9 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
@@ -135,7 +135,9 @@ static int rockchip_drm_bind(struct device *dev)
 	if (ret)
 		goto err_free;
 
-	drm_mode_config_init(drm_dev);
+	ret = drm_mode_config_init(drm_dev);
+	if (ret)
+		goto err_free;
 
 	rockchip_drm_mode_config_init(drm_dev);
 
@@ -174,11 +176,8 @@ static int rockchip_drm_bind(struct device *dev)
 err_unbind_all:
 	component_unbind_all(dev, drm_dev);
 err_mode_config_cleanup:
-	drm_mode_config_cleanup(drm_dev);
 	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


_______________________________________________
Linux-rockchip mailing list
Linux-rockchip@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-rockchip

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

* [PATCH 38/52] drm/rockchip: Drop explicit drm_mode_config_cleanup call
@ 2020-02-19 10:21     ` Daniel Vetter
  0 siblings, 0 replies; 310+ messages in thread
From: Daniel Vetter @ 2020-02-19 10:21 UTC (permalink / raw)
  To: DRI Development
  Cc: Heiko Stübner, Daniel Vetter, Intel Graphics Development,
	Sandy Huang, linux-rockchip, Daniel Vetter, linux-arm-kernel

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

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

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 | 10 +++-------
 1 file changed, 3 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_drv.c b/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
index 20ecb1508a22..d0eba21eebc9 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
@@ -135,7 +135,9 @@ static int rockchip_drm_bind(struct device *dev)
 	if (ret)
 		goto err_free;
 
-	drm_mode_config_init(drm_dev);
+	ret = drm_mode_config_init(drm_dev);
+	if (ret)
+		goto err_free;
 
 	rockchip_drm_mode_config_init(drm_dev);
 
@@ -174,11 +176,8 @@ static int rockchip_drm_bind(struct device *dev)
 err_unbind_all:
 	component_unbind_all(dev, drm_dev);
 err_mode_config_cleanup:
-	drm_mode_config_cleanup(drm_dev);
 	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


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* [PATCH 38/52] drm/rockchip: Drop explicit drm_mode_config_cleanup call
@ 2020-02-19 10:21     ` Daniel Vetter
  0 siblings, 0 replies; 310+ messages in thread
From: Daniel Vetter @ 2020-02-19 10:21 UTC (permalink / raw)
  To: DRI Development
  Cc: Daniel Vetter, Intel Graphics Development, Sandy Huang,
	linux-rockchip, Daniel Vetter, linux-arm-kernel

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

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

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 | 10 +++-------
 1 file changed, 3 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_drv.c b/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
index 20ecb1508a22..d0eba21eebc9 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
@@ -135,7 +135,9 @@ static int rockchip_drm_bind(struct device *dev)
 	if (ret)
 		goto err_free;
 
-	drm_mode_config_init(drm_dev);
+	ret = drm_mode_config_init(drm_dev);
+	if (ret)
+		goto err_free;
 
 	rockchip_drm_mode_config_init(drm_dev);
 
@@ -174,11 +176,8 @@ static int rockchip_drm_bind(struct device *dev)
 err_unbind_all:
 	component_unbind_all(dev, drm_dev);
 err_mode_config_cleanup:
-	drm_mode_config_cleanup(drm_dev);
 	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] 310+ messages in thread

* [Intel-gfx] [PATCH 38/52] drm/rockchip: Drop explicit drm_mode_config_cleanup call
@ 2020-02-19 10:21     ` Daniel Vetter
  0 siblings, 0 replies; 310+ messages in thread
From: Daniel Vetter @ 2020-02-19 10:21 UTC (permalink / raw)
  To: DRI Development
  Cc: Heiko Stübner, Daniel Vetter, Intel Graphics Development,
	Sandy Huang, linux-rockchip, Daniel Vetter, linux-arm-kernel

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

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

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 | 10 +++-------
 1 file changed, 3 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_drv.c b/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
index 20ecb1508a22..d0eba21eebc9 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
@@ -135,7 +135,9 @@ static int rockchip_drm_bind(struct device *dev)
 	if (ret)
 		goto err_free;
 
-	drm_mode_config_init(drm_dev);
+	ret = drm_mode_config_init(drm_dev);
+	if (ret)
+		goto err_free;
 
 	rockchip_drm_mode_config_init(drm_dev);
 
@@ -174,11 +176,8 @@ static int rockchip_drm_bind(struct device *dev)
 err_unbind_all:
 	component_unbind_all(dev, drm_dev);
 err_mode_config_cleanup:
-	drm_mode_config_cleanup(drm_dev);
 	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

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* [PATCH 39/52] drm/stm: Drop explicit drm_mode_config_cleanup call
  2020-02-19 10:20 ` [Intel-gfx] " Daniel Vetter
  (?)
@ 2020-02-19 10:21   ` Daniel Vetter
  -1 siblings, 0 replies; 310+ messages in thread
From: Daniel Vetter @ 2020-02-19 10:21 UTC (permalink / raw)
  To: DRI Development
  Cc: Maxime Coquelin, Daniel Vetter, Intel Graphics Development,
	Philippe Cornu, Yannick Fertre, Benjamin Gaignard, Daniel Vetter,
	Vincent Abriou, linux-stm32, linux-arm-kernel, Alexandre Torgue

It's right above the drm_dev_put().

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

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..5b374531dd8c 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 = drm_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


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* [PATCH 39/52] drm/stm: Drop explicit drm_mode_config_cleanup call
@ 2020-02-19 10:21   ` Daniel Vetter
  0 siblings, 0 replies; 310+ messages in thread
From: Daniel Vetter @ 2020-02-19 10:21 UTC (permalink / raw)
  To: DRI Development
  Cc: Maxime Coquelin, Daniel Vetter, Intel Graphics Development,
	Philippe Cornu, Yannick Fertre, Daniel Vetter, Vincent Abriou,
	linux-stm32, linux-arm-kernel, Alexandre Torgue

It's right above the drm_dev_put().

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

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..5b374531dd8c 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 = drm_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] 310+ messages in thread

* [Intel-gfx] [PATCH 39/52] drm/stm: Drop explicit drm_mode_config_cleanup call
@ 2020-02-19 10:21   ` Daniel Vetter
  0 siblings, 0 replies; 310+ messages in thread
From: Daniel Vetter @ 2020-02-19 10:21 UTC (permalink / raw)
  To: DRI Development
  Cc: Maxime Coquelin, Daniel Vetter, Intel Graphics Development,
	Philippe Cornu, Yannick Fertre, Benjamin Gaignard, Daniel Vetter,
	Vincent Abriou, linux-stm32, linux-arm-kernel, Alexandre Torgue

It's right above the drm_dev_put().

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

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..5b374531dd8c 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 = drm_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

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* [PATCH 40/52] drm/shmob: Drop explicit drm_mode_config_cleanup call
  2020-02-19 10:20 ` [Intel-gfx] " Daniel Vetter
  (?)
@ 2020-02-19 10:21   ` Daniel Vetter
  -1 siblings, 0 replies; 310+ messages in thread
From: Daniel Vetter @ 2020-02-19 10:21 UTC (permalink / raw)
  To: DRI Development
  Cc: Intel Graphics Development, Daniel Vetter, Daniel Vetter,
	Laurent Pinchart, Kieran Bingham, linux-renesas-soc

It's right above the drm_dev_put().

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

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..e6e34bb75ba0 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 = drm_mode_config_init(sdev->ddev);
+	if (ret)
+		return ret;
 
 	shmob_drm_crtc_create(sdev);
 	shmob_drm_encoder_create(sdev);
-- 
2.24.1


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

* [PATCH 40/52] drm/shmob: Drop explicit drm_mode_config_cleanup call
@ 2020-02-19 10:21   ` Daniel Vetter
  0 siblings, 0 replies; 310+ messages in thread
From: Daniel Vetter @ 2020-02-19 10:21 UTC (permalink / raw)
  To: DRI Development
  Cc: Daniel Vetter, Intel Graphics Development, linux-renesas-soc,
	Kieran Bingham, Laurent Pinchart, Daniel Vetter

It's right above the drm_dev_put().

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

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..e6e34bb75ba0 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 = drm_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] 310+ messages in thread

* [Intel-gfx] [PATCH 40/52] drm/shmob: Drop explicit drm_mode_config_cleanup call
@ 2020-02-19 10:21   ` Daniel Vetter
  0 siblings, 0 replies; 310+ messages in thread
From: Daniel Vetter @ 2020-02-19 10:21 UTC (permalink / raw)
  To: DRI Development
  Cc: Daniel Vetter, Intel Graphics Development, linux-renesas-soc,
	Kieran Bingham, Laurent Pinchart, Daniel Vetter

It's right above the drm_dev_put().

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

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..e6e34bb75ba0 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 = drm_mode_config_init(sdev->ddev);
+	if (ret)
+		return ret;
 
 	shmob_drm_crtc_create(sdev);
 	shmob_drm_encoder_create(sdev);
-- 
2.24.1

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* [PATCH 41/52] drm/mtk: Drop explicit drm_mode_config_cleanup call
  2020-02-19 10:20 ` [Intel-gfx] " Daniel Vetter
@ 2020-02-19 10:21   ` Daniel Vetter
  -1 siblings, 0 replies; 310+ messages in thread
From: Daniel Vetter @ 2020-02-19 10:21 UTC (permalink / raw)
  To: DRI Development; +Cc: Daniel Vetter, Intel Graphics Development, Daniel Vetter

It's right above the drm_dev_put().

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

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..947b2cbe2836 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 = drm_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] 310+ messages in thread

* [Intel-gfx] [PATCH 41/52] drm/mtk: Drop explicit drm_mode_config_cleanup call
@ 2020-02-19 10:21   ` Daniel Vetter
  0 siblings, 0 replies; 310+ messages in thread
From: Daniel Vetter @ 2020-02-19 10:21 UTC (permalink / raw)
  To: DRI Development; +Cc: Daniel Vetter, Intel Graphics Development, Daniel Vetter

It's right above the drm_dev_put().

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

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..947b2cbe2836 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 = drm_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

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* [PATCH 42/52] drm/tidss: Drop explicit drm_mode_config_cleanup call
  2020-02-19 10:20 ` [Intel-gfx] " Daniel Vetter
@ 2020-02-19 10:21   ` Daniel Vetter
  -1 siblings, 0 replies; 310+ messages in thread
From: Daniel Vetter @ 2020-02-19 10:21 UTC (permalink / raw)
  To: DRI Development
  Cc: Daniel Vetter, Intel Graphics Development, Tomi Valkeinen,
	Jyri Sarha, Daniel Vetter

It's right above the drm_dev_put().

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.

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 5311e0f1c551..87e07e0e4eae 100644
--- a/drivers/gpu/drm/tidss/tidss_kms.c
+++ b/drivers/gpu/drm/tidss/tidss_kms.c
@@ -208,7 +208,9 @@ int tidss_modeset_init(struct tidss_device *tidss)
 
 	dev_dbg(tidss->dev, "%s\n", __func__);
 
-	drm_mode_config_init(ddev);
+	ret = drm_mode_config_init(ddev);
+	if (ret)
+		return ret;
 
 	ddev->mode_config.min_width = 8;
 	ddev->mode_config.min_height = 8;
@@ -220,11 +222,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)
@@ -235,15 +237,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] 310+ messages in thread

* [Intel-gfx] [PATCH 42/52] drm/tidss: Drop explicit drm_mode_config_cleanup call
@ 2020-02-19 10:21   ` Daniel Vetter
  0 siblings, 0 replies; 310+ messages in thread
From: Daniel Vetter @ 2020-02-19 10:21 UTC (permalink / raw)
  To: DRI Development
  Cc: Daniel Vetter, Intel Graphics Development, Tomi Valkeinen,
	Jyri Sarha, Daniel Vetter

It's right above the drm_dev_put().

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.

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 5311e0f1c551..87e07e0e4eae 100644
--- a/drivers/gpu/drm/tidss/tidss_kms.c
+++ b/drivers/gpu/drm/tidss/tidss_kms.c
@@ -208,7 +208,9 @@ int tidss_modeset_init(struct tidss_device *tidss)
 
 	dev_dbg(tidss->dev, "%s\n", __func__);
 
-	drm_mode_config_init(ddev);
+	ret = drm_mode_config_init(ddev);
+	if (ret)
+		return ret;
 
 	ddev->mode_config.min_width = 8;
 	ddev->mode_config.min_height = 8;
@@ -220,11 +222,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)
@@ -235,15 +237,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

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* [PATCH 43/52] drm/gm12u320: More drmm_
  2020-02-19 10:20 ` [Intel-gfx] " Daniel Vetter
@ 2020-02-19 10:21   ` Daniel Vetter
  -1 siblings, 0 replies; 310+ messages in thread
From: Daniel Vetter @ 2020-02-19 10:21 UTC (permalink / raw)
  To: DRI Development
  Cc: Daniel Vetter, Intel Graphics Development, Hans de Goede, Daniel Vetter

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.

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..5bd26fc6fafa 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 = drm_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] 310+ messages in thread

* [Intel-gfx] [PATCH 43/52] drm/gm12u320: More drmm_
@ 2020-02-19 10:21   ` Daniel Vetter
  0 siblings, 0 replies; 310+ messages in thread
From: Daniel Vetter @ 2020-02-19 10:21 UTC (permalink / raw)
  To: DRI Development
  Cc: Daniel Vetter, Intel Graphics Development, Noralf Trønnes,
	Daniel Vetter

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.

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..5bd26fc6fafa 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 = drm_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

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* [PATCH 44/52] drm/gm12u320: Use devm_drm_dev_init
  2020-02-19 10:20 ` [Intel-gfx] " Daniel Vetter
@ 2020-02-19 10:21   ` Daniel Vetter
  -1 siblings, 0 replies; 310+ messages in thread
From: Daniel Vetter @ 2020-02-19 10:21 UTC (permalink / raw)
  To: DRI Development
  Cc: Daniel Vetter, Intel Graphics Development, Hans de Goede, Daniel Vetter

Only drops the drm_dev_put, but hey a few lines!

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 5bd26fc6fafa..65dfb87ccb13 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 = drm_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] 310+ messages in thread

* [Intel-gfx] [PATCH 44/52] drm/gm12u320: Use devm_drm_dev_init
@ 2020-02-19 10:21   ` Daniel Vetter
  0 siblings, 0 replies; 310+ messages in thread
From: Daniel Vetter @ 2020-02-19 10:21 UTC (permalink / raw)
  To: DRI Development
  Cc: Daniel Vetter, Intel Graphics Development, Noralf Trønnes,
	Daniel Vetter

Only drops the drm_dev_put, but hey a few lines!

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 5bd26fc6fafa..65dfb87ccb13 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 = drm_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

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* [PATCH 45/52] drm/gm12u320: Use helpers for shutdown/suspend/resume
  2020-02-19 10:20 ` [Intel-gfx] " Daniel Vetter
@ 2020-02-19 10:21   ` Daniel Vetter
  -1 siblings, 0 replies; 310+ messages in thread
From: Daniel Vetter @ 2020-02-19 10:21 UTC (permalink / raw)
  To: DRI Development
  Cc: Daniel Vetter, Intel Graphics Development, Hans de Goede, Daniel Vetter

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.

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 65dfb87ccb13..c22b2ee470eb 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] 310+ messages in thread

* [Intel-gfx] [PATCH 45/52] drm/gm12u320: Use helpers for shutdown/suspend/resume
@ 2020-02-19 10:21   ` Daniel Vetter
  0 siblings, 0 replies; 310+ messages in thread
From: Daniel Vetter @ 2020-02-19 10:21 UTC (permalink / raw)
  To: DRI Development
  Cc: Daniel Vetter, Intel Graphics Development, Noralf Trønnes,
	Daniel Vetter

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.

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 65dfb87ccb13..c22b2ee470eb 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

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* [PATCH 46/52] drm/gm12u320: Simplify upload work
  2020-02-19 10:20 ` [Intel-gfx] " Daniel Vetter
@ 2020-02-19 10:21   ` Daniel Vetter
  -1 siblings, 0 replies; 310+ messages in thread
From: Daniel Vetter @ 2020-02-19 10:21 UTC (permalink / raw)
  To: DRI Development
  Cc: Daniel Vetter, Intel Graphics Development, Hans de Goede, Daniel Vetter

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!

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 | 170 +++++++++++++-------------------
 1 file changed, 67 insertions(+), 103 deletions(-)

diff --git a/drivers/gpu/drm/tiny/gm12u320.c b/drivers/gpu/drm/tiny/gm12u320.c
index c22b2ee470eb..46f5cea335a7 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,76 @@ 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.
+	 */
+	schedule_delayed_work(&gm12u320->fb_update.work, IDLE_TIMEOUT);
+
 	return;
 err:
 	/* Do not log errors caused by module unload or device unplug */
@@ -446,36 +431,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);
+		schedule_delayed_work(&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 +556,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 +595,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 +606,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 +635,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] 310+ messages in thread

* [Intel-gfx] [PATCH 46/52] drm/gm12u320: Simplify upload work
@ 2020-02-19 10:21   ` Daniel Vetter
  0 siblings, 0 replies; 310+ messages in thread
From: Daniel Vetter @ 2020-02-19 10:21 UTC (permalink / raw)
  To: DRI Development
  Cc: Daniel Vetter, Intel Graphics Development, Noralf Trønnes,
	Daniel Vetter

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!

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 | 170 +++++++++++++-------------------
 1 file changed, 67 insertions(+), 103 deletions(-)

diff --git a/drivers/gpu/drm/tiny/gm12u320.c b/drivers/gpu/drm/tiny/gm12u320.c
index c22b2ee470eb..46f5cea335a7 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,76 @@ 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.
+	 */
+	schedule_delayed_work(&gm12u320->fb_update.work, IDLE_TIMEOUT);
+
 	return;
 err:
 	/* Do not log errors caused by module unload or device unplug */
@@ -446,36 +431,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);
+		schedule_delayed_work(&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 +556,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 +595,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 +606,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 +635,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

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* [PATCH 47/52] drm/repaper: Drop explicit drm_mode_config_cleanup call
  2020-02-19 10:20 ` [Intel-gfx] " Daniel Vetter
@ 2020-02-19 10:21   ` Daniel Vetter
  -1 siblings, 0 replies; 310+ messages in thread
From: Daniel Vetter @ 2020-02-19 10:21 UTC (permalink / raw)
  To: DRI Development; +Cc: Daniel Vetter, Intel Graphics Development, Daniel Vetter

Allows us to drop the drm_driver.release callback.

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

diff --git a/drivers/gpu/drm/tiny/repaper.c b/drivers/gpu/drm/tiny/repaper.c
index 4741ff670ec9..2f70fb1be200 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",
-- 
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] 310+ messages in thread

* [Intel-gfx] [PATCH 47/52] drm/repaper: Drop explicit drm_mode_config_cleanup call
@ 2020-02-19 10:21   ` Daniel Vetter
  0 siblings, 0 replies; 310+ messages in thread
From: Daniel Vetter @ 2020-02-19 10:21 UTC (permalink / raw)
  To: DRI Development
  Cc: Daniel Vetter, Intel Graphics Development, Noralf Trønnes,
	Daniel Vetter

Allows us to drop the drm_driver.release callback.

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

diff --git a/drivers/gpu/drm/tiny/repaper.c b/drivers/gpu/drm/tiny/repaper.c
index 4741ff670ec9..2f70fb1be200 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",
-- 
2.24.1

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* [PATCH 48/52] drm/mipi-dbi: Move drm_mode_config_init into mipi library
  2020-02-19 10:20 ` [Intel-gfx] " Daniel Vetter
@ 2020-02-19 10:21   ` Daniel Vetter
  -1 siblings, 0 replies; 310+ messages in thread
From: Daniel Vetter @ 2020-02-19 10:21 UTC (permalink / raw)
  To: DRI Development; +Cc: Daniel Vetter, Intel Graphics Development, Daniel Vetter

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.

Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
---
 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] 310+ messages in thread

* [Intel-gfx] [PATCH 48/52] drm/mipi-dbi: Move drm_mode_config_init into mipi library
@ 2020-02-19 10:21   ` Daniel Vetter
  0 siblings, 0 replies; 310+ messages in thread
From: Daniel Vetter @ 2020-02-19 10:21 UTC (permalink / raw)
  To: DRI Development; +Cc: Daniel Vetter, Intel Graphics Development, Daniel Vetter

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.

Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
---
 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

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* [PATCH 49/52] drm/mipi-dbi: Drop explicit drm_mode_config_cleanup call
  2020-02-19 10:20 ` [Intel-gfx] " Daniel Vetter
@ 2020-02-19 10:21   ` Daniel Vetter
  -1 siblings, 0 replies; 310+ messages in thread
From: Daniel Vetter @ 2020-02-19 10:21 UTC (permalink / raw)
  To: DRI Development
  Cc: David Airlie, Daniel Vetter, Intel Graphics Development,
	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.

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  | 16 ----------------
 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, 24 deletions(-)

diff --git a/drivers/gpu/drm/drm_mipi_dbi.c b/drivers/gpu/drm/drm_mipi_dbi.c
index 9de1586659be..c0060a1c569f 100644
--- a/drivers/gpu/drm/drm_mipi_dbi.c
+++ b/drivers/gpu/drm/drm_mipi_dbi.c
@@ -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] 310+ messages in thread

* [Intel-gfx] [PATCH 49/52] drm/mipi-dbi: Drop explicit drm_mode_config_cleanup call
@ 2020-02-19 10:21   ` Daniel Vetter
  0 siblings, 0 replies; 310+ messages in thread
From: Daniel Vetter @ 2020-02-19 10:21 UTC (permalink / raw)
  To: DRI Development
  Cc: David Airlie, Daniel Vetter, Intel Graphics Development,
	Maxime Ripard, Eric Anholt, Noralf Trønnes,
	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.

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  | 16 ----------------
 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, 24 deletions(-)

diff --git a/drivers/gpu/drm/drm_mipi_dbi.c b/drivers/gpu/drm/drm_mipi_dbi.c
index 9de1586659be..c0060a1c569f 100644
--- a/drivers/gpu/drm/drm_mipi_dbi.c
+++ b/drivers/gpu/drm/drm_mipi_dbi.c
@@ -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

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* [PATCH 50/52] drm/udl: Drop explicit drm_mode_config_cleanup call
  2020-02-19 10:20 ` [Intel-gfx] " Daniel Vetter
@ 2020-02-19 10:21   ` Daniel Vetter
  -1 siblings, 0 replies; 310+ messages in thread
From: Daniel Vetter @ 2020-02-19 10:21 UTC (permalink / raw)
  To: DRI Development
  Cc: Sam Ravnborg, Daniel Vetter, Intel Graphics Development,
	Emil Velikov, Gerd Hoffmann, Thomas Zimmermann, Daniel Vetter,
	Dave Airlie, Thomas Gleixner, Sean Paul

It's right above the drm_dev_put().

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

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..cad0c87f8de6 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 = drm_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] 310+ messages in thread

* [Intel-gfx] [PATCH 50/52] drm/udl: Drop explicit drm_mode_config_cleanup call
@ 2020-02-19 10:21   ` Daniel Vetter
  0 siblings, 0 replies; 310+ messages in thread
From: Daniel Vetter @ 2020-02-19 10:21 UTC (permalink / raw)
  To: DRI Development
  Cc: Sam Ravnborg, Daniel Vetter, Intel Graphics Development,
	Noralf Trønnes, Gerd Hoffmann, Thomas Zimmermann,
	Daniel Vetter, Dave Airlie, Thomas Gleixner

It's right above the drm_dev_put().

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

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..cad0c87f8de6 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 = drm_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

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* [PATCH 51/52] drm/udl: drop drm_driver.release hook
  2020-02-19 10:20 ` [Intel-gfx] " Daniel Vetter
@ 2020-02-19 10:21   ` Daniel Vetter
  -1 siblings, 0 replies; 310+ messages in thread
From: Daniel Vetter @ 2020-02-19 10:21 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] 310+ messages in thread

* [Intel-gfx] [PATCH 51/52] drm/udl: drop drm_driver.release hook
@ 2020-02-19 10:21   ` Daniel Vetter
  0 siblings, 0 replies; 310+ messages in thread
From: Daniel Vetter @ 2020-02-19 10:21 UTC (permalink / raw)
  To: DRI Development
  Cc: Sam Ravnborg, Daniel Vetter, Intel Graphics Development,
	Noralf Trønnes, Gerd Hoffmann, Thomas Zimmermann,
	Daniel Vetter, Alex Deucher, Dave Airlie, Thomas Gleixner

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

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* [PATCH 52/52] drm: Add docs for managed resources
  2020-02-19 10:20 ` [Intel-gfx] " Daniel Vetter
@ 2020-02-19 10:21   ` Daniel Vetter
  -1 siblings, 0 replies; 310+ messages in thread
From: Daniel Vetter @ 2020-02-19 10:21 UTC (permalink / raw)
  To: DRI Development; +Cc: Daniel Vetter, Intel Graphics Development, Daniel Vetter

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).

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       | 63 ++++++++++++++++++++++++++++-
 include/drm/drm_drv.h               |  4 ++
 include/drm/drm_managed.h           | 47 +++++++++++++++++++++
 5 files changed, 134 insertions(+), 4 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 428c569aaaf1..b1827ba53924 100644
--- a/drivers/gpu/drm/drm_drv.c
+++ b/drivers/gpu/drm/drm_drv.c
@@ -258,9 +258,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
  * ~~~~~~~~~~~~~~~~~~~~~~
@@ -604,6 +610,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.
  */
@@ -705,6 +714,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 fb44fe65c2cd..7fcbe90d3f46 100644
--- a/drivers/gpu/drm/drm_managed.c
+++ b/drivers/gpu/drm/drm_managed.c
@@ -17,10 +17,22 @@
 /**
  * DOC: managed resources
  *
- * Inspired by sturct &device managed resources, but tied to the lifetime of
+ * 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 at driver load
+ * time.
+ *
+ * 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 when they change
+ * rarely, if ever, during the lifetime of the &drm_device instance.
  */
+
 struct drmres_node {
 	struct list_head		entry;
 	drmres_release_t		release;
@@ -102,6 +114,18 @@ 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
+ * @data: 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);
@@ -132,6 +156,14 @@ int __drmm_add_action(struct drm_device *dev,
 }
 EXPORT_SYMBOL(__drmm_add_action);
 
+/**
+ * drmm_add_action - remave 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)
@@ -160,6 +192,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;
@@ -175,6 +217,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
+ * @size: 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;
@@ -191,6 +243,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 = NULL, *tmp;
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 573cadca4b3d..0e7616bd0858 100644
--- a/include/drm/drm_managed.h
+++ b/include/drm/drm_managed.h
@@ -8,6 +8,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 wwith 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)
 
@@ -22,12 +35,45 @@ 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
+ * @size: 0 terminated string to be duplicated
+ * @gfp: 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)
+
+/**
+ * drmm_kcalloc - &drm_device managed kcalloc()
+ * @dev: DRM device
+ * @size: 0 terminated string to be duplicated
+ * @gfp: 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().
+ */
 {
 	size_t bytes;
 
@@ -41,6 +87,7 @@ static inline void *drmm_kcalloc(struct drm_device *dev,
 {
 	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] 310+ messages in thread

* [Intel-gfx] [PATCH 52/52] drm: Add docs for managed resources
@ 2020-02-19 10:21   ` Daniel Vetter
  0 siblings, 0 replies; 310+ messages in thread
From: Daniel Vetter @ 2020-02-19 10:21 UTC (permalink / raw)
  To: DRI Development; +Cc: Daniel Vetter, Intel Graphics Development, Daniel Vetter

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).

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       | 63 ++++++++++++++++++++++++++++-
 include/drm/drm_drv.h               |  4 ++
 include/drm/drm_managed.h           | 47 +++++++++++++++++++++
 5 files changed, 134 insertions(+), 4 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 428c569aaaf1..b1827ba53924 100644
--- a/drivers/gpu/drm/drm_drv.c
+++ b/drivers/gpu/drm/drm_drv.c
@@ -258,9 +258,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
  * ~~~~~~~~~~~~~~~~~~~~~~
@@ -604,6 +610,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.
  */
@@ -705,6 +714,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 fb44fe65c2cd..7fcbe90d3f46 100644
--- a/drivers/gpu/drm/drm_managed.c
+++ b/drivers/gpu/drm/drm_managed.c
@@ -17,10 +17,22 @@
 /**
  * DOC: managed resources
  *
- * Inspired by sturct &device managed resources, but tied to the lifetime of
+ * 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 at driver load
+ * time.
+ *
+ * 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 when they change
+ * rarely, if ever, during the lifetime of the &drm_device instance.
  */
+
 struct drmres_node {
 	struct list_head		entry;
 	drmres_release_t		release;
@@ -102,6 +114,18 @@ 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
+ * @data: 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);
@@ -132,6 +156,14 @@ int __drmm_add_action(struct drm_device *dev,
 }
 EXPORT_SYMBOL(__drmm_add_action);
 
+/**
+ * drmm_add_action - remave 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)
@@ -160,6 +192,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;
@@ -175,6 +217,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
+ * @size: 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;
@@ -191,6 +243,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 = NULL, *tmp;
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 573cadca4b3d..0e7616bd0858 100644
--- a/include/drm/drm_managed.h
+++ b/include/drm/drm_managed.h
@@ -8,6 +8,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 wwith 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)
 
@@ -22,12 +35,45 @@ 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
+ * @size: 0 terminated string to be duplicated
+ * @gfp: 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)
+
+/**
+ * drmm_kcalloc - &drm_device managed kcalloc()
+ * @dev: DRM device
+ * @size: 0 terminated string to be duplicated
+ * @gfp: 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().
+ */
 {
 	size_t bytes;
 
@@ -41,6 +87,7 @@ static inline void *drmm_kcalloc(struct drm_device *dev,
 {
 	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

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH 37/52] drm/rcar-du: Drop explicit drm_mode_config_cleanup call
  2020-02-19 10:21   ` Daniel Vetter
  (?)
@ 2020-02-19 10:30     ` Geert Uytterhoeven
  -1 siblings, 0 replies; 310+ messages in thread
From: Geert Uytterhoeven @ 2020-02-19 10:30 UTC (permalink / raw)
  To: Daniel Vetter
  Cc: DRI Development, Intel Graphics Development, Daniel Vetter,
	Laurent Pinchart, Kieran Bingham, Linux-Renesas

Hi Daniel,

On Wed, Feb 19, 2020 at 11:22 AM Daniel Vetter <daniel.vetter@ffwll.ch> wrote:
> It's right above the drm_dev_put().
>
> Aside: Another driver with a bit much devm_kzalloc, which should
> probably use drmm_kzalloc instead ...

What's drmm_kzalloc()?
The only references I can find are in this patch series.

Gr{oetje,eeting}s,

                        Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds

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

* Re: [PATCH 37/52] drm/rcar-du: Drop explicit drm_mode_config_cleanup call
@ 2020-02-19 10:30     ` Geert Uytterhoeven
  0 siblings, 0 replies; 310+ messages in thread
From: Geert Uytterhoeven @ 2020-02-19 10:30 UTC (permalink / raw)
  To: Daniel Vetter
  Cc: Intel Graphics Development, DRI Development, Linux-Renesas,
	Kieran Bingham, Laurent Pinchart, Daniel Vetter

Hi Daniel,

On Wed, Feb 19, 2020 at 11:22 AM Daniel Vetter <daniel.vetter@ffwll.ch> wrote:
> It's right above the drm_dev_put().
>
> Aside: Another driver with a bit much devm_kzalloc, which should
> probably use drmm_kzalloc instead ...

What's drmm_kzalloc()?
The only references I can find are in this patch series.

Gr{oetje,eeting}s,

                        Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

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

* Re: [Intel-gfx] [PATCH 37/52] drm/rcar-du: Drop explicit drm_mode_config_cleanup call
@ 2020-02-19 10:30     ` Geert Uytterhoeven
  0 siblings, 0 replies; 310+ messages in thread
From: Geert Uytterhoeven @ 2020-02-19 10:30 UTC (permalink / raw)
  To: Daniel Vetter
  Cc: Intel Graphics Development, DRI Development, Linux-Renesas,
	Kieran Bingham, Laurent Pinchart, Daniel Vetter

Hi Daniel,

On Wed, Feb 19, 2020 at 11:22 AM Daniel Vetter <daniel.vetter@ffwll.ch> wrote:
> It's right above the drm_dev_put().
>
> Aside: Another driver with a bit much devm_kzalloc, which should
> probably use drmm_kzalloc instead ...

What's drmm_kzalloc()?
The only references I can find are in this patch series.

Gr{oetje,eeting}s,

                        Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH 35/52] drm/meson: Drop explicit drm_mode_config_cleanup call
  2020-02-19 10:21   ` Daniel Vetter
  (?)
  (?)
@ 2020-02-19 10:39     ` Neil Armstrong
  -1 siblings, 0 replies; 310+ messages in thread
From: Neil Armstrong @ 2020-02-19 10:39 UTC (permalink / raw)
  To: Daniel Vetter, DRI Development
  Cc: Daniel Vetter, Intel Graphics Development, linux-amlogic,
	linux-arm-kernel, Kevin Hilman

On 19/02/2020 11:21, Daniel Vetter wrote:
> It's right above the drm_dev_put().
> 
> Aside: This driver gets its devm_ stuff all wrong wrt drm_device and
> anything hanging off that. Not the only one unfortunately.
> 
> 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..ae94d14ab7bc 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 = drm_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);
>  }
>  
> 

Reviewed-by: Neil Armstrong <narmstrong@baylibre.com>

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [PATCH 35/52] drm/meson: Drop explicit drm_mode_config_cleanup call
@ 2020-02-19 10:39     ` Neil Armstrong
  0 siblings, 0 replies; 310+ messages in thread
From: Neil Armstrong @ 2020-02-19 10:39 UTC (permalink / raw)
  To: Daniel Vetter, DRI Development
  Cc: Daniel Vetter, Intel Graphics Development, linux-amlogic,
	linux-arm-kernel, Kevin Hilman

On 19/02/2020 11:21, Daniel Vetter wrote:
> It's right above the drm_dev_put().
> 
> Aside: This driver gets its devm_ stuff all wrong wrt drm_device and
> anything hanging off that. Not the only one unfortunately.
> 
> 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..ae94d14ab7bc 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 = drm_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);
>  }
>  
> 

Reviewed-by: Neil Armstrong <narmstrong@baylibre.com>
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

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

* Re: [Intel-gfx] [PATCH 35/52] drm/meson: Drop explicit drm_mode_config_cleanup call
@ 2020-02-19 10:39     ` Neil Armstrong
  0 siblings, 0 replies; 310+ messages in thread
From: Neil Armstrong @ 2020-02-19 10:39 UTC (permalink / raw)
  To: Daniel Vetter, DRI Development
  Cc: Daniel Vetter, Intel Graphics Development, linux-amlogic,
	linux-arm-kernel, Kevin Hilman

On 19/02/2020 11:21, Daniel Vetter wrote:
> It's right above the drm_dev_put().
> 
> Aside: This driver gets its devm_ stuff all wrong wrt drm_device and
> anything hanging off that. Not the only one unfortunately.
> 
> 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..ae94d14ab7bc 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 = drm_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);
>  }
>  
> 

Reviewed-by: Neil Armstrong <narmstrong@baylibre.com>
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH 35/52] drm/meson: Drop explicit drm_mode_config_cleanup call
@ 2020-02-19 10:39     ` Neil Armstrong
  0 siblings, 0 replies; 310+ messages in thread
From: Neil Armstrong @ 2020-02-19 10:39 UTC (permalink / raw)
  To: Daniel Vetter, DRI Development
  Cc: Daniel Vetter, Intel Graphics Development, linux-amlogic,
	linux-arm-kernel, Kevin Hilman

On 19/02/2020 11:21, Daniel Vetter wrote:
> It's right above the drm_dev_put().
> 
> Aside: This driver gets its devm_ stuff all wrong wrt drm_device and
> anything hanging off that. Not the only one unfortunately.
> 
> 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..ae94d14ab7bc 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 = drm_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);
>  }
>  
> 

Reviewed-by: Neil Armstrong <narmstrong@baylibre.com>

_______________________________________________
linux-amlogic mailing list
linux-amlogic@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-amlogic

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

* Re: [PATCH 37/52] drm/rcar-du: Drop explicit drm_mode_config_cleanup call
  2020-02-19 10:30     ` Geert Uytterhoeven
  (?)
@ 2020-02-19 10:56       ` Daniel Vetter
  -1 siblings, 0 replies; 310+ messages in thread
From: Daniel Vetter @ 2020-02-19 10:56 UTC (permalink / raw)
  To: Geert Uytterhoeven
  Cc: DRI Development, Intel Graphics Development, Daniel Vetter,
	Laurent Pinchart, Kieran Bingham, Linux-Renesas

On Wed, Feb 19, 2020 at 11:30 AM Geert Uytterhoeven
<geert@linux-m68k.org> wrote:
>
> Hi Daniel,
>
> On Wed, Feb 19, 2020 at 11:22 AM Daniel Vetter <daniel.vetter@ffwll.ch> wrote:
> > It's right above the drm_dev_put().
> >
> > Aside: Another driver with a bit much devm_kzalloc, which should
> > probably use drmm_kzalloc instead ...
>
> What's drmm_kzalloc()?
> The only references I can find are in this patch series.

Yup, it's all new. Read cover letter for reading instructions for the
entire patch series. I'm afraid the driver patches wont make much
sense without the context. None actually :-/
-Daniel

>
> Gr{oetje,eeting}s,
>
>                         Geert
>
> --
> Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org
>
> In personal conversations with technical people, I call myself a hacker. But
> when I'm talking to journalists I just say "programmer" or something like that.
>                                 -- Linus Torvalds



-- 
Daniel Vetter
Software Engineer, Intel Corporation
+41 (0) 79 365 57 48 - http://blog.ffwll.ch

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

* Re: [PATCH 37/52] drm/rcar-du: Drop explicit drm_mode_config_cleanup call
@ 2020-02-19 10:56       ` Daniel Vetter
  0 siblings, 0 replies; 310+ messages in thread
From: Daniel Vetter @ 2020-02-19 10:56 UTC (permalink / raw)
  To: Geert Uytterhoeven
  Cc: Intel Graphics Development, DRI Development, Linux-Renesas,
	Kieran Bingham, Laurent Pinchart, Daniel Vetter

On Wed, Feb 19, 2020 at 11:30 AM Geert Uytterhoeven
<geert@linux-m68k.org> wrote:
>
> Hi Daniel,
>
> On Wed, Feb 19, 2020 at 11:22 AM Daniel Vetter <daniel.vetter@ffwll.ch> wrote:
> > It's right above the drm_dev_put().
> >
> > Aside: Another driver with a bit much devm_kzalloc, which should
> > probably use drmm_kzalloc instead ...
>
> What's drmm_kzalloc()?
> The only references I can find are in this patch series.

Yup, it's all new. Read cover letter for reading instructions for the
entire patch series. I'm afraid the driver patches wont make much
sense without the context. None actually :-/
-Daniel

>
> Gr{oetje,eeting}s,
>
>                         Geert
>
> --
> Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org
>
> In personal conversations with technical people, I call myself a hacker. But
> when I'm talking to journalists I just say "programmer" or something like that.
>                                 -- Linus Torvalds



-- 
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] 310+ messages in thread

* Re: [Intel-gfx] [PATCH 37/52] drm/rcar-du: Drop explicit drm_mode_config_cleanup call
@ 2020-02-19 10:56       ` Daniel Vetter
  0 siblings, 0 replies; 310+ messages in thread
From: Daniel Vetter @ 2020-02-19 10:56 UTC (permalink / raw)
  To: Geert Uytterhoeven
  Cc: Intel Graphics Development, DRI Development, Linux-Renesas,
	Kieran Bingham, Laurent Pinchart, Daniel Vetter

On Wed, Feb 19, 2020 at 11:30 AM Geert Uytterhoeven
<geert@linux-m68k.org> wrote:
>
> Hi Daniel,
>
> On Wed, Feb 19, 2020 at 11:22 AM Daniel Vetter <daniel.vetter@ffwll.ch> wrote:
> > It's right above the drm_dev_put().
> >
> > Aside: Another driver with a bit much devm_kzalloc, which should
> > probably use drmm_kzalloc instead ...
>
> What's drmm_kzalloc()?
> The only references I can find are in this patch series.

Yup, it's all new. Read cover letter for reading instructions for the
entire patch series. I'm afraid the driver patches wont make much
sense without the context. None actually :-/
-Daniel

>
> Gr{oetje,eeting}s,
>
>                         Geert
>
> --
> Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org
>
> In personal conversations with technical people, I call myself a hacker. But
> when I'm talking to journalists I just say "programmer" or something like that.
>                                 -- Linus Torvalds



-- 
Daniel Vetter
Software Engineer, Intel Corporation
+41 (0) 79 365 57 48 - http://blog.ffwll.ch
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH 37/52] drm/rcar-du: Drop explicit drm_mode_config_cleanup call
  2020-02-19 10:56       ` Daniel Vetter
  (?)
@ 2020-02-19 11:10         ` Geert Uytterhoeven
  -1 siblings, 0 replies; 310+ messages in thread
From: Geert Uytterhoeven @ 2020-02-19 11:10 UTC (permalink / raw)
  To: Daniel Vetter
  Cc: DRI Development, Intel Graphics Development, Daniel Vetter,
	Laurent Pinchart, Kieran Bingham, Linux-Renesas

Hi Daniel,

On Wed, Feb 19, 2020 at 11:57 AM Daniel Vetter <daniel.vetter@ffwll.ch> wrote:
> On Wed, Feb 19, 2020 at 11:30 AM Geert Uytterhoeven
> <geert@linux-m68k.org> wrote:
> > On Wed, Feb 19, 2020 at 11:22 AM Daniel Vetter <daniel.vetter@ffwll.ch> wrote:
> > > It's right above the drm_dev_put().
> > >
> > > Aside: Another driver with a bit much devm_kzalloc, which should
> > > probably use drmm_kzalloc instead ...
> >
> > What's drmm_kzalloc()?
> > The only references I can find are in this patch series.
>
> Yup, it's all new. Read cover letter for reading instructions for the
> entire patch series. I'm afraid the driver patches wont make much
> sense without the context. None actually :-/

IC, as the cover letter was sent only to dri-devel and intel-gfx, many
recipients of the patches won't have received it...
https://lore.kernel.org/dri-devel/20200219102122.1607365-1-daniel.vetter@ffwll.ch/

Gr{oetje,eeting}s,

                        Geert

-- 
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds

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

* Re: [PATCH 37/52] drm/rcar-du: Drop explicit drm_mode_config_cleanup call
@ 2020-02-19 11:10         ` Geert Uytterhoeven
  0 siblings, 0 replies; 310+ messages in thread
From: Geert Uytterhoeven @ 2020-02-19 11:10 UTC (permalink / raw)
  To: Daniel Vetter
  Cc: Intel Graphics Development, DRI Development, Linux-Renesas,
	Kieran Bingham, Laurent Pinchart, Daniel Vetter

Hi Daniel,

On Wed, Feb 19, 2020 at 11:57 AM Daniel Vetter <daniel.vetter@ffwll.ch> wrote:
> On Wed, Feb 19, 2020 at 11:30 AM Geert Uytterhoeven
> <geert@linux-m68k.org> wrote:
> > On Wed, Feb 19, 2020 at 11:22 AM Daniel Vetter <daniel.vetter@ffwll.ch> wrote:
> > > It's right above the drm_dev_put().
> > >
> > > Aside: Another driver with a bit much devm_kzalloc, which should
> > > probably use drmm_kzalloc instead ...
> >
> > What's drmm_kzalloc()?
> > The only references I can find are in this patch series.
>
> Yup, it's all new. Read cover letter for reading instructions for the
> entire patch series. I'm afraid the driver patches wont make much
> sense without the context. None actually :-/

IC, as the cover letter was sent only to dri-devel and intel-gfx, many
recipients of the patches won't have received it...
https://lore.kernel.org/dri-devel/20200219102122.1607365-1-daniel.vetter@ffwll.ch/

Gr{oetje,eeting}s,

                        Geert

-- 
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

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

* Re: [Intel-gfx] [PATCH 37/52] drm/rcar-du: Drop explicit drm_mode_config_cleanup call
@ 2020-02-19 11:10         ` Geert Uytterhoeven
  0 siblings, 0 replies; 310+ messages in thread
From: Geert Uytterhoeven @ 2020-02-19 11:10 UTC (permalink / raw)
  To: Daniel Vetter
  Cc: Intel Graphics Development, DRI Development, Linux-Renesas,
	Kieran Bingham, Laurent Pinchart, Daniel Vetter

Hi Daniel,

On Wed, Feb 19, 2020 at 11:57 AM Daniel Vetter <daniel.vetter@ffwll.ch> wrote:
> On Wed, Feb 19, 2020 at 11:30 AM Geert Uytterhoeven
> <geert@linux-m68k.org> wrote:
> > On Wed, Feb 19, 2020 at 11:22 AM Daniel Vetter <daniel.vetter@ffwll.ch> wrote:
> > > It's right above the drm_dev_put().
> > >
> > > Aside: Another driver with a bit much devm_kzalloc, which should
> > > probably use drmm_kzalloc instead ...
> >
> > What's drmm_kzalloc()?
> > The only references I can find are in this patch series.
>
> Yup, it's all new. Read cover letter for reading instructions for the
> entire patch series. I'm afraid the driver patches wont make much
> sense without the context. None actually :-/

IC, as the cover letter was sent only to dri-devel and intel-gfx, many
recipients of the patches won't have received it...
https://lore.kernel.org/dri-devel/20200219102122.1607365-1-daniel.vetter@ffwll.ch/

Gr{oetje,eeting}s,

                        Geert

-- 
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* [Intel-gfx] ✗ Fi.CI.CHECKPATCH: warning for drm_device managed resources
  2020-02-19 10:20 ` [Intel-gfx] " Daniel Vetter
                   ` (52 preceding siblings ...)
  (?)
@ 2020-02-19 11:30 ` Patchwork
  -1 siblings, 0 replies; 310+ messages in thread
From: Patchwork @ 2020-02-19 11:30 UTC (permalink / raw)
  To: Daniel Vetter; +Cc: intel-gfx

== Series Details ==

Series: drm_device managed resources
URL   : https://patchwork.freedesktop.org/series/73633/
State : warning

== Summary ==

$ dim checkpatch origin/drm-tip
913ef020101d mm/sl[uo]b: export __kmalloc_track(_node)_caller
-:57: WARNING:NO_AUTHOR_SIGN_OFF: Missing Signed-off-by: line by nominal patch author 'Daniel Vetter <daniel.vetter@ffwll.ch>'

total: 0 errors, 1 warnings, 0 checks, 28 lines checked
5b8201a378ad drm/i915: Don't clear drvdata in ->release
-:35: WARNING:NO_AUTHOR_SIGN_OFF: Missing Signed-off-by: line by nominal patch author 'Daniel Vetter <daniel.vetter@ffwll.ch>'

total: 0 errors, 1 warnings, 0 checks, 9 lines checked
7ffeeed91dd5 drm: add managed resources tied to drm_device
-:104: WARNING:NEEDLESS_IF: kfree(NULL) is safe and this check is probably not required
#104: FILE: drivers/gpu/drm/drm_drv.c:843:
+	if (dev->managed.final_kfree)
+		kfree(dev->managed.final_kfree);

-:123: WARNING:FILE_PATH_CHANGES: added, moved or deleted file(s), does MAINTAINERS need updating?
#123: 
new file mode 100644

-:172: CHECK:BRACES: Blank lines aren't necessary after an open brace '{'
#172: FILE: drivers/gpu/drm/drm_managed.c:45:
+{
+

-:178: CHECK:SPACING: No space is necessary after a cast
#178: FILE: drivers/gpu/drm/drm_managed.c:51:
+			       dr, dr->node.name, (unsigned long) dr->node.size);

-:189: ERROR:POINTER_LOCATION: "foo * bar" should be "foo *bar"
#189: FILE: drivers/gpu/drm/drm_managed.c:62:
+static __always_inline struct drmres * alloc_dr(drmres_release_t release,

-:217: CHECK:SPACING: No space is necessary after a cast
#217: FILE: drivers/gpu/drm/drm_managed.c:90:
+		       dr, dr->node.name, (unsigned long) dr->node.size);

-:229: CHECK:SPACING: No space is necessary after a cast
#229: FILE: drivers/gpu/drm/drm_managed.c:102:
+		       dr, dr->node.name, (unsigned long) dr->node.size);

-:246: ERROR:POINTER_LOCATION: "(foo*)" should be "(foo *)"
#246: FILE: drivers/gpu/drm/drm_managed.c:119:
+	dr = alloc_dr(action, data ? sizeof(void*) : 0,

-:252: CHECK:SPACING: No space is necessary after a cast
#252: FILE: drivers/gpu/drm/drm_managed.c:125:
+	void_ptr = (void **) dr->data;

-:259: CHECK:BRACES: Blank lines aren't necessary before a close brace '}'
#259: FILE: drivers/gpu/drm/drm_managed.c:132:
+
+}

-:318: CHECK:UNCOMMENTED_DEFINITION: spinlock_t definition without comment
#318: FILE: include/drm/drm_device.h:79:
+		spinlock_t lock;

-:330: WARNING:SPDX_LICENSE_TAG: Improper SPDX comment style for 'include/drm/drm_managed.h', please use '/*' instead
#330: FILE: include/drm/drm_managed.h:1:
+// SPDX-License-Identifier: GPL-2.0

-:330: WARNING:SPDX_LICENSE_TAG: Missing or malformed SPDX-License-Identifier tag in line 1
#330: FILE: include/drm/drm_managed.h:1:
+// SPDX-License-Identifier: GPL-2.0

-:378: WARNING:NO_AUTHOR_SIGN_OFF: Missing Signed-off-by: line by nominal patch author 'Daniel Vetter <daniel.vetter@ffwll.ch>'

total: 2 errors, 5 warnings, 7 checks, 290 lines checked
06b9d9ecc4bb drm: Set final_kfree in drm_dev_alloc
-:15: ERROR:GIT_COMMIT_ID: Please use git commit description style 'commit <12+ chars of sha1> ("<title line>")' - ie: 'commit 0a6659bdc5e8 ("drm/bochs: new driver")'
#15: 
commit 0a6659bdc5e8221da99eebb176fd9591435e38de

-:25: ERROR:GIT_COMMIT_ID: Please use git commit description style 'commit <12+ chars of sha1> ("<title line>")' - ie: 'commit b1df3a2b24a9 ("drm/virtio: add drm_driver.release callback.")'
#25: 
commit b1df3a2b24a917f8853d43fe9683c0e360d2c33a

-:41: WARNING:BAD_SIGN_OFF: Duplicate signature
#41: 
Cc: Oleksandr Andrushchenko <oleksandr_andrushchenko@epam.com>

-:42: WARNING:BAD_SIGN_OFF: Duplicate signature
#42: 
Cc: xen-devel@lists.xenproject.org

-:84: WARNING:NO_AUTHOR_SIGN_OFF: Missing Signed-off-by: line by nominal patch author 'Daniel Vetter <daniel.vetter@ffwll.ch>'

total: 2 errors, 3 warnings, 0 checks, 29 lines checked
910313be66e8 drm/mipi_dbi: Use drmm_add_final_kfree in all drivers
-:186: WARNING:NO_AUTHOR_SIGN_OFF: Missing Signed-off-by: line by nominal patch author 'Daniel Vetter <daniel.vetter@ffwll.ch>'

total: 0 errors, 1 warnings, 0 checks, 111 lines checked
1922e341743c drm/udl: Use drmm_add_final_kfree
-:48: WARNING:NO_AUTHOR_SIGN_OFF: Missing Signed-off-by: line by nominal patch author 'Daniel Vetter <daniel.vetter@ffwll.ch>'

total: 0 errors, 1 warnings, 0 checks, 21 lines checked
2d7273b79215 drm/udl: Use drmm_add_final_kfree
-:38: WARNING:NO_AUTHOR_SIGN_OFF: Missing Signed-off-by: line by nominal patch author 'Daniel Vetter <daniel.vetter@ffwll.ch>'

total: 0 errors, 1 warnings, 0 checks, 9 lines checked
e39595f35360 drm/qxl: Use drmm_add_final_kfree
-:46: WARNING:NO_AUTHOR_SIGN_OFF: Missing Signed-off-by: line by nominal patch author 'Daniel Vetter <daniel.vetter@ffwll.ch>'

total: 0 errors, 1 warnings, 0 checks, 22 lines checked
de874f4d1c0f drm/i915: Use drmm_add_final_kfree
-:177: WARNING:NO_AUTHOR_SIGN_OFF: Missing Signed-off-by: line by nominal patch author 'Daniel Vetter <daniel.vetter@ffwll.ch>'

total: 0 errors, 1 warnings, 0 checks, 114 lines checked
88fd13f769d2 drm/cirrus: Use drmm_add_final_kfree
-:26: WARNING:OBSOLETE: drivers/gpu/drm/cirrus/cirrus.c is marked as 'obsolete' in the MAINTAINERS hierarchy.  No unnecessary modifications please.

-:29: WARNING:OBSOLETE: drivers/gpu/drm/cirrus/cirrus.c is marked as 'obsolete' in the MAINTAINERS hierarchy.  No unnecessary modifications please.

-:73: WARNING:NO_AUTHOR_SIGN_OFF: Missing Signed-off-by: line by nominal patch author 'Daniel Vetter <daniel.vetter@ffwll.ch>'

total: 0 errors, 3 warnings, 0 checks, 40 lines checked
5774e47048f1 drm/v3d: Use drmm_add_final_kfree
-:121: WARNING:NO_AUTHOR_SIGN_OFF: Missing Signed-off-by: line by nominal patch author 'Daniel Vetter <daniel.vetter@ffwll.ch>'

total: 0 errors, 1 warnings, 0 checks, 95 lines checked
8978c7ce4cb1 drm/tidss: Use drmm_add_final_kfree
-:40: WARNING:NO_AUTHOR_SIGN_OFF: Missing Signed-off-by: line by nominal patch author 'Daniel Vetter <daniel.vetter@ffwll.ch>'

total: 0 errors, 1 warnings, 0 checks, 22 lines checked
6b7e106ad130 drm/mcde: Use drmm_add_final_kfree
-:38: WARNING:NO_AUTHOR_SIGN_OFF: Missing Signed-off-by: line by nominal patch author 'Daniel Vetter <daniel.vetter@ffwll.ch>'

total: 0 errors, 1 warnings, 0 checks, 21 lines checked
4be113f9f517 drm/vgem: Use drmm_add_final_kfree
-:65: WARNING:NO_AUTHOR_SIGN_OFF: Missing Signed-off-by: line by nominal patch author 'Daniel Vetter <daniel.vetter@ffwll.ch>'

total: 0 errors, 1 warnings, 0 checks, 38 lines checked
55caa9d14bf2 drm/vkms: Use drmm_add_final_kfree
-:85: WARNING:NO_AUTHOR_SIGN_OFF: Missing Signed-off-by: line by nominal patch author 'Daniel Vetter <daniel.vetter@ffwll.ch>'

total: 0 errors, 1 warnings, 0 checks, 61 lines checked
d26af393fb38 drm/repaper: Use drmm_add_final_kfree
-:47: WARNING:NO_AUTHOR_SIGN_OFF: Missing Signed-off-by: line by nominal patch author 'Daniel Vetter <daniel.vetter@ffwll.ch>'

total: 0 errors, 1 warnings, 0 checks, 27 lines checked
7f7340798ec9 drm/inigenic: Use drmm_add_final_kfree
-:42: WARNING:NO_AUTHOR_SIGN_OFF: Missing Signed-off-by: line by nominal patch author 'Daniel Vetter <daniel.vetter@ffwll.ch>'

total: 0 errors, 1 warnings, 0 checks, 25 lines checked
c9576f3a393f drm/gm12u320: Use drmm_add_final_kfree
-:38: WARNING:NO_AUTHOR_SIGN_OFF: Missing Signed-off-by: line by nominal patch author 'Daniel Vetter <daniel.vetter@ffwll.ch>'

total: 0 errors, 1 warnings, 0 checks, 21 lines checked
8faf6ae9f858 drm/<drivers>: Use drmm_add_final_kfree
-:75: WARNING:NO_AUTHOR_SIGN_OFF: Missing Signed-off-by: line by nominal patch author 'Daniel Vetter <daniel.vetter@ffwll.ch>'

total: 0 errors, 1 warnings, 0 checks, 42 lines checked
dd0f91d8ffee drm: Cleanups after drmm_add_final_kfree rollout
-:59: WARNING:NO_AUTHOR_SIGN_OFF: Missing Signed-off-by: line by nominal patch author 'Daniel Vetter <daniel.vetter@ffwll.ch>'

total: 0 errors, 1 warnings, 0 checks, 38 lines checked
028bfa683312 drm: Handle dev->unique with drmm_
-:71: CHECK:LINE_SPACING: Please use a blank line after function/struct/union/enum declarations
#71: FILE: include/drm/drm_managed.h:24:
 }
+char *drmm_kstrdup(struct drm_device *dev, const char *s, gfp_t gfp);

-:73: WARNING:NO_AUTHOR_SIGN_OFF: Missing Signed-off-by: line by nominal patch author 'Daniel Vetter <daniel.vetter@ffwll.ch>'

total: 0 errors, 1 warnings, 1 checks, 45 lines checked
5e79da2824c6 drm: Use drmm_ for drm_dev_init cleanup
-:32: WARNING:BLOCK_COMMENT_STYLE: Block comments use a trailing */ on a separate line
#32: FILE: drivers/gpu/drm/drm_drv.c:591:
+	 * enabled. Slightly awkward, but can't really be helped. */

-:104: WARNING:NO_AUTHOR_SIGN_OFF: Missing Signed-off-by: line by nominal patch author 'Daniel Vetter <daniel.vetter@ffwll.ch>'

total: 0 errors, 2 warnings, 0 checks, 81 lines checked
1917e51b84f6 drm: manage drm_minor cleanup with drmm_
-:183: CHECK:SPACING: No space is necessary after a cast
#183: FILE: drivers/gpu/drm/drm_managed.c:148:
+		    * (void **) tmp->data == data) {

-:183: ERROR:SPACING: space prohibited after that '*' (ctx:ExW)
#183: FILE: drivers/gpu/drm/drm_managed.c:148:
+		    * (void **) tmp->data == data) {
 		    ^

-:215: WARNING:NO_AUTHOR_SIGN_OFF: Missing Signed-off-by: line by nominal patch author 'Daniel Vetter <daniel.vetter@ffwll.ch>'

total: 1 errors, 1 warnings, 1 checks, 179 lines checked
9671405e08a0 drm: Manage drm_gem_init with drmm_
-:105: WARNING:NO_AUTHOR_SIGN_OFF: Missing Signed-off-by: line by nominal patch author 'Daniel Vetter <daniel.vetter@ffwll.ch>'

total: 0 errors, 1 warnings, 0 checks, 75 lines checked
ee3f053e5805 drm: Manage drm_vblank_cleanup with drmm_
-:142: CHECK:LINE_SPACING: Please use a blank line after function/struct/union/enum declarations
#142: FILE: include/drm/drm_managed.h:29:
 }
+static inline void *drmm_kmalloc_array(struct drm_device *dev,

-:152: CHECK:LINE_SPACING: Please use a blank line after function/struct/union/enum declarations
#152: FILE: include/drm/drm_managed.h:39:
+}
+static inline void *drmm_kcalloc(struct drm_device *dev,

-:159: WARNING:NO_AUTHOR_SIGN_OFF: Missing Signed-off-by: line by nominal patch author 'Daniel Vetter <daniel.vetter@ffwll.ch>'

total: 0 errors, 1 warnings, 2 checks, 119 lines checked
f95ba04b629e drm: Garbage collect drm_dev_fini
-:11: WARNING:OBSOLETE: drivers/gpu/drm/cirrus/cirrus.c is marked as 'obsolete' in the MAINTAINERS hierarchy.  No unnecessary modifications please.

-:14: WARNING:OBSOLETE: drivers/gpu/drm/cirrus/cirrus.c is marked as 'obsolete' in the MAINTAINERS hierarchy.  No unnecessary modifications please.

-:270: WARNING:NO_AUTHOR_SIGN_OFF: Missing Signed-off-by: line by nominal patch author 'Daniel Vetter <daniel.vetter@ffwll.ch>'

total: 0 errors, 3 warnings, 0 checks, 179 lines checked
23340b1d8ce3 drm: Manage drm_mode_config_init with drmm_
-:147: WARNING:NO_AUTHOR_SIGN_OFF: Missing Signed-off-by: line by nominal patch author 'Daniel Vetter <daniel.vetter@ffwll.ch>'

total: 0 errors, 1 warnings, 0 checks, 98 lines checked
76e7952b72a6 drm/bochs: Remove leftover drm_atomic_helper_shutdown
-:8: ERROR:GIT_COMMIT_ID: Please use git commit description style 'commit <12+ chars of sha1> ("<title line>")' - ie: 'commit 81da8c3b8d3d ("drm/bochs: add drm_driver.release callback.")'
#8: 
commit 81da8c3b8d3df6f05b11300b7d17ccd1f3017fab

-:30: WARNING:NO_AUTHOR_SIGN_OFF: Missing Signed-off-by: line by nominal patch author 'Daniel Vetter <daniel.vetter@ffwll.ch>'

total: 1 errors, 1 warnings, 0 checks, 6 lines checked
32cc07da94c2 drm/bochs: Drop explicit drm_mode_config_cleanup
-:87: WARNING:NO_AUTHOR_SIGN_OFF: Missing Signed-off-by: line by nominal patch author 'Daniel Vetter <daniel.vetter@ffwll.ch>'

total: 0 errors, 1 warnings, 0 checks, 47 lines checked
91b2e8d4ddb0 drm/cirrus: Drop explicit drm_mode_config_cleanup call
-:20: WARNING:OBSOLETE: drivers/gpu/drm/cirrus/cirrus.c is marked as 'obsolete' in the MAINTAINERS hierarchy.  No unnecessary modifications please.

-:23: WARNING:OBSOLETE: drivers/gpu/drm/cirrus/cirrus.c is marked as 'obsolete' in the MAINTAINERS hierarchy.  No unnecessary modifications please.

-:86: WARNING:NO_AUTHOR_SIGN_OFF: Missing Signed-off-by: line by nominal patch author 'Daniel Vetter <daniel.vetter@ffwll.ch>'

total: 0 errors, 3 warnings, 0 checks, 58 lines checked
d0a6cee1f22d drm/cirrus: Fully embrace devm_
-:10: WARNING:TYPO_SPELLING: 'releated' may be misspelled - perhaps 'related'?
#10: 
anymore to use devm_ for everything hw releated. Do it, and in the

-:22: WARNING:OBSOLETE: drivers/gpu/drm/cirrus/cirrus.c is marked as 'obsolete' in the MAINTAINERS hierarchy.  No unnecessary modifications please.

-:25: WARNING:OBSOLETE: drivers/gpu/drm/cirrus/cirrus.c is marked as 'obsolete' in the MAINTAINERS hierarchy.  No unnecessary modifications please.

-:121: WARNING:NO_AUTHOR_SIGN_OFF: Missing Signed-off-by: line by nominal patch author 'Daniel Vetter <daniel.vetter@ffwll.ch>'

total: 0 errors, 4 warnings, 0 checks, 93 lines checked
c727b16e0f8f drm/ingenic: Drop explicit drm_mode_config_cleanup call
-:46: WARNING:NO_AUTHOR_SIGN_OFF: Missing Signed-off-by: line by nominal patch author 'Daniel Vetter <daniel.vetter@ffwll.ch>'

total: 0 errors, 1 warnings, 0 checks, 29 lines checked
ae3a84055194 drm/mcde: Drop explicit drm_mode_config_cleanup call
-:76: WARNING:NO_AUTHOR_SIGN_OFF: Missing Signed-off-by: line by nominal patch author 'Daniel Vetter <daniel.vetter@ffwll.ch>'

total: 0 errors, 1 warnings, 0 checks, 57 lines checked
89b2135f4ca3 drm/mcde: More devm_drm_dev_init
-:60: WARNING:NO_AUTHOR_SIGN_OFF: Missing Signed-off-by: line by nominal patch author 'Daniel Vetter <daniel.vetter@ffwll.ch>'

total: 0 errors, 1 warnings, 0 checks, 37 lines checked
e9af67dabd91 drm/meson: Drop explicit drm_mode_config_cleanup call
-:40: WARNING:NO_AUTHOR_SIGN_OFF: Missing Signed-off-by: line by nominal patch author 'Daniel Vetter <daniel.vetter@ffwll.ch>'

total: 0 errors, 1 warnings, 0 checks, 17 lines checked
18975d3cbcc8 drm/pl111: Drop explicit drm_mode_config_cleanup call
-:59: WARNING:NO_AUTHOR_SIGN_OFF: Missing Signed-off-by: line by nominal patch author 'Daniel Vetter <daniel.vetter@ffwll.ch>'

total: 0 errors, 1 warnings, 0 checks, 38 lines checked
894cc8a4ae26 drm/rcar-du: Drop explicit drm_mode_config_cleanup call
-:42: WARNING:NO_AUTHOR_SIGN_OFF: Missing Signed-off-by: line by nominal patch author 'Daniel Vetter <daniel.vetter@ffwll.ch>'

total: 0 errors, 1 warnings, 0 checks, 17 lines checked
61318d398f4e drm/rockchip: Drop explicit drm_mode_config_cleanup call
-:59: WARNING:NO_AUTHOR_SIGN_OFF: Missing Signed-off-by: line by nominal patch author 'Daniel Vetter <daniel.vetter@ffwll.ch>'

total: 0 errors, 1 warnings, 0 checks, 32 lines checked
0b9c31121f27 drm/stm: Drop explicit drm_mode_config_cleanup call
-:62: WARNING:NO_AUTHOR_SIGN_OFF: Missing Signed-off-by: line by nominal patch author 'Daniel Vetter <daniel.vetter@ffwll.ch>'

total: 0 errors, 1 warnings, 0 checks, 34 lines checked
500e01e42690 drm/shmob: Drop explicit drm_mode_config_cleanup call
-:52: WARNING:NO_AUTHOR_SIGN_OFF: Missing Signed-off-by: line by nominal patch author 'Daniel Vetter <daniel.vetter@ffwll.ch>'

total: 0 errors, 1 warnings, 0 checks, 26 lines checked
ffc1c40c19db drm/mtk: Drop explicit drm_mode_config_cleanup call
-:53: WARNING:NO_AUTHOR_SIGN_OFF: Missing Signed-off-by: line by nominal patch author 'Daniel Vetter <daniel.vetter@ffwll.ch>'

total: 0 errors, 1 warnings, 0 checks, 33 lines checked
23ca53ec2412 drm/tidss: Drop explicit drm_mode_config_cleanup call
-:97: WARNING:NO_AUTHOR_SIGN_OFF: Missing Signed-off-by: line by nominal patch author 'Daniel Vetter <daniel.vetter@ffwll.ch>'

total: 0 errors, 1 warnings, 0 checks, 55 lines checked
4f9b370f4d2b drm/gm12u320: More drmm_
-:76: WARNING:NO_AUTHOR_SIGN_OFF: Missing Signed-off-by: line by nominal patch author 'Daniel Vetter <daniel.vetter@ffwll.ch>'

total: 0 errors, 1 warnings, 0 checks, 50 lines checked
27cf675129b9 drm/gm12u320: Use devm_drm_dev_init
-:88: WARNING:NO_AUTHOR_SIGN_OFF: Missing Signed-off-by: line by nominal patch author 'Daniel Vetter <daniel.vetter@ffwll.ch>'

total: 0 errors, 1 warnings, 0 checks, 65 lines checked
915bcdb4e0ae drm/gm12u320: Use helpers for shutdown/suspend/resume
-:9: WARNING:TYPO_SPELLING: 'implemenation' may be misspelled - perhaps 'implementation'?
#9: 
Also there's a race in the disconnect implemenation. First shut

-:84: WARNING:NO_AUTHOR_SIGN_OFF: Missing Signed-off-by: line by nominal patch author 'Daniel Vetter <daniel.vetter@ffwll.ch>'

total: 0 errors, 2 warnings, 0 checks, 56 lines checked
7c5bdd5a00b3 drm/gm12u320: Simplify upload work
-:150: CHECK:PARENTHESIS_ALIGNMENT: Alignment should match open parenthesis
#150: FILE: drivers/gpu/drm/tiny/gm12u320.c:360:
+		ret = usb_bulk_msg(gm12u320->udev,
+			usb_sndbulkpipe(gm12u320->udev, DATA_SND_EPT),

-:181: CHECK:PARENTHESIS_ALIGNMENT: Alignment should match open parenthesis
#181: FILE: drivers/gpu/drm/tiny/gm12u320.c:378:
+	ret = usb_bulk_msg(gm12u320->udev,
+		usb_sndbulkpipe(gm12u320->udev, DATA_SND_EPT),

-:188: CHECK:PARENTHESIS_ALIGNMENT: Alignment should match open parenthesis
#188: FILE: drivers/gpu/drm/tiny/gm12u320.c:385:
+	ret = usb_bulk_msg(gm12u320->udev,
+		usb_rcvbulkpipe(gm12u320->udev, DATA_RCV_EPT),

-:296: WARNING:NO_AUTHOR_SIGN_OFF: Missing Signed-off-by: line by nominal patch author 'Daniel Vetter <daniel.vetter@ffwll.ch>'

total: 0 errors, 1 warnings, 3 checks, 255 lines checked
bf2a234a3957 drm/repaper: Drop explicit drm_mode_config_cleanup call
-:39: WARNING:NO_AUTHOR_SIGN_OFF: Missing Signed-off-by: line by nominal patch author 'Daniel Vetter <daniel.vetter@ffwll.ch>'

total: 0 errors, 1 warnings, 0 checks, 20 lines checked
74ef43fcef1b drm/mipi-dbi: Move drm_mode_config_init into mipi library
-:118: WARNING:NO_AUTHOR_SIGN_OFF: Missing Signed-off-by: line by nominal patch author 'Daniel Vetter <daniel.vetter@ffwll.ch>'

total: 0 errors, 1 warnings, 0 checks, 66 lines checked
b6a40d07bba7 drm/mipi-dbi: Drop explicit drm_mode_config_cleanup call
-:146: WARNING:NO_AUTHOR_SIGN_OFF: Missing Signed-off-by: line by nominal patch author 'Daniel Vetter <daniel.vetter@ffwll.ch>'

total: 0 errors, 1 warnings, 0 checks, 78 lines checked
5c40275785f8 drm/udl: Drop explicit drm_mode_config_cleanup call
-:96: WARNING:NO_AUTHOR_SIGN_OFF: Missing Signed-off-by: line by nominal patch author 'Daniel Vetter <daniel.vetter@ffwll.ch>'

total: 0 errors, 1 warnings, 0 checks, 55 lines checked
bd18a1acdca1 drm/udl: drop drm_driver.release hook
-:81: WARNING:NO_AUTHOR_SIGN_OFF: Missing Signed-off-by: line by nominal patch author 'Daniel Vetter <daniel.vetter@ffwll.ch>'

total: 0 errors, 1 warnings, 0 checks, 24 lines checked
baf6b6b7b969 drm: Add docs for managed resources
-:322: WARNING:NO_AUTHOR_SIGN_OFF: Missing Signed-off-by: line by nominal patch author 'Daniel Vetter <daniel.vetter@ffwll.ch>'

total: 0 errors, 1 warnings, 0 checks, 231 lines checked

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* [Intel-gfx] ✗ Fi.CI.SPARSE: warning for drm_device managed resources
  2020-02-19 10:20 ` [Intel-gfx] " Daniel Vetter
                   ` (53 preceding siblings ...)
  (?)
@ 2020-02-19 11:32 ` Patchwork
  -1 siblings, 0 replies; 310+ messages in thread
From: Patchwork @ 2020-02-19 11:32 UTC (permalink / raw)
  To: Daniel Vetter; +Cc: intel-gfx

== Series Details ==

Series: drm_device managed resources
URL   : https://patchwork.freedesktop.org/series/73633/
State : warning

== Summary ==

$ dim sparse origin/drm-tip
Sparse version: v0.6.0
Commit: mm/sl[uo]b: export __kmalloc_track(_node)_caller
Okay!

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH 05/52] drm/mipi_dbi: Use drmm_add_final_kfree in all drivers
  2020-02-19 10:20   ` [Intel-gfx] " Daniel Vetter
@ 2020-02-19 11:47     ` Thomas Zimmermann
  -1 siblings, 0 replies; 310+ messages in thread
From: Thomas Zimmermann @ 2020-02-19 11:47 UTC (permalink / raw)
  To: Daniel Vetter, DRI Development
  Cc: David Lechner, David Airlie, Intel Graphics Development,
	Daniel Vetter, Kamlesh Gurudasani, Sam Ravnborg


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

Hi Daniel,

good idea. I guess it's the simple encoder's fault. :) I only read
briefly over the whole thing.

Am 19.02.20 um 11:20 schrieb Daniel Vetter:
> 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).
> 
> 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);

I'd prefer something else than drmm_add_final_kfree().

From what I understand, drmmadd_add_final_kfree() is required so that
the device instance itself gets free. But wiring up garbage collection
manually is easy to forget and a somewhat odd design. If we have to do
that, there's little benefit over calling kfree in the release callback.

Instead, could drivers rather be converted to drm_dev_alloc() where
possible?

For the other cases, could there be a dedicated allocator function that
invokes drmm_add_final_kfree()? Like that

  void*
  __drmm_kzalloc_dev(size_t size, size_t dev_off)
  {
      void *parent = kzalloc(size)

      drm_device *dev = (parent + dev_off)

      __drmm_add_final_kfree(dev, parent);

      return parent;
  }

  /*
   * takes the name of driver's device structure and the
   * name of the drm device structure embedded within
   */
  drmm_kzalloc(parent_type, base)
    (parent_type*)__drm_kzalloc_dev(sizeof(parent_type),
			offsetof(parent_type, base));

Best regards
Thomas

>  
>  	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);
>  
> 

-- 
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: 484 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] 310+ messages in thread

* Re: [Intel-gfx] [PATCH 05/52] drm/mipi_dbi: Use drmm_add_final_kfree in all drivers
@ 2020-02-19 11:47     ` Thomas Zimmermann
  0 siblings, 0 replies; 310+ messages in thread
From: Thomas Zimmermann @ 2020-02-19 11:47 UTC (permalink / raw)
  To: Daniel Vetter, DRI Development
  Cc: David Lechner, David Airlie, Intel Graphics Development,
	Maxime Ripard, Eric Anholt, Noralf Trønnes, Daniel Vetter,
	Kamlesh Gurudasani, Sam Ravnborg


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

Hi Daniel,

good idea. I guess it's the simple encoder's fault. :) I only read
briefly over the whole thing.

Am 19.02.20 um 11:20 schrieb Daniel Vetter:
> 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).
> 
> 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);

I'd prefer something else than drmm_add_final_kfree().

From what I understand, drmmadd_add_final_kfree() is required so that
the device instance itself gets free. But wiring up garbage collection
manually is easy to forget and a somewhat odd design. If we have to do
that, there's little benefit over calling kfree in the release callback.

Instead, could drivers rather be converted to drm_dev_alloc() where
possible?

For the other cases, could there be a dedicated allocator function that
invokes drmm_add_final_kfree()? Like that

  void*
  __drmm_kzalloc_dev(size_t size, size_t dev_off)
  {
      void *parent = kzalloc(size)

      drm_device *dev = (parent + dev_off)

      __drmm_add_final_kfree(dev, parent);

      return parent;
  }

  /*
   * takes the name of driver's device structure and the
   * name of the drm device structure embedded within
   */
  drmm_kzalloc(parent_type, base)
    (parent_type*)__drm_kzalloc_dev(sizeof(parent_type),
			offsetof(parent_type, base));

Best regards
Thomas

>  
>  	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);
>  
> 

-- 
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: 484 bytes --]

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

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* [Intel-gfx] ✓ Fi.CI.BAT: success for drm_device managed resources
  2020-02-19 10:20 ` [Intel-gfx] " Daniel Vetter
                   ` (54 preceding siblings ...)
  (?)
@ 2020-02-19 11:54 ` Patchwork
  -1 siblings, 0 replies; 310+ messages in thread
From: Patchwork @ 2020-02-19 11:54 UTC (permalink / raw)
  To: Daniel Vetter; +Cc: intel-gfx

== Series Details ==

Series: drm_device managed resources
URL   : https://patchwork.freedesktop.org/series/73633/
State : success

== Summary ==

CI Bug Log - changes from CI_DRM_7963 -> Patchwork_16618
====================================================

Summary
-------

  **SUCCESS**

  No regressions found.

  External URL: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_16618/index.html

Known issues
------------

  Here are the changes found in Patchwork_16618 that come from known issues:

### IGT changes ###

#### Issues hit ####

  * igt@kms_frontbuffer_tracking@basic:
    - fi-icl-u3:          [PASS][1] -> [DMESG-WARN][2] ([i915#585]) +38 similar issues
   [1]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7963/fi-icl-u3/igt@kms_frontbuffer_tracking@basic.html
   [2]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_16618/fi-icl-u3/igt@kms_frontbuffer_tracking@basic.html

  
#### Possible fixes ####

  * igt@gem_exec_parallel@contexts:
    - {fi-ehl-1}:         [INCOMPLETE][3] ([i915#937]) -> [PASS][4]
   [3]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7963/fi-ehl-1/igt@gem_exec_parallel@contexts.html
   [4]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_16618/fi-ehl-1/igt@gem_exec_parallel@contexts.html

  * igt@i915_selftest@live_active:
    - fi-icl-dsi:         [DMESG-FAIL][5] ([i915#765]) -> [PASS][6]
   [5]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7963/fi-icl-dsi/igt@i915_selftest@live_active.html
   [6]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_16618/fi-icl-dsi/igt@i915_selftest@live_active.html

  * igt@i915_selftest@live_gem_contexts:
    - fi-cfl-8700k:       [INCOMPLETE][7] ([i915#424]) -> [PASS][8]
   [7]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7963/fi-cfl-8700k/igt@i915_selftest@live_gem_contexts.html
   [8]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_16618/fi-cfl-8700k/igt@i915_selftest@live_gem_contexts.html
    - fi-cml-s:           [DMESG-FAIL][9] ([i915#877]) -> [PASS][10]
   [9]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7963/fi-cml-s/igt@i915_selftest@live_gem_contexts.html
   [10]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_16618/fi-cml-s/igt@i915_selftest@live_gem_contexts.html

  * igt@i915_selftest@live_gt_heartbeat:
    - fi-kbl-7500u:       [DMESG-FAIL][11] ([fdo#112406]) -> [PASS][12]
   [11]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7963/fi-kbl-7500u/igt@i915_selftest@live_gt_heartbeat.html
   [12]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_16618/fi-kbl-7500u/igt@i915_selftest@live_gt_heartbeat.html

  * igt@kms_flip@basic-flip-vs-wf_vblank:
    - fi-bsw-n3050:       [FAIL][13] ([i915#34]) -> [PASS][14]
   [13]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7963/fi-bsw-n3050/igt@kms_flip@basic-flip-vs-wf_vblank.html
   [14]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_16618/fi-bsw-n3050/igt@kms_flip@basic-flip-vs-wf_vblank.html

  
#### Warnings ####

  * igt@amdgpu/amd_prime@amd-to-i915:
    - fi-icl-u3:          [SKIP][15] ([fdo#109315]) -> [SKIP][16] ([fdo#109315] / [i915#585])
   [15]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7963/fi-icl-u3/igt@amdgpu/amd_prime@amd-to-i915.html
   [16]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_16618/fi-icl-u3/igt@amdgpu/amd_prime@amd-to-i915.html

  * igt@i915_pm_rpm@basic-rte:
    - fi-kbl-guc:         [FAIL][17] ([i915#579]) -> [SKIP][18] ([fdo#109271])
   [17]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7963/fi-kbl-guc/igt@i915_pm_rpm@basic-rte.html
   [18]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_16618/fi-kbl-guc/igt@i915_pm_rpm@basic-rte.html

  * igt@kms_chamelium@dp-hpd-fast:
    - fi-icl-u3:          [SKIP][19] ([fdo#109284] / [fdo#111827]) -> [SKIP][20] ([fdo#109284] / [fdo#111827] / [i915#585])
   [19]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7963/fi-icl-u3/igt@kms_chamelium@dp-hpd-fast.html
   [20]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_16618/fi-icl-u3/igt@kms_chamelium@dp-hpd-fast.html

  * igt@kms_force_connector_basic@force-load-detect:
    - fi-icl-u3:          [SKIP][21] ([fdo#109285]) -> [SKIP][22] ([fdo#109285] / [i915#585])
   [21]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7963/fi-icl-u3/igt@kms_force_connector_basic@force-load-detect.html
   [22]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_16618/fi-icl-u3/igt@kms_force_connector_basic@force-load-detect.html

  
  {name}: This element is suppressed. This means it is ignored when computing
          the status of the difference (SUCCESS, WARNING, or FAILURE).

  [fdo#109271]: https://bugs.freedesktop.org/show_bug.cgi?id=109271
  [fdo#109284]: https://bugs.freedesktop.org/show_bug.cgi?id=109284
  [fdo#109285]: https://bugs.freedesktop.org/show_bug.cgi?id=109285
  [fdo#109315]: https://bugs.freedesktop.org/show_bug.cgi?id=109315
  [fdo#111827]: https://bugs.freedesktop.org/show_bug.cgi?id=111827
  [fdo#112406]: https://bugs.freedesktop.org/show_bug.cgi?id=112406
  [i915#34]: https://gitlab.freedesktop.org/drm/intel/issues/34
  [i915#424]: https://gitlab.freedesktop.org/drm/intel/issues/424
  [i915#579]: https://gitlab.freedesktop.org/drm/intel/issues/579
  [i915#585]: https://gitlab.freedesktop.org/drm/intel/issues/585
  [i915#765]: https://gitlab.freedesktop.org/drm/intel/issues/765
  [i915#877]: https://gitlab.freedesktop.org/drm/intel/issues/877
  [i915#937]: https://gitlab.freedesktop.org/drm/intel/issues/937


Participating hosts (50 -> 44)
------------------------------

  Additional (1): fi-kbl-7560u 
  Missing    (7): fi-cml-u2 fi-ilk-m540 fi-hsw-4200u fi-bsw-cyan fi-ctg-p8600 fi-byt-n2820 fi-bdw-samus 


Build changes
-------------

  * CI: CI-20190529 -> None
  * Linux: CI_DRM_7963 -> Patchwork_16618

  CI-20190529: 20190529
  CI_DRM_7963: e0d737598eb749378a5dc4ed3dfafc6f79d512cb @ git://anongit.freedesktop.org/gfx-ci/linux
  IGT_5448: 116020b1f83c1b3994c76882df7f77b6731d78ba @ git://anongit.freedesktop.org/xorg/app/intel-gpu-tools
  Patchwork_16618: baf6b6b7b9692fab9d65b3d1459d20b5e16eeb30 @ git://anongit.freedesktop.org/gfx-ci/linux


== Linux commits ==

baf6b6b7b969 drm: Add docs for managed resources
bd18a1acdca1 drm/udl: drop drm_driver.release hook
5c40275785f8 drm/udl: Drop explicit drm_mode_config_cleanup call
b6a40d07bba7 drm/mipi-dbi: Drop explicit drm_mode_config_cleanup call
74ef43fcef1b drm/mipi-dbi: Move drm_mode_config_init into mipi library
bf2a234a3957 drm/repaper: Drop explicit drm_mode_config_cleanup call
7c5bdd5a00b3 drm/gm12u320: Simplify upload work
915bcdb4e0ae drm/gm12u320: Use helpers for shutdown/suspend/resume
27cf675129b9 drm/gm12u320: Use devm_drm_dev_init
4f9b370f4d2b drm/gm12u320: More drmm_
23ca53ec2412 drm/tidss: Drop explicit drm_mode_config_cleanup call
ffc1c40c19db drm/mtk: Drop explicit drm_mode_config_cleanup call
500e01e42690 drm/shmob: Drop explicit drm_mode_config_cleanup call
0b9c31121f27 drm/stm: Drop explicit drm_mode_config_cleanup call
61318d398f4e drm/rockchip: Drop explicit drm_mode_config_cleanup call
894cc8a4ae26 drm/rcar-du: Drop explicit drm_mode_config_cleanup call
18975d3cbcc8 drm/pl111: Drop explicit drm_mode_config_cleanup call
e9af67dabd91 drm/meson: Drop explicit drm_mode_config_cleanup call
89b2135f4ca3 drm/mcde: More devm_drm_dev_init
ae3a84055194 drm/mcde: Drop explicit drm_mode_config_cleanup call
c727b16e0f8f drm/ingenic: Drop explicit drm_mode_config_cleanup call
d0a6cee1f22d drm/cirrus: Fully embrace devm_
91b2e8d4ddb0 drm/cirrus: Drop explicit drm_mode_config_cleanup call
32cc07da94c2 drm/bochs: Drop explicit drm_mode_config_cleanup
76e7952b72a6 drm/bochs: Remove leftover drm_atomic_helper_shutdown
23340b1d8ce3 drm: Manage drm_mode_config_init with drmm_
f95ba04b629e drm: Garbage collect drm_dev_fini
ee3f053e5805 drm: Manage drm_vblank_cleanup with drmm_
9671405e08a0 drm: Manage drm_gem_init with drmm_
1917e51b84f6 drm: manage drm_minor cleanup with drmm_
5e79da2824c6 drm: Use drmm_ for drm_dev_init cleanup
028bfa683312 drm: Handle dev->unique with drmm_
dd0f91d8ffee drm: Cleanups after drmm_add_final_kfree rollout
8faf6ae9f858 drm/<drivers>: Use drmm_add_final_kfree
c9576f3a393f drm/gm12u320: Use drmm_add_final_kfree
7f7340798ec9 drm/inigenic: Use drmm_add_final_kfree
d26af393fb38 drm/repaper: Use drmm_add_final_kfree
55caa9d14bf2 drm/vkms: Use drmm_add_final_kfree
4be113f9f517 drm/vgem: Use drmm_add_final_kfree
6b7e106ad130 drm/mcde: Use drmm_add_final_kfree
8978c7ce4cb1 drm/tidss: Use drmm_add_final_kfree
5774e47048f1 drm/v3d: Use drmm_add_final_kfree
88fd13f769d2 drm/cirrus: Use drmm_add_final_kfree
de874f4d1c0f drm/i915: Use drmm_add_final_kfree
e39595f35360 drm/qxl: Use drmm_add_final_kfree
2d7273b79215 drm/udl: Use drmm_add_final_kfree
1922e341743c drm/udl: Use drmm_add_final_kfree
910313be66e8 drm/mipi_dbi: Use drmm_add_final_kfree in all drivers
06b9d9ecc4bb drm: Set final_kfree in drm_dev_alloc
7ffeeed91dd5 drm: add managed resources tied to drm_device
5b8201a378ad drm/i915: Don't clear drvdata in ->release
913ef020101d mm/sl[uo]b: export __kmalloc_track(_node)_caller

== Logs ==

For more details see: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_16618/index.html
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH 04/52] drm: Set final_kfree in drm_dev_alloc
  2020-02-19 10:20   ` [Intel-gfx] " Daniel Vetter
  (?)
@ 2020-02-19 12:03     ` Oleksandr Andrushchenko
  -1 siblings, 0 replies; 310+ messages in thread
From: Oleksandr Andrushchenko @ 2020-02-19 12:03 UTC (permalink / raw)
  To: Daniel Vetter, DRI Development
  Cc: David Airlie, Intel Graphics Development, Gerd Hoffmann,
	Thomas Zimmermann, Daniel Vetter, xen-devel

On 2/19/20 12:20 PM, 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.
>
> Cc: Gerd Hoffmann <kraxel@redhat.com>
> Cc: Oleksandr Andrushchenko <oleksandr_andrushchenko@epam.com>
> Cc: xen-devel@lists.xenproject.org
>
> Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
Thank you,
Reviewed-by: Oleksandr Andrushchenko <oleksandr_andrushchenko@epam.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 3e5627d6eba6..9e62e28bbc62 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;
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

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

* Re: [Intel-gfx] [PATCH 04/52] drm: Set final_kfree in drm_dev_alloc
@ 2020-02-19 12:03     ` Oleksandr Andrushchenko
  0 siblings, 0 replies; 310+ messages in thread
From: Oleksandr Andrushchenko @ 2020-02-19 12:03 UTC (permalink / raw)
  To: Daniel Vetter, DRI Development
  Cc: David Airlie, Intel Graphics Development, Maxime Ripard,
	Gerd Hoffmann, Thomas Zimmermann, Daniel Vetter, xen-devel

On 2/19/20 12:20 PM, 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.
>
> Cc: Gerd Hoffmann <kraxel@redhat.com>
> Cc: Oleksandr Andrushchenko <oleksandr_andrushchenko@epam.com>
> Cc: xen-devel@lists.xenproject.org
>
> Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
Thank you,
Reviewed-by: Oleksandr Andrushchenko <oleksandr_andrushchenko@epam.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 3e5627d6eba6..9e62e28bbc62 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;
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [Xen-devel] [PATCH 04/52] drm: Set final_kfree in drm_dev_alloc
@ 2020-02-19 12:03     ` Oleksandr Andrushchenko
  0 siblings, 0 replies; 310+ messages in thread
From: Oleksandr Andrushchenko @ 2020-02-19 12:03 UTC (permalink / raw)
  To: Daniel Vetter, DRI Development
  Cc: Daniel Vetter, David Airlie, Intel Graphics Development,
	Maarten Lankhorst, Maxime Ripard, Gerd Hoffmann,
	Thomas Zimmermann, Daniel Vetter, xen-devel

On 2/19/20 12:20 PM, 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.
>
> Cc: Gerd Hoffmann <kraxel@redhat.com>
> Cc: Oleksandr Andrushchenko <oleksandr_andrushchenko@epam.com>
> Cc: xen-devel@lists.xenproject.org
>
> Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
Thank you,
Reviewed-by: Oleksandr Andrushchenko <oleksandr_andrushchenko@epam.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 3e5627d6eba6..9e62e28bbc62 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;
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

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

* Re: [PATCH 37/52] drm/rcar-du: Drop explicit drm_mode_config_cleanup call
  2020-02-19 11:10         ` Geert Uytterhoeven
  (?)
@ 2020-02-19 12:17           ` Laurent Pinchart
  -1 siblings, 0 replies; 310+ messages in thread
From: Laurent Pinchart @ 2020-02-19 12:17 UTC (permalink / raw)
  To: Daniel Vetter
  Cc: Geert Uytterhoeven, DRI Development, Intel Graphics Development,
	Daniel Vetter, Kieran Bingham, Linux-Renesas

Hi Daniel,

On Wed, Feb 19, 2020 at 12:10:18PM +0100, Geert Uytterhoeven wrote:
> On Wed, Feb 19, 2020 at 11:57 AM Daniel Vetter wrote:
> > On Wed, Feb 19, 2020 at 11:30 AM Geert Uytterhoeven wrote:
> > > On Wed, Feb 19, 2020 at 11:22 AM Daniel Vetter wrote:
> > > > It's right above the drm_dev_put().
> > > >
> > > > Aside: Another driver with a bit much devm_kzalloc, which should
> > > > probably use drmm_kzalloc instead ...
> > >
> > > What's drmm_kzalloc()?
> > > The only references I can find are in this patch series.
> >
> > Yup, it's all new. Read cover letter for reading instructions for the
> > entire patch series. I'm afraid the driver patches wont make much
> > sense without the context. None actually :-/
> 
> IC, as the cover letter was sent only to dri-devel and intel-gfx, many
> recipients of the patches won't have received it...
> https://lore.kernel.org/dri-devel/20200219102122.1607365-1-daniel.vetter@ffwll.ch/

I was also going to mention that it would be nice to send the cover
letter to all recipients from the series, otherwise it's a bit painful.
Daniel, is this something that could be integrated in your workflow ?

-- 
Regards,

Laurent Pinchart

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

* Re: [PATCH 37/52] drm/rcar-du: Drop explicit drm_mode_config_cleanup call
@ 2020-02-19 12:17           ` Laurent Pinchart
  0 siblings, 0 replies; 310+ messages in thread
From: Laurent Pinchart @ 2020-02-19 12:17 UTC (permalink / raw)
  To: Daniel Vetter
  Cc: Intel Graphics Development, DRI Development, Linux-Renesas,
	Kieran Bingham, Geert Uytterhoeven, Daniel Vetter

Hi Daniel,

On Wed, Feb 19, 2020 at 12:10:18PM +0100, Geert Uytterhoeven wrote:
> On Wed, Feb 19, 2020 at 11:57 AM Daniel Vetter wrote:
> > On Wed, Feb 19, 2020 at 11:30 AM Geert Uytterhoeven wrote:
> > > On Wed, Feb 19, 2020 at 11:22 AM Daniel Vetter wrote:
> > > > It's right above the drm_dev_put().
> > > >
> > > > Aside: Another driver with a bit much devm_kzalloc, which should
> > > > probably use drmm_kzalloc instead ...
> > >
> > > What's drmm_kzalloc()?
> > > The only references I can find are in this patch series.
> >
> > Yup, it's all new. Read cover letter for reading instructions for the
> > entire patch series. I'm afraid the driver patches wont make much
> > sense without the context. None actually :-/
> 
> IC, as the cover letter was sent only to dri-devel and intel-gfx, many
> recipients of the patches won't have received it...
> https://lore.kernel.org/dri-devel/20200219102122.1607365-1-daniel.vetter@ffwll.ch/

I was also going to mention that it would be nice to send the cover
letter to all recipients from the series, otherwise it's a bit painful.
Daniel, is this something that could be integrated in your workflow ?

-- 
Regards,

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

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

* Re: [Intel-gfx] [PATCH 37/52] drm/rcar-du: Drop explicit drm_mode_config_cleanup call
@ 2020-02-19 12:17           ` Laurent Pinchart
  0 siblings, 0 replies; 310+ messages in thread
From: Laurent Pinchart @ 2020-02-19 12:17 UTC (permalink / raw)
  To: Daniel Vetter
  Cc: Intel Graphics Development, DRI Development, Linux-Renesas,
	Kieran Bingham, Geert Uytterhoeven, Daniel Vetter

Hi Daniel,

On Wed, Feb 19, 2020 at 12:10:18PM +0100, Geert Uytterhoeven wrote:
> On Wed, Feb 19, 2020 at 11:57 AM Daniel Vetter wrote:
> > On Wed, Feb 19, 2020 at 11:30 AM Geert Uytterhoeven wrote:
> > > On Wed, Feb 19, 2020 at 11:22 AM Daniel Vetter wrote:
> > > > It's right above the drm_dev_put().
> > > >
> > > > Aside: Another driver with a bit much devm_kzalloc, which should
> > > > probably use drmm_kzalloc instead ...
> > >
> > > What's drmm_kzalloc()?
> > > The only references I can find are in this patch series.
> >
> > Yup, it's all new. Read cover letter for reading instructions for the
> > entire patch series. I'm afraid the driver patches wont make much
> > sense without the context. None actually :-/
> 
> IC, as the cover letter was sent only to dri-devel and intel-gfx, many
> recipients of the patches won't have received it...
> https://lore.kernel.org/dri-devel/20200219102122.1607365-1-daniel.vetter@ffwll.ch/

I was also going to mention that it would be nice to send the cover
letter to all recipients from the series, otherwise it's a bit painful.
Daniel, is this something that could be integrated in your workflow ?

-- 
Regards,

Laurent Pinchart
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH 03/52] drm: add managed resources tied to drm_device
  2020-02-19 10:20   ` [Intel-gfx] " Daniel Vetter
@ 2020-02-19 12:31     ` Neil Armstrong
  -1 siblings, 0 replies; 310+ messages in thread
From: Neil Armstrong @ 2020-02-19 12:31 UTC (permalink / raw)
  To: Daniel Vetter, DRI Development
  Cc: Daniel Vetter, Intel Graphics Development, Greg Kroah-Hartman,
	Rafael J. Wysocki

Hi,

On 19/02/2020 11:20, Daniel Vetter wrote:
> 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.
> 
> 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           |  13 ++-
>  drivers/gpu/drm/drm_internal.h      |   3 +
>  drivers/gpu/drm/drm_managed.c       | 173 ++++++++++++++++++++++++++++
>  include/drm/drm_device.h            |  12 ++
>  include/drm/drm_managed.h           |  25 ++++
>  include/drm/drm_print.h             |   6 +
>  8 files changed, 239 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 ca0ca775d37f..53d8fa170143 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..3e5627d6eba6 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,16 @@ static void drm_dev_release(struct kref *ref)
>  		dev->driver->release(dev);
>  	} else {
>  		drm_dev_fini(dev);
> -		kfree(dev);
> +		if (!dev->managed.final_kfree) {
> +			WARN_ON(!list_empty(&dev->managed.resources));
> +			kfree(dev);
> +		}
>  	}
> +
> +	drm_managed_release(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..ee7c7253af61
> --- /dev/null
> +++ b/drivers/gpu/drm/drm_managed.c
> @@ -0,0 +1,173 @@
> +// 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 sturct &device managed resources, but tied to the lifetime of

--------------------/\ struct

> + * 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 (%lu bytes)\n",
> +			       dr, dr->node.name, (unsigned long) dr->node.size);
> +
> +		if (dr->node.release)
> +			dr->node.release(dev, dr->node.size ? dr->data : NULL);
> +
> +		list_del(&dr->node.entry);
> +		kfree(dr);
> +	}
> +	drm_dbg_drmres(dev, "drmres release end\n");
> +}
> +
> +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;
> +}
> +
> +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);
> +}
> +
> +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);
> +}

Maybe del_dr/add_dr as static ?

> +
> +void drmm_add_final_kfree(struct drm_device *dev, void *parent)
> +{
> +	WARN_ON(dev->managed.final_kfree);
> +	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)
> +		return -ENOMEM;
> +	dr->node.name = name;
> +	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)
> +		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 = 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->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_kfree);
> diff --git a/include/drm/drm_device.h b/include/drm/drm_device.h
> index bb60a949f416..2790c9ed614e 100644
> --- a/include/drm/drm_device.h
> +++ b/include/drm/drm_device.h
> @@ -67,6 +67,18 @@ 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 {
> +		struct list_head resources;
> +		void *final_kfree;
> +		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..75f2c8932c69
> --- /dev/null
> +++ b/include/drm/drm_managed.h
> @@ -0,0 +1,25 @@
> +// SPDX-License-Identifier: GPL-2.0
> +
> +#include <linux/types.h>
> +#include <linux/gfp.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);
> 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__)
>  
>  
>  /*
> 

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

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

* Re: [Intel-gfx] [PATCH 03/52] drm: add managed resources tied to drm_device
@ 2020-02-19 12:31     ` Neil Armstrong
  0 siblings, 0 replies; 310+ messages in thread
From: Neil Armstrong @ 2020-02-19 12:31 UTC (permalink / raw)
  To: Daniel Vetter, DRI Development
  Cc: Daniel Vetter, Intel Graphics Development, Greg Kroah-Hartman,
	Rafael J. Wysocki

Hi,

On 19/02/2020 11:20, Daniel Vetter wrote:
> 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.
> 
> 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           |  13 ++-
>  drivers/gpu/drm/drm_internal.h      |   3 +
>  drivers/gpu/drm/drm_managed.c       | 173 ++++++++++++++++++++++++++++
>  include/drm/drm_device.h            |  12 ++
>  include/drm/drm_managed.h           |  25 ++++
>  include/drm/drm_print.h             |   6 +
>  8 files changed, 239 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 ca0ca775d37f..53d8fa170143 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..3e5627d6eba6 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,16 @@ static void drm_dev_release(struct kref *ref)
>  		dev->driver->release(dev);
>  	} else {
>  		drm_dev_fini(dev);
> -		kfree(dev);
> +		if (!dev->managed.final_kfree) {
> +			WARN_ON(!list_empty(&dev->managed.resources));
> +			kfree(dev);
> +		}
>  	}
> +
> +	drm_managed_release(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..ee7c7253af61
> --- /dev/null
> +++ b/drivers/gpu/drm/drm_managed.c
> @@ -0,0 +1,173 @@
> +// 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 sturct &device managed resources, but tied to the lifetime of

--------------------/\ struct

> + * 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 (%lu bytes)\n",
> +			       dr, dr->node.name, (unsigned long) dr->node.size);
> +
> +		if (dr->node.release)
> +			dr->node.release(dev, dr->node.size ? dr->data : NULL);
> +
> +		list_del(&dr->node.entry);
> +		kfree(dr);
> +	}
> +	drm_dbg_drmres(dev, "drmres release end\n");
> +}
> +
> +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;
> +}
> +
> +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);
> +}
> +
> +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);
> +}

Maybe del_dr/add_dr as static ?

> +
> +void drmm_add_final_kfree(struct drm_device *dev, void *parent)
> +{
> +	WARN_ON(dev->managed.final_kfree);
> +	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)
> +		return -ENOMEM;
> +	dr->node.name = name;
> +	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)
> +		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 = 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->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_kfree);
> diff --git a/include/drm/drm_device.h b/include/drm/drm_device.h
> index bb60a949f416..2790c9ed614e 100644
> --- a/include/drm/drm_device.h
> +++ b/include/drm/drm_device.h
> @@ -67,6 +67,18 @@ 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 {
> +		struct list_head resources;
> +		void *final_kfree;
> +		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..75f2c8932c69
> --- /dev/null
> +++ b/include/drm/drm_managed.h
> @@ -0,0 +1,25 @@
> +// SPDX-License-Identifier: GPL-2.0
> +
> +#include <linux/types.h>
> +#include <linux/gfp.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);
> 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__)
>  
>  
>  /*
> 

Neil
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH 37/52] drm/rcar-du: Drop explicit drm_mode_config_cleanup call
  2020-02-19 12:17           ` Laurent Pinchart
  (?)
@ 2020-02-19 12:40             ` Daniel Vetter
  -1 siblings, 0 replies; 310+ messages in thread
From: Daniel Vetter @ 2020-02-19 12:40 UTC (permalink / raw)
  To: Laurent Pinchart
  Cc: Daniel Vetter, Geert Uytterhoeven, DRI Development,
	Intel Graphics Development, Daniel Vetter, Kieran Bingham,
	Linux-Renesas

On Wed, Feb 19, 2020 at 02:17:27PM +0200, Laurent Pinchart wrote:
> Hi Daniel,
> 
> On Wed, Feb 19, 2020 at 12:10:18PM +0100, Geert Uytterhoeven wrote:
> > On Wed, Feb 19, 2020 at 11:57 AM Daniel Vetter wrote:
> > > On Wed, Feb 19, 2020 at 11:30 AM Geert Uytterhoeven wrote:
> > > > On Wed, Feb 19, 2020 at 11:22 AM Daniel Vetter wrote:
> > > > > It's right above the drm_dev_put().
> > > > >
> > > > > Aside: Another driver with a bit much devm_kzalloc, which should
> > > > > probably use drmm_kzalloc instead ...
> > > >
> > > > What's drmm_kzalloc()?
> > > > The only references I can find are in this patch series.
> > >
> > > Yup, it's all new. Read cover letter for reading instructions for the
> > > entire patch series. I'm afraid the driver patches wont make much
> > > sense without the context. None actually :-/
> > 
> > IC, as the cover letter was sent only to dri-devel and intel-gfx, many
> > recipients of the patches won't have received it...
> > https://lore.kernel.org/dri-devel/20200219102122.1607365-1-daniel.vetter@ffwll.ch/
> 
> I was also going to mention that it would be nice to send the cover
> letter to all recipients from the series, otherwise it's a bit painful.
> Daniel, is this something that could be integrated in your workflow ?

No, the usual result of that if you do it is that mail servers scream at
you for too many recipients.

dri-devel is on lore.kernel.org now, with full historical backlog, so all
there.

https://lore.kernel.org/dri-devel/20200219102122.1607365-1-daniel.vetter@ffwll.ch/T/#t

Cheers, Daniel
-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch

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

* Re: [PATCH 37/52] drm/rcar-du: Drop explicit drm_mode_config_cleanup call
@ 2020-02-19 12:40             ` Daniel Vetter
  0 siblings, 0 replies; 310+ messages in thread
From: Daniel Vetter @ 2020-02-19 12:40 UTC (permalink / raw)
  To: Laurent Pinchart
  Cc: Daniel Vetter, Intel Graphics Development, DRI Development,
	Linux-Renesas, Kieran Bingham, Geert Uytterhoeven, Daniel Vetter

On Wed, Feb 19, 2020 at 02:17:27PM +0200, Laurent Pinchart wrote:
> Hi Daniel,
> 
> On Wed, Feb 19, 2020 at 12:10:18PM +0100, Geert Uytterhoeven wrote:
> > On Wed, Feb 19, 2020 at 11:57 AM Daniel Vetter wrote:
> > > On Wed, Feb 19, 2020 at 11:30 AM Geert Uytterhoeven wrote:
> > > > On Wed, Feb 19, 2020 at 11:22 AM Daniel Vetter wrote:
> > > > > It's right above the drm_dev_put().
> > > > >
> > > > > Aside: Another driver with a bit much devm_kzalloc, which should
> > > > > probably use drmm_kzalloc instead ...
> > > >
> > > > What's drmm_kzalloc()?
> > > > The only references I can find are in this patch series.
> > >
> > > Yup, it's all new. Read cover letter for reading instructions for the
> > > entire patch series. I'm afraid the driver patches wont make much
> > > sense without the context. None actually :-/
> > 
> > IC, as the cover letter was sent only to dri-devel and intel-gfx, many
> > recipients of the patches won't have received it...
> > https://lore.kernel.org/dri-devel/20200219102122.1607365-1-daniel.vetter@ffwll.ch/
> 
> I was also going to mention that it would be nice to send the cover
> letter to all recipients from the series, otherwise it's a bit painful.
> Daniel, is this something that could be integrated in your workflow ?

No, the usual result of that if you do it is that mail servers scream at
you for too many recipients.

dri-devel is on lore.kernel.org now, with full historical backlog, so all
there.

https://lore.kernel.org/dri-devel/20200219102122.1607365-1-daniel.vetter@ffwll.ch/T/#t

Cheers, Daniel
-- 
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] 310+ messages in thread

* Re: [Intel-gfx] [PATCH 37/52] drm/rcar-du: Drop explicit drm_mode_config_cleanup call
@ 2020-02-19 12:40             ` Daniel Vetter
  0 siblings, 0 replies; 310+ messages in thread
From: Daniel Vetter @ 2020-02-19 12:40 UTC (permalink / raw)
  To: Laurent Pinchart
  Cc: Daniel Vetter, Intel Graphics Development, DRI Development,
	Linux-Renesas, Kieran Bingham, Geert Uytterhoeven, Daniel Vetter

On Wed, Feb 19, 2020 at 02:17:27PM +0200, Laurent Pinchart wrote:
> Hi Daniel,
> 
> On Wed, Feb 19, 2020 at 12:10:18PM +0100, Geert Uytterhoeven wrote:
> > On Wed, Feb 19, 2020 at 11:57 AM Daniel Vetter wrote:
> > > On Wed, Feb 19, 2020 at 11:30 AM Geert Uytterhoeven wrote:
> > > > On Wed, Feb 19, 2020 at 11:22 AM Daniel Vetter wrote:
> > > > > It's right above the drm_dev_put().
> > > > >
> > > > > Aside: Another driver with a bit much devm_kzalloc, which should
> > > > > probably use drmm_kzalloc instead ...
> > > >
> > > > What's drmm_kzalloc()?
> > > > The only references I can find are in this patch series.
> > >
> > > Yup, it's all new. Read cover letter for reading instructions for the
> > > entire patch series. I'm afraid the driver patches wont make much
> > > sense without the context. None actually :-/
> > 
> > IC, as the cover letter was sent only to dri-devel and intel-gfx, many
> > recipients of the patches won't have received it...
> > https://lore.kernel.org/dri-devel/20200219102122.1607365-1-daniel.vetter@ffwll.ch/
> 
> I was also going to mention that it would be nice to send the cover
> letter to all recipients from the series, otherwise it's a bit painful.
> Daniel, is this something that could be integrated in your workflow ?

No, the usual result of that if you do it is that mail servers scream at
you for too many recipients.

dri-devel is on lore.kernel.org now, with full historical backlog, so all
there.

https://lore.kernel.org/dri-devel/20200219102122.1607365-1-daniel.vetter@ffwll.ch/T/#t

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

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

* Re: [PATCH 05/52] drm/mipi_dbi: Use drmm_add_final_kfree in all drivers
  2020-02-19 11:47     ` [Intel-gfx] " Thomas Zimmermann
@ 2020-02-19 12:45       ` Thomas Zimmermann
  -1 siblings, 0 replies; 310+ messages in thread
From: Thomas Zimmermann @ 2020-02-19 12:45 UTC (permalink / raw)
  To: Daniel Vetter, DRI Development
  Cc: David Lechner, David Airlie, Intel Graphics Development,
	Daniel Vetter, Kamlesh Gurudasani, Sam Ravnborg


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



Am 19.02.20 um 12:47 schrieb Thomas Zimmermann:
> Hi Daniel,
> 
> good idea. I guess it's the simple encoder's fault. :) I only read
> briefly over the whole thing.
> 
> Am 19.02.20 um 11:20 schrieb Daniel Vetter:
>> 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).
>>
>> 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);
> 
> I'd prefer something else than drmm_add_final_kfree().
> 
> From what I understand, drmmadd_add_final_kfree() is required so that
> the device instance itself gets free. But wiring up garbage collection
> manually is easy to forget and a somewhat odd design. If we have to do
> that, there's little benefit over calling kfree in the release callback.
> 
> Instead, could drivers rather be converted to drm_dev_alloc() where
> possible?
> 
> For the other cases, could there be a dedicated allocator function that
> invokes drmm_add_final_kfree()? Like that
> 
>   void*
>   __drmm_kzalloc_dev(size_t size, size_t dev_off)
>   {
>       void *parent = kzalloc(size)
> 
>       drm_device *dev = (parent + dev_off)
> 
>       __drmm_add_final_kfree(dev, parent);
> 
>       return parent;
>   }
> 
>   /*
>    * takes the name of driver's device structure and the
>    * name of the drm device structure embedded within
>    */
>   drmm_kzalloc(parent_type, base)
>     (parent_type*)__drm_kzalloc_dev(sizeof(parent_type),
> 			offsetof(parent_type, base));

This is supposed to be a #define statement

> 
> Best regards
> Thomas
> 
>>  
>>  	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);
>>  
>>
> 
> 
> _______________________________________________
> 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] 310+ messages in thread

* Re: [Intel-gfx] [PATCH 05/52] drm/mipi_dbi: Use drmm_add_final_kfree in all drivers
@ 2020-02-19 12:45       ` Thomas Zimmermann
  0 siblings, 0 replies; 310+ messages in thread
From: Thomas Zimmermann @ 2020-02-19 12:45 UTC (permalink / raw)
  To: Daniel Vetter, DRI Development
  Cc: David Lechner, David Airlie, Intel Graphics Development,
	Daniel Vetter, Kamlesh Gurudasani, Sam Ravnborg


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



Am 19.02.20 um 12:47 schrieb Thomas Zimmermann:
> Hi Daniel,
> 
> good idea. I guess it's the simple encoder's fault. :) I only read
> briefly over the whole thing.
> 
> Am 19.02.20 um 11:20 schrieb Daniel Vetter:
>> 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).
>>
>> 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);
> 
> I'd prefer something else than drmm_add_final_kfree().
> 
> From what I understand, drmmadd_add_final_kfree() is required so that
> the device instance itself gets free. But wiring up garbage collection
> manually is easy to forget and a somewhat odd design. If we have to do
> that, there's little benefit over calling kfree in the release callback.
> 
> Instead, could drivers rather be converted to drm_dev_alloc() where
> possible?
> 
> For the other cases, could there be a dedicated allocator function that
> invokes drmm_add_final_kfree()? Like that
> 
>   void*
>   __drmm_kzalloc_dev(size_t size, size_t dev_off)
>   {
>       void *parent = kzalloc(size)
> 
>       drm_device *dev = (parent + dev_off)
> 
>       __drmm_add_final_kfree(dev, parent);
> 
>       return parent;
>   }
> 
>   /*
>    * takes the name of driver's device structure and the
>    * name of the drm device structure embedded within
>    */
>   drmm_kzalloc(parent_type, base)
>     (parent_type*)__drm_kzalloc_dev(sizeof(parent_type),
> 			offsetof(parent_type, base));

This is supposed to be a #define statement

> 
> Best regards
> Thomas
> 
>>  
>>  	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);
>>  
>>
> 
> 
> _______________________________________________
> 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 --]

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH 05/52] drm/mipi_dbi: Use drmm_add_final_kfree in all drivers
  2020-02-19 11:47     ` [Intel-gfx] " Thomas Zimmermann
@ 2020-02-19 13:23       ` Daniel Vetter
  -1 siblings, 0 replies; 310+ messages in thread
From: Daniel Vetter @ 2020-02-19 13:23 UTC (permalink / raw)
  To: Thomas Zimmermann
  Cc: David Lechner, David Airlie, Intel Graphics Development,
	DRI Development, Daniel Vetter, Kamlesh Gurudasani, Sam Ravnborg

On Wed, Feb 19, 2020 at 12:47 PM Thomas Zimmermann <tzimmermann@suse.de> wrote:
>
> Hi Daniel,
>
> good idea. I guess it's the simple encoder's fault. :) I only read
> briefly over the whole thing.
>
> Am 19.02.20 um 11:20 schrieb Daniel Vetter:
> > 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).
> >
> > 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);
>
> I'd prefer something else than drmm_add_final_kfree().
>
> From what I understand, drmmadd_add_final_kfree() is required so that
> the device instance itself gets free. But wiring up garbage collection
> manually is easy to forget and a somewhat odd design. If we have to do
> that, there's little benefit over calling kfree in the release callback.
>
> Instead, could drivers rather be converted to drm_dev_alloc() where
> possible?

Uh, we want to get away from drm_dev_alloc because that doesn't allow
embedding of struct drm_device.

> For the other cases, could there be a dedicated allocator function that
> invokes drmm_add_final_kfree()? Like that
>
>   void*
>   __drmm_kzalloc_dev(size_t size, size_t dev_off)
>   {
>       void *parent = kzalloc(size)
>
>       drm_device *dev = (parent + dev_off)
>
>       __drmm_add_final_kfree(dev, parent);
>
>       return parent;
>   }
>
>   /*
>    * takes the name of driver's device structure and the
>    * name of the drm device structure embedded within
>    */
>   drmm_kzalloc(parent_type, base)
>     (parent_type*)__drm_kzalloc_dev(sizeof(parent_type),
>                         offsetof(parent_type, base));

drmm_kzalloc exists and works, and is used plenty in this series. The
trouble is you can only use it once the drm_device is initialized, so
there's a chicken/egg problem.

But your idea is sound, and I already proposed it in the todo list of
the final patch as devm_drm_dev_alloc. It's just at 50+ patches,
there's a limit of what's reasonable to do in the first round.

I think if you read the entire thing (skipping the driver patches you
don't care about) it will make a lot more sense what's going on.

Cheers, Daniel

>
> Best regards
> Thomas
>
> >
> >       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);
> >
> >
>
> --
> 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] 310+ messages in thread

* Re: [Intel-gfx] [PATCH 05/52] drm/mipi_dbi: Use drmm_add_final_kfree in all drivers
@ 2020-02-19 13:23       ` Daniel Vetter
  0 siblings, 0 replies; 310+ messages in thread
From: Daniel Vetter @ 2020-02-19 13:23 UTC (permalink / raw)
  To: Thomas Zimmermann
  Cc: David Lechner, David Airlie, Intel Graphics Development,
	Maxime Ripard, Eric Anholt, Noralf Trønnes, DRI Development,
	Daniel Vetter, Kamlesh Gurudasani, Sam Ravnborg

On Wed, Feb 19, 2020 at 12:47 PM Thomas Zimmermann <tzimmermann@suse.de> wrote:
>
> Hi Daniel,
>
> good idea. I guess it's the simple encoder's fault. :) I only read
> briefly over the whole thing.
>
> Am 19.02.20 um 11:20 schrieb Daniel Vetter:
> > 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).
> >
> > 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);
>
> I'd prefer something else than drmm_add_final_kfree().
>
> From what I understand, drmmadd_add_final_kfree() is required so that
> the device instance itself gets free. But wiring up garbage collection
> manually is easy to forget and a somewhat odd design. If we have to do
> that, there's little benefit over calling kfree in the release callback.
>
> Instead, could drivers rather be converted to drm_dev_alloc() where
> possible?

Uh, we want to get away from drm_dev_alloc because that doesn't allow
embedding of struct drm_device.

> For the other cases, could there be a dedicated allocator function that
> invokes drmm_add_final_kfree()? Like that
>
>   void*
>   __drmm_kzalloc_dev(size_t size, size_t dev_off)
>   {
>       void *parent = kzalloc(size)
>
>       drm_device *dev = (parent + dev_off)
>
>       __drmm_add_final_kfree(dev, parent);
>
>       return parent;
>   }
>
>   /*
>    * takes the name of driver's device structure and the
>    * name of the drm device structure embedded within
>    */
>   drmm_kzalloc(parent_type, base)
>     (parent_type*)__drm_kzalloc_dev(sizeof(parent_type),
>                         offsetof(parent_type, base));

drmm_kzalloc exists and works, and is used plenty in this series. The
trouble is you can only use it once the drm_device is initialized, so
there's a chicken/egg problem.

But your idea is sound, and I already proposed it in the todo list of
the final patch as devm_drm_dev_alloc. It's just at 50+ patches,
there's a limit of what's reasonable to do in the first round.

I think if you read the entire thing (skipping the driver patches you
don't care about) it will make a lot more sense what's going on.

Cheers, Daniel

>
> Best regards
> Thomas
>
> >
> >       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);
> >
> >
>
> --
> 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
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH 03/52] drm: add managed resources tied to drm_device
  2020-02-19 12:31     ` [Intel-gfx] " Neil Armstrong
@ 2020-02-19 13:24       ` Daniel Vetter
  -1 siblings, 0 replies; 310+ messages in thread
From: Daniel Vetter @ 2020-02-19 13:24 UTC (permalink / raw)
  To: Neil Armstrong
  Cc: Daniel Vetter, Intel Graphics Development, Greg Kroah-Hartman,
	DRI Development, Rafael J. Wysocki

On Wed, Feb 19, 2020 at 1:31 PM Neil Armstrong <narmstrong@baylibre.com> wrote:
>
> Hi,
>
> On 19/02/2020 11:20, Daniel Vetter wrote:
> > 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.
> >
> > 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           |  13 ++-
> >  drivers/gpu/drm/drm_internal.h      |   3 +
> >  drivers/gpu/drm/drm_managed.c       | 173 ++++++++++++++++++++++++++++
> >  include/drm/drm_device.h            |  12 ++
> >  include/drm/drm_managed.h           |  25 ++++
> >  include/drm/drm_print.h             |   6 +
> >  8 files changed, 239 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 ca0ca775d37f..53d8fa170143 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..3e5627d6eba6 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,16 @@ static void drm_dev_release(struct kref *ref)
> >               dev->driver->release(dev);
> >       } else {
> >               drm_dev_fini(dev);
> > -             kfree(dev);
> > +             if (!dev->managed.final_kfree) {
> > +                     WARN_ON(!list_empty(&dev->managed.resources));
> > +                     kfree(dev);
> > +             }
> >       }
> > +
> > +     drm_managed_release(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..ee7c7253af61
> > --- /dev/null
> > +++ b/drivers/gpu/drm/drm_managed.c
> > @@ -0,0 +1,173 @@
> > +// 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 sturct &device managed resources, but tied to the lifetime of
>
> --------------------/\ struct

I fixed this, but accidentally squashed the fix in the wrong patch.
Will shuffle.

>
> > + * 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 (%lu bytes)\n",
> > +                            dr, dr->node.name, (unsigned long) dr->node.size);
> > +
> > +             if (dr->node.release)
> > +                     dr->node.release(dev, dr->node.size ? dr->data : NULL);
> > +
> > +             list_del(&dr->node.entry);
> > +             kfree(dr);
> > +     }
> > +     drm_dbg_drmres(dev, "drmres release end\n");
> > +}
> > +
> > +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;
> > +}
> > +
> > +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);
> > +}
> > +
> > +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);
> > +}
>
> Maybe del_dr/add_dr as static ?

Very much, thanks for cachting.

Cheers, Daniel

>
> > +
> > +void drmm_add_final_kfree(struct drm_device *dev, void *parent)
> > +{
> > +     WARN_ON(dev->managed.final_kfree);
> > +     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)
> > +             return -ENOMEM;
> > +     dr->node.name = name;
> > +     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)
> > +             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 = 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->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_kfree);
> > diff --git a/include/drm/drm_device.h b/include/drm/drm_device.h
> > index bb60a949f416..2790c9ed614e 100644
> > --- a/include/drm/drm_device.h
> > +++ b/include/drm/drm_device.h
> > @@ -67,6 +67,18 @@ 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 {
> > +             struct list_head resources;
> > +             void *final_kfree;
> > +             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..75f2c8932c69
> > --- /dev/null
> > +++ b/include/drm/drm_managed.h
> > @@ -0,0 +1,25 @@
> > +// SPDX-License-Identifier: GPL-2.0
> > +
> > +#include <linux/types.h>
> > +#include <linux/gfp.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);
> > 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__)
> >
> >
> >  /*
> >
>
> Neil



-- 
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] 310+ messages in thread

* Re: [Intel-gfx] [PATCH 03/52] drm: add managed resources tied to drm_device
@ 2020-02-19 13:24       ` Daniel Vetter
  0 siblings, 0 replies; 310+ messages in thread
From: Daniel Vetter @ 2020-02-19 13:24 UTC (permalink / raw)
  To: Neil Armstrong
  Cc: Daniel Vetter, Intel Graphics Development, Greg Kroah-Hartman,
	DRI Development, Rafael J. Wysocki

On Wed, Feb 19, 2020 at 1:31 PM Neil Armstrong <narmstrong@baylibre.com> wrote:
>
> Hi,
>
> On 19/02/2020 11:20, Daniel Vetter wrote:
> > 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.
> >
> > 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           |  13 ++-
> >  drivers/gpu/drm/drm_internal.h      |   3 +
> >  drivers/gpu/drm/drm_managed.c       | 173 ++++++++++++++++++++++++++++
> >  include/drm/drm_device.h            |  12 ++
> >  include/drm/drm_managed.h           |  25 ++++
> >  include/drm/drm_print.h             |   6 +
> >  8 files changed, 239 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 ca0ca775d37f..53d8fa170143 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..3e5627d6eba6 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,16 @@ static void drm_dev_release(struct kref *ref)
> >               dev->driver->release(dev);
> >       } else {
> >               drm_dev_fini(dev);
> > -             kfree(dev);
> > +             if (!dev->managed.final_kfree) {
> > +                     WARN_ON(!list_empty(&dev->managed.resources));
> > +                     kfree(dev);
> > +             }
> >       }
> > +
> > +     drm_managed_release(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..ee7c7253af61
> > --- /dev/null
> > +++ b/drivers/gpu/drm/drm_managed.c
> > @@ -0,0 +1,173 @@
> > +// 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 sturct &device managed resources, but tied to the lifetime of
>
> --------------------/\ struct

I fixed this, but accidentally squashed the fix in the wrong patch.
Will shuffle.

>
> > + * 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 (%lu bytes)\n",
> > +                            dr, dr->node.name, (unsigned long) dr->node.size);
> > +
> > +             if (dr->node.release)
> > +                     dr->node.release(dev, dr->node.size ? dr->data : NULL);
> > +
> > +             list_del(&dr->node.entry);
> > +             kfree(dr);
> > +     }
> > +     drm_dbg_drmres(dev, "drmres release end\n");
> > +}
> > +
> > +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;
> > +}
> > +
> > +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);
> > +}
> > +
> > +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);
> > +}
>
> Maybe del_dr/add_dr as static ?

Very much, thanks for cachting.

Cheers, Daniel

>
> > +
> > +void drmm_add_final_kfree(struct drm_device *dev, void *parent)
> > +{
> > +     WARN_ON(dev->managed.final_kfree);
> > +     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)
> > +             return -ENOMEM;
> > +     dr->node.name = name;
> > +     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)
> > +             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 = 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->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_kfree);
> > diff --git a/include/drm/drm_device.h b/include/drm/drm_device.h
> > index bb60a949f416..2790c9ed614e 100644
> > --- a/include/drm/drm_device.h
> > +++ b/include/drm/drm_device.h
> > @@ -67,6 +67,18 @@ 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 {
> > +             struct list_head resources;
> > +             void *final_kfree;
> > +             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..75f2c8932c69
> > --- /dev/null
> > +++ b/include/drm/drm_managed.h
> > @@ -0,0 +1,25 @@
> > +// SPDX-License-Identifier: GPL-2.0
> > +
> > +#include <linux/types.h>
> > +#include <linux/gfp.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);
> > 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__)
> >
> >
> >  /*
> >
>
> Neil



-- 
Daniel Vetter
Software Engineer, Intel Corporation
+41 (0) 79 365 57 48 - http://blog.ffwll.ch
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH 03/52] drm: add managed resources tied to drm_device
  2020-02-19 10:20   ` [Intel-gfx] " Daniel Vetter
@ 2020-02-19 13:28     ` Laurent Pinchart
  -1 siblings, 0 replies; 310+ messages in thread
From: Laurent Pinchart @ 2020-02-19 13:28 UTC (permalink / raw)
  To: Daniel Vetter
  Cc: Daniel Vetter, Intel Graphics Development, Greg Kroah-Hartman,
	DRI Development, Rafael J. Wysocki

Hi Daniel,

Thank you for the patch.

On Wed, Feb 19, 2020 at 11:20:33AM +0100, Daniel Vetter wrote:
> 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.

This is all a very good idea ! Many subsystems are plagged by drivers
using devm_k*alloc to allocate data accessible by userspace. Since the
introduction of devm_*, we've likely reduced the number of memory leaks,
but I'm pretty sure we've increased the risk of crashes as I've seen
some drivers that used .release() callbacks correctly being naively
converted to incorrect devm_* usage :-(

This leads me to a question: if other subsystems have the same problem,
could we turn this implementation into something more generic ? It
doesn't have to be done right away and shouldn't block merging this
series, but I think it would be very useful.

> v2: Do all the kerneldoc at the end, to avoid lots of fairly pointless
> shuffling while getting everything into shape.
> 
> 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           |  13 ++-
>  drivers/gpu/drm/drm_internal.h      |   3 +
>  drivers/gpu/drm/drm_managed.c       | 173 ++++++++++++++++++++++++++++
>  include/drm/drm_device.h            |  12 ++
>  include/drm/drm_managed.h           |  25 ++++
>  include/drm/drm_print.h             |   6 +
>  8 files changed, 239 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 ca0ca775d37f..53d8fa170143 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..3e5627d6eba6 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,16 @@ static void drm_dev_release(struct kref *ref)
>  		dev->driver->release(dev);
>  	} else {
>  		drm_dev_fini(dev);
> -		kfree(dev);
> +		if (!dev->managed.final_kfree) {
> +			WARN_ON(!list_empty(&dev->managed.resources));
> +			kfree(dev);
> +		}
>  	}
> +
> +	drm_managed_release(dev);
> +
> +	if (dev->managed.final_kfree)
> +		kfree(dev->managed.final_kfree);

Should we do this even if the driver implements .release() ? The
callback may free dev.

>  }
>  
>  /**
> 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..ee7c7253af61
> --- /dev/null
> +++ b/drivers/gpu/drm/drm_managed.c
> @@ -0,0 +1,173 @@
> +// 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 sturct &device managed resources, but tied to the lifetime of

s/sturct/struct/

> + * 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().
> +	 */

Do we want to make this API usable for DMA ?

> +	u8 __aligned(ARCH_KMALLOC_MINALIGN) data[];
> +};
> +
> +void drm_managed_release(struct drm_device *dev)
> +{
> +

Extra blank line.

> +	struct drmres *dr, *tmp;

I'm sure a better name than tmp can be found. res, resource or node ?

> +
> +	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 (%lu bytes)\n",
> +			       dr, dr->node.name, (unsigned long) dr->node.size);

No need to cast to unsigned long, you can replace %lu with %zu instead.

> +
> +		if (dr->node.release)
> +			dr->node.release(dev, dr->node.size ? dr->data : NULL);

Shouldn't this be

			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");
> +}
> +
> +static __always_inline struct drmres * alloc_dr(drmres_release_t release,
> +						size_t size, gfp_t gfp, int nid)

Why always inline ?

Let's give the function a better name, even if it's internal. alloc_dr
sounds like it could conflict, and it's also not very clear in a
backtrace that it's DRM-specific. drmm_alloc_resource ?

> +{
> +	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;
> +}
> +
> +void del_dr(struct drm_device *dev, struct drmres *dr)

And drmm_del_resource ?

> +{
> +	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);
> +}
> +
> +void add_dr(struct drm_device *dev, struct drmres *dr)

And drmm_add_resource ?

> +{
> +	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);
> +	dev->managed.final_kfree = parent;
> +}
> +EXPORT_SYMBOL(drmm_add_final_kfree);

As you mentioned this is quite a bit of a hack, but I think we can live
with it for now.

> +
> +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)
> +		return -ENOMEM;
> +	dr->node.name = name;
> +	void_ptr = (void **) dr->data;

I'd write (void **)&dr->data; to make it clear that you're taking the
address of the data array. Arrays decay to pointers in C, so it's
equivalent, but with & I had to realize data was an array before
figuring out what the code was doing.

> +	*void_ptr = data;

I may be mistaken, but if data == NULL, you pass 0 as the size to
alloc_dr, and dr will have an empty data array. Aren't you then
overflowing your allocation ?

> +
> +	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)
> +		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 = NULL, *tmp;

res, resource or node here too ?

> +	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->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_kfree);
> diff --git a/include/drm/drm_device.h b/include/drm/drm_device.h
> index bb60a949f416..2790c9ed614e 100644
> --- a/include/drm/drm_device.h
> +++ b/include/drm/drm_device.h
> @@ -67,6 +67,18 @@ 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 {
> +		struct list_head resources;
> +		void *final_kfree;
> +		spinlock_t lock;

Would it be a good time to #include <linux/spinlock.h> at the top ?

> +	} 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..75f2c8932c69
> --- /dev/null
> +++ b/include/drm/drm_managed.h
> @@ -0,0 +1,25 @@
> +// SPDX-License-Identifier: GPL-2.0

No header guard ?

> +
> +#include <linux/types.h>
> +#include <linux/gfp.h>

Alphabetically sorted ?

> +
> +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);
> 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__)
>  
>  
>  /*

-- 
Regards,

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

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

* Re: [Intel-gfx] [PATCH 03/52] drm: add managed resources tied to drm_device
@ 2020-02-19 13:28     ` Laurent Pinchart
  0 siblings, 0 replies; 310+ messages in thread
From: Laurent Pinchart @ 2020-02-19 13:28 UTC (permalink / raw)
  To: Daniel Vetter
  Cc: Daniel Vetter, Intel Graphics Development, Greg Kroah-Hartman,
	DRI Development, Rafael J. Wysocki

Hi Daniel,

Thank you for the patch.

On Wed, Feb 19, 2020 at 11:20:33AM +0100, Daniel Vetter wrote:
> 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.

This is all a very good idea ! Many subsystems are plagged by drivers
using devm_k*alloc to allocate data accessible by userspace. Since the
introduction of devm_*, we've likely reduced the number of memory leaks,
but I'm pretty sure we've increased the risk of crashes as I've seen
some drivers that used .release() callbacks correctly being naively
converted to incorrect devm_* usage :-(

This leads me to a question: if other subsystems have the same problem,
could we turn this implementation into something more generic ? It
doesn't have to be done right away and shouldn't block merging this
series, but I think it would be very useful.

> v2: Do all the kerneldoc at the end, to avoid lots of fairly pointless
> shuffling while getting everything into shape.
> 
> 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           |  13 ++-
>  drivers/gpu/drm/drm_internal.h      |   3 +
>  drivers/gpu/drm/drm_managed.c       | 173 ++++++++++++++++++++++++++++
>  include/drm/drm_device.h            |  12 ++
>  include/drm/drm_managed.h           |  25 ++++
>  include/drm/drm_print.h             |   6 +
>  8 files changed, 239 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 ca0ca775d37f..53d8fa170143 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..3e5627d6eba6 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,16 @@ static void drm_dev_release(struct kref *ref)
>  		dev->driver->release(dev);
>  	} else {
>  		drm_dev_fini(dev);
> -		kfree(dev);
> +		if (!dev->managed.final_kfree) {
> +			WARN_ON(!list_empty(&dev->managed.resources));
> +			kfree(dev);
> +		}
>  	}
> +
> +	drm_managed_release(dev);
> +
> +	if (dev->managed.final_kfree)
> +		kfree(dev->managed.final_kfree);

Should we do this even if the driver implements .release() ? The
callback may free dev.

>  }
>  
>  /**
> 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..ee7c7253af61
> --- /dev/null
> +++ b/drivers/gpu/drm/drm_managed.c
> @@ -0,0 +1,173 @@
> +// 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 sturct &device managed resources, but tied to the lifetime of

s/sturct/struct/

> + * 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().
> +	 */

Do we want to make this API usable for DMA ?

> +	u8 __aligned(ARCH_KMALLOC_MINALIGN) data[];
> +};
> +
> +void drm_managed_release(struct drm_device *dev)
> +{
> +

Extra blank line.

> +	struct drmres *dr, *tmp;

I'm sure a better name than tmp can be found. res, resource or node ?

> +
> +	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 (%lu bytes)\n",
> +			       dr, dr->node.name, (unsigned long) dr->node.size);

No need to cast to unsigned long, you can replace %lu with %zu instead.

> +
> +		if (dr->node.release)
> +			dr->node.release(dev, dr->node.size ? dr->data : NULL);

Shouldn't this be

			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");
> +}
> +
> +static __always_inline struct drmres * alloc_dr(drmres_release_t release,
> +						size_t size, gfp_t gfp, int nid)

Why always inline ?

Let's give the function a better name, even if it's internal. alloc_dr
sounds like it could conflict, and it's also not very clear in a
backtrace that it's DRM-specific. drmm_alloc_resource ?

> +{
> +	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;
> +}
> +
> +void del_dr(struct drm_device *dev, struct drmres *dr)

And drmm_del_resource ?

> +{
> +	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);
> +}
> +
> +void add_dr(struct drm_device *dev, struct drmres *dr)

And drmm_add_resource ?

> +{
> +	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);
> +	dev->managed.final_kfree = parent;
> +}
> +EXPORT_SYMBOL(drmm_add_final_kfree);

As you mentioned this is quite a bit of a hack, but I think we can live
with it for now.

> +
> +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)
> +		return -ENOMEM;
> +	dr->node.name = name;
> +	void_ptr = (void **) dr->data;

I'd write (void **)&dr->data; to make it clear that you're taking the
address of the data array. Arrays decay to pointers in C, so it's
equivalent, but with & I had to realize data was an array before
figuring out what the code was doing.

> +	*void_ptr = data;

I may be mistaken, but if data == NULL, you pass 0 as the size to
alloc_dr, and dr will have an empty data array. Aren't you then
overflowing your allocation ?

> +
> +	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)
> +		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 = NULL, *tmp;

res, resource or node here too ?

> +	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->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_kfree);
> diff --git a/include/drm/drm_device.h b/include/drm/drm_device.h
> index bb60a949f416..2790c9ed614e 100644
> --- a/include/drm/drm_device.h
> +++ b/include/drm/drm_device.h
> @@ -67,6 +67,18 @@ 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 {
> +		struct list_head resources;
> +		void *final_kfree;
> +		spinlock_t lock;

Would it be a good time to #include <linux/spinlock.h> at the top ?

> +	} 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..75f2c8932c69
> --- /dev/null
> +++ b/include/drm/drm_managed.h
> @@ -0,0 +1,25 @@
> +// SPDX-License-Identifier: GPL-2.0

No header guard ?

> +
> +#include <linux/types.h>
> +#include <linux/gfp.h>

Alphabetically sorted ?

> +
> +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);
> 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__)
>  
>  
>  /*

-- 
Regards,

Laurent Pinchart
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH 05/52] drm/mipi_dbi: Use drmm_add_final_kfree in all drivers
  2020-02-19 13:23       ` [Intel-gfx] " Daniel Vetter
@ 2020-02-19 13:29         ` Thomas Zimmermann
  -1 siblings, 0 replies; 310+ messages in thread
From: Thomas Zimmermann @ 2020-02-19 13:29 UTC (permalink / raw)
  To: Daniel Vetter
  Cc: David Lechner, David Airlie, Intel Graphics Development,
	DRI Development, Daniel Vetter, Kamlesh Gurudasani, Sam Ravnborg


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

Hi

Am 19.02.20 um 14:23 schrieb Daniel Vetter:
> On Wed, Feb 19, 2020 at 12:47 PM Thomas Zimmermann <tzimmermann@suse.de> wrote:
>>
>> Hi Daniel,
>>
>> good idea. I guess it's the simple encoder's fault. :) I only read
>> briefly over the whole thing.
>>
>> Am 19.02.20 um 11:20 schrieb Daniel Vetter:
>>> 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).
>>>
>>> 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);
>>
>> I'd prefer something else than drmm_add_final_kfree().
>>
>> From what I understand, drmmadd_add_final_kfree() is required so that
>> the device instance itself gets free. But wiring up garbage collection
>> manually is easy to forget and a somewhat odd design. If we have to do
>> that, there's little benefit over calling kfree in the release callback.
>>
>> Instead, could drivers rather be converted to drm_dev_alloc() where
>> possible?
> 
> Uh, we want to get away from drm_dev_alloc because that doesn't allow
> embedding of struct drm_device.
> 
>> For the other cases, could there be a dedicated allocator function that
>> invokes drmm_add_final_kfree()? Like that
>>
>>   void*
>>   __drmm_kzalloc_dev(size_t size, size_t dev_off)
>>   {
>>       void *parent = kzalloc(size)
>>
>>       drm_device *dev = (parent + dev_off)
>>
>>       __drmm_add_final_kfree(dev, parent);
>>
>>       return parent;
>>   }
>>
>>   /*
>>    * takes the name of driver's device structure and the
>>    * name of the drm device structure embedded within
>>    */
>>   drmm_kzalloc(parent_type, base)
>>     (parent_type*)__drm_kzalloc_dev(sizeof(parent_type),
>>                         offsetof(parent_type, base));
> 
> drmm_kzalloc exists and works, and is used plenty in this series. The
> trouble is you can only use it once the drm_device is initialized, so
> there's a chicken/egg problem.

That line of the example was a total mess. Sorry. It actually was
supposed to look something like this.

   /*
    * takes the name of driver's device structure and the
    * name of the drm device structure embedded within
    */
   #define drmm_kzalloc_dev(parent_type, base) \
     (parent_type*)__drm_kzalloc_dev(sizeof(parent_type),
                         offsetof(parent_type, base));

__drm_kzalloc_dev() is the allocator function for device instances and
drm_kzalloc_dev() is a macro that makes it convenient.

Best regards
Thomas

> 
> But your idea is sound, and I already proposed it in the todo list of
> the final patch as devm_drm_dev_alloc. It's just at 50+ patches,
> there's a limit of what's reasonable to do in the first round.
> 
> I think if you read the entire thing (skipping the driver patches you
> don't care about) it will make a lot more sense what's going on.
> 
> Cheers, Daniel
> 
>>
>> Best regards
>> Thomas
>>
>>>
>>>       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);
>>>
>>>
>>
>> --
>> 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] 310+ messages in thread

* Re: [Intel-gfx] [PATCH 05/52] drm/mipi_dbi: Use drmm_add_final_kfree in all drivers
@ 2020-02-19 13:29         ` Thomas Zimmermann
  0 siblings, 0 replies; 310+ messages in thread
From: Thomas Zimmermann @ 2020-02-19 13:29 UTC (permalink / raw)
  To: Daniel Vetter
  Cc: David Lechner, David Airlie, Intel Graphics Development,
	DRI Development, Daniel Vetter, Kamlesh Gurudasani, Sam Ravnborg


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

Hi

Am 19.02.20 um 14:23 schrieb Daniel Vetter:
> On Wed, Feb 19, 2020 at 12:47 PM Thomas Zimmermann <tzimmermann@suse.de> wrote:
>>
>> Hi Daniel,
>>
>> good idea. I guess it's the simple encoder's fault. :) I only read
>> briefly over the whole thing.
>>
>> Am 19.02.20 um 11:20 schrieb Daniel Vetter:
>>> 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).
>>>
>>> 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);
>>
>> I'd prefer something else than drmm_add_final_kfree().
>>
>> From what I understand, drmmadd_add_final_kfree() is required so that
>> the device instance itself gets free. But wiring up garbage collection
>> manually is easy to forget and a somewhat odd design. If we have to do
>> that, there's little benefit over calling kfree in the release callback.
>>
>> Instead, could drivers rather be converted to drm_dev_alloc() where
>> possible?
> 
> Uh, we want to get away from drm_dev_alloc because that doesn't allow
> embedding of struct drm_device.
> 
>> For the other cases, could there be a dedicated allocator function that
>> invokes drmm_add_final_kfree()? Like that
>>
>>   void*
>>   __drmm_kzalloc_dev(size_t size, size_t dev_off)
>>   {
>>       void *parent = kzalloc(size)
>>
>>       drm_device *dev = (parent + dev_off)
>>
>>       __drmm_add_final_kfree(dev, parent);
>>
>>       return parent;
>>   }
>>
>>   /*
>>    * takes the name of driver's device structure and the
>>    * name of the drm device structure embedded within
>>    */
>>   drmm_kzalloc(parent_type, base)
>>     (parent_type*)__drm_kzalloc_dev(sizeof(parent_type),
>>                         offsetof(parent_type, base));
> 
> drmm_kzalloc exists and works, and is used plenty in this series. The
> trouble is you can only use it once the drm_device is initialized, so
> there's a chicken/egg problem.

That line of the example was a total mess. Sorry. It actually was
supposed to look something like this.

   /*
    * takes the name of driver's device structure and the
    * name of the drm device structure embedded within
    */
   #define drmm_kzalloc_dev(parent_type, base) \
     (parent_type*)__drm_kzalloc_dev(sizeof(parent_type),
                         offsetof(parent_type, base));

__drm_kzalloc_dev() is the allocator function for device instances and
drm_kzalloc_dev() is a macro that makes it convenient.

Best regards
Thomas

> 
> But your idea is sound, and I already proposed it in the todo list of
> the final patch as devm_drm_dev_alloc. It's just at 50+ patches,
> there's a limit of what's reasonable to do in the first round.
> 
> I think if you read the entire thing (skipping the driver patches you
> don't care about) it will make a lot more sense what's going on.
> 
> Cheers, Daniel
> 
>>
>> Best regards
>> Thomas
>>
>>>
>>>       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);
>>>
>>>
>>
>> --
>> 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 --]

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH 03/52] drm: add managed resources tied to drm_device
  2020-02-19 13:28     ` [Intel-gfx] " Laurent Pinchart
@ 2020-02-19 13:33       ` Greg Kroah-Hartman
  -1 siblings, 0 replies; 310+ messages in thread
From: Greg Kroah-Hartman @ 2020-02-19 13:33 UTC (permalink / raw)
  To: Laurent Pinchart
  Cc: Daniel Vetter, Intel Graphics Development, Rafael J. Wysocki,
	DRI Development, Daniel Vetter

On Wed, Feb 19, 2020 at 03:28:47PM +0200, Laurent Pinchart wrote:
> Hi Daniel,
> 
> Thank you for the patch.
> 
> On Wed, Feb 19, 2020 at 11:20:33AM +0100, Daniel Vetter wrote:
> > 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.
> 
> This is all a very good idea ! Many subsystems are plagged by drivers
> using devm_k*alloc to allocate data accessible by userspace. Since the
> introduction of devm_*, we've likely reduced the number of memory leaks,
> but I'm pretty sure we've increased the risk of crashes as I've seen
> some drivers that used .release() callbacks correctly being naively
> converted to incorrect devm_* usage :-(
> 
> This leads me to a question: if other subsystems have the same problem,
> could we turn this implementation into something more generic ? It
> doesn't have to be done right away and shouldn't block merging this
> series, but I think it would be very useful.

It shouldn't be that hard to tie this into a drv_m() type of a thing
(driver_memory?)

And yes, I think it's much better than devm_* for the obvious reasons of
this being needed here.

thanks,

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

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

* Re: [Intel-gfx] [PATCH 03/52] drm: add managed resources tied to drm_device
@ 2020-02-19 13:33       ` Greg Kroah-Hartman
  0 siblings, 0 replies; 310+ messages in thread
From: Greg Kroah-Hartman @ 2020-02-19 13:33 UTC (permalink / raw)
  To: Laurent Pinchart
  Cc: Daniel Vetter, Intel Graphics Development, Rafael J. Wysocki,
	DRI Development, Daniel Vetter

On Wed, Feb 19, 2020 at 03:28:47PM +0200, Laurent Pinchart wrote:
> Hi Daniel,
> 
> Thank you for the patch.
> 
> On Wed, Feb 19, 2020 at 11:20:33AM +0100, Daniel Vetter wrote:
> > 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.
> 
> This is all a very good idea ! Many subsystems are plagged by drivers
> using devm_k*alloc to allocate data accessible by userspace. Since the
> introduction of devm_*, we've likely reduced the number of memory leaks,
> but I'm pretty sure we've increased the risk of crashes as I've seen
> some drivers that used .release() callbacks correctly being naively
> converted to incorrect devm_* usage :-(
> 
> This leads me to a question: if other subsystems have the same problem,
> could we turn this implementation into something more generic ? It
> doesn't have to be done right away and shouldn't block merging this
> series, but I think it would be very useful.

It shouldn't be that hard to tie this into a drv_m() type of a thing
(driver_memory?)

And yes, I think it's much better than devm_* for the obvious reasons of
this being needed here.

thanks,

greg k-h
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH 04/52] drm: Set final_kfree in drm_dev_alloc
  2020-02-19 10:20   ` [Intel-gfx] " Daniel Vetter
  (?)
@ 2020-02-19 13:39     ` Laurent Pinchart
  -1 siblings, 0 replies; 310+ messages in thread
From: Laurent Pinchart @ 2020-02-19 13:39 UTC (permalink / raw)
  To: Daniel Vetter
  Cc: Oleksandr Andrushchenko, David Airlie,
	Intel Graphics Development, DRI Development, Gerd Hoffmann,
	Thomas Zimmermann, Daniel Vetter, xen-devel

Hi Daniel,

Thank you for the patch.

On Wed, Feb 19, 2020 at 11:20:34AM +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.

I'd split this patch in two then, with the Xen first coming first, and
with an explanation in the commit message of the second patch about why
you call drmm_add_final_kfree() in drm_dev_alloc().

> 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
> 
> 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 3e5627d6eba6..9e62e28bbc62 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);

drmm_add_final_kfree() can only be called once. Does this mean that a
driver using drm_dev_alloc() isn't allowed to use drmm_add_final_kfree()
to tract its own private structure ?

> +
>  	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;

-- 
Regards,

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

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

* Re: [Intel-gfx] [PATCH 04/52] drm: Set final_kfree in drm_dev_alloc
@ 2020-02-19 13:39     ` Laurent Pinchart
  0 siblings, 0 replies; 310+ messages in thread
From: Laurent Pinchart @ 2020-02-19 13:39 UTC (permalink / raw)
  To: Daniel Vetter
  Cc: Oleksandr Andrushchenko, David Airlie,
	Intel Graphics Development, DRI Development, Gerd Hoffmann,
	Thomas Zimmermann, Daniel Vetter, xen-devel

Hi Daniel,

Thank you for the patch.

On Wed, Feb 19, 2020 at 11:20:34AM +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.

I'd split this patch in two then, with the Xen first coming first, and
with an explanation in the commit message of the second patch about why
you call drmm_add_final_kfree() in drm_dev_alloc().

> 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
> 
> 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 3e5627d6eba6..9e62e28bbc62 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);

drmm_add_final_kfree() can only be called once. Does this mean that a
driver using drm_dev_alloc() isn't allowed to use drmm_add_final_kfree()
to tract its own private structure ?

> +
>  	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;

-- 
Regards,

Laurent Pinchart
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [Xen-devel] [PATCH 04/52] drm: Set final_kfree in drm_dev_alloc
@ 2020-02-19 13:39     ` Laurent Pinchart
  0 siblings, 0 replies; 310+ messages in thread
From: Laurent Pinchart @ 2020-02-19 13:39 UTC (permalink / raw)
  To: Daniel Vetter
  Cc: Oleksandr Andrushchenko, David Airlie,
	Intel Graphics Development, DRI Development, Gerd Hoffmann,
	Thomas Zimmermann, Daniel Vetter, xen-devel

Hi Daniel,

Thank you for the patch.

On Wed, Feb 19, 2020 at 11:20:34AM +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.

I'd split this patch in two then, with the Xen first coming first, and
with an explanation in the commit message of the second patch about why
you call drmm_add_final_kfree() in drm_dev_alloc().

> 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
> 
> 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 3e5627d6eba6..9e62e28bbc62 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);

drmm_add_final_kfree() can only be called once. Does this mean that a
driver using drm_dev_alloc() isn't allowed to use drmm_add_final_kfree()
to tract its own private structure ?

> +
>  	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;

-- 
Regards,

Laurent Pinchart

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

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

* Re: [PATCH 07/52] drm/udl: Use drmm_add_final_kfree
  2020-02-19 10:20   ` [Intel-gfx] " Daniel Vetter
@ 2020-02-19 13:42     ` Laurent Pinchart
  -1 siblings, 0 replies; 310+ messages in thread
From: Laurent Pinchart @ 2020-02-19 13:42 UTC (permalink / raw)
  To: Daniel Vetter
  Cc: Sean Paul, Intel Graphics Development, Emil Velikov,
	DRI Development, Thomas Zimmermann, Dave Airlie, Daniel Vetter,
	Thomas Gleixner, Sam Ravnborg

Hi Daniel,

Thank you for the patch.

On Wed, Feb 19, 2020 at 11:20:37AM +0100, Daniel Vetter wrote:
> 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.
> 
> Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>

Did you mean to squash this with the previous commit ?

> 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 | 3 +--
>  1 file changed, 1 insertion(+), 2 deletions(-)
> 
> diff --git a/drivers/gpu/drm/udl/udl_drv.c b/drivers/gpu/drm/udl/udl_drv.c
> index d5b89711ab1e..6a5594946096 100644
> --- a/drivers/gpu/drm/udl/udl_drv.c
> +++ b/drivers/gpu/drm/udl/udl_drv.c
> @@ -81,8 +81,7 @@ static struct udl_device *udl_driver_create(struct usb_interface *interface)
>  
>  	r = udl_init(udl);
>  	if (r) {
> -		drm_dev_fini(&udl->drm);
> -		kfree(udl);
> +		drm_dev_put(&udl->drm);
>  		return ERR_PTR(r);
>  	}
>  

-- 
Regards,

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

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

* Re: [Intel-gfx] [PATCH 07/52] drm/udl: Use drmm_add_final_kfree
@ 2020-02-19 13:42     ` Laurent Pinchart
  0 siblings, 0 replies; 310+ messages in thread
From: Laurent Pinchart @ 2020-02-19 13:42 UTC (permalink / raw)
  To: Daniel Vetter
  Cc: Intel Graphics Development, DRI Development, Thomas Zimmermann,
	Dave Airlie, Daniel Vetter, Thomas Gleixner, Sam Ravnborg

Hi Daniel,

Thank you for the patch.

On Wed, Feb 19, 2020 at 11:20:37AM +0100, Daniel Vetter wrote:
> 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.
> 
> Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>

Did you mean to squash this with the previous commit ?

> 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 | 3 +--
>  1 file changed, 1 insertion(+), 2 deletions(-)
> 
> diff --git a/drivers/gpu/drm/udl/udl_drv.c b/drivers/gpu/drm/udl/udl_drv.c
> index d5b89711ab1e..6a5594946096 100644
> --- a/drivers/gpu/drm/udl/udl_drv.c
> +++ b/drivers/gpu/drm/udl/udl_drv.c
> @@ -81,8 +81,7 @@ static struct udl_device *udl_driver_create(struct usb_interface *interface)
>  
>  	r = udl_init(udl);
>  	if (r) {
> -		drm_dev_fini(&udl->drm);
> -		kfree(udl);
> +		drm_dev_put(&udl->drm);
>  		return ERR_PTR(r);
>  	}
>  

-- 
Regards,

Laurent Pinchart
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH 27/52] drm: Manage drm_mode_config_init with drmm_
  2020-02-19 10:20   ` [Intel-gfx] " Daniel Vetter
@ 2020-02-19 13:49     ` Laurent Pinchart
  -1 siblings, 0 replies; 310+ messages in thread
From: Laurent Pinchart @ 2020-02-19 13:49 UTC (permalink / raw)
  To: Daniel Vetter
  Cc: Daniel Vetter, Intel Graphics Development, Sam Ravnborg,
	Thomas Zimmermann, DRI Development

Hi Daniel,

Thank you for the patch.

On Wed, Feb 19, 2020 at 11:20:57AM +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 not 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, so deprecate that hook to discourage future users.
> 
> v2: Fixup the example in the kerneldoc too.
> 
> Cc: "Noralf Trønnes" <noralf@tronnes.org>
> Cc: Sam Ravnborg <sam@ravnborg.org>
> Cc: Thomas Zimmermann <tzimmermann@suse.de>
> Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
> ---
>  drivers/gpu/drm/drm_drv.c         | 21 +++++----------------
>  drivers/gpu/drm/drm_mode_config.c | 12 +++++++++++-
>  include/drm/drm_mode_config.h     |  2 +-
>  3 files changed, 17 insertions(+), 18 deletions(-)
> 
> diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c
> index 3cf40864d4a6..428c569aaaf1 100644
> --- a/drivers/gpu/drm/drm_drv.c
> +++ b/drivers/gpu/drm/drm_drv.c
> @@ -267,8 +267,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 +277,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 +303,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 +703,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 +714,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_mode_config.c b/drivers/gpu/drm/drm_mode_config.c
> index 08e6eff6a179..957db1edba0c 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,8 @@ void drm_mode_config_init(struct drm_device *dev)
>  		drm_modeset_acquire_fini(&modeset_ctx);
>  		dma_resv_fini(&resv);
>  	}
> +
> +	return drmm_add_action(dev, drm_mode_config_init_release, NULL);

If this fails, shouldn't drm_mode_config_cleanup() be called here ?

>  }
>  EXPORT_SYMBOL(drm_mode_config_init);
>  
> diff --git a/include/drm/drm_mode_config.h b/include/drm/drm_mode_config.h
> index 3bcbe30339f0..160a3e4b51c3 100644
> --- a/include/drm/drm_mode_config.h
> +++ b/include/drm/drm_mode_config.h
> @@ -929,7 +929,7 @@ 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);
>  void drm_mode_config_reset(struct drm_device *dev);
>  void drm_mode_config_cleanup(struct drm_device *dev);
>  

-- 
Regards,

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

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

* Re: [Intel-gfx] [PATCH 27/52] drm: Manage drm_mode_config_init with drmm_
@ 2020-02-19 13:49     ` Laurent Pinchart
  0 siblings, 0 replies; 310+ messages in thread
From: Laurent Pinchart @ 2020-02-19 13:49 UTC (permalink / raw)
  To: Daniel Vetter
  Cc: Daniel Vetter, Intel Graphics Development, Sam Ravnborg,
	Thomas Zimmermann, DRI Development

Hi Daniel,

Thank you for the patch.

On Wed, Feb 19, 2020 at 11:20:57AM +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 not 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, so deprecate that hook to discourage future users.
> 
> v2: Fixup the example in the kerneldoc too.
> 
> Cc: "Noralf Trønnes" <noralf@tronnes.org>
> Cc: Sam Ravnborg <sam@ravnborg.org>
> Cc: Thomas Zimmermann <tzimmermann@suse.de>
> Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
> ---
>  drivers/gpu/drm/drm_drv.c         | 21 +++++----------------
>  drivers/gpu/drm/drm_mode_config.c | 12 +++++++++++-
>  include/drm/drm_mode_config.h     |  2 +-
>  3 files changed, 17 insertions(+), 18 deletions(-)
> 
> diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c
> index 3cf40864d4a6..428c569aaaf1 100644
> --- a/drivers/gpu/drm/drm_drv.c
> +++ b/drivers/gpu/drm/drm_drv.c
> @@ -267,8 +267,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 +277,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 +303,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 +703,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 +714,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_mode_config.c b/drivers/gpu/drm/drm_mode_config.c
> index 08e6eff6a179..957db1edba0c 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,8 @@ void drm_mode_config_init(struct drm_device *dev)
>  		drm_modeset_acquire_fini(&modeset_ctx);
>  		dma_resv_fini(&resv);
>  	}
> +
> +	return drmm_add_action(dev, drm_mode_config_init_release, NULL);

If this fails, shouldn't drm_mode_config_cleanup() be called here ?

>  }
>  EXPORT_SYMBOL(drm_mode_config_init);
>  
> diff --git a/include/drm/drm_mode_config.h b/include/drm/drm_mode_config.h
> index 3bcbe30339f0..160a3e4b51c3 100644
> --- a/include/drm/drm_mode_config.h
> +++ b/include/drm/drm_mode_config.h
> @@ -929,7 +929,7 @@ 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);
>  void drm_mode_config_reset(struct drm_device *dev);
>  void drm_mode_config_cleanup(struct drm_device *dev);
>  

-- 
Regards,

Laurent Pinchart
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH 37/52] drm/rcar-du: Drop explicit drm_mode_config_cleanup call
  2020-02-19 10:21   ` Daniel Vetter
  (?)
@ 2020-02-19 13:53     ` Laurent Pinchart
  -1 siblings, 0 replies; 310+ messages in thread
From: Laurent Pinchart @ 2020-02-19 13:53 UTC (permalink / raw)
  To: Daniel Vetter
  Cc: DRI Development, Intel Graphics Development, linux-renesas-soc,
	Kieran Bingham, Daniel Vetter

Hi Daniel,

Thank you for the patch.

On Wed, Feb 19, 2020 at 11:21:07AM +0100, Daniel Vetter wrote:
> It's right above the drm_dev_put().

Could you mention in the commit message that the call can be dropped
because drm_mode_config_init() uses the managed API to handle cleaning
automatically, removing the need to do so in drivers ? Otherwise when
someone will look at the commit later, without having the full context
in mind, the reason why the call is dropped won't be immediately clear.
With this fixed,

Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>

This also applies to similar patches for other drivers.

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

I agree, but I'm not sure this should be part of the commit message :-)

> 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..dcdc1580b511 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 = drm_mode_config_init(dev);
> +	if (ret)
> +		return ret;
>  
>  	dev->mode_config.min_width = 0;
>  	dev->mode_config.min_height = 0;

-- 
Regards,

Laurent Pinchart

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

* Re: [PATCH 37/52] drm/rcar-du: Drop explicit drm_mode_config_cleanup call
@ 2020-02-19 13:53     ` Laurent Pinchart
  0 siblings, 0 replies; 310+ messages in thread
From: Laurent Pinchart @ 2020-02-19 13:53 UTC (permalink / raw)
  To: Daniel Vetter
  Cc: linux-renesas-soc, Daniel Vetter, Intel Graphics Development,
	Kieran Bingham, DRI Development

Hi Daniel,

Thank you for the patch.

On Wed, Feb 19, 2020 at 11:21:07AM +0100, Daniel Vetter wrote:
> It's right above the drm_dev_put().

Could you mention in the commit message that the call can be dropped
because drm_mode_config_init() uses the managed API to handle cleaning
automatically, removing the need to do so in drivers ? Otherwise when
someone will look at the commit later, without having the full context
in mind, the reason why the call is dropped won't be immediately clear.
With this fixed,

Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>

This also applies to similar patches for other drivers.

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

I agree, but I'm not sure this should be part of the commit message :-)

> 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..dcdc1580b511 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 = drm_mode_config_init(dev);
> +	if (ret)
> +		return ret;
>  
>  	dev->mode_config.min_width = 0;
>  	dev->mode_config.min_height = 0;

-- 
Regards,

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

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

* Re: [Intel-gfx] [PATCH 37/52] drm/rcar-du: Drop explicit drm_mode_config_cleanup call
@ 2020-02-19 13:53     ` Laurent Pinchart
  0 siblings, 0 replies; 310+ messages in thread
From: Laurent Pinchart @ 2020-02-19 13:53 UTC (permalink / raw)
  To: Daniel Vetter
  Cc: linux-renesas-soc, Daniel Vetter, Intel Graphics Development,
	Kieran Bingham, DRI Development

Hi Daniel,

Thank you for the patch.

On Wed, Feb 19, 2020 at 11:21:07AM +0100, Daniel Vetter wrote:
> It's right above the drm_dev_put().

Could you mention in the commit message that the call can be dropped
because drm_mode_config_init() uses the managed API to handle cleaning
automatically, removing the need to do so in drivers ? Otherwise when
someone will look at the commit later, without having the full context
in mind, the reason why the call is dropped won't be immediately clear.
With this fixed,

Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>

This also applies to similar patches for other drivers.

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

I agree, but I'm not sure this should be part of the commit message :-)

> 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..dcdc1580b511 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 = drm_mode_config_init(dev);
> +	if (ret)
> +		return ret;
>  
>  	dev->mode_config.min_width = 0;
>  	dev->mode_config.min_height = 0;

-- 
Regards,

Laurent Pinchart
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH 40/52] drm/shmob: Drop explicit drm_mode_config_cleanup call
  2020-02-19 10:21   ` Daniel Vetter
  (?)
@ 2020-02-19 13:57     ` Laurent Pinchart
  -1 siblings, 0 replies; 310+ messages in thread
From: Laurent Pinchart @ 2020-02-19 13:57 UTC (permalink / raw)
  To: Daniel Vetter
  Cc: DRI Development, Intel Graphics Development, linux-renesas-soc,
	Kieran Bingham, Daniel Vetter

Hi Daniel,

Thank you for the patch.

On Wed, Feb 19, 2020 at 11:21:10AM +0100, Daniel Vetter wrote:
> It's right above the drm_dev_put().
> 
> Aside: Another driver with a bit much devm_kzalloc, which should
> probably use drmm_kzalloc instead ...

With the same comments as the one for the rcar-du patch taken into
account,

Reviewed-by: 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..e6e34bb75ba0 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 = drm_mode_config_init(sdev->ddev);
> +	if (ret)
> +		return ret;
>  
>  	shmob_drm_crtc_create(sdev);
>  	shmob_drm_encoder_create(sdev);

-- 
Regards,

Laurent Pinchart

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

* Re: [PATCH 40/52] drm/shmob: Drop explicit drm_mode_config_cleanup call
@ 2020-02-19 13:57     ` Laurent Pinchart
  0 siblings, 0 replies; 310+ messages in thread
From: Laurent Pinchart @ 2020-02-19 13:57 UTC (permalink / raw)
  To: Daniel Vetter
  Cc: linux-renesas-soc, Daniel Vetter, Intel Graphics Development,
	Kieran Bingham, DRI Development

Hi Daniel,

Thank you for the patch.

On Wed, Feb 19, 2020 at 11:21:10AM +0100, Daniel Vetter wrote:
> It's right above the drm_dev_put().
> 
> Aside: Another driver with a bit much devm_kzalloc, which should
> probably use drmm_kzalloc instead ...

With the same comments as the one for the rcar-du patch taken into
account,

Reviewed-by: 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..e6e34bb75ba0 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 = drm_mode_config_init(sdev->ddev);
> +	if (ret)
> +		return ret;
>  
>  	shmob_drm_crtc_create(sdev);
>  	shmob_drm_encoder_create(sdev);

-- 
Regards,

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

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

* Re: [Intel-gfx] [PATCH 40/52] drm/shmob: Drop explicit drm_mode_config_cleanup call
@ 2020-02-19 13:57     ` Laurent Pinchart
  0 siblings, 0 replies; 310+ messages in thread
From: Laurent Pinchart @ 2020-02-19 13:57 UTC (permalink / raw)
  To: Daniel Vetter
  Cc: linux-renesas-soc, Daniel Vetter, Intel Graphics Development,
	Kieran Bingham, DRI Development

Hi Daniel,

Thank you for the patch.

On Wed, Feb 19, 2020 at 11:21:10AM +0100, Daniel Vetter wrote:
> It's right above the drm_dev_put().
> 
> Aside: Another driver with a bit much devm_kzalloc, which should
> probably use drmm_kzalloc instead ...

With the same comments as the one for the rcar-du patch taken into
account,

Reviewed-by: 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..e6e34bb75ba0 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 = drm_mode_config_init(sdev->ddev);
> +	if (ret)
> +		return ret;
>  
>  	shmob_drm_crtc_create(sdev);
>  	shmob_drm_encoder_create(sdev);

-- 
Regards,

Laurent Pinchart
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH 03/52] drm: add managed resources tied to drm_device
  2020-02-19 13:28     ` [Intel-gfx] " Laurent Pinchart
@ 2020-02-19 13:57       ` Daniel Vetter
  -1 siblings, 0 replies; 310+ messages in thread
From: Daniel Vetter @ 2020-02-19 13:57 UTC (permalink / raw)
  To: Laurent Pinchart
  Cc: Daniel Vetter, Intel Graphics Development, Greg Kroah-Hartman,
	DRI Development, Rafael J. Wysocki

On Wed, Feb 19, 2020 at 2:29 PM Laurent Pinchart
<laurent.pinchart@ideasonboard.com> wrote:
>
> Hi Daniel,
>
> Thank you for the patch.
>
> On Wed, Feb 19, 2020 at 11:20:33AM +0100, Daniel Vetter wrote:
> > 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.
>
> This is all a very good idea ! Many subsystems are plagged by drivers
> using devm_k*alloc to allocate data accessible by userspace. Since the
> introduction of devm_*, we've likely reduced the number of memory leaks,
> but I'm pretty sure we've increased the risk of crashes as I've seen
> some drivers that used .release() callbacks correctly being naively
> converted to incorrect devm_* usage :-(
>
> This leads me to a question: if other subsystems have the same problem,
> could we turn this implementation into something more generic ? It
> doesn't have to be done right away and shouldn't block merging this
> series, but I think it would be very useful.

That's why I'm cc'ing devres maintainers (Greg&Rafael for driver core)
on this. I do think we should make this distinct from devm, with
distinct types, so that the compiler can help us catch bugs, and it's
easier to spot mistakes in review (in cases where both variants
exists, e.g. devm_kzalloc and drmm_kzalloc). Disjoint examples would
be devm_ioremap (iounmap only on the final drm_dev_put is a bug) or
drmm_connector_init (release the drm_connector already at device
driver unbind with devres is a bug).

> > v2: Do all the kerneldoc at the end, to avoid lots of fairly pointless
> > shuffling while getting everything into shape.
> >
> > 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           |  13 ++-
> >  drivers/gpu/drm/drm_internal.h      |   3 +
> >  drivers/gpu/drm/drm_managed.c       | 173 ++++++++++++++++++++++++++++
> >  include/drm/drm_device.h            |  12 ++
> >  include/drm/drm_managed.h           |  25 ++++
> >  include/drm/drm_print.h             |   6 +
> >  8 files changed, 239 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 ca0ca775d37f..53d8fa170143 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..3e5627d6eba6 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,16 @@ static void drm_dev_release(struct kref *ref)
> >               dev->driver->release(dev);
> >       } else {
> >               drm_dev_fini(dev);
> > -             kfree(dev);
> > +             if (!dev->managed.final_kfree) {
> > +                     WARN_ON(!list_empty(&dev->managed.resources));
> > +                     kfree(dev);
> > +             }
> >       }
> > +
> > +     drm_managed_release(dev);
> > +
> > +     if (dev->managed.final_kfree)
> > +             kfree(dev->managed.final_kfree);
>
> Should we do this even if the driver implements .release() ? The
> callback may free dev.

There's going to be a WARN_ON(!dev->managed.final_kfree) a bit later
in the series, once all drivers are converted over. And a bunch of the
above code disappears again.

So I think it'll be all fine at the end.

> >  }
> >
> >  /**
> > 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..ee7c7253af61
> > --- /dev/null
> > +++ b/drivers/gpu/drm/drm_managed.c
> > @@ -0,0 +1,173 @@
> > +// 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 sturct &device managed resources, but tied to the lifetime of
>
> s/sturct/struct/

Yeah misplaced fixup, it's somewhere else in the series, already
shuffled in my local branch.

> > + * 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().
> > +      */
>
> Do we want to make this API usable for DMA ?

Dunno. Maybe. Was easier to just copy it over instead of thinking
about whether breaking this is useful or not - not doing this might
also break cacheline alignment and stuff like that, which drivers
legit can optimize for allocations bound to drm_device lifetime.

> > +     u8 __aligned(ARCH_KMALLOC_MINALIGN) data[];
> > +};
> > +
> > +void drm_managed_release(struct drm_device *dev)
> > +{
> > +
>
> Extra blank line.

Will fix.

> > +     struct drmres *dr, *tmp;
>
> I'm sure a better name than tmp can be found. res, resource or node ?

It's the temporary list cursor the _safe() variants need, I just call
them tmp since you should never access them outside of that macro.
Otherwise I'm all for more meaningful names, but here this might tempt
people to do something stupid.

> > +
> > +     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 (%lu bytes)\n",
> > +                            dr, dr->node.name, (unsigned long) dr->node.size);
>
> No need to cast to unsigned long, you can replace %lu with %zu instead.

Fixed.

> > +
> > +             if (dr->node.release)
> > +                     dr->node.release(dev, dr->node.size ? dr->data : NULL);
>
> Shouldn't this be
>
>                         dr->node.release(dev, dr->node.size ? *(void **)&dr->data : NULL);
>
> ?

Hm. Nothing oopsed in my testing, so now I'm confused. Your & is
definitely wrong, we don't want to pass the address of the data
pointer, but the actual data (which in turn is of type (void*). But I
have no idea why the lack of * didn't result in a fireworks show,
because some of the callbacks I'm using make use of the void*
parameter.

> > +
> > +             list_del(&dr->node.entry);
> > +             kfree(dr);
> > +     }
> > +     drm_dbg_drmres(dev, "drmres release end\n");
> > +}
> > +
> > +static __always_inline struct drmres * alloc_dr(drmres_release_t release,
> > +                                             size_t size, gfp_t gfp, int nid)
>
> Why always inline ?

Because kmalloc_track_caller.

> Let's give the function a better name, even if it's internal. alloc_dr
> sounds like it could conflict, and it's also not very clear in a
> backtrace that it's DRM-specific. drmm_alloc_resource ?

Copypasta from devres.c, but I can change this if consensus points to
longer names.

> > +{
> > +     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;
> > +}
> > +
> > +void del_dr(struct drm_device *dev, struct drmres *dr)
>
> And drmm_del_resource ?
>
> > +{
> > +     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);
> > +}
> > +
> > +void add_dr(struct drm_device *dev, struct drmres *dr)
>
> And drmm_add_resource ?
>
> > +{
> > +     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);
> > +     dev->managed.final_kfree = parent;
> > +}
> > +EXPORT_SYMBOL(drmm_add_final_kfree);
>
> As you mentioned this is quite a bit of a hack, but I think we can live
> with it for now.
>
> > +
> > +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)
> > +             return -ENOMEM;
> > +     dr->node.name = name;
> > +     void_ptr = (void **) dr->data;
>
> I'd write (void **)&dr->data; to make it clear that you're taking the
> address of the data array. Arrays decay to pointers in C, so it's
> equivalent, but with & I had to realize data was an array before
> figuring out what the code was doing.

We're not doing that. We're treating ->data as a void* pointer, but
the data itself is a void*. So I very much don't want to take the
address of that thing. Or I'm totally confused about what's going on
here.

> > +     *void_ptr = data;
>
> I may be mistaken, but if data == NULL, you pass 0 as the size to
> alloc_dr, and dr will have an empty data array. Aren't you then
> overflowing your allocation ?

Huh indeed, how did this work. Needs to be protected with an if
(data). I think I need a few unit tests for v2.

> > +
> > +     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)
> > +             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 = NULL, *tmp;
>
> res, resource or node here too ?

Hm yeah, here it's not the tmp list cursor for the _safe version. I
was once when I started typing. Will rename.

> > +     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->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_kfree);
> > diff --git a/include/drm/drm_device.h b/include/drm/drm_device.h
> > index bb60a949f416..2790c9ed614e 100644
> > --- a/include/drm/drm_device.h
> > +++ b/include/drm/drm_device.h
> > @@ -67,6 +67,18 @@ 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 {
> > +             struct list_head resources;
> > +             void *final_kfree;
> > +             spinlock_t lock;
>
> Would it be a good time to #include <linux/spinlock.h> at the top ?

Dunno, seems to compile :-) My approach to #includes is to just add
more until the compiler is happy.

> > +     } 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..75f2c8932c69
> > --- /dev/null
> > +++ b/include/drm/drm_managed.h
> > @@ -0,0 +1,25 @@
> > +// SPDX-License-Identifier: GPL-2.0
>
> No header guard ?

Hm yeah, will add.

> > +
> > +#include <linux/types.h>
> > +#include <linux/gfp.h>
>
> Alphabetically sorted ?

Will do.

Thanks a lot for your detailed review.
-Daniel

> > +
> > +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);
> > 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__)
> >
> >
> >  /*
>
> --
> Regards,
>
> Laurent Pinchart



-- 
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] 310+ messages in thread

* Re: [Intel-gfx] [PATCH 03/52] drm: add managed resources tied to drm_device
@ 2020-02-19 13:57       ` Daniel Vetter
  0 siblings, 0 replies; 310+ messages in thread
From: Daniel Vetter @ 2020-02-19 13:57 UTC (permalink / raw)
  To: Laurent Pinchart
  Cc: Daniel Vetter, Intel Graphics Development, Greg Kroah-Hartman,
	DRI Development, Rafael J. Wysocki

On Wed, Feb 19, 2020 at 2:29 PM Laurent Pinchart
<laurent.pinchart@ideasonboard.com> wrote:
>
> Hi Daniel,
>
> Thank you for the patch.
>
> On Wed, Feb 19, 2020 at 11:20:33AM +0100, Daniel Vetter wrote:
> > 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.
>
> This is all a very good idea ! Many subsystems are plagged by drivers
> using devm_k*alloc to allocate data accessible by userspace. Since the
> introduction of devm_*, we've likely reduced the number of memory leaks,
> but I'm pretty sure we've increased the risk of crashes as I've seen
> some drivers that used .release() callbacks correctly being naively
> converted to incorrect devm_* usage :-(
>
> This leads me to a question: if other subsystems have the same problem,
> could we turn this implementation into something more generic ? It
> doesn't have to be done right away and shouldn't block merging this
> series, but I think it would be very useful.

That's why I'm cc'ing devres maintainers (Greg&Rafael for driver core)
on this. I do think we should make this distinct from devm, with
distinct types, so that the compiler can help us catch bugs, and it's
easier to spot mistakes in review (in cases where both variants
exists, e.g. devm_kzalloc and drmm_kzalloc). Disjoint examples would
be devm_ioremap (iounmap only on the final drm_dev_put is a bug) or
drmm_connector_init (release the drm_connector already at device
driver unbind with devres is a bug).

> > v2: Do all the kerneldoc at the end, to avoid lots of fairly pointless
> > shuffling while getting everything into shape.
> >
> > 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           |  13 ++-
> >  drivers/gpu/drm/drm_internal.h      |   3 +
> >  drivers/gpu/drm/drm_managed.c       | 173 ++++++++++++++++++++++++++++
> >  include/drm/drm_device.h            |  12 ++
> >  include/drm/drm_managed.h           |  25 ++++
> >  include/drm/drm_print.h             |   6 +
> >  8 files changed, 239 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 ca0ca775d37f..53d8fa170143 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..3e5627d6eba6 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,16 @@ static void drm_dev_release(struct kref *ref)
> >               dev->driver->release(dev);
> >       } else {
> >               drm_dev_fini(dev);
> > -             kfree(dev);
> > +             if (!dev->managed.final_kfree) {
> > +                     WARN_ON(!list_empty(&dev->managed.resources));
> > +                     kfree(dev);
> > +             }
> >       }
> > +
> > +     drm_managed_release(dev);
> > +
> > +     if (dev->managed.final_kfree)
> > +             kfree(dev->managed.final_kfree);
>
> Should we do this even if the driver implements .release() ? The
> callback may free dev.

There's going to be a WARN_ON(!dev->managed.final_kfree) a bit later
in the series, once all drivers are converted over. And a bunch of the
above code disappears again.

So I think it'll be all fine at the end.

> >  }
> >
> >  /**
> > 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..ee7c7253af61
> > --- /dev/null
> > +++ b/drivers/gpu/drm/drm_managed.c
> > @@ -0,0 +1,173 @@
> > +// 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 sturct &device managed resources, but tied to the lifetime of
>
> s/sturct/struct/

Yeah misplaced fixup, it's somewhere else in the series, already
shuffled in my local branch.

> > + * 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().
> > +      */
>
> Do we want to make this API usable for DMA ?

Dunno. Maybe. Was easier to just copy it over instead of thinking
about whether breaking this is useful or not - not doing this might
also break cacheline alignment and stuff like that, which drivers
legit can optimize for allocations bound to drm_device lifetime.

> > +     u8 __aligned(ARCH_KMALLOC_MINALIGN) data[];
> > +};
> > +
> > +void drm_managed_release(struct drm_device *dev)
> > +{
> > +
>
> Extra blank line.

Will fix.

> > +     struct drmres *dr, *tmp;
>
> I'm sure a better name than tmp can be found. res, resource or node ?

It's the temporary list cursor the _safe() variants need, I just call
them tmp since you should never access them outside of that macro.
Otherwise I'm all for more meaningful names, but here this might tempt
people to do something stupid.

> > +
> > +     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 (%lu bytes)\n",
> > +                            dr, dr->node.name, (unsigned long) dr->node.size);
>
> No need to cast to unsigned long, you can replace %lu with %zu instead.

Fixed.

> > +
> > +             if (dr->node.release)
> > +                     dr->node.release(dev, dr->node.size ? dr->data : NULL);
>
> Shouldn't this be
>
>                         dr->node.release(dev, dr->node.size ? *(void **)&dr->data : NULL);
>
> ?

Hm. Nothing oopsed in my testing, so now I'm confused. Your & is
definitely wrong, we don't want to pass the address of the data
pointer, but the actual data (which in turn is of type (void*). But I
have no idea why the lack of * didn't result in a fireworks show,
because some of the callbacks I'm using make use of the void*
parameter.

> > +
> > +             list_del(&dr->node.entry);
> > +             kfree(dr);
> > +     }
> > +     drm_dbg_drmres(dev, "drmres release end\n");
> > +}
> > +
> > +static __always_inline struct drmres * alloc_dr(drmres_release_t release,
> > +                                             size_t size, gfp_t gfp, int nid)
>
> Why always inline ?

Because kmalloc_track_caller.

> Let's give the function a better name, even if it's internal. alloc_dr
> sounds like it could conflict, and it's also not very clear in a
> backtrace that it's DRM-specific. drmm_alloc_resource ?

Copypasta from devres.c, but I can change this if consensus points to
longer names.

> > +{
> > +     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;
> > +}
> > +
> > +void del_dr(struct drm_device *dev, struct drmres *dr)
>
> And drmm_del_resource ?
>
> > +{
> > +     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);
> > +}
> > +
> > +void add_dr(struct drm_device *dev, struct drmres *dr)
>
> And drmm_add_resource ?
>
> > +{
> > +     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);
> > +     dev->managed.final_kfree = parent;
> > +}
> > +EXPORT_SYMBOL(drmm_add_final_kfree);
>
> As you mentioned this is quite a bit of a hack, but I think we can live
> with it for now.
>
> > +
> > +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)
> > +             return -ENOMEM;
> > +     dr->node.name = name;
> > +     void_ptr = (void **) dr->data;
>
> I'd write (void **)&dr->data; to make it clear that you're taking the
> address of the data array. Arrays decay to pointers in C, so it's
> equivalent, but with & I had to realize data was an array before
> figuring out what the code was doing.

We're not doing that. We're treating ->data as a void* pointer, but
the data itself is a void*. So I very much don't want to take the
address of that thing. Or I'm totally confused about what's going on
here.

> > +     *void_ptr = data;
>
> I may be mistaken, but if data == NULL, you pass 0 as the size to
> alloc_dr, and dr will have an empty data array. Aren't you then
> overflowing your allocation ?

Huh indeed, how did this work. Needs to be protected with an if
(data). I think I need a few unit tests for v2.

> > +
> > +     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)
> > +             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 = NULL, *tmp;
>
> res, resource or node here too ?

Hm yeah, here it's not the tmp list cursor for the _safe version. I
was once when I started typing. Will rename.

> > +     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->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_kfree);
> > diff --git a/include/drm/drm_device.h b/include/drm/drm_device.h
> > index bb60a949f416..2790c9ed614e 100644
> > --- a/include/drm/drm_device.h
> > +++ b/include/drm/drm_device.h
> > @@ -67,6 +67,18 @@ 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 {
> > +             struct list_head resources;
> > +             void *final_kfree;
> > +             spinlock_t lock;
>
> Would it be a good time to #include <linux/spinlock.h> at the top ?

Dunno, seems to compile :-) My approach to #includes is to just add
more until the compiler is happy.

> > +     } 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..75f2c8932c69
> > --- /dev/null
> > +++ b/include/drm/drm_managed.h
> > @@ -0,0 +1,25 @@
> > +// SPDX-License-Identifier: GPL-2.0
>
> No header guard ?

Hm yeah, will add.

> > +
> > +#include <linux/types.h>
> > +#include <linux/gfp.h>
>
> Alphabetically sorted ?

Will do.

Thanks a lot for your detailed review.
-Daniel

> > +
> > +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);
> > 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__)
> >
> >
> >  /*
>
> --
> Regards,
>
> Laurent Pinchart



-- 
Daniel Vetter
Software Engineer, Intel Corporation
+41 (0) 79 365 57 48 - http://blog.ffwll.ch
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH 19/52] drm/<drivers>: Use drmm_add_final_kfree
  2020-02-19 10:20   ` [Intel-gfx] " Daniel Vetter
@ 2020-02-19 14:11     ` Laurent Pinchart
  -1 siblings, 0 replies; 310+ messages in thread
From: Laurent Pinchart @ 2020-02-19 14:11 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

Hi Daniel,

Thank you for the patch.

On Wed, Feb 19, 2020 at 11:20:49AM +0100, Daniel Vetter wrote:
> These are the leftover drivers that didn't have a ->release hook that
> needed to be updated.
> 
> 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);

Instead of sprinkling calls to drmm_add_final_kfree() everywhere,
wouldn't it be better to pass the parent pointer to drm_dev_init() ?

>  
>  	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);

-- 
Regards,

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

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

* Re: [Intel-gfx] [PATCH 19/52] drm/<drivers>: Use drmm_add_final_kfree
@ 2020-02-19 14:11     ` Laurent Pinchart
  0 siblings, 0 replies; 310+ messages in thread
From: Laurent Pinchart @ 2020-02-19 14:11 UTC (permalink / raw)
  To: Daniel Vetter
  Cc: Intel Graphics Development, Russell King, DRI Development,
	James (Qian) Wang, Daniel Vetter, Mihail Atanassov

Hi Daniel,

Thank you for the patch.

On Wed, Feb 19, 2020 at 11:20:49AM +0100, Daniel Vetter wrote:
> These are the leftover drivers that didn't have a ->release hook that
> needed to be updated.
> 
> 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);

Instead of sprinkling calls to drmm_add_final_kfree() everywhere,
wouldn't it be better to pass the parent pointer to drm_dev_init() ?

>  
>  	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);

-- 
Regards,

Laurent Pinchart
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH 24/52] drm: Manage drm_gem_init with drmm_
  2020-02-19 10:20   ` [Intel-gfx] " Daniel Vetter
@ 2020-02-19 14:22     ` Laurent Pinchart
  -1 siblings, 0 replies; 310+ messages in thread
From: Laurent Pinchart @ 2020-02-19 14:22 UTC (permalink / raw)
  To: Daniel Vetter; +Cc: Daniel Vetter, Intel Graphics Development, DRI Development

Hi Daniel,

Thank you for the patch.

On Wed, Feb 19, 2020 at 11:20:54AM +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>
> ---
>  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 03a1fb377830..7b3df1188da9 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);

This looks fine as such (although I'm not sure if the managed API
overhead is really worth it for core code), but it leads to a potential
issue: if we handle more of the cleanup through the managed API, how do
we ensure that the cleanup functions are called in the right order (when
order matters) ?

>  }
>  
>  /**
> 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);

-- 
Regards,

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

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

* Re: [Intel-gfx] [PATCH 24/52] drm: Manage drm_gem_init with drmm_
@ 2020-02-19 14:22     ` Laurent Pinchart
  0 siblings, 0 replies; 310+ messages in thread
From: Laurent Pinchart @ 2020-02-19 14:22 UTC (permalink / raw)
  To: Daniel Vetter; +Cc: Daniel Vetter, Intel Graphics Development, DRI Development

Hi Daniel,

Thank you for the patch.

On Wed, Feb 19, 2020 at 11:20:54AM +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>
> ---
>  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 03a1fb377830..7b3df1188da9 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);

This looks fine as such (although I'm not sure if the managed API
overhead is really worth it for core code), but it leads to a potential
issue: if we handle more of the cleanup through the managed API, how do
we ensure that the cleanup functions are called in the right order (when
order matters) ?

>  }
>  
>  /**
> 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);

-- 
Regards,

Laurent Pinchart
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH 03/52] drm: add managed resources tied to drm_device
  2020-02-19 13:33       ` [Intel-gfx] " Greg Kroah-Hartman
@ 2020-02-19 14:22         ` Daniel Vetter
  -1 siblings, 0 replies; 310+ messages in thread
From: Daniel Vetter @ 2020-02-19 14:22 UTC (permalink / raw)
  To: Greg Kroah-Hartman
  Cc: Daniel Vetter, Intel Graphics Development, Laurent Pinchart,
	DRI Development, Rafael J. Wysocki

On Wed, Feb 19, 2020 at 2:33 PM Greg Kroah-Hartman
<gregkh@linuxfoundation.org> wrote:
>
> On Wed, Feb 19, 2020 at 03:28:47PM +0200, Laurent Pinchart wrote:
> > Hi Daniel,
> >
> > Thank you for the patch.
> >
> > On Wed, Feb 19, 2020 at 11:20:33AM +0100, Daniel Vetter wrote:
> > > 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.
> >
> > This is all a very good idea ! Many subsystems are plagged by drivers
> > using devm_k*alloc to allocate data accessible by userspace. Since the
> > introduction of devm_*, we've likely reduced the number of memory leaks,
> > but I'm pretty sure we've increased the risk of crashes as I've seen
> > some drivers that used .release() callbacks correctly being naively
> > converted to incorrect devm_* usage :-(
> >
> > This leads me to a question: if other subsystems have the same problem,
> > could we turn this implementation into something more generic ? It
> > doesn't have to be done right away and shouldn't block merging this
> > series, but I think it would be very useful.
>
> It shouldn't be that hard to tie this into a drv_m() type of a thing
> (driver_memory?)
>
> And yes, I think it's much better than devm_* for the obvious reasons of
> this being needed here.

There's two reasons I went with copypasta instead of trying to share code:
- Type checking, I definitely don't want people to mix up devm_ with
drmm_. But even if we do a drv_m that subsystems could embed we do
have quite a few different types of component drivers (and with
drm_panel and drm_bridge even standardized), and I don't want people
to be able to pass the wrong kind of struct to e.g. a managed
drmm_connector_init - it really needs to be the drm_device, not a
panel or bridge or something else.

- We could still share the code as a kind of implementation/backend
library. But it's not much, and with embedding I could use the drm
device logging stuff which is kinda nice. But if there's more demand
for this I can definitely see the point in sharing this, as Laurent
pointed out with the tiny optimization with not allocating a NULL void
* that I've done (and screwed up) it's not entirely trivial code.

Cheers, Daniel
-- 
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] 310+ messages in thread

* Re: [Intel-gfx] [PATCH 03/52] drm: add managed resources tied to drm_device
@ 2020-02-19 14:22         ` Daniel Vetter
  0 siblings, 0 replies; 310+ messages in thread
From: Daniel Vetter @ 2020-02-19 14:22 UTC (permalink / raw)
  To: Greg Kroah-Hartman
  Cc: Daniel Vetter, Intel Graphics Development, Laurent Pinchart,
	DRI Development, Rafael J. Wysocki

On Wed, Feb 19, 2020 at 2:33 PM Greg Kroah-Hartman
<gregkh@linuxfoundation.org> wrote:
>
> On Wed, Feb 19, 2020 at 03:28:47PM +0200, Laurent Pinchart wrote:
> > Hi Daniel,
> >
> > Thank you for the patch.
> >
> > On Wed, Feb 19, 2020 at 11:20:33AM +0100, Daniel Vetter wrote:
> > > 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.
> >
> > This is all a very good idea ! Many subsystems are plagged by drivers
> > using devm_k*alloc to allocate data accessible by userspace. Since the
> > introduction of devm_*, we've likely reduced the number of memory leaks,
> > but I'm pretty sure we've increased the risk of crashes as I've seen
> > some drivers that used .release() callbacks correctly being naively
> > converted to incorrect devm_* usage :-(
> >
> > This leads me to a question: if other subsystems have the same problem,
> > could we turn this implementation into something more generic ? It
> > doesn't have to be done right away and shouldn't block merging this
> > series, but I think it would be very useful.
>
> It shouldn't be that hard to tie this into a drv_m() type of a thing
> (driver_memory?)
>
> And yes, I think it's much better than devm_* for the obvious reasons of
> this being needed here.

There's two reasons I went with copypasta instead of trying to share code:
- Type checking, I definitely don't want people to mix up devm_ with
drmm_. But even if we do a drv_m that subsystems could embed we do
have quite a few different types of component drivers (and with
drm_panel and drm_bridge even standardized), and I don't want people
to be able to pass the wrong kind of struct to e.g. a managed
drmm_connector_init - it really needs to be the drm_device, not a
panel or bridge or something else.

- We could still share the code as a kind of implementation/backend
library. But it's not much, and with embedding I could use the drm
device logging stuff which is kinda nice. But if there's more demand
for this I can definitely see the point in sharing this, as Laurent
pointed out with the tiny optimization with not allocating a NULL void
* that I've done (and screwed up) it's not entirely trivial code.

Cheers, Daniel
-- 
Daniel Vetter
Software Engineer, Intel Corporation
+41 (0) 79 365 57 48 - http://blog.ffwll.ch
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH 21/52] drm: Handle dev->unique with drmm_
  2020-02-19 10:20   ` [Intel-gfx] " Daniel Vetter
@ 2020-02-19 14:28     ` Laurent Pinchart
  -1 siblings, 0 replies; 310+ messages in thread
From: Laurent Pinchart @ 2020-02-19 14:28 UTC (permalink / raw)
  To: Daniel Vetter; +Cc: Daniel Vetter, Intel Graphics Development, DRI Development

Hi Daniel,

Thank you for the patch.

On Wed, Feb 19, 2020 at 11:20:51AM +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>
> ---
>  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 1ee606b4a4f9..782fd5d6f8b2 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);
>  
> @@ -1063,8 +1062,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 ee7c7253af61..d8a484e19830 100644
> --- a/drivers/gpu/drm/drm_managed.c
> +++ b/drivers/gpu/drm/drm_managed.c
> @@ -147,6 +147,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)

Do we need support for gfp_t other than GFP_KERNEL ? Given that the
memory will be released when the drm_device is destroyed, GFP_ATOMIC
would seem of dubious use to me, and we may want to not make it possible
to use it.

> +{
> +	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 = NULL, *tmp;
> diff --git a/include/drm/drm_managed.h b/include/drm/drm_managed.h
> index 75f2c8932c69..240edd395e88 100644
> --- a/include/drm/drm_managed.h
> +++ b/include/drm/drm_managed.h
> @@ -21,5 +21,6 @@ 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);

-- 
Regards,

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

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

* Re: [Intel-gfx] [PATCH 21/52] drm: Handle dev->unique with drmm_
@ 2020-02-19 14:28     ` Laurent Pinchart
  0 siblings, 0 replies; 310+ messages in thread
From: Laurent Pinchart @ 2020-02-19 14:28 UTC (permalink / raw)
  To: Daniel Vetter; +Cc: Daniel Vetter, Intel Graphics Development, DRI Development

Hi Daniel,

Thank you for the patch.

On Wed, Feb 19, 2020 at 11:20:51AM +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>
> ---
>  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 1ee606b4a4f9..782fd5d6f8b2 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);
>  
> @@ -1063,8 +1062,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 ee7c7253af61..d8a484e19830 100644
> --- a/drivers/gpu/drm/drm_managed.c
> +++ b/drivers/gpu/drm/drm_managed.c
> @@ -147,6 +147,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)

Do we need support for gfp_t other than GFP_KERNEL ? Given that the
memory will be released when the drm_device is destroyed, GFP_ATOMIC
would seem of dubious use to me, and we may want to not make it possible
to use it.

> +{
> +	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 = NULL, *tmp;
> diff --git a/include/drm/drm_managed.h b/include/drm/drm_managed.h
> index 75f2c8932c69..240edd395e88 100644
> --- a/include/drm/drm_managed.h
> +++ b/include/drm/drm_managed.h
> @@ -21,5 +21,6 @@ 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);

-- 
Regards,

Laurent Pinchart
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH 37/52] drm/rcar-du: Drop explicit drm_mode_config_cleanup call
  2020-02-19 13:53     ` Laurent Pinchart
  (?)
@ 2020-02-19 14:29       ` Daniel Vetter
  -1 siblings, 0 replies; 310+ messages in thread
From: Daniel Vetter @ 2020-02-19 14:29 UTC (permalink / raw)
  To: Laurent Pinchart
  Cc: DRI Development, Intel Graphics Development,
	open list:DRM DRIVERS FOR RENESAS, Kieran Bingham, Daniel Vetter

On Wed, Feb 19, 2020 at 2:53 PM Laurent Pinchart
<laurent.pinchart@ideasonboard.com> wrote:
>
> Hi Daniel,
>
> Thank you for the patch.
>
> On Wed, Feb 19, 2020 at 11:21:07AM +0100, Daniel Vetter wrote:
> > It's right above the drm_dev_put().
>
> Could you mention in the commit message that the call can be dropped
> because drm_mode_config_init() uses the managed API to handle cleaning
> automatically, removing the need to do so in drivers ? Otherwise when
> someone will look at the commit later, without having the full context
> in mind, the reason why the call is dropped won't be immediately clear.
> With this fixed,

Yeah I need to add that, since that explains the need for checking the
return value of drm_mode_config_init.

> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
>
> This also applies to similar patches for other drivers.
>
> > Aside: Another driver with a bit much devm_kzalloc, which should
> > probably use drmm_kzalloc instead ...
>
> I agree, but I'm not sure this should be part of the commit message :-)

I'm trying to use this patch series as an education campaign about the
dangers of devm_kzalloc. Hence why I tried to touch as many drivers as
feasible (the ones I've did not touched have even more fundamental
lifetime issues and would blow up simply by switching to drm_dev_put()
for some reason or another). You alredy understand this stuff, so it's
a bit redundant here for your driver ...

I'm not sure about the other devm_kzalloc in rcar-du, but the one in
rcar_du_encoder_init seems to contain a drm_encoder, and drm_encoder
is a userspace visible thing. The others would need careful analysis,
but as a defensive move I'd e.g. not devm_kzalloc your driver private
structure behind drm_device->dev_private. It can work, but just a bit
too risky imo and hard to review for correctness.
-Daniel

> > 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..dcdc1580b511 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 = drm_mode_config_init(dev);
> > +     if (ret)
> > +             return ret;
> >
> >       dev->mode_config.min_width = 0;
> >       dev->mode_config.min_height = 0;
>
> --
> Regards,
>
> Laurent Pinchart



-- 
Daniel Vetter
Software Engineer, Intel Corporation
+41 (0) 79 365 57 48 - http://blog.ffwll.ch

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

* Re: [PATCH 37/52] drm/rcar-du: Drop explicit drm_mode_config_cleanup call
@ 2020-02-19 14:29       ` Daniel Vetter
  0 siblings, 0 replies; 310+ messages in thread
From: Daniel Vetter @ 2020-02-19 14:29 UTC (permalink / raw)
  To: Laurent Pinchart
  Cc: open list:DRM DRIVERS FOR RENESAS, Daniel Vetter,
	Intel Graphics Development, Kieran Bingham, DRI Development

On Wed, Feb 19, 2020 at 2:53 PM Laurent Pinchart
<laurent.pinchart@ideasonboard.com> wrote:
>
> Hi Daniel,
>
> Thank you for the patch.
>
> On Wed, Feb 19, 2020 at 11:21:07AM +0100, Daniel Vetter wrote:
> > It's right above the drm_dev_put().
>
> Could you mention in the commit message that the call can be dropped
> because drm_mode_config_init() uses the managed API to handle cleaning
> automatically, removing the need to do so in drivers ? Otherwise when
> someone will look at the commit later, without having the full context
> in mind, the reason why the call is dropped won't be immediately clear.
> With this fixed,

Yeah I need to add that, since that explains the need for checking the
return value of drm_mode_config_init.

> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
>
> This also applies to similar patches for other drivers.
>
> > Aside: Another driver with a bit much devm_kzalloc, which should
> > probably use drmm_kzalloc instead ...
>
> I agree, but I'm not sure this should be part of the commit message :-)

I'm trying to use this patch series as an education campaign about the
dangers of devm_kzalloc. Hence why I tried to touch as many drivers as
feasible (the ones I've did not touched have even more fundamental
lifetime issues and would blow up simply by switching to drm_dev_put()
for some reason or another). You alredy understand this stuff, so it's
a bit redundant here for your driver ...

I'm not sure about the other devm_kzalloc in rcar-du, but the one in
rcar_du_encoder_init seems to contain a drm_encoder, and drm_encoder
is a userspace visible thing. The others would need careful analysis,
but as a defensive move I'd e.g. not devm_kzalloc your driver private
structure behind drm_device->dev_private. It can work, but just a bit
too risky imo and hard to review for correctness.
-Daniel

> > 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..dcdc1580b511 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 = drm_mode_config_init(dev);
> > +     if (ret)
> > +             return ret;
> >
> >       dev->mode_config.min_width = 0;
> >       dev->mode_config.min_height = 0;
>
> --
> Regards,
>
> Laurent Pinchart



-- 
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] 310+ messages in thread

* Re: [Intel-gfx] [PATCH 37/52] drm/rcar-du: Drop explicit drm_mode_config_cleanup call
@ 2020-02-19 14:29       ` Daniel Vetter
  0 siblings, 0 replies; 310+ messages in thread
From: Daniel Vetter @ 2020-02-19 14:29 UTC (permalink / raw)
  To: Laurent Pinchart
  Cc: open list:DRM DRIVERS FOR RENESAS, Daniel Vetter,
	Intel Graphics Development, Kieran Bingham, DRI Development

On Wed, Feb 19, 2020 at 2:53 PM Laurent Pinchart
<laurent.pinchart@ideasonboard.com> wrote:
>
> Hi Daniel,
>
> Thank you for the patch.
>
> On Wed, Feb 19, 2020 at 11:21:07AM +0100, Daniel Vetter wrote:
> > It's right above the drm_dev_put().
>
> Could you mention in the commit message that the call can be dropped
> because drm_mode_config_init() uses the managed API to handle cleaning
> automatically, removing the need to do so in drivers ? Otherwise when
> someone will look at the commit later, without having the full context
> in mind, the reason why the call is dropped won't be immediately clear.
> With this fixed,

Yeah I need to add that, since that explains the need for checking the
return value of drm_mode_config_init.

> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
>
> This also applies to similar patches for other drivers.
>
> > Aside: Another driver with a bit much devm_kzalloc, which should
> > probably use drmm_kzalloc instead ...
>
> I agree, but I'm not sure this should be part of the commit message :-)

I'm trying to use this patch series as an education campaign about the
dangers of devm_kzalloc. Hence why I tried to touch as many drivers as
feasible (the ones I've did not touched have even more fundamental
lifetime issues and would blow up simply by switching to drm_dev_put()
for some reason or another). You alredy understand this stuff, so it's
a bit redundant here for your driver ...

I'm not sure about the other devm_kzalloc in rcar-du, but the one in
rcar_du_encoder_init seems to contain a drm_encoder, and drm_encoder
is a userspace visible thing. The others would need careful analysis,
but as a defensive move I'd e.g. not devm_kzalloc your driver private
structure behind drm_device->dev_private. It can work, but just a bit
too risky imo and hard to review for correctness.
-Daniel

> > 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..dcdc1580b511 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 = drm_mode_config_init(dev);
> > +     if (ret)
> > +             return ret;
> >
> >       dev->mode_config.min_width = 0;
> >       dev->mode_config.min_height = 0;
>
> --
> Regards,
>
> Laurent Pinchart



-- 
Daniel Vetter
Software Engineer, Intel Corporation
+41 (0) 79 365 57 48 - http://blog.ffwll.ch
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH 19/52] drm/<drivers>: Use drmm_add_final_kfree
  2020-02-19 14:11     ` [Intel-gfx] " Laurent Pinchart
@ 2020-02-19 14:30       ` Daniel Vetter
  -1 siblings, 0 replies; 310+ messages in thread
From: Daniel Vetter @ 2020-02-19 14:30 UTC (permalink / raw)
  To: Laurent Pinchart
  Cc: Intel Graphics Development, Liviu Dudau, Russell King,
	DRI Development, Hans de Goede, James (Qian) Wang, Daniel Vetter,
	Mihail Atanassov

On Wed, Feb 19, 2020 at 3:11 PM Laurent Pinchart
<laurent.pinchart@ideasonboard.com> wrote:
>
> Hi Daniel,
>
> Thank you for the patch.
>
> On Wed, Feb 19, 2020 at 11:20:49AM +0100, Daniel Vetter wrote:
> > These are the leftover drivers that didn't have a ->release hook that
> > needed to be updated.
> >
> > 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);
>
> Instead of sprinkling calls to drmm_add_final_kfree() everywhere,
> wouldn't it be better to pass the parent pointer to drm_dev_init() ?

Would lead to a horrendous monster patch, and even with this splitting
there were a few corner cases. My plan is to add a devm_drm_dev_alloc
pattern which combines the usual pattern that most drivers use, see
the last patch for all these glorious ideas.

So yeah I hope this will all go away (or mostly at least), but for
bisecting I didn't come up with a better idea to get this all off the
ground unfortunately.
-Daniel

>
> >
> >       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);
>
> --
> Regards,
>
> Laurent Pinchart



-- 
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] 310+ messages in thread

* Re: [Intel-gfx] [PATCH 19/52] drm/<drivers>: Use drmm_add_final_kfree
@ 2020-02-19 14:30       ` Daniel Vetter
  0 siblings, 0 replies; 310+ messages in thread
From: Daniel Vetter @ 2020-02-19 14:30 UTC (permalink / raw)
  To: Laurent Pinchart
  Cc: Intel Graphics Development, Russell King, DRI Development,
	James (Qian) Wang, Daniel Vetter, Mihail Atanassov

On Wed, Feb 19, 2020 at 3:11 PM Laurent Pinchart
<laurent.pinchart@ideasonboard.com> wrote:
>
> Hi Daniel,
>
> Thank you for the patch.
>
> On Wed, Feb 19, 2020 at 11:20:49AM +0100, Daniel Vetter wrote:
> > These are the leftover drivers that didn't have a ->release hook that
> > needed to be updated.
> >
> > 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);
>
> Instead of sprinkling calls to drmm_add_final_kfree() everywhere,
> wouldn't it be better to pass the parent pointer to drm_dev_init() ?

Would lead to a horrendous monster patch, and even with this splitting
there were a few corner cases. My plan is to add a devm_drm_dev_alloc
pattern which combines the usual pattern that most drivers use, see
the last patch for all these glorious ideas.

So yeah I hope this will all go away (or mostly at least), but for
bisecting I didn't come up with a better idea to get this all off the
ground unfortunately.
-Daniel

>
> >
> >       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);
>
> --
> Regards,
>
> Laurent Pinchart



-- 
Daniel Vetter
Software Engineer, Intel Corporation
+41 (0) 79 365 57 48 - http://blog.ffwll.ch
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH 05/52] drm/mipi_dbi: Use drmm_add_final_kfree in all drivers
  2020-02-19 13:29         ` [Intel-gfx] " Thomas Zimmermann
@ 2020-02-19 14:32           ` Daniel Vetter
  -1 siblings, 0 replies; 310+ messages in thread
From: Daniel Vetter @ 2020-02-19 14:32 UTC (permalink / raw)
  To: Thomas Zimmermann
  Cc: David Lechner, David Airlie, Intel Graphics Development,
	DRI Development, Daniel Vetter, Kamlesh Gurudasani, Sam Ravnborg

On Wed, Feb 19, 2020 at 2:29 PM Thomas Zimmermann <tzimmermann@suse.de> wrote:
>
> Hi
>
> Am 19.02.20 um 14:23 schrieb Daniel Vetter:
> > On Wed, Feb 19, 2020 at 12:47 PM Thomas Zimmermann <tzimmermann@suse.de> wrote:
> >>
> >> Hi Daniel,
> >>
> >> good idea. I guess it's the simple encoder's fault. :) I only read
> >> briefly over the whole thing.
> >>
> >> Am 19.02.20 um 11:20 schrieb Daniel Vetter:
> >>> 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).
> >>>
> >>> 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);
> >>
> >> I'd prefer something else than drmm_add_final_kfree().
> >>
> >> From what I understand, drmmadd_add_final_kfree() is required so that
> >> the device instance itself gets free. But wiring up garbage collection
> >> manually is easy to forget and a somewhat odd design. If we have to do
> >> that, there's little benefit over calling kfree in the release callback.
> >>
> >> Instead, could drivers rather be converted to drm_dev_alloc() where
> >> possible?
> >
> > Uh, we want to get away from drm_dev_alloc because that doesn't allow
> > embedding of struct drm_device.
> >
> >> For the other cases, could there be a dedicated allocator function that
> >> invokes drmm_add_final_kfree()? Like that
> >>
> >>   void*
> >>   __drmm_kzalloc_dev(size_t size, size_t dev_off)
> >>   {
> >>       void *parent = kzalloc(size)
> >>
> >>       drm_device *dev = (parent + dev_off)
> >>
> >>       __drmm_add_final_kfree(dev, parent);
> >>
> >>       return parent;
> >>   }
> >>
> >>   /*
> >>    * takes the name of driver's device structure and the
> >>    * name of the drm device structure embedded within
> >>    */
> >>   drmm_kzalloc(parent_type, base)
> >>     (parent_type*)__drm_kzalloc_dev(sizeof(parent_type),
> >>                         offsetof(parent_type, base));
> >
> > drmm_kzalloc exists and works, and is used plenty in this series. The
> > trouble is you can only use it once the drm_device is initialized, so
> > there's a chicken/egg problem.
>
> That line of the example was a total mess. Sorry. It actually was
> supposed to look something like this.
>
>    /*
>     * takes the name of driver's device structure and the
>     * name of the drm device structure embedded within
>     */
>    #define drmm_kzalloc_dev(parent_type, base) \
>      (parent_type*)__drm_kzalloc_dev(sizeof(parent_type),
>                          offsetof(parent_type, base));
>
> __drm_kzalloc_dev() is the allocator function for device instances and
> drm_kzalloc_dev() is a macro that makes it convenient.

Yup, exactly, except I had called it devm_drm_dev_alloc in the todo
list in the last patch, combining the kzalloc() + devm_drm_dev_init()
+ drmm_add_final_kfree(). But exactly this idea behind slightly
different choice of paint. I think a lot of drivers would benefit from
such a macro.
-Daniel

>
> Best regards
> Thomas
>
> >
> > But your idea is sound, and I already proposed it in the todo list of
> > the final patch as devm_drm_dev_alloc. It's just at 50+ patches,
> > there's a limit of what's reasonable to do in the first round.
> >
> > I think if you read the entire thing (skipping the driver patches you
> > don't care about) it will make a lot more sense what's going on.
> >
> > Cheers, Daniel
> >
> >>
> >> Best regards
> >> Thomas
> >>
> >>>
> >>>       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);
> >>>
> >>>
> >>
> >> --
> >> 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] 310+ messages in thread

* Re: [Intel-gfx] [PATCH 05/52] drm/mipi_dbi: Use drmm_add_final_kfree in all drivers
@ 2020-02-19 14:32           ` Daniel Vetter
  0 siblings, 0 replies; 310+ messages in thread
From: Daniel Vetter @ 2020-02-19 14:32 UTC (permalink / raw)
  To: Thomas Zimmermann
  Cc: David Lechner, David Airlie, Intel Graphics Development,
	DRI Development, Daniel Vetter, Kamlesh Gurudasani, Sam Ravnborg

On Wed, Feb 19, 2020 at 2:29 PM Thomas Zimmermann <tzimmermann@suse.de> wrote:
>
> Hi
>
> Am 19.02.20 um 14:23 schrieb Daniel Vetter:
> > On Wed, Feb 19, 2020 at 12:47 PM Thomas Zimmermann <tzimmermann@suse.de> wrote:
> >>
> >> Hi Daniel,
> >>
> >> good idea. I guess it's the simple encoder's fault. :) I only read
> >> briefly over the whole thing.
> >>
> >> Am 19.02.20 um 11:20 schrieb Daniel Vetter:
> >>> 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).
> >>>
> >>> 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);
> >>
> >> I'd prefer something else than drmm_add_final_kfree().
> >>
> >> From what I understand, drmmadd_add_final_kfree() is required so that
> >> the device instance itself gets free. But wiring up garbage collection
> >> manually is easy to forget and a somewhat odd design. If we have to do
> >> that, there's little benefit over calling kfree in the release callback.
> >>
> >> Instead, could drivers rather be converted to drm_dev_alloc() where
> >> possible?
> >
> > Uh, we want to get away from drm_dev_alloc because that doesn't allow
> > embedding of struct drm_device.
> >
> >> For the other cases, could there be a dedicated allocator function that
> >> invokes drmm_add_final_kfree()? Like that
> >>
> >>   void*
> >>   __drmm_kzalloc_dev(size_t size, size_t dev_off)
> >>   {
> >>       void *parent = kzalloc(size)
> >>
> >>       drm_device *dev = (parent + dev_off)
> >>
> >>       __drmm_add_final_kfree(dev, parent);
> >>
> >>       return parent;
> >>   }
> >>
> >>   /*
> >>    * takes the name of driver's device structure and the
> >>    * name of the drm device structure embedded within
> >>    */
> >>   drmm_kzalloc(parent_type, base)
> >>     (parent_type*)__drm_kzalloc_dev(sizeof(parent_type),
> >>                         offsetof(parent_type, base));
> >
> > drmm_kzalloc exists and works, and is used plenty in this series. The
> > trouble is you can only use it once the drm_device is initialized, so
> > there's a chicken/egg problem.
>
> That line of the example was a total mess. Sorry. It actually was
> supposed to look something like this.
>
>    /*
>     * takes the name of driver's device structure and the
>     * name of the drm device structure embedded within
>     */
>    #define drmm_kzalloc_dev(parent_type, base) \
>      (parent_type*)__drm_kzalloc_dev(sizeof(parent_type),
>                          offsetof(parent_type, base));
>
> __drm_kzalloc_dev() is the allocator function for device instances and
> drm_kzalloc_dev() is a macro that makes it convenient.

Yup, exactly, except I had called it devm_drm_dev_alloc in the todo
list in the last patch, combining the kzalloc() + devm_drm_dev_init()
+ drmm_add_final_kfree(). But exactly this idea behind slightly
different choice of paint. I think a lot of drivers would benefit from
such a macro.
-Daniel

>
> Best regards
> Thomas
>
> >
> > But your idea is sound, and I already proposed it in the todo list of
> > the final patch as devm_drm_dev_alloc. It's just at 50+ patches,
> > there's a limit of what's reasonable to do in the first round.
> >
> > I think if you read the entire thing (skipping the driver patches you
> > don't care about) it will make a lot more sense what's going on.
> >
> > Cheers, Daniel
> >
> >>
> >> Best regards
> >> Thomas
> >>
> >>>
> >>>       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);
> >>>
> >>>
> >>
> >> --
> >> 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
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH 22/52] drm: Use drmm_ for drm_dev_init cleanup
  2020-02-19 10:20   ` [Intel-gfx] " Daniel Vetter
@ 2020-02-19 14:35     ` Laurent Pinchart
  -1 siblings, 0 replies; 310+ messages in thread
From: Laurent Pinchart @ 2020-02-19 14:35 UTC (permalink / raw)
  To: Daniel Vetter; +Cc: Daniel Vetter, Intel Graphics Development, DRI Development

Hi Daniel,

Thank you for the patch.

On Wed, Feb 19, 2020 at 11:20:52AM +0100, Daniel Vetter wrote:
> 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(-)

Is the managed API overhead, coupled with the fact that the code size
doesn't get reduced, worth it for core code ?

> diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c
> index 782fd5d6f8b2..1f7ab88d9435 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);
>  

-- 
Regards,

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

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

* Re: [Intel-gfx] [PATCH 22/52] drm: Use drmm_ for drm_dev_init cleanup
@ 2020-02-19 14:35     ` Laurent Pinchart
  0 siblings, 0 replies; 310+ messages in thread
From: Laurent Pinchart @ 2020-02-19 14:35 UTC (permalink / raw)
  To: Daniel Vetter; +Cc: Daniel Vetter, Intel Graphics Development, DRI Development

Hi Daniel,

Thank you for the patch.

On Wed, Feb 19, 2020 at 11:20:52AM +0100, Daniel Vetter wrote:
> 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(-)

Is the managed API overhead, coupled with the fact that the code size
doesn't get reduced, worth it for core code ?

> diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c
> index 782fd5d6f8b2..1f7ab88d9435 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);
>  

-- 
Regards,

Laurent Pinchart
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH 24/52] drm: Manage drm_gem_init with drmm_
  2020-02-19 14:22     ` [Intel-gfx] " Laurent Pinchart
@ 2020-02-19 14:37       ` Daniel Vetter
  -1 siblings, 0 replies; 310+ messages in thread
From: Daniel Vetter @ 2020-02-19 14:37 UTC (permalink / raw)
  To: Laurent Pinchart
  Cc: Daniel Vetter, Intel Graphics Development, DRI Development

On Wed, Feb 19, 2020 at 3:22 PM Laurent Pinchart
<laurent.pinchart@ideasonboard.com> wrote:
>
> Hi Daniel,
>
> Thank you for the patch.
>
> On Wed, Feb 19, 2020 at 11:20:54AM +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>
> > ---
> >  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 03a1fb377830..7b3df1188da9 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);
>
> This looks fine as such (although I'm not sure if the managed API
> overhead is really worth it for core code), but it leads to a potential
> issue: if we handle more of the cleanup through the managed API, how do
> we ensure that the cleanup functions are called in the right order (when
> order matters) ?

KASAN essentially (already helped while developing this), plus review.
It's still the same problem like reviewing onion unwind code, it's
just less fragile for the normal case.

I also think that if you have ordering constraints in your drm_device
release functions, there's a more fundamental problem going on.
Unfortunately we have a lot of these, which is why converting
everything in drm, including drivers, is not going to be easy nor
quick. There's a lot of problems. E.g. naively converting all
drm_connector allocations from devm_kzalloc to drmm_kzalloc still
means they get released too early, since the drm_mode_config_init
happens before you set up the connectors. So you still have the
problem that your connector_funcs->destroy gets called on already
freed memory. Lots of work ahead.
-Daniel


> >  }
> >
> >  /**
> > 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);
>
> --
> Regards,
>
> Laurent Pinchart



-- 
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] 310+ messages in thread

* Re: [Intel-gfx] [PATCH 24/52] drm: Manage drm_gem_init with drmm_
@ 2020-02-19 14:37       ` Daniel Vetter
  0 siblings, 0 replies; 310+ messages in thread
From: Daniel Vetter @ 2020-02-19 14:37 UTC (permalink / raw)
  To: Laurent Pinchart
  Cc: Daniel Vetter, Intel Graphics Development, DRI Development

On Wed, Feb 19, 2020 at 3:22 PM Laurent Pinchart
<laurent.pinchart@ideasonboard.com> wrote:
>
> Hi Daniel,
>
> Thank you for the patch.
>
> On Wed, Feb 19, 2020 at 11:20:54AM +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>
> > ---
> >  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 03a1fb377830..7b3df1188da9 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);
>
> This looks fine as such (although I'm not sure if the managed API
> overhead is really worth it for core code), but it leads to a potential
> issue: if we handle more of the cleanup through the managed API, how do
> we ensure that the cleanup functions are called in the right order (when
> order matters) ?

KASAN essentially (already helped while developing this), plus review.
It's still the same problem like reviewing onion unwind code, it's
just less fragile for the normal case.

I also think that if you have ordering constraints in your drm_device
release functions, there's a more fundamental problem going on.
Unfortunately we have a lot of these, which is why converting
everything in drm, including drivers, is not going to be easy nor
quick. There's a lot of problems. E.g. naively converting all
drm_connector allocations from devm_kzalloc to drmm_kzalloc still
means they get released too early, since the drm_mode_config_init
happens before you set up the connectors. So you still have the
problem that your connector_funcs->destroy gets called on already
freed memory. Lots of work ahead.
-Daniel


> >  }
> >
> >  /**
> > 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);
>
> --
> Regards,
>
> Laurent Pinchart



-- 
Daniel Vetter
Software Engineer, Intel Corporation
+41 (0) 79 365 57 48 - http://blog.ffwll.ch
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH 19/52] drm/<drivers>: Use drmm_add_final_kfree
  2020-02-19 14:30       ` [Intel-gfx] " Daniel Vetter
@ 2020-02-19 14:39         ` Laurent Pinchart
  -1 siblings, 0 replies; 310+ messages in thread
From: Laurent Pinchart @ 2020-02-19 14:39 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

Hi Daniel,

On Wed, Feb 19, 2020 at 03:30:59PM +0100, Daniel Vetter wrote:
> On Wed, Feb 19, 2020 at 3:11 PM Laurent Pinchart wrote:
> > On Wed, Feb 19, 2020 at 11:20:49AM +0100, Daniel Vetter wrote:
> > > These are the leftover drivers that didn't have a ->release hook that
> > > needed to be updated.
> > >
> > > 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);
> >
> > Instead of sprinkling calls to drmm_add_final_kfree() everywhere,
> > wouldn't it be better to pass the parent pointer to drm_dev_init() ?
> 
> Would lead to a horrendous monster patch, and even with this splitting
> there were a few corner cases.

It could be generated by coccinelle, with the semantic patch included in
the commit message, so that regenerating it should be possible when
merging if conflict arise.

> My plan is to add a devm_drm_dev_alloc
> pattern which combines the usual pattern that most drivers use, see
> the last patch for all these glorious ideas.

OK I will.

> So yeah I hope this will all go away (or mostly at least), but for
> bisecting I didn't come up with a better idea to get this all off the
> ground unfortunately.
> 
> > >
> > >       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);

-- 
Regards,

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

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

* Re: [Intel-gfx] [PATCH 19/52] drm/<drivers>: Use drmm_add_final_kfree
@ 2020-02-19 14:39         ` Laurent Pinchart
  0 siblings, 0 replies; 310+ messages in thread
From: Laurent Pinchart @ 2020-02-19 14:39 UTC (permalink / raw)
  To: Daniel Vetter
  Cc: Intel Graphics Development, Russell King, DRI Development,
	James (Qian) Wang, Daniel Vetter, Mihail Atanassov

Hi Daniel,

On Wed, Feb 19, 2020 at 03:30:59PM +0100, Daniel Vetter wrote:
> On Wed, Feb 19, 2020 at 3:11 PM Laurent Pinchart wrote:
> > On Wed, Feb 19, 2020 at 11:20:49AM +0100, Daniel Vetter wrote:
> > > These are the leftover drivers that didn't have a ->release hook that
> > > needed to be updated.
> > >
> > > 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);
> >
> > Instead of sprinkling calls to drmm_add_final_kfree() everywhere,
> > wouldn't it be better to pass the parent pointer to drm_dev_init() ?
> 
> Would lead to a horrendous monster patch, and even with this splitting
> there were a few corner cases.

It could be generated by coccinelle, with the semantic patch included in
the commit message, so that regenerating it should be possible when
merging if conflict arise.

> My plan is to add a devm_drm_dev_alloc
> pattern which combines the usual pattern that most drivers use, see
> the last patch for all these glorious ideas.

OK I will.

> So yeah I hope this will all go away (or mostly at least), but for
> bisecting I didn't come up with a better idea to get this all off the
> ground unfortunately.
> 
> > >
> > >       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);

-- 
Regards,

Laurent Pinchart
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH 04/52] drm: Set final_kfree in drm_dev_alloc
  2020-02-19 13:39     ` [Intel-gfx] " Laurent Pinchart
  (?)
@ 2020-02-19 14:41       ` Daniel Vetter
  -1 siblings, 0 replies; 310+ messages in thread
From: Daniel Vetter @ 2020-02-19 14:41 UTC (permalink / raw)
  To: Laurent Pinchart
  Cc: Oleksandr Andrushchenko, David Airlie,
	Intel Graphics Development, DRI Development, Gerd Hoffmann,
	Thomas Zimmermann, Daniel Vetter, xen-devel

On Wed, Feb 19, 2020 at 2:39 PM Laurent Pinchart
<laurent.pinchart@ideasonboard.com> wrote:
>
> Hi Daniel,
>
> Thank you for the patch.
>
> On Wed, Feb 19, 2020 at 11:20:34AM +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.
>
> I'd split this patch in two then, with the Xen first coming first, and
> with an explanation in the commit message of the second patch about why
> you call drmm_add_final_kfree() in drm_dev_alloc().
>
> > 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
> >
> > 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 3e5627d6eba6..9e62e28bbc62 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);
>
> drmm_add_final_kfree() can only be called once. Does this mean that a
> driver using drm_dev_alloc() isn't allowed to use drmm_add_final_kfree()
> to tract its own private structure ?

There is only _one_ final kfree() for the structure containing
drm_device. Anything else you can just allocate with drmm_kzalloc, and
it will be cleaned up before. The chicken/egg doesn't just exist
around init time with drm_device, but also at cleanup time - the list
of cleanup actions is stored in drm_device, plus the logging macros
also need a drm_device. Which means we really, really, really need to
make sure that the drm_device is the very last thing that goes away.
Hence this special case. I was semi-tempted to drill through the slab
debug layer and add a check that the drm_device pointer in the
final_kfree is actually within the slab allocation block. Just to make
sure people use this correctly, and not just as a "hey here's a random
kmalloc block I want you to release, thxokbye". Because doing that
would cause a few use-after-free (or a leak).
-Daniel

>
> > +
> >       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;
>
> --
> Regards,
>
> Laurent Pinchart



-- 
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] 310+ messages in thread

* Re: [Intel-gfx] [PATCH 04/52] drm: Set final_kfree in drm_dev_alloc
@ 2020-02-19 14:41       ` Daniel Vetter
  0 siblings, 0 replies; 310+ messages in thread
From: Daniel Vetter @ 2020-02-19 14:41 UTC (permalink / raw)
  To: Laurent Pinchart
  Cc: Oleksandr Andrushchenko, David Airlie,
	Intel Graphics Development, DRI Development, Gerd Hoffmann,
	Thomas Zimmermann, Daniel Vetter, xen-devel

On Wed, Feb 19, 2020 at 2:39 PM Laurent Pinchart
<laurent.pinchart@ideasonboard.com> wrote:
>
> Hi Daniel,
>
> Thank you for the patch.
>
> On Wed, Feb 19, 2020 at 11:20:34AM +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.
>
> I'd split this patch in two then, with the Xen first coming first, and
> with an explanation in the commit message of the second patch about why
> you call drmm_add_final_kfree() in drm_dev_alloc().
>
> > 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
> >
> > 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 3e5627d6eba6..9e62e28bbc62 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);
>
> drmm_add_final_kfree() can only be called once. Does this mean that a
> driver using drm_dev_alloc() isn't allowed to use drmm_add_final_kfree()
> to tract its own private structure ?

There is only _one_ final kfree() for the structure containing
drm_device. Anything else you can just allocate with drmm_kzalloc, and
it will be cleaned up before. The chicken/egg doesn't just exist
around init time with drm_device, but also at cleanup time - the list
of cleanup actions is stored in drm_device, plus the logging macros
also need a drm_device. Which means we really, really, really need to
make sure that the drm_device is the very last thing that goes away.
Hence this special case. I was semi-tempted to drill through the slab
debug layer and add a check that the drm_device pointer in the
final_kfree is actually within the slab allocation block. Just to make
sure people use this correctly, and not just as a "hey here's a random
kmalloc block I want you to release, thxokbye". Because doing that
would cause a few use-after-free (or a leak).
-Daniel

>
> > +
> >       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;
>
> --
> Regards,
>
> Laurent Pinchart



-- 
Daniel Vetter
Software Engineer, Intel Corporation
+41 (0) 79 365 57 48 - http://blog.ffwll.ch
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [Xen-devel] [PATCH 04/52] drm: Set final_kfree in drm_dev_alloc
@ 2020-02-19 14:41       ` Daniel Vetter
  0 siblings, 0 replies; 310+ messages in thread
From: Daniel Vetter @ 2020-02-19 14:41 UTC (permalink / raw)
  To: Laurent Pinchart
  Cc: Oleksandr Andrushchenko, David Airlie,
	Intel Graphics Development, DRI Development, Gerd Hoffmann,
	Thomas Zimmermann, Daniel Vetter, xen-devel

On Wed, Feb 19, 2020 at 2:39 PM Laurent Pinchart
<laurent.pinchart@ideasonboard.com> wrote:
>
> Hi Daniel,
>
> Thank you for the patch.
>
> On Wed, Feb 19, 2020 at 11:20:34AM +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.
>
> I'd split this patch in two then, with the Xen first coming first, and
> with an explanation in the commit message of the second patch about why
> you call drmm_add_final_kfree() in drm_dev_alloc().
>
> > 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
> >
> > 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 3e5627d6eba6..9e62e28bbc62 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);
>
> drmm_add_final_kfree() can only be called once. Does this mean that a
> driver using drm_dev_alloc() isn't allowed to use drmm_add_final_kfree()
> to tract its own private structure ?

There is only _one_ final kfree() for the structure containing
drm_device. Anything else you can just allocate with drmm_kzalloc, and
it will be cleaned up before. The chicken/egg doesn't just exist
around init time with drm_device, but also at cleanup time - the list
of cleanup actions is stored in drm_device, plus the logging macros
also need a drm_device. Which means we really, really, really need to
make sure that the drm_device is the very last thing that goes away.
Hence this special case. I was semi-tempted to drill through the slab
debug layer and add a check that the drm_device pointer in the
final_kfree is actually within the slab allocation block. Just to make
sure people use this correctly, and not just as a "hey here's a random
kmalloc block I want you to release, thxokbye". Because doing that
would cause a few use-after-free (or a leak).
-Daniel

>
> > +
> >       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;
>
> --
> Regards,
>
> Laurent Pinchart



-- 
Daniel Vetter
Software Engineer, Intel Corporation
+41 (0) 79 365 57 48 - http://blog.ffwll.ch

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

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

* Re: [PATCH 07/52] drm/udl: Use drmm_add_final_kfree
  2020-02-19 13:42     ` [Intel-gfx] " Laurent Pinchart
@ 2020-02-19 14:43       ` Daniel Vetter
  -1 siblings, 0 replies; 310+ messages in thread
From: Daniel Vetter @ 2020-02-19 14:43 UTC (permalink / raw)
  To: Laurent Pinchart
  Cc: Sean Paul, Intel Graphics Development, Emil Velikov,
	DRI Development, Thomas Zimmermann, Dave Airlie, Daniel Vetter,
	Thomas Gleixner, Sam Ravnborg

On Wed, Feb 19, 2020 at 2:42 PM Laurent Pinchart
<laurent.pinchart@ideasonboard.com> wrote:
>
> Hi Daniel,
>
> Thank you for the patch.
>
> On Wed, Feb 19, 2020 at 11:20:37AM +0100, Daniel Vetter wrote:
> > 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.
> >
> > Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
>
> Did you mean to squash this with the previous commit ?

Uh yes indeed. Will squash.
-Daniel

>
> > 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 | 3 +--
> >  1 file changed, 1 insertion(+), 2 deletions(-)
> >
> > diff --git a/drivers/gpu/drm/udl/udl_drv.c b/drivers/gpu/drm/udl/udl_drv.c
> > index d5b89711ab1e..6a5594946096 100644
> > --- a/drivers/gpu/drm/udl/udl_drv.c
> > +++ b/drivers/gpu/drm/udl/udl_drv.c
> > @@ -81,8 +81,7 @@ static struct udl_device *udl_driver_create(struct usb_interface *interface)
> >
> >       r = udl_init(udl);
> >       if (r) {
> > -             drm_dev_fini(&udl->drm);
> > -             kfree(udl);
> > +             drm_dev_put(&udl->drm);
> >               return ERR_PTR(r);
> >       }
> >
>
> --
> Regards,
>
> Laurent Pinchart



-- 
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] 310+ messages in thread

* Re: [Intel-gfx] [PATCH 07/52] drm/udl: Use drmm_add_final_kfree
@ 2020-02-19 14:43       ` Daniel Vetter
  0 siblings, 0 replies; 310+ messages in thread
From: Daniel Vetter @ 2020-02-19 14:43 UTC (permalink / raw)
  To: Laurent Pinchart
  Cc: Intel Graphics Development, DRI Development, Thomas Zimmermann,
	Dave Airlie, Daniel Vetter, Thomas Gleixner, Sam Ravnborg

On Wed, Feb 19, 2020 at 2:42 PM Laurent Pinchart
<laurent.pinchart@ideasonboard.com> wrote:
>
> Hi Daniel,
>
> Thank you for the patch.
>
> On Wed, Feb 19, 2020 at 11:20:37AM +0100, Daniel Vetter wrote:
> > 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.
> >
> > Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
>
> Did you mean to squash this with the previous commit ?

Uh yes indeed. Will squash.
-Daniel

>
> > 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 | 3 +--
> >  1 file changed, 1 insertion(+), 2 deletions(-)
> >
> > diff --git a/drivers/gpu/drm/udl/udl_drv.c b/drivers/gpu/drm/udl/udl_drv.c
> > index d5b89711ab1e..6a5594946096 100644
> > --- a/drivers/gpu/drm/udl/udl_drv.c
> > +++ b/drivers/gpu/drm/udl/udl_drv.c
> > @@ -81,8 +81,7 @@ static struct udl_device *udl_driver_create(struct usb_interface *interface)
> >
> >       r = udl_init(udl);
> >       if (r) {
> > -             drm_dev_fini(&udl->drm);
> > -             kfree(udl);
> > +             drm_dev_put(&udl->drm);
> >               return ERR_PTR(r);
> >       }
> >
>
> --
> Regards,
>
> Laurent Pinchart



-- 
Daniel Vetter
Software Engineer, Intel Corporation
+41 (0) 79 365 57 48 - http://blog.ffwll.ch
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH 23/52] drm: manage drm_minor cleanup with drmm_
  2020-02-19 10:20   ` [Intel-gfx] " Daniel Vetter
@ 2020-02-19 14:47     ` Laurent Pinchart
  -1 siblings, 0 replies; 310+ messages in thread
From: Laurent Pinchart @ 2020-02-19 14:47 UTC (permalink / raw)
  To: Daniel Vetter; +Cc: Daniel Vetter, Intel Graphics Development, DRI Development

Hi Daniel,

Thank you for the patch.

On Wed, Feb 19, 2020 at 11:20:53AM +0100, Daniel Vetter wrote:
> 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.
> 
> 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 1f7ab88d9435..03a1fb377830 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);

The need to do the drmm_remove_action() dance, with the need for
drmm_remove_action() in the first place, just to remove those three
lines of manual cleanup really seems overkill to me. Automation is nice,
but not everything is a nail even if all you have is a hammer.

> -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 d8a484e19830..fb44fe65c2cd 100644
> --- a/drivers/gpu/drm/drm_managed.c
> +++ b/drivers/gpu/drm/drm_managed.c
> @@ -132,6 +132,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) {

As before, &tmp->data, and let's rename tmp.

> +			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 240edd395e88..df30f9355902 100644
> --- a/include/drm/drm_managed.h
> +++ b/include/drm/drm_managed.h
> @@ -14,6 +14,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;

-- 
Regards,

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

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

* Re: [Intel-gfx] [PATCH 23/52] drm: manage drm_minor cleanup with drmm_
@ 2020-02-19 14:47     ` Laurent Pinchart
  0 siblings, 0 replies; 310+ messages in thread
From: Laurent Pinchart @ 2020-02-19 14:47 UTC (permalink / raw)
  To: Daniel Vetter; +Cc: Daniel Vetter, Intel Graphics Development, DRI Development

Hi Daniel,

Thank you for the patch.

On Wed, Feb 19, 2020 at 11:20:53AM +0100, Daniel Vetter wrote:
> 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.
> 
> 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 1f7ab88d9435..03a1fb377830 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);

The need to do the drmm_remove_action() dance, with the need for
drmm_remove_action() in the first place, just to remove those three
lines of manual cleanup really seems overkill to me. Automation is nice,
but not everything is a nail even if all you have is a hammer.

> -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 d8a484e19830..fb44fe65c2cd 100644
> --- a/drivers/gpu/drm/drm_managed.c
> +++ b/drivers/gpu/drm/drm_managed.c
> @@ -132,6 +132,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) {

As before, &tmp->data, and let's rename tmp.

> +			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 240edd395e88..df30f9355902 100644
> --- a/include/drm/drm_managed.h
> +++ b/include/drm/drm_managed.h
> @@ -14,6 +14,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;

-- 
Regards,

Laurent Pinchart
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH 24/52] drm: Manage drm_gem_init with drmm_
  2020-02-19 14:37       ` [Intel-gfx] " Daniel Vetter
@ 2020-02-19 14:52         ` Laurent Pinchart
  -1 siblings, 0 replies; 310+ messages in thread
From: Laurent Pinchart @ 2020-02-19 14:52 UTC (permalink / raw)
  To: Daniel Vetter; +Cc: Daniel Vetter, Intel Graphics Development, DRI Development

Hi Daniel,

On Wed, Feb 19, 2020 at 03:37:46PM +0100, Daniel Vetter wrote:
> On Wed, Feb 19, 2020 at 3:22 PM Laurent Pinchart wrote:
> > On Wed, Feb 19, 2020 at 11:20:54AM +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>
> > > ---
> > >  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 03a1fb377830..7b3df1188da9 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);
> >
> > This looks fine as such (although I'm not sure if the managed API
> > overhead is really worth it for core code), but it leads to a potential
> > issue: if we handle more of the cleanup through the managed API, how do
> > we ensure that the cleanup functions are called in the right order (when
> > order matters) ?
> 
> KASAN essentially (already helped while developing this), plus review.
> It's still the same problem like reviewing onion unwind code, it's
> just less fragile for the normal case.

That wasn't really my question though. If there are ordering
constraints, and if we want to honour them, the ordering of cleanups
need to be documented in the API (and of course implemented). We may for
instance want to always do cleanups in the reverse order of the
allocations.

> I also think that if you have ordering constraints in your drm_device
> release functions, there's a more fundamental problem going on.
> Unfortunately we have a lot of these, which is why converting
> everything in drm, including drivers, is not going to be easy nor
> quick. There's a lot of problems. E.g. naively converting all
> drm_connector allocations from devm_kzalloc to drmm_kzalloc still
> means they get released too early, since the drm_mode_config_init
> happens before you set up the connectors. So you still have the
> problem that your connector_funcs->destroy gets called on already
> freed memory. Lots of work ahead.

Yes that's the kind of issue I was thinking about. We have ordering
constraints, they will not go away. What's your idea on how to handle
this ?

> > >  }
> > >
> > >  /**
> > > 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);

-- 
Regards,

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

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

* Re: [Intel-gfx] [PATCH 24/52] drm: Manage drm_gem_init with drmm_
@ 2020-02-19 14:52         ` Laurent Pinchart
  0 siblings, 0 replies; 310+ messages in thread
From: Laurent Pinchart @ 2020-02-19 14:52 UTC (permalink / raw)
  To: Daniel Vetter; +Cc: Daniel Vetter, Intel Graphics Development, DRI Development

Hi Daniel,

On Wed, Feb 19, 2020 at 03:37:46PM +0100, Daniel Vetter wrote:
> On Wed, Feb 19, 2020 at 3:22 PM Laurent Pinchart wrote:
> > On Wed, Feb 19, 2020 at 11:20:54AM +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>
> > > ---
> > >  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 03a1fb377830..7b3df1188da9 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);
> >
> > This looks fine as such (although I'm not sure if the managed API
> > overhead is really worth it for core code), but it leads to a potential
> > issue: if we handle more of the cleanup through the managed API, how do
> > we ensure that the cleanup functions are called in the right order (when
> > order matters) ?
> 
> KASAN essentially (already helped while developing this), plus review.
> It's still the same problem like reviewing onion unwind code, it's
> just less fragile for the normal case.

That wasn't really my question though. If there are ordering
constraints, and if we want to honour them, the ordering of cleanups
need to be documented in the API (and of course implemented). We may for
instance want to always do cleanups in the reverse order of the
allocations.

> I also think that if you have ordering constraints in your drm_device
> release functions, there's a more fundamental problem going on.
> Unfortunately we have a lot of these, which is why converting
> everything in drm, including drivers, is not going to be easy nor
> quick. There's a lot of problems. E.g. naively converting all
> drm_connector allocations from devm_kzalloc to drmm_kzalloc still
> means they get released too early, since the drm_mode_config_init
> happens before you set up the connectors. So you still have the
> problem that your connector_funcs->destroy gets called on already
> freed memory. Lots of work ahead.

Yes that's the kind of issue I was thinking about. We have ordering
constraints, they will not go away. What's your idea on how to handle
this ?

> > >  }
> > >
> > >  /**
> > > 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);

-- 
Regards,

Laurent Pinchart
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH 24/52] drm: Manage drm_gem_init with drmm_
  2020-02-19 14:52         ` [Intel-gfx] " Laurent Pinchart
@ 2020-02-19 14:56           ` Daniel Vetter
  -1 siblings, 0 replies; 310+ messages in thread
From: Daniel Vetter @ 2020-02-19 14:56 UTC (permalink / raw)
  To: Laurent Pinchart
  Cc: Daniel Vetter, Intel Graphics Development, DRI Development

On Wed, Feb 19, 2020 at 3:52 PM Laurent Pinchart
<laurent.pinchart@ideasonboard.com> wrote:
>
> Hi Daniel,
>
> On Wed, Feb 19, 2020 at 03:37:46PM +0100, Daniel Vetter wrote:
> > On Wed, Feb 19, 2020 at 3:22 PM Laurent Pinchart wrote:
> > > On Wed, Feb 19, 2020 at 11:20:54AM +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>
> > > > ---
> > > >  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 03a1fb377830..7b3df1188da9 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);
> > >
> > > This looks fine as such (although I'm not sure if the managed API
> > > overhead is really worth it for core code), but it leads to a potential
> > > issue: if we handle more of the cleanup through the managed API, how do
> > > we ensure that the cleanup functions are called in the right order (when
> > > order matters) ?
> >
> > KASAN essentially (already helped while developing this), plus review.
> > It's still the same problem like reviewing onion unwind code, it's
> > just less fragile for the normal case.
>
> That wasn't really my question though. If there are ordering
> constraints, and if we want to honour them, the ordering of cleanups
> need to be documented in the API (and of course implemented). We may for
> instance want to always do cleanups in the reverse order of the
> allocations.
>
> > I also think that if you have ordering constraints in your drm_device
> > release functions, there's a more fundamental problem going on.
> > Unfortunately we have a lot of these, which is why converting
> > everything in drm, including drivers, is not going to be easy nor
> > quick. There's a lot of problems. E.g. naively converting all
> > drm_connector allocations from devm_kzalloc to drmm_kzalloc still
> > means they get released too early, since the drm_mode_config_init
> > happens before you set up the connectors. So you still have the
> > problem that your connector_funcs->destroy gets called on already
> > freed memory. Lots of work ahead.
>
> Yes that's the kind of issue I was thinking about. We have ordering
> constraints, they will not go away. What's your idea on how to handle
> this ?

drmm_ guarantees that release actions are executed in reverse order of
how they're added. That's the right thing to do in 99% of cases. For
the others you need manual unwind logic, maybe with a combined release
action. Or some some safety checks in your release hook. I think the
drm_minor_alloc conversion is a useful example of some of the problems
that can lurk, and options for handling it all.
-Daniel

>
> > > >  }
> > > >
> > > >  /**
> > > > 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);
>
> --
> Regards,
>
> Laurent Pinchart



-- 
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] 310+ messages in thread

* Re: [Intel-gfx] [PATCH 24/52] drm: Manage drm_gem_init with drmm_
@ 2020-02-19 14:56           ` Daniel Vetter
  0 siblings, 0 replies; 310+ messages in thread
From: Daniel Vetter @ 2020-02-19 14:56 UTC (permalink / raw)
  To: Laurent Pinchart
  Cc: Daniel Vetter, Intel Graphics Development, DRI Development

On Wed, Feb 19, 2020 at 3:52 PM Laurent Pinchart
<laurent.pinchart@ideasonboard.com> wrote:
>
> Hi Daniel,
>
> On Wed, Feb 19, 2020 at 03:37:46PM +0100, Daniel Vetter wrote:
> > On Wed, Feb 19, 2020 at 3:22 PM Laurent Pinchart wrote:
> > > On Wed, Feb 19, 2020 at 11:20:54AM +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>
> > > > ---
> > > >  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 03a1fb377830..7b3df1188da9 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);
> > >
> > > This looks fine as such (although I'm not sure if the managed API
> > > overhead is really worth it for core code), but it leads to a potential
> > > issue: if we handle more of the cleanup through the managed API, how do
> > > we ensure that the cleanup functions are called in the right order (when
> > > order matters) ?
> >
> > KASAN essentially (already helped while developing this), plus review.
> > It's still the same problem like reviewing onion unwind code, it's
> > just less fragile for the normal case.
>
> That wasn't really my question though. If there are ordering
> constraints, and if we want to honour them, the ordering of cleanups
> need to be documented in the API (and of course implemented). We may for
> instance want to always do cleanups in the reverse order of the
> allocations.
>
> > I also think that if you have ordering constraints in your drm_device
> > release functions, there's a more fundamental problem going on.
> > Unfortunately we have a lot of these, which is why converting
> > everything in drm, including drivers, is not going to be easy nor
> > quick. There's a lot of problems. E.g. naively converting all
> > drm_connector allocations from devm_kzalloc to drmm_kzalloc still
> > means they get released too early, since the drm_mode_config_init
> > happens before you set up the connectors. So you still have the
> > problem that your connector_funcs->destroy gets called on already
> > freed memory. Lots of work ahead.
>
> Yes that's the kind of issue I was thinking about. We have ordering
> constraints, they will not go away. What's your idea on how to handle
> this ?

drmm_ guarantees that release actions are executed in reverse order of
how they're added. That's the right thing to do in 99% of cases. For
the others you need manual unwind logic, maybe with a combined release
action. Or some some safety checks in your release hook. I think the
drm_minor_alloc conversion is a useful example of some of the problems
that can lurk, and options for handling it all.
-Daniel

>
> > > >  }
> > > >
> > > >  /**
> > > > 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);
>
> --
> Regards,
>
> Laurent Pinchart



-- 
Daniel Vetter
Software Engineer, Intel Corporation
+41 (0) 79 365 57 48 - http://blog.ffwll.ch
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH 52/52] drm: Add docs for managed resources
  2020-02-19 10:21   ` [Intel-gfx] " Daniel Vetter
@ 2020-02-19 15:08     ` Laurent Pinchart
  -1 siblings, 0 replies; 310+ messages in thread
From: Laurent Pinchart @ 2020-02-19 15:08 UTC (permalink / raw)
  To: Daniel Vetter; +Cc: Daniel Vetter, Intel Graphics Development, DRI Development

Hi Daniel,

Thank you for the patch.

On Wed, Feb 19, 2020 at 11:21:22AM +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.

Do you think it would be hard to do this already, in order to avoid
drmm_add_final_kfree() ?

> - 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).

I think it will get messy if we try to use the managed API for too many
things.

> 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).
> 
> 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       | 63 ++++++++++++++++++++++++++++-
>  include/drm/drm_drv.h               |  4 ++
>  include/drm/drm_managed.h           | 47 +++++++++++++++++++++
>  5 files changed, 134 insertions(+), 4 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 428c569aaaf1..b1827ba53924 100644
> --- a/drivers/gpu/drm/drm_drv.c
> +++ b/drivers/gpu/drm/drm_drv.c
> @@ -258,9 +258,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
>   * ~~~~~~~~~~~~~~~~~~~~~~
> @@ -604,6 +610,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.
>   */
> @@ -705,6 +714,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 fb44fe65c2cd..7fcbe90d3f46 100644
> --- a/drivers/gpu/drm/drm_managed.c
> +++ b/drivers/gpu/drm/drm_managed.c
> @@ -17,10 +17,22 @@
>  /**
>   * DOC: managed resources
>   *
> - * Inspired by sturct &device managed resources, but tied to the lifetime of
> + * 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 at driver load
> + * time.

Maybe drop "at driver load time" as it could also happen later ?

> + *
> + * 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 when they change

s/only when they/only for resources that/ ?

> + * rarely, if ever, during the lifetime of the &drm_device instance.
>   */
> +
>  struct drmres_node {
>  	struct list_head		entry;
>  	drmres_release_t		release;
> @@ -102,6 +114,18 @@ 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
> + * @data: 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);
> @@ -132,6 +156,14 @@ int __drmm_add_action(struct drm_device *dev,
>  }
>  EXPORT_SYMBOL(__drmm_add_action);
>  
> +/**
> + * drmm_add_action - remave a managed release action to a &drm_device

s/remave/remove/

> + * @dev: DRM device
> + * @action: release function
> + * @data: opaque pointer, passed to @action
> + *
> + * This function removes a release action added by drmm_add_action.

s/drmm_add_action/drmm_add_action()/

> + */
>  void drmm_remove_action(struct drm_device *dev,
>  			drmres_release_t action,
>  			void *data)
> @@ -160,6 +192,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;
> @@ -175,6 +217,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
> + * @size: 0 terminated string to be duplicated

s/0 terminated/0-terminated/

> + * @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;
> @@ -191,6 +243,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 = NULL, *tmp;
> 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.

I'm afraid we can't necessarily do this. Drivers may create multiple
userspace-facing devices, or other resources used within the kernel (for
instance a driver could expose both a DRM and a V4L2 device, or
registers clocks used by other devices). We thus need a .release()
function in the general case to handle this, as the top-level structure
needs to be reference-counted.

I agree this isn't the norm, so we can document the .release() function
as being rarely used, and recommend the drmm_* API, but we can't
deprecate it completely.

>  	 */
>  	void (*release) (struct drm_device *);
>  
> diff --git a/include/drm/drm_managed.h b/include/drm/drm_managed.h
> index 573cadca4b3d..0e7616bd0858 100644
> --- a/include/drm/drm_managed.h
> +++ b/include/drm/drm_managed.h
> @@ -8,6 +8,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 wwith optional parameter @data to the

s/wwith/with/

> + * 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)
>  
> @@ -22,12 +35,45 @@ 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
> + * @size: 0 terminated string to be duplicated

s/0 terminated/0-terminated/

> + * @gfp: 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)
> +
> +/**
> + * drmm_kcalloc - &drm_device managed kcalloc()
> + * @dev: DRM device
> + * @size: 0 terminated string to be duplicated

Ditto.

> + * @gfp: 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().
> + */
>  {
>  	size_t bytes;
>  
> @@ -41,6 +87,7 @@ static inline void *drmm_kcalloc(struct drm_device *dev,
>  {
>  	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);

-- 
Regards,

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

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

* Re: [Intel-gfx] [PATCH 52/52] drm: Add docs for managed resources
@ 2020-02-19 15:08     ` Laurent Pinchart
  0 siblings, 0 replies; 310+ messages in thread
From: Laurent Pinchart @ 2020-02-19 15:08 UTC (permalink / raw)
  To: Daniel Vetter; +Cc: Daniel Vetter, Intel Graphics Development, DRI Development

Hi Daniel,

Thank you for the patch.

On Wed, Feb 19, 2020 at 11:21:22AM +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.

Do you think it would be hard to do this already, in order to avoid
drmm_add_final_kfree() ?

> - 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).

I think it will get messy if we try to use the managed API for too many
things.

> 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).
> 
> 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       | 63 ++++++++++++++++++++++++++++-
>  include/drm/drm_drv.h               |  4 ++
>  include/drm/drm_managed.h           | 47 +++++++++++++++++++++
>  5 files changed, 134 insertions(+), 4 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 428c569aaaf1..b1827ba53924 100644
> --- a/drivers/gpu/drm/drm_drv.c
> +++ b/drivers/gpu/drm/drm_drv.c
> @@ -258,9 +258,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
>   * ~~~~~~~~~~~~~~~~~~~~~~
> @@ -604,6 +610,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.
>   */
> @@ -705,6 +714,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 fb44fe65c2cd..7fcbe90d3f46 100644
> --- a/drivers/gpu/drm/drm_managed.c
> +++ b/drivers/gpu/drm/drm_managed.c
> @@ -17,10 +17,22 @@
>  /**
>   * DOC: managed resources
>   *
> - * Inspired by sturct &device managed resources, but tied to the lifetime of
> + * 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 at driver load
> + * time.

Maybe drop "at driver load time" as it could also happen later ?

> + *
> + * 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 when they change

s/only when they/only for resources that/ ?

> + * rarely, if ever, during the lifetime of the &drm_device instance.
>   */
> +
>  struct drmres_node {
>  	struct list_head		entry;
>  	drmres_release_t		release;
> @@ -102,6 +114,18 @@ 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
> + * @data: 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);
> @@ -132,6 +156,14 @@ int __drmm_add_action(struct drm_device *dev,
>  }
>  EXPORT_SYMBOL(__drmm_add_action);
>  
> +/**
> + * drmm_add_action - remave a managed release action to a &drm_device

s/remave/remove/

> + * @dev: DRM device
> + * @action: release function
> + * @data: opaque pointer, passed to @action
> + *
> + * This function removes a release action added by drmm_add_action.

s/drmm_add_action/drmm_add_action()/

> + */
>  void drmm_remove_action(struct drm_device *dev,
>  			drmres_release_t action,
>  			void *data)
> @@ -160,6 +192,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;
> @@ -175,6 +217,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
> + * @size: 0 terminated string to be duplicated

s/0 terminated/0-terminated/

> + * @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;
> @@ -191,6 +243,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 = NULL, *tmp;
> 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.

I'm afraid we can't necessarily do this. Drivers may create multiple
userspace-facing devices, or other resources used within the kernel (for
instance a driver could expose both a DRM and a V4L2 device, or
registers clocks used by other devices). We thus need a .release()
function in the general case to handle this, as the top-level structure
needs to be reference-counted.

I agree this isn't the norm, so we can document the .release() function
as being rarely used, and recommend the drmm_* API, but we can't
deprecate it completely.

>  	 */
>  	void (*release) (struct drm_device *);
>  
> diff --git a/include/drm/drm_managed.h b/include/drm/drm_managed.h
> index 573cadca4b3d..0e7616bd0858 100644
> --- a/include/drm/drm_managed.h
> +++ b/include/drm/drm_managed.h
> @@ -8,6 +8,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 wwith optional parameter @data to the

s/wwith/with/

> + * 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)
>  
> @@ -22,12 +35,45 @@ 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
> + * @size: 0 terminated string to be duplicated

s/0 terminated/0-terminated/

> + * @gfp: 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)
> +
> +/**
> + * drmm_kcalloc - &drm_device managed kcalloc()
> + * @dev: DRM device
> + * @size: 0 terminated string to be duplicated

Ditto.

> + * @gfp: 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().
> + */
>  {
>  	size_t bytes;
>  
> @@ -41,6 +87,7 @@ static inline void *drmm_kcalloc(struct drm_device *dev,
>  {
>  	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);

-- 
Regards,

Laurent Pinchart
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH 21/52] drm: Handle dev->unique with drmm_
  2020-02-19 14:28     ` [Intel-gfx] " Laurent Pinchart
@ 2020-02-19 15:24       ` Daniel Vetter
  -1 siblings, 0 replies; 310+ messages in thread
From: Daniel Vetter @ 2020-02-19 15:24 UTC (permalink / raw)
  To: Laurent Pinchart, Greg KH
  Cc: Daniel Vetter, Intel Graphics Development, DRI Development

On Wed, Feb 19, 2020 at 3:28 PM Laurent Pinchart
<laurent.pinchart@ideasonboard.com> wrote:
>
> Hi Daniel,
>
> Thank you for the patch.
>
> On Wed, Feb 19, 2020 at 11:20:51AM +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>
> > ---
> >  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 1ee606b4a4f9..782fd5d6f8b2 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);
> >
> > @@ -1063,8 +1062,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 ee7c7253af61..d8a484e19830 100644
> > --- a/drivers/gpu/drm/drm_managed.c
> > +++ b/drivers/gpu/drm/drm_managed.c
> > @@ -147,6 +147,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)
>
> Do we need support for gfp_t other than GFP_KERNEL ? Given that the
> memory will be released when the drm_device is destroyed, GFP_ATOMIC
> would seem of dubious use to me, and we may want to not make it possible
> to use it.

Hm .. I just copied the devm_ functions with struct drm_device
substituting struct device. I agree there's not going to be a use-case
for anything else than GFP_KERNEL. If there ever will be, I guess we
could add a __drm_kmallock for that case.

The downside of dropping the gfp argument is that drmm_ wont be a
drop-in replacament for devm_k*alloc functions anymore. Adding Greg,
maybe he has a good idea about what we should be doing here?

Personally I'd be happy to drop the gfp argument, it feels somewhat
pointless for these.
-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 = NULL, *tmp;
> > diff --git a/include/drm/drm_managed.h b/include/drm/drm_managed.h
> > index 75f2c8932c69..240edd395e88 100644
> > --- a/include/drm/drm_managed.h
> > +++ b/include/drm/drm_managed.h
> > @@ -21,5 +21,6 @@ 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);
>
> --
> Regards,
>
> Laurent Pinchart



-- 
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] 310+ messages in thread

* Re: [Intel-gfx] [PATCH 21/52] drm: Handle dev->unique with drmm_
@ 2020-02-19 15:24       ` Daniel Vetter
  0 siblings, 0 replies; 310+ messages in thread
From: Daniel Vetter @ 2020-02-19 15:24 UTC (permalink / raw)
  To: Laurent Pinchart, Greg KH
  Cc: Daniel Vetter, Intel Graphics Development, DRI Development

On Wed, Feb 19, 2020 at 3:28 PM Laurent Pinchart
<laurent.pinchart@ideasonboard.com> wrote:
>
> Hi Daniel,
>
> Thank you for the patch.
>
> On Wed, Feb 19, 2020 at 11:20:51AM +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>
> > ---
> >  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 1ee606b4a4f9..782fd5d6f8b2 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);
> >
> > @@ -1063,8 +1062,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 ee7c7253af61..d8a484e19830 100644
> > --- a/drivers/gpu/drm/drm_managed.c
> > +++ b/drivers/gpu/drm/drm_managed.c
> > @@ -147,6 +147,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)
>
> Do we need support for gfp_t other than GFP_KERNEL ? Given that the
> memory will be released when the drm_device is destroyed, GFP_ATOMIC
> would seem of dubious use to me, and we may want to not make it possible
> to use it.

Hm .. I just copied the devm_ functions with struct drm_device
substituting struct device. I agree there's not going to be a use-case
for anything else than GFP_KERNEL. If there ever will be, I guess we
could add a __drm_kmallock for that case.

The downside of dropping the gfp argument is that drmm_ wont be a
drop-in replacament for devm_k*alloc functions anymore. Adding Greg,
maybe he has a good idea about what we should be doing here?

Personally I'd be happy to drop the gfp argument, it feels somewhat
pointless for these.
-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 = NULL, *tmp;
> > diff --git a/include/drm/drm_managed.h b/include/drm/drm_managed.h
> > index 75f2c8932c69..240edd395e88 100644
> > --- a/include/drm/drm_managed.h
> > +++ b/include/drm/drm_managed.h
> > @@ -21,5 +21,6 @@ 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);
>
> --
> Regards,
>
> Laurent Pinchart



-- 
Daniel Vetter
Software Engineer, Intel Corporation
+41 (0) 79 365 57 48 - http://blog.ffwll.ch
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH 22/52] drm: Use drmm_ for drm_dev_init cleanup
  2020-02-19 14:35     ` [Intel-gfx] " Laurent Pinchart
@ 2020-02-19 15:27       ` Daniel Vetter
  -1 siblings, 0 replies; 310+ messages in thread
From: Daniel Vetter @ 2020-02-19 15:27 UTC (permalink / raw)
  To: Laurent Pinchart
  Cc: Daniel Vetter, Intel Graphics Development, DRI Development

On Wed, Feb 19, 2020 at 3:35 PM Laurent Pinchart
<laurent.pinchart@ideasonboard.com> wrote:
>
> Hi Daniel,
>
> Thank you for the patch.
>
> On Wed, Feb 19, 2020 at 11:20:52AM +0100, Daniel Vetter wrote:
> > 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(-)
>
> Is the managed API overhead, coupled with the fact that the code size
> doesn't get reduced, worth it for core code ?

I've mostly done this as an example, to show how if you do this
consistently, you can drop a few if (is_it_set_up) checks and remove
the onion unwinding with lots of gotos. I do think it's worth it from
that pov, since long-term I want to get to a world where everything
related to drm_device gets unwound with drmm_ actions. The logging
output becomes fairly nice if you enable it :-)

But yeah stand-alone it's not a good pitch. Heck even the overall
patch series is still a net loss I think, simply because this is just
the bare minimum to get started.
-Daniel

> > diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c
> > index 782fd5d6f8b2..1f7ab88d9435 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);
> >
>
> --
> Regards,
>
> Laurent Pinchart



-- 
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] 310+ messages in thread

* Re: [Intel-gfx] [PATCH 22/52] drm: Use drmm_ for drm_dev_init cleanup
@ 2020-02-19 15:27       ` Daniel Vetter
  0 siblings, 0 replies; 310+ messages in thread
From: Daniel Vetter @ 2020-02-19 15:27 UTC (permalink / raw)
  To: Laurent Pinchart
  Cc: Daniel Vetter, Intel Graphics Development, DRI Development

On Wed, Feb 19, 2020 at 3:35 PM Laurent Pinchart
<laurent.pinchart@ideasonboard.com> wrote:
>
> Hi Daniel,
>
> Thank you for the patch.
>
> On Wed, Feb 19, 2020 at 11:20:52AM +0100, Daniel Vetter wrote:
> > 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(-)
>
> Is the managed API overhead, coupled with the fact that the code size
> doesn't get reduced, worth it for core code ?

I've mostly done this as an example, to show how if you do this
consistently, you can drop a few if (is_it_set_up) checks and remove
the onion unwinding with lots of gotos. I do think it's worth it from
that pov, since long-term I want to get to a world where everything
related to drm_device gets unwound with drmm_ actions. The logging
output becomes fairly nice if you enable it :-)

But yeah stand-alone it's not a good pitch. Heck even the overall
patch series is still a net loss I think, simply because this is just
the bare minimum to get started.
-Daniel

> > diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c
> > index 782fd5d6f8b2..1f7ab88d9435 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);
> >
>
> --
> Regards,
>
> Laurent Pinchart



-- 
Daniel Vetter
Software Engineer, Intel Corporation
+41 (0) 79 365 57 48 - http://blog.ffwll.ch
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH 19/52] drm/<drivers>: Use drmm_add_final_kfree
  2020-02-19 14:39         ` [Intel-gfx] " Laurent Pinchart
@ 2020-02-19 15:29           ` Daniel Vetter
  -1 siblings, 0 replies; 310+ messages in thread
From: Daniel Vetter @ 2020-02-19 15:29 UTC (permalink / raw)
  To: Laurent Pinchart
  Cc: Intel Graphics Development, Liviu Dudau, Russell King,
	DRI Development, Hans de Goede, James (Qian) Wang, Daniel Vetter,
	Mihail Atanassov

On Wed, Feb 19, 2020 at 3:39 PM Laurent Pinchart
<laurent.pinchart@ideasonboard.com> wrote:
>
> Hi Daniel,
>
> On Wed, Feb 19, 2020 at 03:30:59PM +0100, Daniel Vetter wrote:
> > On Wed, Feb 19, 2020 at 3:11 PM Laurent Pinchart wrote:
> > > On Wed, Feb 19, 2020 at 11:20:49AM +0100, Daniel Vetter wrote:
> > > > These are the leftover drivers that didn't have a ->release hook that
> > > > needed to be updated.
> > > >
> > > > 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);
> > >
> > > Instead of sprinkling calls to drmm_add_final_kfree() everywhere,
> > > wouldn't it be better to pass the parent pointer to drm_dev_init() ?
> >
> > Would lead to a horrendous monster patch, and even with this splitting
> > there were a few corner cases.
>
> It could be generated by coccinelle, with the semantic patch included in
> the commit message, so that regenerating it should be possible when
> merging if conflict arise.

It's not that easy, because drivers are buggy. So you need to review
the remove/release implementation for all of them (which I've done) to
make sure you're not making things worse with some additional
use-after-free or something else horrible. That's why this is so much
split up.

So automated patch for this is out of the window imo.
-Daniel

> > My plan is to add a devm_drm_dev_alloc
> > pattern which combines the usual pattern that most drivers use, see
> > the last patch for all these glorious ideas.
>
> OK I will.
>
> > So yeah I hope this will all go away (or mostly at least), but for
> > bisecting I didn't come up with a better idea to get this all off the
> > ground unfortunately.
> >
> > > >
> > > >       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);
>
> --
> Regards,
>
> Laurent Pinchart



-- 
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] 310+ messages in thread

* Re: [Intel-gfx] [PATCH 19/52] drm/<drivers>: Use drmm_add_final_kfree
@ 2020-02-19 15:29           ` Daniel Vetter
  0 siblings, 0 replies; 310+ messages in thread
From: Daniel Vetter @ 2020-02-19 15:29 UTC (permalink / raw)
  To: Laurent Pinchart
  Cc: Intel Graphics Development, Russell King, DRI Development,
	James (Qian) Wang, Daniel Vetter, Mihail Atanassov

On Wed, Feb 19, 2020 at 3:39 PM Laurent Pinchart
<laurent.pinchart@ideasonboard.com> wrote:
>
> Hi Daniel,
>
> On Wed, Feb 19, 2020 at 03:30:59PM +0100, Daniel Vetter wrote:
> > On Wed, Feb 19, 2020 at 3:11 PM Laurent Pinchart wrote:
> > > On Wed, Feb 19, 2020 at 11:20:49AM +0100, Daniel Vetter wrote:
> > > > These are the leftover drivers that didn't have a ->release hook that
> > > > needed to be updated.
> > > >
> > > > 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);
> > >
> > > Instead of sprinkling calls to drmm_add_final_kfree() everywhere,
> > > wouldn't it be better to pass the parent pointer to drm_dev_init() ?
> >
> > Would lead to a horrendous monster patch, and even with this splitting
> > there were a few corner cases.
>
> It could be generated by coccinelle, with the semantic patch included in
> the commit message, so that regenerating it should be possible when
> merging if conflict arise.

It's not that easy, because drivers are buggy. So you need to review
the remove/release implementation for all of them (which I've done) to
make sure you're not making things worse with some additional
use-after-free or something else horrible. That's why this is so much
split up.

So automated patch for this is out of the window imo.
-Daniel

> > My plan is to add a devm_drm_dev_alloc
> > pattern which combines the usual pattern that most drivers use, see
> > the last patch for all these glorious ideas.
>
> OK I will.
>
> > So yeah I hope this will all go away (or mostly at least), but for
> > bisecting I didn't come up with a better idea to get this all off the
> > ground unfortunately.
> >
> > > >
> > > >       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);
>
> --
> Regards,
>
> Laurent Pinchart



-- 
Daniel Vetter
Software Engineer, Intel Corporation
+41 (0) 79 365 57 48 - http://blog.ffwll.ch
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH 23/52] drm: manage drm_minor cleanup with drmm_
  2020-02-19 14:47     ` [Intel-gfx] " Laurent Pinchart
@ 2020-02-19 15:34       ` Daniel Vetter
  -1 siblings, 0 replies; 310+ messages in thread
From: Daniel Vetter @ 2020-02-19 15:34 UTC (permalink / raw)
  To: Laurent Pinchart
  Cc: Daniel Vetter, Intel Graphics Development, DRI Development

On Wed, Feb 19, 2020 at 3:47 PM Laurent Pinchart
<laurent.pinchart@ideasonboard.com> wrote:
>
> Hi Daniel,
>
> Thank you for the patch.
>
> On Wed, Feb 19, 2020 at 11:20:53AM +0100, Daniel Vetter wrote:
> > 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.
> >
> > 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 1f7ab88d9435..03a1fb377830 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);
>
> The need to do the drmm_remove_action() dance, with the need for
> drmm_remove_action() in the first place, just to remove those three
> lines of manual cleanup really seems overkill to me. Automation is nice,
> but not everything is a nail even if all you have is a hammer.

Still the same thing, I wanted to have onion unwinding for everything.
If we keep some things outside of drmm_ then I have to carefully
interleave the drm_managed_release with the cleanup actions, and
review that across all drivers. Which I had to do anyway, but this way
it's at least somewhat of a split-up.

Essentially for a safe conversion you need to look at what's the last
thing the code right before drm_managed_release manually cleans up
(whether drm core or drivers doesn't matter, so lots of reviewing).
And then converting that over to drmm_. Repeat until everything is
handled.

If you decide to not handle something because it's not worth it the
review complexity across all our drivers goes through the roof (and
there's soooooooo many special cases). Plus the core cleanup sequence
gets real nasty where you have to interleave all kinds of things.

I guess you could say I could just register one action for the
drm_dev_fini stuff, but I kinda wanted to start out with an example of
what this could look like in driver cleanup code. Ofc since it's core
code there's not going to be amplified code savings, but as an example
it's still useful I think.
-Daniel

> > -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 d8a484e19830..fb44fe65c2cd 100644
> > --- a/drivers/gpu/drm/drm_managed.c
> > +++ b/drivers/gpu/drm/drm_managed.c
> > @@ -132,6 +132,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) {
>
> As before, &tmp->data, and let's rename tmp.
>
> > +                     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 240edd395e88..df30f9355902 100644
> > --- a/include/drm/drm_managed.h
> > +++ b/include/drm/drm_managed.h
> > @@ -14,6 +14,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;
>
> --
> Regards,
>
> Laurent Pinchart



-- 
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] 310+ messages in thread

* Re: [Intel-gfx] [PATCH 23/52] drm: manage drm_minor cleanup with drmm_
@ 2020-02-19 15:34       ` Daniel Vetter
  0 siblings, 0 replies; 310+ messages in thread
From: Daniel Vetter @ 2020-02-19 15:34 UTC (permalink / raw)
  To: Laurent Pinchart
  Cc: Daniel Vetter, Intel Graphics Development, DRI Development

On Wed, Feb 19, 2020 at 3:47 PM Laurent Pinchart
<laurent.pinchart@ideasonboard.com> wrote:
>
> Hi Daniel,
>
> Thank you for the patch.
>
> On Wed, Feb 19, 2020 at 11:20:53AM +0100, Daniel Vetter wrote:
> > 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.
> >
> > 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 1f7ab88d9435..03a1fb377830 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);
>
> The need to do the drmm_remove_action() dance, with the need for
> drmm_remove_action() in the first place, just to remove those three
> lines of manual cleanup really seems overkill to me. Automation is nice,
> but not everything is a nail even if all you have is a hammer.

Still the same thing, I wanted to have onion unwinding for everything.
If we keep some things outside of drmm_ then I have to carefully
interleave the drm_managed_release with the cleanup actions, and
review that across all drivers. Which I had to do anyway, but this way
it's at least somewhat of a split-up.

Essentially for a safe conversion you need to look at what's the last
thing the code right before drm_managed_release manually cleans up
(whether drm core or drivers doesn't matter, so lots of reviewing).
And then converting that over to drmm_. Repeat until everything is
handled.

If you decide to not handle something because it's not worth it the
review complexity across all our drivers goes through the roof (and
there's soooooooo many special cases). Plus the core cleanup sequence
gets real nasty where you have to interleave all kinds of things.

I guess you could say I could just register one action for the
drm_dev_fini stuff, but I kinda wanted to start out with an example of
what this could look like in driver cleanup code. Ofc since it's core
code there's not going to be amplified code savings, but as an example
it's still useful I think.
-Daniel

> > -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 d8a484e19830..fb44fe65c2cd 100644
> > --- a/drivers/gpu/drm/drm_managed.c
> > +++ b/drivers/gpu/drm/drm_managed.c
> > @@ -132,6 +132,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) {
>
> As before, &tmp->data, and let's rename tmp.
>
> > +                     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 240edd395e88..df30f9355902 100644
> > --- a/include/drm/drm_managed.h
> > +++ b/include/drm/drm_managed.h
> > @@ -14,6 +14,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;
>
> --
> Regards,
>
> Laurent Pinchart



-- 
Daniel Vetter
Software Engineer, Intel Corporation
+41 (0) 79 365 57 48 - http://blog.ffwll.ch
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH 22/52] drm: Use drmm_ for drm_dev_init cleanup
  2020-02-19 15:27       ` [Intel-gfx] " Daniel Vetter
@ 2020-02-19 15:37         ` Laurent Pinchart
  -1 siblings, 0 replies; 310+ messages in thread
From: Laurent Pinchart @ 2020-02-19 15:37 UTC (permalink / raw)
  To: Daniel Vetter; +Cc: Daniel Vetter, Intel Graphics Development, DRI Development

Hi Daniel,

On Wed, Feb 19, 2020 at 04:27:57PM +0100, Daniel Vetter wrote:
> On Wed, Feb 19, 2020 at 3:35 PM Laurent Pinchart wrote:
> > On Wed, Feb 19, 2020 at 11:20:52AM +0100, Daniel Vetter wrote:
> > > 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(-)
> >
> > Is the managed API overhead, coupled with the fact that the code size
> > doesn't get reduced, worth it for core code ?
> 
> I've mostly done this as an example, to show how if you do this
> consistently, you can drop a few if (is_it_set_up) checks and remove
> the onion unwinding with lots of gotos.

That's however more a matter of making the cleanup handlers idempotent
than using a managed API, isn't it ?

> I do think it's worth it from
> that pov, since long-term I want to get to a world where everything
> related to drm_device gets unwound with drmm_ actions. The logging
> output becomes fairly nice if you enable it :-)
> 
> But yeah stand-alone it's not a good pitch. Heck even the overall
> patch series is still a net loss I think, simply because this is just
> the bare minimum to get started.
> -Daniel
> 
> > > diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c
> > > index 782fd5d6f8b2..1f7ab88d9435 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);
> > >

-- 
Regards,

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

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

* Re: [Intel-gfx] [PATCH 22/52] drm: Use drmm_ for drm_dev_init cleanup
@ 2020-02-19 15:37         ` Laurent Pinchart
  0 siblings, 0 replies; 310+ messages in thread
From: Laurent Pinchart @ 2020-02-19 15:37 UTC (permalink / raw)
  To: Daniel Vetter; +Cc: Daniel Vetter, Intel Graphics Development, DRI Development

Hi Daniel,

On Wed, Feb 19, 2020 at 04:27:57PM +0100, Daniel Vetter wrote:
> On Wed, Feb 19, 2020 at 3:35 PM Laurent Pinchart wrote:
> > On Wed, Feb 19, 2020 at 11:20:52AM +0100, Daniel Vetter wrote:
> > > 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(-)
> >
> > Is the managed API overhead, coupled with the fact that the code size
> > doesn't get reduced, worth it for core code ?
> 
> I've mostly done this as an example, to show how if you do this
> consistently, you can drop a few if (is_it_set_up) checks and remove
> the onion unwinding with lots of gotos.

That's however more a matter of making the cleanup handlers idempotent
than using a managed API, isn't it ?

> I do think it's worth it from
> that pov, since long-term I want to get to a world where everything
> related to drm_device gets unwound with drmm_ actions. The logging
> output becomes fairly nice if you enable it :-)
> 
> But yeah stand-alone it's not a good pitch. Heck even the overall
> patch series is still a net loss I think, simply because this is just
> the bare minimum to get started.
> -Daniel
> 
> > > diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c
> > > index 782fd5d6f8b2..1f7ab88d9435 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);
> > >

-- 
Regards,

Laurent Pinchart
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH 52/52] drm: Add docs for managed resources
  2020-02-19 15:08     ` [Intel-gfx] " Laurent Pinchart
@ 2020-02-19 15:40       ` Daniel Vetter
  -1 siblings, 0 replies; 310+ messages in thread
From: Daniel Vetter @ 2020-02-19 15:40 UTC (permalink / raw)
  To: Laurent Pinchart
  Cc: Daniel Vetter, Intel Graphics Development, DRI Development

On Wed, Feb 19, 2020 at 4:08 PM Laurent Pinchart
<laurent.pinchart@ideasonboard.com> wrote:
>
> Hi Daniel,
>
> Thank you for the patch.
>
> On Wed, Feb 19, 2020 at 11:21:22AM +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.
>
> Do you think it would be hard to do this already, in order to avoid
> drmm_add_final_kfree() ?

It's another 31 patches on top of this 52 patch series. Not hard per
se, but there's a lot going on already here, and a lot of this is very
tricky stuff that required endless amounts of reviewing everything.
I'd like to do the more automated stuff as a follow-up if possible,
I'm pretty sure I've not see a huge amount of exceptions from the
normal pattern. Iirc vgem and vkms need a rework to invert their
cleanup logic, so add 2 more patches for those. Everything else
follows the standard pattern iirc.

> > - 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).
>
> I think it will get messy if we try to use the managed API for too many
> things.

Hm why? I kinda plan to use it for everything you'd want to clean up
from drm_driver.release.

> > 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).
> >
> > 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       | 63 ++++++++++++++++++++++++++++-
> >  include/drm/drm_drv.h               |  4 ++
> >  include/drm/drm_managed.h           | 47 +++++++++++++++++++++
> >  5 files changed, 134 insertions(+), 4 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 428c569aaaf1..b1827ba53924 100644
> > --- a/drivers/gpu/drm/drm_drv.c
> > +++ b/drivers/gpu/drm/drm_drv.c
> > @@ -258,9 +258,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
> >   * ~~~~~~~~~~~~~~~~~~~~~~
> > @@ -604,6 +610,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.
> >   */
> > @@ -705,6 +714,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 fb44fe65c2cd..7fcbe90d3f46 100644
> > --- a/drivers/gpu/drm/drm_managed.c
> > +++ b/drivers/gpu/drm/drm_managed.c
> > @@ -17,10 +17,22 @@
> >  /**
> >   * DOC: managed resources
> >   *
> > - * Inspired by sturct &device managed resources, but tied to the lifetime of
> > + * 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 at driver load
> > + * time.
>
> Maybe drop "at driver load time" as it could also happen later ?

Maybe "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 when they change
>
> s/only when they/only for resources that/ ?
>
> > + * rarely, if ever, during the lifetime of the &drm_device instance.
> >   */
> > +
> >  struct drmres_node {
> >       struct list_head                entry;
> >       drmres_release_t                release;
> > @@ -102,6 +114,18 @@ 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
> > + * @data: 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);
> > @@ -132,6 +156,14 @@ int __drmm_add_action(struct drm_device *dev,
> >  }
> >  EXPORT_SYMBOL(__drmm_add_action);
> >
> > +/**
> > + * drmm_add_action - remave a managed release action to a &drm_device
>
> s/remave/remove/
>
> > + * @dev: DRM device
> > + * @action: release function
> > + * @data: opaque pointer, passed to @action
> > + *
> > + * This function removes a release action added by drmm_add_action.
>
> s/drmm_add_action/drmm_add_action()/
>
> > + */
> >  void drmm_remove_action(struct drm_device *dev,
> >                       drmres_release_t action,
> >                       void *data)
> > @@ -160,6 +192,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;
> > @@ -175,6 +217,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
> > + * @size: 0 terminated string to be duplicated
>
> s/0 terminated/0-terminated/
>
> > + * @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;
> > @@ -191,6 +243,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 = NULL, *tmp;
> > 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.
>
> I'm afraid we can't necessarily do this. Drivers may create multiple
> userspace-facing devices, or other resources used within the kernel (for
> instance a driver could expose both a DRM and a V4L2 device, or
> registers clocks used by other devices). We thus need a .release()
> function in the general case to handle this, as the top-level structure
> needs to be reference-counted.
>
> I agree this isn't the norm, so we can document the .release() function
> as being rarely used, and recommend the drmm_* API, but we can't
> deprecate it completely.

drmm_add_action(drm_device, put_the_overall_thing, the_overall_thing);
is what I have in mind for anyone that still needs a ->release
function for special stuff.

So instead of a single release function you get an unlimited number of
them, and the single release function becomes kinda pointless.

Agreed on all your other minor suggestions, I'll go ahead and add them.
-Daniel

>
> >        */
> >       void (*release) (struct drm_device *);
> >
> > diff --git a/include/drm/drm_managed.h b/include/drm/drm_managed.h
> > index 573cadca4b3d..0e7616bd0858 100644
> > --- a/include/drm/drm_managed.h
> > +++ b/include/drm/drm_managed.h
> > @@ -8,6 +8,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 wwith optional parameter @data to the
>
> s/wwith/with/
>
> > + * 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)
> >
> > @@ -22,12 +35,45 @@ 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
> > + * @size: 0 terminated string to be duplicated
>
> s/0 terminated/0-terminated/
>
> > + * @gfp: 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)
> > +
> > +/**
> > + * drmm_kcalloc - &drm_device managed kcalloc()
> > + * @dev: DRM device
> > + * @size: 0 terminated string to be duplicated
>
> Ditto.
>
> > + * @gfp: 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().
> > + */
> >  {
> >       size_t bytes;
> >
> > @@ -41,6 +87,7 @@ static inline void *drmm_kcalloc(struct drm_device *dev,
> >  {
> >       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);
>
> --
> Regards,
>
> Laurent Pinchart



-- 
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] 310+ messages in thread

* Re: [Intel-gfx] [PATCH 52/52] drm: Add docs for managed resources
@ 2020-02-19 15:40       ` Daniel Vetter
  0 siblings, 0 replies; 310+ messages in thread
From: Daniel Vetter @ 2020-02-19 15:40 UTC (permalink / raw)
  To: Laurent Pinchart
  Cc: Daniel Vetter, Intel Graphics Development, DRI Development

On Wed, Feb 19, 2020 at 4:08 PM Laurent Pinchart
<laurent.pinchart@ideasonboard.com> wrote:
>
> Hi Daniel,
>
> Thank you for the patch.
>
> On Wed, Feb 19, 2020 at 11:21:22AM +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.
>
> Do you think it would be hard to do this already, in order to avoid
> drmm_add_final_kfree() ?

It's another 31 patches on top of this 52 patch series. Not hard per
se, but there's a lot going on already here, and a lot of this is very
tricky stuff that required endless amounts of reviewing everything.
I'd like to do the more automated stuff as a follow-up if possible,
I'm pretty sure I've not see a huge amount of exceptions from the
normal pattern. Iirc vgem and vkms need a rework to invert their
cleanup logic, so add 2 more patches for those. Everything else
follows the standard pattern iirc.

> > - 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).
>
> I think it will get messy if we try to use the managed API for too many
> things.

Hm why? I kinda plan to use it for everything you'd want to clean up
from drm_driver.release.

> > 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).
> >
> > 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       | 63 ++++++++++++++++++++++++++++-
> >  include/drm/drm_drv.h               |  4 ++
> >  include/drm/drm_managed.h           | 47 +++++++++++++++++++++
> >  5 files changed, 134 insertions(+), 4 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 428c569aaaf1..b1827ba53924 100644
> > --- a/drivers/gpu/drm/drm_drv.c
> > +++ b/drivers/gpu/drm/drm_drv.c
> > @@ -258,9 +258,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
> >   * ~~~~~~~~~~~~~~~~~~~~~~
> > @@ -604,6 +610,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.
> >   */
> > @@ -705,6 +714,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 fb44fe65c2cd..7fcbe90d3f46 100644
> > --- a/drivers/gpu/drm/drm_managed.c
> > +++ b/drivers/gpu/drm/drm_managed.c
> > @@ -17,10 +17,22 @@
> >  /**
> >   * DOC: managed resources
> >   *
> > - * Inspired by sturct &device managed resources, but tied to the lifetime of
> > + * 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 at driver load
> > + * time.
>
> Maybe drop "at driver load time" as it could also happen later ?

Maybe "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 when they change
>
> s/only when they/only for resources that/ ?
>
> > + * rarely, if ever, during the lifetime of the &drm_device instance.
> >   */
> > +
> >  struct drmres_node {
> >       struct list_head                entry;
> >       drmres_release_t                release;
> > @@ -102,6 +114,18 @@ 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
> > + * @data: 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);
> > @@ -132,6 +156,14 @@ int __drmm_add_action(struct drm_device *dev,
> >  }
> >  EXPORT_SYMBOL(__drmm_add_action);
> >
> > +/**
> > + * drmm_add_action - remave a managed release action to a &drm_device
>
> s/remave/remove/
>
> > + * @dev: DRM device
> > + * @action: release function
> > + * @data: opaque pointer, passed to @action
> > + *
> > + * This function removes a release action added by drmm_add_action.
>
> s/drmm_add_action/drmm_add_action()/
>
> > + */
> >  void drmm_remove_action(struct drm_device *dev,
> >                       drmres_release_t action,
> >                       void *data)
> > @@ -160,6 +192,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;
> > @@ -175,6 +217,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
> > + * @size: 0 terminated string to be duplicated
>
> s/0 terminated/0-terminated/
>
> > + * @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;
> > @@ -191,6 +243,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 = NULL, *tmp;
> > 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.
>
> I'm afraid we can't necessarily do this. Drivers may create multiple
> userspace-facing devices, or other resources used within the kernel (for
> instance a driver could expose both a DRM and a V4L2 device, or
> registers clocks used by other devices). We thus need a .release()
> function in the general case to handle this, as the top-level structure
> needs to be reference-counted.
>
> I agree this isn't the norm, so we can document the .release() function
> as being rarely used, and recommend the drmm_* API, but we can't
> deprecate it completely.

drmm_add_action(drm_device, put_the_overall_thing, the_overall_thing);
is what I have in mind for anyone that still needs a ->release
function for special stuff.

So instead of a single release function you get an unlimited number of
them, and the single release function becomes kinda pointless.

Agreed on all your other minor suggestions, I'll go ahead and add them.
-Daniel

>
> >        */
> >       void (*release) (struct drm_device *);
> >
> > diff --git a/include/drm/drm_managed.h b/include/drm/drm_managed.h
> > index 573cadca4b3d..0e7616bd0858 100644
> > --- a/include/drm/drm_managed.h
> > +++ b/include/drm/drm_managed.h
> > @@ -8,6 +8,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 wwith optional parameter @data to the
>
> s/wwith/with/
>
> > + * 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)
> >
> > @@ -22,12 +35,45 @@ 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
> > + * @size: 0 terminated string to be duplicated
>
> s/0 terminated/0-terminated/
>
> > + * @gfp: 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)
> > +
> > +/**
> > + * drmm_kcalloc - &drm_device managed kcalloc()
> > + * @dev: DRM device
> > + * @size: 0 terminated string to be duplicated
>
> Ditto.
>
> > + * @gfp: 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().
> > + */
> >  {
> >       size_t bytes;
> >
> > @@ -41,6 +87,7 @@ static inline void *drmm_kcalloc(struct drm_device *dev,
> >  {
> >       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);
>
> --
> Regards,
>
> Laurent Pinchart



-- 
Daniel Vetter
Software Engineer, Intel Corporation
+41 (0) 79 365 57 48 - http://blog.ffwll.ch
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH 22/52] drm: Use drmm_ for drm_dev_init cleanup
  2020-02-19 15:37         ` [Intel-gfx] " Laurent Pinchart
@ 2020-02-19 15:44           ` Daniel Vetter
  -1 siblings, 0 replies; 310+ messages in thread
From: Daniel Vetter @ 2020-02-19 15:44 UTC (permalink / raw)
  To: Laurent Pinchart
  Cc: Daniel Vetter, Intel Graphics Development, DRI Development

On Wed, Feb 19, 2020 at 4:38 PM Laurent Pinchart
<laurent.pinchart@ideasonboard.com> wrote:
>
> Hi Daniel,
>
> On Wed, Feb 19, 2020 at 04:27:57PM +0100, Daniel Vetter wrote:
> > On Wed, Feb 19, 2020 at 3:35 PM Laurent Pinchart wrote:
> > > On Wed, Feb 19, 2020 at 11:20:52AM +0100, Daniel Vetter wrote:
> > > > 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(-)
> > >
> > > Is the managed API overhead, coupled with the fact that the code size
> > > doesn't get reduced, worth it for core code ?
> >
> > I've mostly done this as an example, to show how if you do this
> > consistently, you can drop a few if (is_it_set_up) checks and remove
> > the onion unwinding with lots of gotos.
>
> That's however more a matter of making the cleanup handlers idempotent
> than using a managed API, isn't it ?

With the managed api you can drop the if (is_it_set_up/allocated)
checks since you no longer need them to be idempotent for simpler code
flow. That's at least the point I've tried to make with this patch.
-Daniel

> > I do think it's worth it from
> > that pov, since long-term I want to get to a world where everything
> > related to drm_device gets unwound with drmm_ actions. The logging
> > output becomes fairly nice if you enable it :-)
> >
> > But yeah stand-alone it's not a good pitch. Heck even the overall
> > patch series is still a net loss I think, simply because this is just
> > the bare minimum to get started.
> > -Daniel
> >
> > > > diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c
> > > > index 782fd5d6f8b2..1f7ab88d9435 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);
> > > >
>
> --
> Regards,
>
> Laurent Pinchart



-- 
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] 310+ messages in thread

* Re: [Intel-gfx] [PATCH 22/52] drm: Use drmm_ for drm_dev_init cleanup
@ 2020-02-19 15:44           ` Daniel Vetter
  0 siblings, 0 replies; 310+ messages in thread
From: Daniel Vetter @ 2020-02-19 15:44 UTC (permalink / raw)
  To: Laurent Pinchart
  Cc: Daniel Vetter, Intel Graphics Development, DRI Development

On Wed, Feb 19, 2020 at 4:38 PM Laurent Pinchart
<laurent.pinchart@ideasonboard.com> wrote:
>
> Hi Daniel,
>
> On Wed, Feb 19, 2020 at 04:27:57PM +0100, Daniel Vetter wrote:
> > On Wed, Feb 19, 2020 at 3:35 PM Laurent Pinchart wrote:
> > > On Wed, Feb 19, 2020 at 11:20:52AM +0100, Daniel Vetter wrote:
> > > > 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(-)
> > >
> > > Is the managed API overhead, coupled with the fact that the code size
> > > doesn't get reduced, worth it for core code ?
> >
> > I've mostly done this as an example, to show how if you do this
> > consistently, you can drop a few if (is_it_set_up) checks and remove
> > the onion unwinding with lots of gotos.
>
> That's however more a matter of making the cleanup handlers idempotent
> than using a managed API, isn't it ?

With the managed api you can drop the if (is_it_set_up/allocated)
checks since you no longer need them to be idempotent for simpler code
flow. That's at least the point I've tried to make with this patch.
-Daniel

> > I do think it's worth it from
> > that pov, since long-term I want to get to a world where everything
> > related to drm_device gets unwound with drmm_ actions. The logging
> > output becomes fairly nice if you enable it :-)
> >
> > But yeah stand-alone it's not a good pitch. Heck even the overall
> > patch series is still a net loss I think, simply because this is just
> > the bare minimum to get started.
> > -Daniel
> >
> > > > diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c
> > > > index 782fd5d6f8b2..1f7ab88d9435 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);
> > > >
>
> --
> Regards,
>
> Laurent Pinchart



-- 
Daniel Vetter
Software Engineer, Intel Corporation
+41 (0) 79 365 57 48 - http://blog.ffwll.ch
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH 27/52] drm: Manage drm_mode_config_init with drmm_
  2020-02-19 13:49     ` [Intel-gfx] " Laurent Pinchart
@ 2020-02-19 15:47       ` Daniel Vetter
  -1 siblings, 0 replies; 310+ messages in thread
From: Daniel Vetter @ 2020-02-19 15:47 UTC (permalink / raw)
  To: Laurent Pinchart
  Cc: Daniel Vetter, Intel Graphics Development, Sam Ravnborg,
	Thomas Zimmermann, DRI Development

On Wed, Feb 19, 2020 at 2:50 PM Laurent Pinchart
<laurent.pinchart@ideasonboard.com> wrote:
>
> Hi Daniel,
>
> Thank you for the patch.
>
> On Wed, Feb 19, 2020 at 11:20:57AM +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 not 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, so deprecate that hook to discourage future users.
> >
> > v2: Fixup the example in the kerneldoc too.
> >
> > Cc: "Noralf Trønnes" <noralf@tronnes.org>
> > Cc: Sam Ravnborg <sam@ravnborg.org>
> > Cc: Thomas Zimmermann <tzimmermann@suse.de>
> > Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
> > ---
> >  drivers/gpu/drm/drm_drv.c         | 21 +++++----------------
> >  drivers/gpu/drm/drm_mode_config.c | 12 +++++++++++-
> >  include/drm/drm_mode_config.h     |  2 +-
> >  3 files changed, 17 insertions(+), 18 deletions(-)
> >
> > diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c
> > index 3cf40864d4a6..428c569aaaf1 100644
> > --- a/drivers/gpu/drm/drm_drv.c
> > +++ b/drivers/gpu/drm/drm_drv.c
> > @@ -267,8 +267,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 +277,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 +303,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 +703,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 +714,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_mode_config.c b/drivers/gpu/drm/drm_mode_config.c
> > index 08e6eff6a179..957db1edba0c 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,8 @@ void drm_mode_config_init(struct drm_device *dev)
> >               drm_modeset_acquire_fini(&modeset_ctx);
> >               dma_resv_fini(&resv);
> >       }
> > +
> > +     return drmm_add_action(dev, drm_mode_config_init_release, NULL);
>
> If this fails, shouldn't drm_mode_config_cleanup() be called here ?

Maybe for ocd reasons, but not for actually cleaning up anything. It's
just a bunch of empty lists that drm_mode_config_cleanup will walk and
do nothing about. Not sure I should add that ...
-Daniel

> >  }
> >  EXPORT_SYMBOL(drm_mode_config_init);
> >
> > diff --git a/include/drm/drm_mode_config.h b/include/drm/drm_mode_config.h
> > index 3bcbe30339f0..160a3e4b51c3 100644
> > --- a/include/drm/drm_mode_config.h
> > +++ b/include/drm/drm_mode_config.h
> > @@ -929,7 +929,7 @@ 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);
> >  void drm_mode_config_reset(struct drm_device *dev);
> >  void drm_mode_config_cleanup(struct drm_device *dev);
> >
>
> --
> Regards,
>
> Laurent Pinchart



-- 
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] 310+ messages in thread

* Re: [Intel-gfx] [PATCH 27/52] drm: Manage drm_mode_config_init with drmm_
@ 2020-02-19 15:47       ` Daniel Vetter
  0 siblings, 0 replies; 310+ messages in thread
From: Daniel Vetter @ 2020-02-19 15:47 UTC (permalink / raw)
  To: Laurent Pinchart
  Cc: Daniel Vetter, Intel Graphics Development, Sam Ravnborg,
	Thomas Zimmermann, DRI Development

On Wed, Feb 19, 2020 at 2:50 PM Laurent Pinchart
<laurent.pinchart@ideasonboard.com> wrote:
>
> Hi Daniel,
>
> Thank you for the patch.
>
> On Wed, Feb 19, 2020 at 11:20:57AM +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 not 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, so deprecate that hook to discourage future users.
> >
> > v2: Fixup the example in the kerneldoc too.
> >
> > Cc: "Noralf Trønnes" <noralf@tronnes.org>
> > Cc: Sam Ravnborg <sam@ravnborg.org>
> > Cc: Thomas Zimmermann <tzimmermann@suse.de>
> > Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
> > ---
> >  drivers/gpu/drm/drm_drv.c         | 21 +++++----------------
> >  drivers/gpu/drm/drm_mode_config.c | 12 +++++++++++-
> >  include/drm/drm_mode_config.h     |  2 +-
> >  3 files changed, 17 insertions(+), 18 deletions(-)
> >
> > diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c
> > index 3cf40864d4a6..428c569aaaf1 100644
> > --- a/drivers/gpu/drm/drm_drv.c
> > +++ b/drivers/gpu/drm/drm_drv.c
> > @@ -267,8 +267,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 +277,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 +303,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 +703,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 +714,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_mode_config.c b/drivers/gpu/drm/drm_mode_config.c
> > index 08e6eff6a179..957db1edba0c 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,8 @@ void drm_mode_config_init(struct drm_device *dev)
> >               drm_modeset_acquire_fini(&modeset_ctx);
> >               dma_resv_fini(&resv);
> >       }
> > +
> > +     return drmm_add_action(dev, drm_mode_config_init_release, NULL);
>
> If this fails, shouldn't drm_mode_config_cleanup() be called here ?

Maybe for ocd reasons, but not for actually cleaning up anything. It's
just a bunch of empty lists that drm_mode_config_cleanup will walk and
do nothing about. Not sure I should add that ...
-Daniel

> >  }
> >  EXPORT_SYMBOL(drm_mode_config_init);
> >
> > diff --git a/include/drm/drm_mode_config.h b/include/drm/drm_mode_config.h
> > index 3bcbe30339f0..160a3e4b51c3 100644
> > --- a/include/drm/drm_mode_config.h
> > +++ b/include/drm/drm_mode_config.h
> > @@ -929,7 +929,7 @@ 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);
> >  void drm_mode_config_reset(struct drm_device *dev);
> >  void drm_mode_config_cleanup(struct drm_device *dev);
> >
>
> --
> Regards,
>
> Laurent Pinchart



-- 
Daniel Vetter
Software Engineer, Intel Corporation
+41 (0) 79 365 57 48 - http://blog.ffwll.ch
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH 27/52] drm: Manage drm_mode_config_init with drmm_
  2020-02-19 15:47       ` [Intel-gfx] " Daniel Vetter
@ 2020-02-19 16:07         ` Laurent Pinchart
  -1 siblings, 0 replies; 310+ messages in thread
From: Laurent Pinchart @ 2020-02-19 16:07 UTC (permalink / raw)
  To: Daniel Vetter
  Cc: Daniel Vetter, Intel Graphics Development, Sam Ravnborg,
	Thomas Zimmermann, DRI Development

Hi Daniel,

On Wed, Feb 19, 2020 at 04:47:55PM +0100, Daniel Vetter wrote:
> On Wed, Feb 19, 2020 at 2:50 PM Laurent Pinchart wrote:
> > On Wed, Feb 19, 2020 at 11:20:57AM +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 not 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, so deprecate that hook to discourage future users.
> > >
> > > v2: Fixup the example in the kerneldoc too.
> > >
> > > Cc: "Noralf Trønnes" <noralf@tronnes.org>
> > > Cc: Sam Ravnborg <sam@ravnborg.org>
> > > Cc: Thomas Zimmermann <tzimmermann@suse.de>
> > > Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
> > > ---
> > >  drivers/gpu/drm/drm_drv.c         | 21 +++++----------------
> > >  drivers/gpu/drm/drm_mode_config.c | 12 +++++++++++-
> > >  include/drm/drm_mode_config.h     |  2 +-
> > >  3 files changed, 17 insertions(+), 18 deletions(-)
> > >
> > > diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c
> > > index 3cf40864d4a6..428c569aaaf1 100644
> > > --- a/drivers/gpu/drm/drm_drv.c
> > > +++ b/drivers/gpu/drm/drm_drv.c
> > > @@ -267,8 +267,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 +277,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 +303,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 +703,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 +714,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_mode_config.c b/drivers/gpu/drm/drm_mode_config.c
> > > index 08e6eff6a179..957db1edba0c 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,8 @@ void drm_mode_config_init(struct drm_device *dev)
> > >               drm_modeset_acquire_fini(&modeset_ctx);
> > >               dma_resv_fini(&resv);
> > >       }
> > > +
> > > +     return drmm_add_action(dev, drm_mode_config_init_release, NULL);
> >
> > If this fails, shouldn't drm_mode_config_cleanup() be called here ?
> 
> Maybe for ocd reasons, but not for actually cleaning up anything. It's
> just a bunch of empty lists that drm_mode_config_cleanup will walk and
> do nothing about. Not sure I should add that ...

How about the ida init, and the mutex_init() that isn't a no-op when
lock debugging is enabled ?

> > >  }
> > >  EXPORT_SYMBOL(drm_mode_config_init);
> > >
> > > diff --git a/include/drm/drm_mode_config.h b/include/drm/drm_mode_config.h
> > > index 3bcbe30339f0..160a3e4b51c3 100644
> > > --- a/include/drm/drm_mode_config.h
> > > +++ b/include/drm/drm_mode_config.h
> > > @@ -929,7 +929,7 @@ 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);
> > >  void drm_mode_config_reset(struct drm_device *dev);
> > >  void drm_mode_config_cleanup(struct drm_device *dev);
> > >

-- 
Regards,

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

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

* Re: [Intel-gfx] [PATCH 27/52] drm: Manage drm_mode_config_init with drmm_
@ 2020-02-19 16:07         ` Laurent Pinchart
  0 siblings, 0 replies; 310+ messages in thread
From: Laurent Pinchart @ 2020-02-19 16:07 UTC (permalink / raw)
  To: Daniel Vetter
  Cc: Daniel Vetter, Intel Graphics Development, Sam Ravnborg,
	Thomas Zimmermann, DRI Development

Hi Daniel,

On Wed, Feb 19, 2020 at 04:47:55PM +0100, Daniel Vetter wrote:
> On Wed, Feb 19, 2020 at 2:50 PM Laurent Pinchart wrote:
> > On Wed, Feb 19, 2020 at 11:20:57AM +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 not 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, so deprecate that hook to discourage future users.
> > >
> > > v2: Fixup the example in the kerneldoc too.
> > >
> > > Cc: "Noralf Trønnes" <noralf@tronnes.org>
> > > Cc: Sam Ravnborg <sam@ravnborg.org>
> > > Cc: Thomas Zimmermann <tzimmermann@suse.de>
> > > Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
> > > ---
> > >  drivers/gpu/drm/drm_drv.c         | 21 +++++----------------
> > >  drivers/gpu/drm/drm_mode_config.c | 12 +++++++++++-
> > >  include/drm/drm_mode_config.h     |  2 +-
> > >  3 files changed, 17 insertions(+), 18 deletions(-)
> > >
> > > diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c
> > > index 3cf40864d4a6..428c569aaaf1 100644
> > > --- a/drivers/gpu/drm/drm_drv.c
> > > +++ b/drivers/gpu/drm/drm_drv.c
> > > @@ -267,8 +267,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 +277,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 +303,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 +703,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 +714,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_mode_config.c b/drivers/gpu/drm/drm_mode_config.c
> > > index 08e6eff6a179..957db1edba0c 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,8 @@ void drm_mode_config_init(struct drm_device *dev)
> > >               drm_modeset_acquire_fini(&modeset_ctx);
> > >               dma_resv_fini(&resv);
> > >       }
> > > +
> > > +     return drmm_add_action(dev, drm_mode_config_init_release, NULL);
> >
> > If this fails, shouldn't drm_mode_config_cleanup() be called here ?
> 
> Maybe for ocd reasons, but not for actually cleaning up anything. It's
> just a bunch of empty lists that drm_mode_config_cleanup will walk and
> do nothing about. Not sure I should add that ...

How about the ida init, and the mutex_init() that isn't a no-op when
lock debugging is enabled ?

> > >  }
> > >  EXPORT_SYMBOL(drm_mode_config_init);
> > >
> > > diff --git a/include/drm/drm_mode_config.h b/include/drm/drm_mode_config.h
> > > index 3bcbe30339f0..160a3e4b51c3 100644
> > > --- a/include/drm/drm_mode_config.h
> > > +++ b/include/drm/drm_mode_config.h
> > > @@ -929,7 +929,7 @@ 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);
> > >  void drm_mode_config_reset(struct drm_device *dev);
> > >  void drm_mode_config_cleanup(struct drm_device *dev);
> > >

-- 
Regards,

Laurent Pinchart
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [Intel-gfx] [PATCH 03/52] drm: add managed resources tied to drm_device
  2020-02-19 14:22         ` [Intel-gfx] " Daniel Vetter
@ 2020-02-19 16:09           ` Emil Velikov
  -1 siblings, 0 replies; 310+ messages in thread
From: Emil Velikov @ 2020-02-19 16:09 UTC (permalink / raw)
  To: Daniel Vetter
  Cc: Rafael J. Wysocki, Greg Kroah-Hartman,
	Intel Graphics Development, DRI Development, Laurent Pinchart,
	Daniel Vetter

On Wed, 19 Feb 2020 at 14:23, Daniel Vetter <daniel.vetter@ffwll.ch> wrote:
>
> On Wed, Feb 19, 2020 at 2:33 PM Greg Kroah-Hartman
> <gregkh@linuxfoundation.org> wrote:
> >
> > On Wed, Feb 19, 2020 at 03:28:47PM +0200, Laurent Pinchart wrote:
> > > Hi Daniel,
> > >
> > > Thank you for the patch.
> > >
> > > On Wed, Feb 19, 2020 at 11:20:33AM +0100, Daniel Vetter wrote:
> > > > 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.
> > >
> > > This is all a very good idea ! Many subsystems are plagged by drivers
> > > using devm_k*alloc to allocate data accessible by userspace. Since the
> > > introduction of devm_*, we've likely reduced the number of memory leaks,
> > > but I'm pretty sure we've increased the risk of crashes as I've seen
> > > some drivers that used .release() callbacks correctly being naively
> > > converted to incorrect devm_* usage :-(
> > >
> > > This leads me to a question: if other subsystems have the same problem,
> > > could we turn this implementation into something more generic ? It
> > > doesn't have to be done right away and shouldn't block merging this
> > > series, but I think it would be very useful.
> >
> > It shouldn't be that hard to tie this into a drv_m() type of a thing
> > (driver_memory?)
> >
> > And yes, I think it's much better than devm_* for the obvious reasons of
> > this being needed here.
>
> There's two reasons I went with copypasta instead of trying to share code:
> - Type checking, I definitely don't want people to mix up devm_ with
> drmm_. But even if we do a drv_m that subsystems could embed we do
> have quite a few different types of component drivers (and with
> drm_panel and drm_bridge even standardized), and I don't want people
> to be able to pass the wrong kind of struct to e.g. a managed
> drmm_connector_init - it really needs to be the drm_device, not a
> panel or bridge or something else.
>
> - We could still share the code as a kind of implementation/backend
> library. But it's not much, and with embedding I could use the drm
> device logging stuff which is kinda nice. But if there's more demand
> for this I can definitely see the point in sharing this, as Laurent
> pointed out with the tiny optimization with not allocating a NULL void
> * that I've done (and screwed up) it's not entirely trivial code.
>

My 2c as they say, although closer to a brain dump :-)

On one hand the drm_device has an embedded struct device. On the other
drm_device preserves state which outlives the embedded struct device.

Would it make sense to keep drm_device better related to the
underlying device? Effectively moving the $misc state to drm_driver.
This idea does raise another question - struct drm_driver unlike many
other struct $foo_driver, does not embedded device_driver :-(
So if one is to cover the above two, then the embedding concerns will
be elevated.

WRT type safety, with the embedded work sorted, one could introduce
trivial helpers for drmm_connector_init and friends.

In another email you've also raised the question of API diversity and
reviews, I believe. IMHO one could start with a bare minimum set and
extend as needed.
Based on the prompt response from Greg, I suspect review won't be an issue.

If people agree with my analysis and considering the size/complexity
of drm_device <> drm_driver reshuffle, we could add a TODO task.
I suspect the underlying work will be larger than the current 52 patch
set, so doing it in one go will be PITA.

HTH
Emil

* Based on the following quick greps
$git grep -W "struct [a-zA-Z0-9-]*_driver {" -- include/ | grep -w
"struct device_driver\>.*;"  | wc -l
56
$git cgrep "struct [a-zA-Z0-9-]*_driver {" -- include/ | wc -l
71
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

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

* Re: [Intel-gfx] [PATCH 03/52] drm: add managed resources tied to drm_device
@ 2020-02-19 16:09           ` Emil Velikov
  0 siblings, 0 replies; 310+ messages in thread
From: Emil Velikov @ 2020-02-19 16:09 UTC (permalink / raw)
  To: Daniel Vetter
  Cc: Rafael J. Wysocki, Greg Kroah-Hartman,
	Intel Graphics Development, DRI Development, Laurent Pinchart,
	Daniel Vetter

On Wed, 19 Feb 2020 at 14:23, Daniel Vetter <daniel.vetter@ffwll.ch> wrote:
>
> On Wed, Feb 19, 2020 at 2:33 PM Greg Kroah-Hartman
> <gregkh@linuxfoundation.org> wrote:
> >
> > On Wed, Feb 19, 2020 at 03:28:47PM +0200, Laurent Pinchart wrote:
> > > Hi Daniel,
> > >
> > > Thank you for the patch.
> > >
> > > On Wed, Feb 19, 2020 at 11:20:33AM +0100, Daniel Vetter wrote:
> > > > 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.
> > >
> > > This is all a very good idea ! Many subsystems are plagged by drivers
> > > using devm_k*alloc to allocate data accessible by userspace. Since the
> > > introduction of devm_*, we've likely reduced the number of memory leaks,
> > > but I'm pretty sure we've increased the risk of crashes as I've seen
> > > some drivers that used .release() callbacks correctly being naively
> > > converted to incorrect devm_* usage :-(
> > >
> > > This leads me to a question: if other subsystems have the same problem,
> > > could we turn this implementation into something more generic ? It
> > > doesn't have to be done right away and shouldn't block merging this
> > > series, but I think it would be very useful.
> >
> > It shouldn't be that hard to tie this into a drv_m() type of a thing
> > (driver_memory?)
> >
> > And yes, I think it's much better than devm_* for the obvious reasons of
> > this being needed here.
>
> There's two reasons I went with copypasta instead of trying to share code:
> - Type checking, I definitely don't want people to mix up devm_ with
> drmm_. But even if we do a drv_m that subsystems could embed we do
> have quite a few different types of component drivers (and with
> drm_panel and drm_bridge even standardized), and I don't want people
> to be able to pass the wrong kind of struct to e.g. a managed
> drmm_connector_init - it really needs to be the drm_device, not a
> panel or bridge or something else.
>
> - We could still share the code as a kind of implementation/backend
> library. But it's not much, and with embedding I could use the drm
> device logging stuff which is kinda nice. But if there's more demand
> for this I can definitely see the point in sharing this, as Laurent
> pointed out with the tiny optimization with not allocating a NULL void
> * that I've done (and screwed up) it's not entirely trivial code.
>

My 2c as they say, although closer to a brain dump :-)

On one hand the drm_device has an embedded struct device. On the other
drm_device preserves state which outlives the embedded struct device.

Would it make sense to keep drm_device better related to the
underlying device? Effectively moving the $misc state to drm_driver.
This idea does raise another question - struct drm_driver unlike many
other struct $foo_driver, does not embedded device_driver :-(
So if one is to cover the above two, then the embedding concerns will
be elevated.

WRT type safety, with the embedded work sorted, one could introduce
trivial helpers for drmm_connector_init and friends.

In another email you've also raised the question of API diversity and
reviews, I believe. IMHO one could start with a bare minimum set and
extend as needed.
Based on the prompt response from Greg, I suspect review won't be an issue.

If people agree with my analysis and considering the size/complexity
of drm_device <> drm_driver reshuffle, we could add a TODO task.
I suspect the underlying work will be larger than the current 52 patch
set, so doing it in one go will be PITA.

HTH
Emil

* Based on the following quick greps
$git grep -W "struct [a-zA-Z0-9-]*_driver {" -- include/ | grep -w
"struct device_driver\>.*;"  | wc -l
56
$git cgrep "struct [a-zA-Z0-9-]*_driver {" -- include/ | wc -l
71
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH 13/52] drm/mcde: Use drmm_add_final_kfree
  2020-02-19 10:20   ` [Intel-gfx] " Daniel Vetter
@ 2020-02-19 16:12     ` Linus Walleij
  -1 siblings, 0 replies; 310+ messages in thread
From: Linus Walleij @ 2020-02-19 16:12 UTC (permalink / raw)
  To: Daniel Vetter; +Cc: Daniel Vetter, Intel Graphics Development, DRI Development

On Wed, Feb 19, 2020 at 11:21 AM Daniel Vetter <daniel.vetter@ffwll.ch> wrote:

> With this we can drop the final kfree from the release function.
>
> Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
> Cc: Linus Walleij <linus.walleij@linaro.org>

Reviewed-by: Linus Walleij <linus.walleij@linaro.org>

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

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

* Re: [Intel-gfx] [PATCH 13/52] drm/mcde: Use drmm_add_final_kfree
@ 2020-02-19 16:12     ` Linus Walleij
  0 siblings, 0 replies; 310+ messages in thread
From: Linus Walleij @ 2020-02-19 16:12 UTC (permalink / raw)
  To: Daniel Vetter; +Cc: Daniel Vetter, Intel Graphics Development, DRI Development

On Wed, Feb 19, 2020 at 11:21 AM Daniel Vetter <daniel.vetter@ffwll.ch> wrote:

> With this we can drop the final kfree from the release function.
>
> Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
> Cc: Linus Walleij <linus.walleij@linaro.org>

Reviewed-by: Linus Walleij <linus.walleij@linaro.org>

Yours,
Linus Walleij
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH 33/52] drm/mcde: Drop explicit drm_mode_config_cleanup call
  2020-02-19 10:21   ` [Intel-gfx] " Daniel Vetter
@ 2020-02-19 16:12     ` Linus Walleij
  -1 siblings, 0 replies; 310+ messages in thread
From: Linus Walleij @ 2020-02-19 16:12 UTC (permalink / raw)
  To: Daniel Vetter; +Cc: Daniel Vetter, Intel Graphics Development, DRI Development

On Wed, Feb 19, 2020 at 11:22 AM Daniel Vetter <daniel.vetter@ffwll.ch> wrote:

> Allows us to drop the drm_driver.release callback.
>
> Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
> Cc: Linus Walleij <linus.walleij@linaro.org>

Reviewed-by: Linus Walleij <linus.walleij@linaro.org>

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

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

* Re: [Intel-gfx] [PATCH 33/52] drm/mcde: Drop explicit drm_mode_config_cleanup call
@ 2020-02-19 16:12     ` Linus Walleij
  0 siblings, 0 replies; 310+ messages in thread
From: Linus Walleij @ 2020-02-19 16:12 UTC (permalink / raw)
  To: Daniel Vetter; +Cc: Daniel Vetter, Intel Graphics Development, DRI Development

On Wed, Feb 19, 2020 at 11:22 AM Daniel Vetter <daniel.vetter@ffwll.ch> wrote:

> Allows us to drop the drm_driver.release callback.
>
> Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
> Cc: Linus Walleij <linus.walleij@linaro.org>

Reviewed-by: Linus Walleij <linus.walleij@linaro.org>

Yours,
Linus Walleij
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH 34/52] drm/mcde: More devm_drm_dev_init
  2020-02-19 10:21   ` [Intel-gfx] " Daniel Vetter
@ 2020-02-19 16:13     ` Linus Walleij
  -1 siblings, 0 replies; 310+ messages in thread
From: Linus Walleij @ 2020-02-19 16:13 UTC (permalink / raw)
  To: Daniel Vetter; +Cc: Daniel Vetter, Intel Graphics Development, DRI Development

On Wed, Feb 19, 2020 at 11:22 AM Daniel Vetter <daniel.vetter@ffwll.ch> wrote:

> 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.
>
> Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
> Cc: Linus Walleij <linus.walleij@linaro.org>

Reviewed-by: Linus Walleij <linus.walleij@linaro.org>

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

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

* Re: [Intel-gfx] [PATCH 34/52] drm/mcde: More devm_drm_dev_init
@ 2020-02-19 16:13     ` Linus Walleij
  0 siblings, 0 replies; 310+ messages in thread
From: Linus Walleij @ 2020-02-19 16:13 UTC (permalink / raw)
  To: Daniel Vetter; +Cc: Daniel Vetter, Intel Graphics Development, DRI Development

On Wed, Feb 19, 2020 at 11:22 AM Daniel Vetter <daniel.vetter@ffwll.ch> wrote:

> 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.
>
> Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
> Cc: Linus Walleij <linus.walleij@linaro.org>

Reviewed-by: Linus Walleij <linus.walleij@linaro.org>

Yours,
Linus Walleij
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [Intel-gfx] [PATCH 03/52] drm: add managed resources tied to drm_device
  2020-02-19 16:09           ` Emil Velikov
@ 2020-02-19 16:22             ` Daniel Vetter
  -1 siblings, 0 replies; 310+ messages in thread
From: Daniel Vetter @ 2020-02-19 16:22 UTC (permalink / raw)
  To: Emil Velikov
  Cc: Rafael J. Wysocki, Greg Kroah-Hartman,
	Intel Graphics Development, DRI Development, Laurent Pinchart,
	Daniel Vetter

On Wed, Feb 19, 2020 at 5:09 PM Emil Velikov <emil.l.velikov@gmail.com> wrote:
>
> On Wed, 19 Feb 2020 at 14:23, Daniel Vetter <daniel.vetter@ffwll.ch> wrote:
> >
> > On Wed, Feb 19, 2020 at 2:33 PM Greg Kroah-Hartman
> > <gregkh@linuxfoundation.org> wrote:
> > >
> > > On Wed, Feb 19, 2020 at 03:28:47PM +0200, Laurent Pinchart wrote:
> > > > Hi Daniel,
> > > >
> > > > Thank you for the patch.
> > > >
> > > > On Wed, Feb 19, 2020 at 11:20:33AM +0100, Daniel Vetter wrote:
> > > > > 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.
> > > >
> > > > This is all a very good idea ! Many subsystems are plagged by drivers
> > > > using devm_k*alloc to allocate data accessible by userspace. Since the
> > > > introduction of devm_*, we've likely reduced the number of memory leaks,
> > > > but I'm pretty sure we've increased the risk of crashes as I've seen
> > > > some drivers that used .release() callbacks correctly being naively
> > > > converted to incorrect devm_* usage :-(
> > > >
> > > > This leads me to a question: if other subsystems have the same problem,
> > > > could we turn this implementation into something more generic ? It
> > > > doesn't have to be done right away and shouldn't block merging this
> > > > series, but I think it would be very useful.
> > >
> > > It shouldn't be that hard to tie this into a drv_m() type of a thing
> > > (driver_memory?)
> > >
> > > And yes, I think it's much better than devm_* for the obvious reasons of
> > > this being needed here.
> >
> > There's two reasons I went with copypasta instead of trying to share code:
> > - Type checking, I definitely don't want people to mix up devm_ with
> > drmm_. But even if we do a drv_m that subsystems could embed we do
> > have quite a few different types of component drivers (and with
> > drm_panel and drm_bridge even standardized), and I don't want people
> > to be able to pass the wrong kind of struct to e.g. a managed
> > drmm_connector_init - it really needs to be the drm_device, not a
> > panel or bridge or something else.
> >
> > - We could still share the code as a kind of implementation/backend
> > library. But it's not much, and with embedding I could use the drm
> > device logging stuff which is kinda nice. But if there's more demand
> > for this I can definitely see the point in sharing this, as Laurent
> > pointed out with the tiny optimization with not allocating a NULL void
> > * that I've done (and screwed up) it's not entirely trivial code.
> >
>
> My 2c as they say, although closer to a brain dump :-)
>
> On one hand the drm_device has an embedded struct device. On the other
> drm_device preserves state which outlives the embedded struct device.
>
> Would it make sense to keep drm_device better related to the
> underlying device? Effectively moving the $misc state to drm_driver.
> This idea does raise another question - struct drm_driver unlike many
> other struct $foo_driver, does not embedded device_driver :-(
> So if one is to cover the above two, then the embedding concerns will
> be elevated.

drm_driver isn't a bus device driver in the linux driver model sense,
but an uapi thing that sits on top of some underlying device. So maybe
better to rename drm_driver to drm_interface_driver, and drm_device to
drm_interface. But that would be giantic churn and probably lots of
confusion. We do require a link between drm_device->struct device
nowadays, but that's just to guarantee userspace can find the
drm_device in sysfs somewhere and make sense of what it actually
drives.

That's also why the lifetimes for the two things are totally
different. The device driver an all it's resources are tied to the
underlying physical device, and resources can be released when that
driver<->device link is broken (either unbind or hotunplug). That's
what devm_ does. The drm_driver/drm_device otoh is tied to the
userspace api, and can only disappear once all the userspace handles
have been cleaned up and released. And we have an enormous amount of
those, with all the mmaps, and shared fd for dma-buf, sync_file,
synobj and whatever else. The drm_device can only be cleaned up once
userspace has closed all these things, or we'll go boom somewhere. The
only connection is that the userspace interface drives the underlying
hw (as long as it's still there) and the hw side holds a reference on
the uapi side (drm_dev_get/put) to make sure the userspace side
doesn't go poof and disappear when no one has the /dev node open :-)

But aside from these links they're completely separate worlds, and
mixing up the lifetimes results in all kinds of bad things happening.
Ofc normally these two things exist at the same time, but hotunplug
makes things very interesting here. And traditionally we've handled it
badly, if at all in drm.

> WRT type safety, with the embedded work sorted, one could introduce
> trivial helpers for drmm_connector_init and friends.
>
> In another email you've also raised the question of API diversity and
> reviews, I believe. IMHO one could start with a bare minimum set and
> extend as needed.
> Based on the prompt response from Greg, I suspect review won't be an issue.

The drmm_ stuff in here is the bare minimum we need to get started. I
expect lots of stuff will be added, but those are all just going to be
convenience functions on top of the drmm_add_action primitive.

> If people agree with my analysis and considering the size/complexity
> of drm_device <> drm_driver reshuffle, we could add a TODO task.
> I suspect the underlying work will be larger than the current 52 patch
> set, so doing it in one go will be PITA.

I'm not following what you want to shuffle. drm_driver is entirely
static and kinda global, drm_device is the per-instance structure we
have. And here we mean per-userspace uapi interface instance. So I
guess I'm confused what you want to do?
-Daniel

>
> HTH
> Emil
>
> * Based on the following quick greps
> $git grep -W "struct [a-zA-Z0-9-]*_driver {" -- include/ | grep -w
> "struct device_driver\>.*;"  | wc -l
> 56
> $git cgrep "struct [a-zA-Z0-9-]*_driver {" -- include/ | wc -l
> 71



-- 
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] 310+ messages in thread

* Re: [Intel-gfx] [PATCH 03/52] drm: add managed resources tied to drm_device
@ 2020-02-19 16:22             ` Daniel Vetter
  0 siblings, 0 replies; 310+ messages in thread
From: Daniel Vetter @ 2020-02-19 16:22 UTC (permalink / raw)
  To: Emil Velikov
  Cc: Rafael J. Wysocki, Greg Kroah-Hartman,
	Intel Graphics Development, DRI Development, Laurent Pinchart,
	Daniel Vetter

On Wed, Feb 19, 2020 at 5:09 PM Emil Velikov <emil.l.velikov@gmail.com> wrote:
>
> On Wed, 19 Feb 2020 at 14:23, Daniel Vetter <daniel.vetter@ffwll.ch> wrote:
> >
> > On Wed, Feb 19, 2020 at 2:33 PM Greg Kroah-Hartman
> > <gregkh@linuxfoundation.org> wrote:
> > >
> > > On Wed, Feb 19, 2020 at 03:28:47PM +0200, Laurent Pinchart wrote:
> > > > Hi Daniel,
> > > >
> > > > Thank you for the patch.
> > > >
> > > > On Wed, Feb 19, 2020 at 11:20:33AM +0100, Daniel Vetter wrote:
> > > > > 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.
> > > >
> > > > This is all a very good idea ! Many subsystems are plagged by drivers
> > > > using devm_k*alloc to allocate data accessible by userspace. Since the
> > > > introduction of devm_*, we've likely reduced the number of memory leaks,
> > > > but I'm pretty sure we've increased the risk of crashes as I've seen
> > > > some drivers that used .release() callbacks correctly being naively
> > > > converted to incorrect devm_* usage :-(
> > > >
> > > > This leads me to a question: if other subsystems have the same problem,
> > > > could we turn this implementation into something more generic ? It
> > > > doesn't have to be done right away and shouldn't block merging this
> > > > series, but I think it would be very useful.
> > >
> > > It shouldn't be that hard to tie this into a drv_m() type of a thing
> > > (driver_memory?)
> > >
> > > And yes, I think it's much better than devm_* for the obvious reasons of
> > > this being needed here.
> >
> > There's two reasons I went with copypasta instead of trying to share code:
> > - Type checking, I definitely don't want people to mix up devm_ with
> > drmm_. But even if we do a drv_m that subsystems could embed we do
> > have quite a few different types of component drivers (and with
> > drm_panel and drm_bridge even standardized), and I don't want people
> > to be able to pass the wrong kind of struct to e.g. a managed
> > drmm_connector_init - it really needs to be the drm_device, not a
> > panel or bridge or something else.
> >
> > - We could still share the code as a kind of implementation/backend
> > library. But it's not much, and with embedding I could use the drm
> > device logging stuff which is kinda nice. But if there's more demand
> > for this I can definitely see the point in sharing this, as Laurent
> > pointed out with the tiny optimization with not allocating a NULL void
> > * that I've done (and screwed up) it's not entirely trivial code.
> >
>
> My 2c as they say, although closer to a brain dump :-)
>
> On one hand the drm_device has an embedded struct device. On the other
> drm_device preserves state which outlives the embedded struct device.
>
> Would it make sense to keep drm_device better related to the
> underlying device? Effectively moving the $misc state to drm_driver.
> This idea does raise another question - struct drm_driver unlike many
> other struct $foo_driver, does not embedded device_driver :-(
> So if one is to cover the above two, then the embedding concerns will
> be elevated.

drm_driver isn't a bus device driver in the linux driver model sense,
but an uapi thing that sits on top of some underlying device. So maybe
better to rename drm_driver to drm_interface_driver, and drm_device to
drm_interface. But that would be giantic churn and probably lots of
confusion. We do require a link between drm_device->struct device
nowadays, but that's just to guarantee userspace can find the
drm_device in sysfs somewhere and make sense of what it actually
drives.

That's also why the lifetimes for the two things are totally
different. The device driver an all it's resources are tied to the
underlying physical device, and resources can be released when that
driver<->device link is broken (either unbind or hotunplug). That's
what devm_ does. The drm_driver/drm_device otoh is tied to the
userspace api, and can only disappear once all the userspace handles
have been cleaned up and released. And we have an enormous amount of
those, with all the mmaps, and shared fd for dma-buf, sync_file,
synobj and whatever else. The drm_device can only be cleaned up once
userspace has closed all these things, or we'll go boom somewhere. The
only connection is that the userspace interface drives the underlying
hw (as long as it's still there) and the hw side holds a reference on
the uapi side (drm_dev_get/put) to make sure the userspace side
doesn't go poof and disappear when no one has the /dev node open :-)

But aside from these links they're completely separate worlds, and
mixing up the lifetimes results in all kinds of bad things happening.
Ofc normally these two things exist at the same time, but hotunplug
makes things very interesting here. And traditionally we've handled it
badly, if at all in drm.

> WRT type safety, with the embedded work sorted, one could introduce
> trivial helpers for drmm_connector_init and friends.
>
> In another email you've also raised the question of API diversity and
> reviews, I believe. IMHO one could start with a bare minimum set and
> extend as needed.
> Based on the prompt response from Greg, I suspect review won't be an issue.

The drmm_ stuff in here is the bare minimum we need to get started. I
expect lots of stuff will be added, but those are all just going to be
convenience functions on top of the drmm_add_action primitive.

> If people agree with my analysis and considering the size/complexity
> of drm_device <> drm_driver reshuffle, we could add a TODO task.
> I suspect the underlying work will be larger than the current 52 patch
> set, so doing it in one go will be PITA.

I'm not following what you want to shuffle. drm_driver is entirely
static and kinda global, drm_device is the per-instance structure we
have. And here we mean per-userspace uapi interface instance. So I
guess I'm confused what you want to do?
-Daniel

>
> HTH
> Emil
>
> * Based on the following quick greps
> $git grep -W "struct [a-zA-Z0-9-]*_driver {" -- include/ | grep -w
> "struct device_driver\>.*;"  | wc -l
> 56
> $git cgrep "struct [a-zA-Z0-9-]*_driver {" -- include/ | wc -l
> 71



-- 
Daniel Vetter
Software Engineer, Intel Corporation
+41 (0) 79 365 57 48 - http://blog.ffwll.ch
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH 27/52] drm: Manage drm_mode_config_init with drmm_
  2020-02-19 16:07         ` [Intel-gfx] " Laurent Pinchart
@ 2020-02-19 16:23           ` Daniel Vetter
  -1 siblings, 0 replies; 310+ messages in thread
From: Daniel Vetter @ 2020-02-19 16:23 UTC (permalink / raw)
  To: Laurent Pinchart
  Cc: Daniel Vetter, Intel Graphics Development, Sam Ravnborg,
	Thomas Zimmermann, DRI Development

On Wed, Feb 19, 2020 at 5:08 PM Laurent Pinchart
<laurent.pinchart@ideasonboard.com> wrote:
>
> Hi Daniel,
>
> On Wed, Feb 19, 2020 at 04:47:55PM +0100, Daniel Vetter wrote:
> > On Wed, Feb 19, 2020 at 2:50 PM Laurent Pinchart wrote:
> > > On Wed, Feb 19, 2020 at 11:20:57AM +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 not 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, so deprecate that hook to discourage future users.
> > > >
> > > > v2: Fixup the example in the kerneldoc too.
> > > >
> > > > Cc: "Noralf Trønnes" <noralf@tronnes.org>
> > > > Cc: Sam Ravnborg <sam@ravnborg.org>
> > > > Cc: Thomas Zimmermann <tzimmermann@suse.de>
> > > > Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
> > > > ---
> > > >  drivers/gpu/drm/drm_drv.c         | 21 +++++----------------
> > > >  drivers/gpu/drm/drm_mode_config.c | 12 +++++++++++-
> > > >  include/drm/drm_mode_config.h     |  2 +-
> > > >  3 files changed, 17 insertions(+), 18 deletions(-)
> > > >
> > > > diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c
> > > > index 3cf40864d4a6..428c569aaaf1 100644
> > > > --- a/drivers/gpu/drm/drm_drv.c
> > > > +++ b/drivers/gpu/drm/drm_drv.c
> > > > @@ -267,8 +267,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 +277,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 +303,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 +703,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 +714,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_mode_config.c b/drivers/gpu/drm/drm_mode_config.c
> > > > index 08e6eff6a179..957db1edba0c 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,8 @@ void drm_mode_config_init(struct drm_device *dev)
> > > >               drm_modeset_acquire_fini(&modeset_ctx);
> > > >               dma_resv_fini(&resv);
> > > >       }
> > > > +
> > > > +     return drmm_add_action(dev, drm_mode_config_init_release, NULL);
> > >
> > > If this fails, shouldn't drm_mode_config_cleanup() be called here ?
> >
> > Maybe for ocd reasons, but not for actually cleaning up anything. It's
> > just a bunch of empty lists that drm_mode_config_cleanup will walk and
> > do nothing about. Not sure I should add that ...
>
> How about the ida init, and the mutex_init() that isn't a no-op when
> lock debugging is enabled ?

Hm right, I'll fix this.

Fun thing is that I've found a pile of missing mutex_destroy and
ida_cleanup() while reviewing all the code I've read. Not sure I've
fixed them all up ...
-Daniel

>
> > > >  }
> > > >  EXPORT_SYMBOL(drm_mode_config_init);
> > > >
> > > > diff --git a/include/drm/drm_mode_config.h b/include/drm/drm_mode_config.h
> > > > index 3bcbe30339f0..160a3e4b51c3 100644
> > > > --- a/include/drm/drm_mode_config.h
> > > > +++ b/include/drm/drm_mode_config.h
> > > > @@ -929,7 +929,7 @@ 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);
> > > >  void drm_mode_config_reset(struct drm_device *dev);
> > > >  void drm_mode_config_cleanup(struct drm_device *dev);
> > > >
>
> --
> Regards,
>
> Laurent Pinchart



-- 
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] 310+ messages in thread

* Re: [Intel-gfx] [PATCH 27/52] drm: Manage drm_mode_config_init with drmm_
@ 2020-02-19 16:23           ` Daniel Vetter
  0 siblings, 0 replies; 310+ messages in thread
From: Daniel Vetter @ 2020-02-19 16:23 UTC (permalink / raw)
  To: Laurent Pinchart
  Cc: Daniel Vetter, Intel Graphics Development, Sam Ravnborg,
	Thomas Zimmermann, DRI Development

On Wed, Feb 19, 2020 at 5:08 PM Laurent Pinchart
<laurent.pinchart@ideasonboard.com> wrote:
>
> Hi Daniel,
>
> On Wed, Feb 19, 2020 at 04:47:55PM +0100, Daniel Vetter wrote:
> > On Wed, Feb 19, 2020 at 2:50 PM Laurent Pinchart wrote:
> > > On Wed, Feb 19, 2020 at 11:20:57AM +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 not 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, so deprecate that hook to discourage future users.
> > > >
> > > > v2: Fixup the example in the kerneldoc too.
> > > >
> > > > Cc: "Noralf Trønnes" <noralf@tronnes.org>
> > > > Cc: Sam Ravnborg <sam@ravnborg.org>
> > > > Cc: Thomas Zimmermann <tzimmermann@suse.de>
> > > > Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
> > > > ---
> > > >  drivers/gpu/drm/drm_drv.c         | 21 +++++----------------
> > > >  drivers/gpu/drm/drm_mode_config.c | 12 +++++++++++-
> > > >  include/drm/drm_mode_config.h     |  2 +-
> > > >  3 files changed, 17 insertions(+), 18 deletions(-)
> > > >
> > > > diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c
> > > > index 3cf40864d4a6..428c569aaaf1 100644
> > > > --- a/drivers/gpu/drm/drm_drv.c
> > > > +++ b/drivers/gpu/drm/drm_drv.c
> > > > @@ -267,8 +267,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 +277,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 +303,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 +703,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 +714,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_mode_config.c b/drivers/gpu/drm/drm_mode_config.c
> > > > index 08e6eff6a179..957db1edba0c 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,8 @@ void drm_mode_config_init(struct drm_device *dev)
> > > >               drm_modeset_acquire_fini(&modeset_ctx);
> > > >               dma_resv_fini(&resv);
> > > >       }
> > > > +
> > > > +     return drmm_add_action(dev, drm_mode_config_init_release, NULL);
> > >
> > > If this fails, shouldn't drm_mode_config_cleanup() be called here ?
> >
> > Maybe for ocd reasons, but not for actually cleaning up anything. It's
> > just a bunch of empty lists that drm_mode_config_cleanup will walk and
> > do nothing about. Not sure I should add that ...
>
> How about the ida init, and the mutex_init() that isn't a no-op when
> lock debugging is enabled ?

Hm right, I'll fix this.

Fun thing is that I've found a pile of missing mutex_destroy and
ida_cleanup() while reviewing all the code I've read. Not sure I've
fixed them all up ...
-Daniel

>
> > > >  }
> > > >  EXPORT_SYMBOL(drm_mode_config_init);
> > > >
> > > > diff --git a/include/drm/drm_mode_config.h b/include/drm/drm_mode_config.h
> > > > index 3bcbe30339f0..160a3e4b51c3 100644
> > > > --- a/include/drm/drm_mode_config.h
> > > > +++ b/include/drm/drm_mode_config.h
> > > > @@ -929,7 +929,7 @@ 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);
> > > >  void drm_mode_config_reset(struct drm_device *dev);
> > > >  void drm_mode_config_cleanup(struct drm_device *dev);
> > > >
>
> --
> Regards,
>
> Laurent Pinchart



-- 
Daniel Vetter
Software Engineer, Intel Corporation
+41 (0) 79 365 57 48 - http://blog.ffwll.ch
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [Intel-gfx] [PATCH 03/52] drm: add managed resources tied to drm_device
  2020-02-19 16:22             ` Daniel Vetter
@ 2020-02-19 16:41               ` Emil Velikov
  -1 siblings, 0 replies; 310+ messages in thread
From: Emil Velikov @ 2020-02-19 16:41 UTC (permalink / raw)
  To: Daniel Vetter
  Cc: Rafael J. Wysocki, Greg Kroah-Hartman,
	Intel Graphics Development, DRI Development, Laurent Pinchart,
	Daniel Vetter

On Wed, 19 Feb 2020 at 16:22, Daniel Vetter <daniel.vetter@ffwll.ch> wrote:
>
> On Wed, Feb 19, 2020 at 5:09 PM Emil Velikov <emil.l.velikov@gmail.com> wrote:
> >
> > On Wed, 19 Feb 2020 at 14:23, Daniel Vetter <daniel.vetter@ffwll.ch> wrote:
> > >
> > > On Wed, Feb 19, 2020 at 2:33 PM Greg Kroah-Hartman
> > > <gregkh@linuxfoundation.org> wrote:
> > > >
> > > > On Wed, Feb 19, 2020 at 03:28:47PM +0200, Laurent Pinchart wrote:
> > > > > Hi Daniel,
> > > > >
> > > > > Thank you for the patch.
> > > > >
> > > > > On Wed, Feb 19, 2020 at 11:20:33AM +0100, Daniel Vetter wrote:
> > > > > > 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.
> > > > >
> > > > > This is all a very good idea ! Many subsystems are plagged by drivers
> > > > > using devm_k*alloc to allocate data accessible by userspace. Since the
> > > > > introduction of devm_*, we've likely reduced the number of memory leaks,
> > > > > but I'm pretty sure we've increased the risk of crashes as I've seen
> > > > > some drivers that used .release() callbacks correctly being naively
> > > > > converted to incorrect devm_* usage :-(
> > > > >
> > > > > This leads me to a question: if other subsystems have the same problem,
> > > > > could we turn this implementation into something more generic ? It
> > > > > doesn't have to be done right away and shouldn't block merging this
> > > > > series, but I think it would be very useful.
> > > >
> > > > It shouldn't be that hard to tie this into a drv_m() type of a thing
> > > > (driver_memory?)
> > > >
> > > > And yes, I think it's much better than devm_* for the obvious reasons of
> > > > this being needed here.
> > >
> > > There's two reasons I went with copypasta instead of trying to share code:
> > > - Type checking, I definitely don't want people to mix up devm_ with
> > > drmm_. But even if we do a drv_m that subsystems could embed we do
> > > have quite a few different types of component drivers (and with
> > > drm_panel and drm_bridge even standardized), and I don't want people
> > > to be able to pass the wrong kind of struct to e.g. a managed
> > > drmm_connector_init - it really needs to be the drm_device, not a
> > > panel or bridge or something else.
> > >
> > > - We could still share the code as a kind of implementation/backend
> > > library. But it's not much, and with embedding I could use the drm
> > > device logging stuff which is kinda nice. But if there's more demand
> > > for this I can definitely see the point in sharing this, as Laurent
> > > pointed out with the tiny optimization with not allocating a NULL void
> > > * that I've done (and screwed up) it's not entirely trivial code.
> > >
> >
> > My 2c as they say, although closer to a brain dump :-)
> >
> > On one hand the drm_device has an embedded struct device. On the other
> > drm_device preserves state which outlives the embedded struct device.
> >
> > Would it make sense to keep drm_device better related to the
> > underlying device? Effectively moving the $misc state to drm_driver.
> > This idea does raise another question - struct drm_driver unlike many
> > other struct $foo_driver, does not embedded device_driver :-(
> > So if one is to cover the above two, then the embedding concerns will
> > be elevated.
>
> drm_driver isn't a bus device driver in the linux driver model sense,
> but an uapi thing that sits on top of some underlying device. So maybe
> better to rename drm_driver to drm_interface_driver, and drm_device to
> drm_interface. But that would be giantic churn and probably lots of
> confusion. We do require a link between drm_device->struct device
> nowadays, but that's just to guarantee userspace can find the
> drm_device in sysfs somewhere and make sense of what it actually
> drives.
>
> That's also why the lifetimes for the two things are totally
> different. The device driver an all it's resources are tied to the
> underlying physical device, and resources can be released when that
> driver<->device link is broken (either unbind or hotunplug). That's
> what devm_ does. The drm_driver/drm_device otoh is tied to the
> userspace api, and can only disappear once all the userspace handles
> have been cleaned up and released. And we have an enormous amount of
> those, with all the mmaps, and shared fd for dma-buf, sync_file,
> synobj and whatever else. The drm_device can only be cleaned up once
> userspace has closed all these things, or we'll go boom somewhere. The
> only connection is that the userspace interface drives the underlying
> hw (as long as it's still there) and the hw side holds a reference on
> the uapi side (drm_dev_get/put) to make sure the userspace side
> doesn't go poof and disappear when no one has the /dev node open :-)
>
> But aside from these links they're completely separate worlds, and
> mixing up the lifetimes results in all kinds of bad things happening.
> Ofc normally these two things exist at the same time, but hotunplug
> makes things very interesting here. And traditionally we've handled it
> badly, if at all in drm.
>
Seems like my drm_device/drm_driver definitions were off.

Thanks a lot for clarifying.
-Emil
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

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

* Re: [Intel-gfx] [PATCH 03/52] drm: add managed resources tied to drm_device
@ 2020-02-19 16:41               ` Emil Velikov
  0 siblings, 0 replies; 310+ messages in thread
From: Emil Velikov @ 2020-02-19 16:41 UTC (permalink / raw)
  To: Daniel Vetter
  Cc: Rafael J. Wysocki, Greg Kroah-Hartman,
	Intel Graphics Development, DRI Development, Laurent Pinchart,
	Daniel Vetter

On Wed, 19 Feb 2020 at 16:22, Daniel Vetter <daniel.vetter@ffwll.ch> wrote:
>
> On Wed, Feb 19, 2020 at 5:09 PM Emil Velikov <emil.l.velikov@gmail.com> wrote:
> >
> > On Wed, 19 Feb 2020 at 14:23, Daniel Vetter <daniel.vetter@ffwll.ch> wrote:
> > >
> > > On Wed, Feb 19, 2020 at 2:33 PM Greg Kroah-Hartman
> > > <gregkh@linuxfoundation.org> wrote:
> > > >
> > > > On Wed, Feb 19, 2020 at 03:28:47PM +0200, Laurent Pinchart wrote:
> > > > > Hi Daniel,
> > > > >
> > > > > Thank you for the patch.
> > > > >
> > > > > On Wed, Feb 19, 2020 at 11:20:33AM +0100, Daniel Vetter wrote:
> > > > > > 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.
> > > > >
> > > > > This is all a very good idea ! Many subsystems are plagged by drivers
> > > > > using devm_k*alloc to allocate data accessible by userspace. Since the
> > > > > introduction of devm_*, we've likely reduced the number of memory leaks,
> > > > > but I'm pretty sure we've increased the risk of crashes as I've seen
> > > > > some drivers that used .release() callbacks correctly being naively
> > > > > converted to incorrect devm_* usage :-(
> > > > >
> > > > > This leads me to a question: if other subsystems have the same problem,
> > > > > could we turn this implementation into something more generic ? It
> > > > > doesn't have to be done right away and shouldn't block merging this
> > > > > series, but I think it would be very useful.
> > > >
> > > > It shouldn't be that hard to tie this into a drv_m() type of a thing
> > > > (driver_memory?)
> > > >
> > > > And yes, I think it's much better than devm_* for the obvious reasons of
> > > > this being needed here.
> > >
> > > There's two reasons I went with copypasta instead of trying to share code:
> > > - Type checking, I definitely don't want people to mix up devm_ with
> > > drmm_. But even if we do a drv_m that subsystems could embed we do
> > > have quite a few different types of component drivers (and with
> > > drm_panel and drm_bridge even standardized), and I don't want people
> > > to be able to pass the wrong kind of struct to e.g. a managed
> > > drmm_connector_init - it really needs to be the drm_device, not a
> > > panel or bridge or something else.
> > >
> > > - We could still share the code as a kind of implementation/backend
> > > library. But it's not much, and with embedding I could use the drm
> > > device logging stuff which is kinda nice. But if there's more demand
> > > for this I can definitely see the point in sharing this, as Laurent
> > > pointed out with the tiny optimization with not allocating a NULL void
> > > * that I've done (and screwed up) it's not entirely trivial code.
> > >
> >
> > My 2c as they say, although closer to a brain dump :-)
> >
> > On one hand the drm_device has an embedded struct device. On the other
> > drm_device preserves state which outlives the embedded struct device.
> >
> > Would it make sense to keep drm_device better related to the
> > underlying device? Effectively moving the $misc state to drm_driver.
> > This idea does raise another question - struct drm_driver unlike many
> > other struct $foo_driver, does not embedded device_driver :-(
> > So if one is to cover the above two, then the embedding concerns will
> > be elevated.
>
> drm_driver isn't a bus device driver in the linux driver model sense,
> but an uapi thing that sits on top of some underlying device. So maybe
> better to rename drm_driver to drm_interface_driver, and drm_device to
> drm_interface. But that would be giantic churn and probably lots of
> confusion. We do require a link between drm_device->struct device
> nowadays, but that's just to guarantee userspace can find the
> drm_device in sysfs somewhere and make sense of what it actually
> drives.
>
> That's also why the lifetimes for the two things are totally
> different. The device driver an all it's resources are tied to the
> underlying physical device, and resources can be released when that
> driver<->device link is broken (either unbind or hotunplug). That's
> what devm_ does. The drm_driver/drm_device otoh is tied to the
> userspace api, and can only disappear once all the userspace handles
> have been cleaned up and released. And we have an enormous amount of
> those, with all the mmaps, and shared fd for dma-buf, sync_file,
> synobj and whatever else. The drm_device can only be cleaned up once
> userspace has closed all these things, or we'll go boom somewhere. The
> only connection is that the userspace interface drives the underlying
> hw (as long as it's still there) and the hw side holds a reference on
> the uapi side (drm_dev_get/put) to make sure the userspace side
> doesn't go poof and disappear when no one has the /dev node open :-)
>
> But aside from these links they're completely separate worlds, and
> mixing up the lifetimes results in all kinds of bad things happening.
> Ofc normally these two things exist at the same time, but hotunplug
> makes things very interesting here. And traditionally we've handled it
> badly, if at all in drm.
>
Seems like my drm_device/drm_driver definitions were off.

Thanks a lot for clarifying.
-Emil
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [Intel-gfx] [PATCH 03/52] drm: add managed resources tied to drm_device
  2020-02-19 16:22             ` Daniel Vetter
@ 2020-02-19 16:46               ` Laurent Pinchart
  -1 siblings, 0 replies; 310+ messages in thread
From: Laurent Pinchart @ 2020-02-19 16:46 UTC (permalink / raw)
  To: Daniel Vetter
  Cc: Rafael J. Wysocki, Greg Kroah-Hartman,
	Intel Graphics Development, Emil Velikov, DRI Development,
	Daniel Vetter

Hi Daniel,

On Wed, Feb 19, 2020 at 05:22:38PM +0100, Daniel Vetter wrote:
> On Wed, Feb 19, 2020 at 5:09 PM Emil Velikov wrote:
> > On Wed, 19 Feb 2020 at 14:23, Daniel Vetter wrote:
> >> On Wed, Feb 19, 2020 at 2:33 PM Greg Kroah-Hartman wrote:
> >>> On Wed, Feb 19, 2020 at 03:28:47PM +0200, Laurent Pinchart wrote:
> >>>> On Wed, Feb 19, 2020 at 11:20:33AM +0100, Daniel Vetter wrote:
> >>>>> 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.
> >>>>
> >>>> This is all a very good idea ! Many subsystems are plagged by drivers
> >>>> using devm_k*alloc to allocate data accessible by userspace. Since the
> >>>> introduction of devm_*, we've likely reduced the number of memory leaks,
> >>>> but I'm pretty sure we've increased the risk of crashes as I've seen
> >>>> some drivers that used .release() callbacks correctly being naively
> >>>> converted to incorrect devm_* usage :-(
> >>>>
> >>>> This leads me to a question: if other subsystems have the same problem,
> >>>> could we turn this implementation into something more generic ? It
> >>>> doesn't have to be done right away and shouldn't block merging this
> >>>> series, but I think it would be very useful.
> >>>
> >>> It shouldn't be that hard to tie this into a drv_m() type of a thing
> >>> (driver_memory?)
> >>>
> >>> And yes, I think it's much better than devm_* for the obvious reasons of
> >>> this being needed here.
> >>
> >> There's two reasons I went with copypasta instead of trying to share code:
> >> - Type checking, I definitely don't want people to mix up devm_ with
> >> drmm_. But even if we do a drv_m that subsystems could embed we do
> >> have quite a few different types of component drivers (and with
> >> drm_panel and drm_bridge even standardized), and I don't want people
> >> to be able to pass the wrong kind of struct to e.g. a managed
> >> drmm_connector_init - it really needs to be the drm_device, not a
> >> panel or bridge or something else.
> >>
> >> - We could still share the code as a kind of implementation/backend
> >> library. But it's not much, and with embedding I could use the drm
> >> device logging stuff which is kinda nice. But if there's more demand
> >> for this I can definitely see the point in sharing this, as Laurent
> >> pointed out with the tiny optimization with not allocating a NULL void
> >> * that I've done (and screwed up) it's not entirely trivial code.
> >
> > My 2c as they say, although closer to a brain dump :-)
> >
> > On one hand the drm_device has an embedded struct device. On the other
> > drm_device preserves state which outlives the embedded struct device.
> >
> > Would it make sense to keep drm_device better related to the
> > underlying device? Effectively moving the $misc state to drm_driver.
> > This idea does raise another question - struct drm_driver unlike many
> > other struct $foo_driver, does not embedded device_driver :-(
> > So if one is to cover the above two, then the embedding concerns will
> > be elevated.
> 
> drm_driver isn't a bus device driver in the linux driver model sense,
> but an uapi thing that sits on top of some underlying device. So maybe
> better to rename drm_driver to drm_interface_driver, and drm_device to
> drm_interface. But that would be giantic churn and probably lots of
> confusion. We do require a link between drm_device->struct device
> nowadays, but that's just to guarantee userspace can find the
> drm_device in sysfs somewhere and make sense of what it actually
> drives.

If we wanted to rename drm_driver to align with the rest of the kernel,
it should probably be drm_device_ops, with the non-ops fields being
moved to a separate structure.

I don't mind churn (but I agree it may not be worth it), but even if we
don't rename the structure, I think it would be very useful to remove
the non-const fields, in order to allow storing the structure as a
global static const struct. Function pointers in non-const memory can be
a security issue. As far as I can tell, the only blocker is the
legacy_dev_list field.

> That's also why the lifetimes for the two things are totally
> different. The device driver an all it's resources are tied to the
> underlying physical device, and resources can be released when that
> driver<->device link is broken (either unbind or hotunplug). That's
> what devm_ does. The drm_driver/drm_device otoh is tied to the
> userspace api, and can only disappear once all the userspace handles
> have been cleaned up and released.

And so they're tied to the lifetime of the struct device that models the
userspace interface. Shame they're both called device :-)

> And we have an enormous amount of those, with all the mmaps, and
> shared fd for dma-buf, sync_file, synobj and whatever else. The
> drm_device can only be cleaned up once userspace has closed all these
> things, or we'll go boom somewhere. The only connection is that the
> userspace interface drives the underlying hw (as long as it's still
> there) and the hw side holds a reference on the uapi side
> (drm_dev_get/put) to make sure the userspace side doesn't go poof and
> disappear when no one has the /dev node open :-)
> 
> But aside from these links they're completely separate worlds, and
> mixing up the lifetimes results in all kinds of bad things happening.
> Ofc normally these two things exist at the same time, but hotunplug
> makes things very interesting here. And traditionally we've handled it
> badly, if at all in drm.
> 
> > WRT type safety, with the embedded work sorted, one could introduce
> > trivial helpers for drmm_connector_init and friends.
> >
> > In another email you've also raised the question of API diversity and
> > reviews, I believe. IMHO one could start with a bare minimum set and
> > extend as needed.
> > Based on the prompt response from Greg, I suspect review won't be an issue.
> 
> The drmm_ stuff in here is the bare minimum we need to get started. I
> expect lots of stuff will be added, but those are all just going to be
> convenience functions on top of the drmm_add_action primitive.
> 
> > If people agree with my analysis and considering the size/complexity
> > of drm_device <> drm_driver reshuffle, we could add a TODO task.
> > I suspect the underlying work will be larger than the current 52 patch
> > set, so doing it in one go will be PITA.
> 
> I'm not following what you want to shuffle. drm_driver is entirely
> static and kinda global, drm_device is the per-instance structure we
> have. And here we mean per-userspace uapi interface instance. So I
> guess I'm confused what you want to do?
> 
> > * Based on the following quick greps
> > $git grep -W "struct [a-zA-Z0-9-]*_driver {" -- include/ | grep -w
> > "struct device_driver\>.*;"  | wc -l
> > 56
> > $git cgrep "struct [a-zA-Z0-9-]*_driver {" -- include/ | wc -l
> > 71

-- 
Regards,

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

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

* Re: [Intel-gfx] [PATCH 03/52] drm: add managed resources tied to drm_device
@ 2020-02-19 16:46               ` Laurent Pinchart
  0 siblings, 0 replies; 310+ messages in thread
From: Laurent Pinchart @ 2020-02-19 16:46 UTC (permalink / raw)
  To: Daniel Vetter
  Cc: Rafael J. Wysocki, Greg Kroah-Hartman,
	Intel Graphics Development, DRI Development, Daniel Vetter

Hi Daniel,

On Wed, Feb 19, 2020 at 05:22:38PM +0100, Daniel Vetter wrote:
> On Wed, Feb 19, 2020 at 5:09 PM Emil Velikov wrote:
> > On Wed, 19 Feb 2020 at 14:23, Daniel Vetter wrote:
> >> On Wed, Feb 19, 2020 at 2:33 PM Greg Kroah-Hartman wrote:
> >>> On Wed, Feb 19, 2020 at 03:28:47PM +0200, Laurent Pinchart wrote:
> >>>> On Wed, Feb 19, 2020 at 11:20:33AM +0100, Daniel Vetter wrote:
> >>>>> 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.
> >>>>
> >>>> This is all a very good idea ! Many subsystems are plagged by drivers
> >>>> using devm_k*alloc to allocate data accessible by userspace. Since the
> >>>> introduction of devm_*, we've likely reduced the number of memory leaks,
> >>>> but I'm pretty sure we've increased the risk of crashes as I've seen
> >>>> some drivers that used .release() callbacks correctly being naively
> >>>> converted to incorrect devm_* usage :-(
> >>>>
> >>>> This leads me to a question: if other subsystems have the same problem,
> >>>> could we turn this implementation into something more generic ? It
> >>>> doesn't have to be done right away and shouldn't block merging this
> >>>> series, but I think it would be very useful.
> >>>
> >>> It shouldn't be that hard to tie this into a drv_m() type of a thing
> >>> (driver_memory?)
> >>>
> >>> And yes, I think it's much better than devm_* for the obvious reasons of
> >>> this being needed here.
> >>
> >> There's two reasons I went with copypasta instead of trying to share code:
> >> - Type checking, I definitely don't want people to mix up devm_ with
> >> drmm_. But even if we do a drv_m that subsystems could embed we do
> >> have quite a few different types of component drivers (and with
> >> drm_panel and drm_bridge even standardized), and I don't want people
> >> to be able to pass the wrong kind of struct to e.g. a managed
> >> drmm_connector_init - it really needs to be the drm_device, not a
> >> panel or bridge or something else.
> >>
> >> - We could still share the code as a kind of implementation/backend
> >> library. But it's not much, and with embedding I could use the drm
> >> device logging stuff which is kinda nice. But if there's more demand
> >> for this I can definitely see the point in sharing this, as Laurent
> >> pointed out with the tiny optimization with not allocating a NULL void
> >> * that I've done (and screwed up) it's not entirely trivial code.
> >
> > My 2c as they say, although closer to a brain dump :-)
> >
> > On one hand the drm_device has an embedded struct device. On the other
> > drm_device preserves state which outlives the embedded struct device.
> >
> > Would it make sense to keep drm_device better related to the
> > underlying device? Effectively moving the $misc state to drm_driver.
> > This idea does raise another question - struct drm_driver unlike many
> > other struct $foo_driver, does not embedded device_driver :-(
> > So if one is to cover the above two, then the embedding concerns will
> > be elevated.
> 
> drm_driver isn't a bus device driver in the linux driver model sense,
> but an uapi thing that sits on top of some underlying device. So maybe
> better to rename drm_driver to drm_interface_driver, and drm_device to
> drm_interface. But that would be giantic churn and probably lots of
> confusion. We do require a link between drm_device->struct device
> nowadays, but that's just to guarantee userspace can find the
> drm_device in sysfs somewhere and make sense of what it actually
> drives.

If we wanted to rename drm_driver to align with the rest of the kernel,
it should probably be drm_device_ops, with the non-ops fields being
moved to a separate structure.

I don't mind churn (but I agree it may not be worth it), but even if we
don't rename the structure, I think it would be very useful to remove
the non-const fields, in order to allow storing the structure as a
global static const struct. Function pointers in non-const memory can be
a security issue. As far as I can tell, the only blocker is the
legacy_dev_list field.

> That's also why the lifetimes for the two things are totally
> different. The device driver an all it's resources are tied to the
> underlying physical device, and resources can be released when that
> driver<->device link is broken (either unbind or hotunplug). That's
> what devm_ does. The drm_driver/drm_device otoh is tied to the
> userspace api, and can only disappear once all the userspace handles
> have been cleaned up and released.

And so they're tied to the lifetime of the struct device that models the
userspace interface. Shame they're both called device :-)

> And we have an enormous amount of those, with all the mmaps, and
> shared fd for dma-buf, sync_file, synobj and whatever else. The
> drm_device can only be cleaned up once userspace has closed all these
> things, or we'll go boom somewhere. The only connection is that the
> userspace interface drives the underlying hw (as long as it's still
> there) and the hw side holds a reference on the uapi side
> (drm_dev_get/put) to make sure the userspace side doesn't go poof and
> disappear when no one has the /dev node open :-)
> 
> But aside from these links they're completely separate worlds, and
> mixing up the lifetimes results in all kinds of bad things happening.
> Ofc normally these two things exist at the same time, but hotunplug
> makes things very interesting here. And traditionally we've handled it
> badly, if at all in drm.
> 
> > WRT type safety, with the embedded work sorted, one could introduce
> > trivial helpers for drmm_connector_init and friends.
> >
> > In another email you've also raised the question of API diversity and
> > reviews, I believe. IMHO one could start with a bare minimum set and
> > extend as needed.
> > Based on the prompt response from Greg, I suspect review won't be an issue.
> 
> The drmm_ stuff in here is the bare minimum we need to get started. I
> expect lots of stuff will be added, but those are all just going to be
> convenience functions on top of the drmm_add_action primitive.
> 
> > If people agree with my analysis and considering the size/complexity
> > of drm_device <> drm_driver reshuffle, we could add a TODO task.
> > I suspect the underlying work will be larger than the current 52 patch
> > set, so doing it in one go will be PITA.
> 
> I'm not following what you want to shuffle. drm_driver is entirely
> static and kinda global, drm_device is the per-instance structure we
> have. And here we mean per-userspace uapi interface instance. So I
> guess I'm confused what you want to do?
> 
> > * Based on the following quick greps
> > $git grep -W "struct [a-zA-Z0-9-]*_driver {" -- include/ | grep -w
> > "struct device_driver\>.*;"  | wc -l
> > 56
> > $git cgrep "struct [a-zA-Z0-9-]*_driver {" -- include/ | wc -l
> > 71

-- 
Regards,

Laurent Pinchart
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [Intel-gfx] [PATCH 03/52] drm: add managed resources tied to drm_device
  2020-02-19 16:46               ` Laurent Pinchart
@ 2020-02-19 16:53                 ` Daniel Vetter
  -1 siblings, 0 replies; 310+ messages in thread
From: Daniel Vetter @ 2020-02-19 16:53 UTC (permalink / raw)
  To: Laurent Pinchart
  Cc: Rafael J. Wysocki, Greg Kroah-Hartman,
	Intel Graphics Development, Emil Velikov, DRI Development,
	Daniel Vetter

On Wed, Feb 19, 2020 at 5:46 PM Laurent Pinchart
<laurent.pinchart@ideasonboard.com> wrote:
>
> Hi Daniel,
>
> On Wed, Feb 19, 2020 at 05:22:38PM +0100, Daniel Vetter wrote:
> > On Wed, Feb 19, 2020 at 5:09 PM Emil Velikov wrote:
> > > On Wed, 19 Feb 2020 at 14:23, Daniel Vetter wrote:
> > >> On Wed, Feb 19, 2020 at 2:33 PM Greg Kroah-Hartman wrote:
> > >>> On Wed, Feb 19, 2020 at 03:28:47PM +0200, Laurent Pinchart wrote:
> > >>>> On Wed, Feb 19, 2020 at 11:20:33AM +0100, Daniel Vetter wrote:
> > >>>>> 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.
> > >>>>
> > >>>> This is all a very good idea ! Many subsystems are plagged by drivers
> > >>>> using devm_k*alloc to allocate data accessible by userspace. Since the
> > >>>> introduction of devm_*, we've likely reduced the number of memory leaks,
> > >>>> but I'm pretty sure we've increased the risk of crashes as I've seen
> > >>>> some drivers that used .release() callbacks correctly being naively
> > >>>> converted to incorrect devm_* usage :-(
> > >>>>
> > >>>> This leads me to a question: if other subsystems have the same problem,
> > >>>> could we turn this implementation into something more generic ? It
> > >>>> doesn't have to be done right away and shouldn't block merging this
> > >>>> series, but I think it would be very useful.
> > >>>
> > >>> It shouldn't be that hard to tie this into a drv_m() type of a thing
> > >>> (driver_memory?)
> > >>>
> > >>> And yes, I think it's much better than devm_* for the obvious reasons of
> > >>> this being needed here.
> > >>
> > >> There's two reasons I went with copypasta instead of trying to share code:
> > >> - Type checking, I definitely don't want people to mix up devm_ with
> > >> drmm_. But even if we do a drv_m that subsystems could embed we do
> > >> have quite a few different types of component drivers (and with
> > >> drm_panel and drm_bridge even standardized), and I don't want people
> > >> to be able to pass the wrong kind of struct to e.g. a managed
> > >> drmm_connector_init - it really needs to be the drm_device, not a
> > >> panel or bridge or something else.
> > >>
> > >> - We could still share the code as a kind of implementation/backend
> > >> library. But it's not much, and with embedding I could use the drm
> > >> device logging stuff which is kinda nice. But if there's more demand
> > >> for this I can definitely see the point in sharing this, as Laurent
> > >> pointed out with the tiny optimization with not allocating a NULL void
> > >> * that I've done (and screwed up) it's not entirely trivial code.
> > >
> > > My 2c as they say, although closer to a brain dump :-)
> > >
> > > On one hand the drm_device has an embedded struct device. On the other
> > > drm_device preserves state which outlives the embedded struct device.
> > >
> > > Would it make sense to keep drm_device better related to the
> > > underlying device? Effectively moving the $misc state to drm_driver.
> > > This idea does raise another question - struct drm_driver unlike many
> > > other struct $foo_driver, does not embedded device_driver :-(
> > > So if one is to cover the above two, then the embedding concerns will
> > > be elevated.
> >
> > drm_driver isn't a bus device driver in the linux driver model sense,
> > but an uapi thing that sits on top of some underlying device. So maybe
> > better to rename drm_driver to drm_interface_driver, and drm_device to
> > drm_interface. But that would be giantic churn and probably lots of
> > confusion. We do require a link between drm_device->struct device
> > nowadays, but that's just to guarantee userspace can find the
> > drm_device in sysfs somewhere and make sense of what it actually
> > drives.
>
> If we wanted to rename drm_driver to align with the rest of the kernel,
> it should probably be drm_device_ops, with the non-ops fields being
> moved to a separate structure.
>
> I don't mind churn (but I agree it may not be worth it), but even if we
> don't rename the structure, I think it would be very useful to remove
> the non-const fields, in order to allow storing the structure as a
> global static const struct. Function pointers in non-const memory can be
> a security issue. As far as I can tell, the only blocker is the
> legacy_dev_list field.

Oh man ... we could make the legacy_dev_list depend on
CONFIG_DRM_LEGACY and the INIT_LIST_HEAD also depend upon
DRIVER_LEGACY and then at least all the new drivers could make their
drm_driver structure const. Or something along those lines.

Properly ditching legacy_dev_list is probably not worth it, since
those drivers tend to be all root exploits anyway :-)

Cheers, Daniel

> > That's also why the lifetimes for the two things are totally
> > different. The device driver an all it's resources are tied to the
> > underlying physical device, and resources can be released when that
> > driver<->device link is broken (either unbind or hotunplug). That's
> > what devm_ does. The drm_driver/drm_device otoh is tied to the
> > userspace api, and can only disappear once all the userspace handles
> > have been cleaned up and released.
>
> And so they're tied to the lifetime of the struct device that models the
> userspace interface. Shame they're both called device :-)
>
> > And we have an enormous amount of those, with all the mmaps, and
> > shared fd for dma-buf, sync_file, synobj and whatever else. The
> > drm_device can only be cleaned up once userspace has closed all these
> > things, or we'll go boom somewhere. The only connection is that the
> > userspace interface drives the underlying hw (as long as it's still
> > there) and the hw side holds a reference on the uapi side
> > (drm_dev_get/put) to make sure the userspace side doesn't go poof and
> > disappear when no one has the /dev node open :-)
> >
> > But aside from these links they're completely separate worlds, and
> > mixing up the lifetimes results in all kinds of bad things happening.
> > Ofc normally these two things exist at the same time, but hotunplug
> > makes things very interesting here. And traditionally we've handled it
> > badly, if at all in drm.
> >
> > > WRT type safety, with the embedded work sorted, one could introduce
> > > trivial helpers for drmm_connector_init and friends.
> > >
> > > In another email you've also raised the question of API diversity and
> > > reviews, I believe. IMHO one could start with a bare minimum set and
> > > extend as needed.
> > > Based on the prompt response from Greg, I suspect review won't be an issue.
> >
> > The drmm_ stuff in here is the bare minimum we need to get started. I
> > expect lots of stuff will be added, but those are all just going to be
> > convenience functions on top of the drmm_add_action primitive.
> >
> > > If people agree with my analysis and considering the size/complexity
> > > of drm_device <> drm_driver reshuffle, we could add a TODO task.
> > > I suspect the underlying work will be larger than the current 52 patch
> > > set, so doing it in one go will be PITA.
> >
> > I'm not following what you want to shuffle. drm_driver is entirely
> > static and kinda global, drm_device is the per-instance structure we
> > have. And here we mean per-userspace uapi interface instance. So I
> > guess I'm confused what you want to do?
> >
> > > * Based on the following quick greps
> > > $git grep -W "struct [a-zA-Z0-9-]*_driver {" -- include/ | grep -w
> > > "struct device_driver\>.*;"  | wc -l
> > > 56
> > > $git cgrep "struct [a-zA-Z0-9-]*_driver {" -- include/ | wc -l
> > > 71
>
> --
> Regards,
>
> Laurent Pinchart



-- 
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] 310+ messages in thread

* Re: [Intel-gfx] [PATCH 03/52] drm: add managed resources tied to drm_device
@ 2020-02-19 16:53                 ` Daniel Vetter
  0 siblings, 0 replies; 310+ messages in thread
From: Daniel Vetter @ 2020-02-19 16:53 UTC (permalink / raw)
  To: Laurent Pinchart
  Cc: Rafael J. Wysocki, Greg Kroah-Hartman,
	Intel Graphics Development, DRI Development, Daniel Vetter

On Wed, Feb 19, 2020 at 5:46 PM Laurent Pinchart
<laurent.pinchart@ideasonboard.com> wrote:
>
> Hi Daniel,
>
> On Wed, Feb 19, 2020 at 05:22:38PM +0100, Daniel Vetter wrote:
> > On Wed, Feb 19, 2020 at 5:09 PM Emil Velikov wrote:
> > > On Wed, 19 Feb 2020 at 14:23, Daniel Vetter wrote:
> > >> On Wed, Feb 19, 2020 at 2:33 PM Greg Kroah-Hartman wrote:
> > >>> On Wed, Feb 19, 2020 at 03:28:47PM +0200, Laurent Pinchart wrote:
> > >>>> On Wed, Feb 19, 2020 at 11:20:33AM +0100, Daniel Vetter wrote:
> > >>>>> 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.
> > >>>>
> > >>>> This is all a very good idea ! Many subsystems are plagged by drivers
> > >>>> using devm_k*alloc to allocate data accessible by userspace. Since the
> > >>>> introduction of devm_*, we've likely reduced the number of memory leaks,
> > >>>> but I'm pretty sure we've increased the risk of crashes as I've seen
> > >>>> some drivers that used .release() callbacks correctly being naively
> > >>>> converted to incorrect devm_* usage :-(
> > >>>>
> > >>>> This leads me to a question: if other subsystems have the same problem,
> > >>>> could we turn this implementation into something more generic ? It
> > >>>> doesn't have to be done right away and shouldn't block merging this
> > >>>> series, but I think it would be very useful.
> > >>>
> > >>> It shouldn't be that hard to tie this into a drv_m() type of a thing
> > >>> (driver_memory?)
> > >>>
> > >>> And yes, I think it's much better than devm_* for the obvious reasons of
> > >>> this being needed here.
> > >>
> > >> There's two reasons I went with copypasta instead of trying to share code:
> > >> - Type checking, I definitely don't want people to mix up devm_ with
> > >> drmm_. But even if we do a drv_m that subsystems could embed we do
> > >> have quite a few different types of component drivers (and with
> > >> drm_panel and drm_bridge even standardized), and I don't want people
> > >> to be able to pass the wrong kind of struct to e.g. a managed
> > >> drmm_connector_init - it really needs to be the drm_device, not a
> > >> panel or bridge or something else.
> > >>
> > >> - We could still share the code as a kind of implementation/backend
> > >> library. But it's not much, and with embedding I could use the drm
> > >> device logging stuff which is kinda nice. But if there's more demand
> > >> for this I can definitely see the point in sharing this, as Laurent
> > >> pointed out with the tiny optimization with not allocating a NULL void
> > >> * that I've done (and screwed up) it's not entirely trivial code.
> > >
> > > My 2c as they say, although closer to a brain dump :-)
> > >
> > > On one hand the drm_device has an embedded struct device. On the other
> > > drm_device preserves state which outlives the embedded struct device.
> > >
> > > Would it make sense to keep drm_device better related to the
> > > underlying device? Effectively moving the $misc state to drm_driver.
> > > This idea does raise another question - struct drm_driver unlike many
> > > other struct $foo_driver, does not embedded device_driver :-(
> > > So if one is to cover the above two, then the embedding concerns will
> > > be elevated.
> >
> > drm_driver isn't a bus device driver in the linux driver model sense,
> > but an uapi thing that sits on top of some underlying device. So maybe
> > better to rename drm_driver to drm_interface_driver, and drm_device to
> > drm_interface. But that would be giantic churn and probably lots of
> > confusion. We do require a link between drm_device->struct device
> > nowadays, but that's just to guarantee userspace can find the
> > drm_device in sysfs somewhere and make sense of what it actually
> > drives.
>
> If we wanted to rename drm_driver to align with the rest of the kernel,
> it should probably be drm_device_ops, with the non-ops fields being
> moved to a separate structure.
>
> I don't mind churn (but I agree it may not be worth it), but even if we
> don't rename the structure, I think it would be very useful to remove
> the non-const fields, in order to allow storing the structure as a
> global static const struct. Function pointers in non-const memory can be
> a security issue. As far as I can tell, the only blocker is the
> legacy_dev_list field.

Oh man ... we could make the legacy_dev_list depend on
CONFIG_DRM_LEGACY and the INIT_LIST_HEAD also depend upon
DRIVER_LEGACY and then at least all the new drivers could make their
drm_driver structure const. Or something along those lines.

Properly ditching legacy_dev_list is probably not worth it, since
those drivers tend to be all root exploits anyway :-)

Cheers, Daniel

> > That's also why the lifetimes for the two things are totally
> > different. The device driver an all it's resources are tied to the
> > underlying physical device, and resources can be released when that
> > driver<->device link is broken (either unbind or hotunplug). That's
> > what devm_ does. The drm_driver/drm_device otoh is tied to the
> > userspace api, and can only disappear once all the userspace handles
> > have been cleaned up and released.
>
> And so they're tied to the lifetime of the struct device that models the
> userspace interface. Shame they're both called device :-)
>
> > And we have an enormous amount of those, with all the mmaps, and
> > shared fd for dma-buf, sync_file, synobj and whatever else. The
> > drm_device can only be cleaned up once userspace has closed all these
> > things, or we'll go boom somewhere. The only connection is that the
> > userspace interface drives the underlying hw (as long as it's still
> > there) and the hw side holds a reference on the uapi side
> > (drm_dev_get/put) to make sure the userspace side doesn't go poof and
> > disappear when no one has the /dev node open :-)
> >
> > But aside from these links they're completely separate worlds, and
> > mixing up the lifetimes results in all kinds of bad things happening.
> > Ofc normally these two things exist at the same time, but hotunplug
> > makes things very interesting here. And traditionally we've handled it
> > badly, if at all in drm.
> >
> > > WRT type safety, with the embedded work sorted, one could introduce
> > > trivial helpers for drmm_connector_init and friends.
> > >
> > > In another email you've also raised the question of API diversity and
> > > reviews, I believe. IMHO one could start with a bare minimum set and
> > > extend as needed.
> > > Based on the prompt response from Greg, I suspect review won't be an issue.
> >
> > The drmm_ stuff in here is the bare minimum we need to get started. I
> > expect lots of stuff will be added, but those are all just going to be
> > convenience functions on top of the drmm_add_action primitive.
> >
> > > If people agree with my analysis and considering the size/complexity
> > > of drm_device <> drm_driver reshuffle, we could add a TODO task.
> > > I suspect the underlying work will be larger than the current 52 patch
> > > set, so doing it in one go will be PITA.
> >
> > I'm not following what you want to shuffle. drm_driver is entirely
> > static and kinda global, drm_device is the per-instance structure we
> > have. And here we mean per-userspace uapi interface instance. So I
> > guess I'm confused what you want to do?
> >
> > > * Based on the following quick greps
> > > $git grep -W "struct [a-zA-Z0-9-]*_driver {" -- include/ | grep -w
> > > "struct device_driver\>.*;"  | wc -l
> > > 56
> > > $git cgrep "struct [a-zA-Z0-9-]*_driver {" -- include/ | wc -l
> > > 71
>
> --
> Regards,
>
> Laurent Pinchart



-- 
Daniel Vetter
Software Engineer, Intel Corporation
+41 (0) 79 365 57 48 - http://blog.ffwll.ch
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH 03/52] drm: add managed resources tied to drm_device
  2020-02-19 14:22         ` [Intel-gfx] " Daniel Vetter
@ 2020-02-19 17:00           ` Greg Kroah-Hartman
  -1 siblings, 0 replies; 310+ messages in thread
From: Greg Kroah-Hartman @ 2020-02-19 17:00 UTC (permalink / raw)
  To: Daniel Vetter
  Cc: Daniel Vetter, Intel Graphics Development, Laurent Pinchart,
	DRI Development, Rafael J. Wysocki

On Wed, Feb 19, 2020 at 03:22:49PM +0100, Daniel Vetter wrote:
> On Wed, Feb 19, 2020 at 2:33 PM Greg Kroah-Hartman
> <gregkh@linuxfoundation.org> wrote:
> >
> > On Wed, Feb 19, 2020 at 03:28:47PM +0200, Laurent Pinchart wrote:
> > > Hi Daniel,
> > >
> > > Thank you for the patch.
> > >
> > > On Wed, Feb 19, 2020 at 11:20:33AM +0100, Daniel Vetter wrote:
> > > > 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.
> > >
> > > This is all a very good idea ! Many subsystems are plagged by drivers
> > > using devm_k*alloc to allocate data accessible by userspace. Since the
> > > introduction of devm_*, we've likely reduced the number of memory leaks,
> > > but I'm pretty sure we've increased the risk of crashes as I've seen
> > > some drivers that used .release() callbacks correctly being naively
> > > converted to incorrect devm_* usage :-(
> > >
> > > This leads me to a question: if other subsystems have the same problem,
> > > could we turn this implementation into something more generic ? It
> > > doesn't have to be done right away and shouldn't block merging this
> > > series, but I think it would be very useful.
> >
> > It shouldn't be that hard to tie this into a drv_m() type of a thing
> > (driver_memory?)
> >
> > And yes, I think it's much better than devm_* for the obvious reasons of
> > this being needed here.
> 
> There's two reasons I went with copypasta instead of trying to share code:
> - Type checking, I definitely don't want people to mix up devm_ with
> drmm_. But even if we do a drv_m that subsystems could embed we do
> have quite a few different types of component drivers (and with
> drm_panel and drm_bridge even standardized), and I don't want people
> to be able to pass the wrong kind of struct to e.g. a managed
> drmm_connector_init - it really needs to be the drm_device, not a
> panel or bridge or something else.

Fair enough, that makes sense.

> - We could still share the code as a kind of implementation/backend
> library. But it's not much, and with embedding I could use the drm
> device logging stuff which is kinda nice. But if there's more demand
> for this I can definitely see the point in sharing this, as Laurent
> pointed out with the tiny optimization with not allocating a NULL void
> * that I've done (and screwed up) it's not entirely trivial code.

I think moving over time to having this be a backend library is good.
But no rush/issues here with this going in now, it solves a real need
and we can refactor it later on to try to make it more "bus/class"
generic as needed.

thanks,

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

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

* Re: [Intel-gfx] [PATCH 03/52] drm: add managed resources tied to drm_device
@ 2020-02-19 17:00           ` Greg Kroah-Hartman
  0 siblings, 0 replies; 310+ messages in thread
From: Greg Kroah-Hartman @ 2020-02-19 17:00 UTC (permalink / raw)
  To: Daniel Vetter
  Cc: Daniel Vetter, Intel Graphics Development, Laurent Pinchart,
	DRI Development, Rafael J. Wysocki

On Wed, Feb 19, 2020 at 03:22:49PM +0100, Daniel Vetter wrote:
> On Wed, Feb 19, 2020 at 2:33 PM Greg Kroah-Hartman
> <gregkh@linuxfoundation.org> wrote:
> >
> > On Wed, Feb 19, 2020 at 03:28:47PM +0200, Laurent Pinchart wrote:
> > > Hi Daniel,
> > >
> > > Thank you for the patch.
> > >
> > > On Wed, Feb 19, 2020 at 11:20:33AM +0100, Daniel Vetter wrote:
> > > > 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.
> > >
> > > This is all a very good idea ! Many subsystems are plagged by drivers
> > > using devm_k*alloc to allocate data accessible by userspace. Since the
> > > introduction of devm_*, we've likely reduced the number of memory leaks,
> > > but I'm pretty sure we've increased the risk of crashes as I've seen
> > > some drivers that used .release() callbacks correctly being naively
> > > converted to incorrect devm_* usage :-(
> > >
> > > This leads me to a question: if other subsystems have the same problem,
> > > could we turn this implementation into something more generic ? It
> > > doesn't have to be done right away and shouldn't block merging this
> > > series, but I think it would be very useful.
> >
> > It shouldn't be that hard to tie this into a drv_m() type of a thing
> > (driver_memory?)
> >
> > And yes, I think it's much better than devm_* for the obvious reasons of
> > this being needed here.
> 
> There's two reasons I went with copypasta instead of trying to share code:
> - Type checking, I definitely don't want people to mix up devm_ with
> drmm_. But even if we do a drv_m that subsystems could embed we do
> have quite a few different types of component drivers (and with
> drm_panel and drm_bridge even standardized), and I don't want people
> to be able to pass the wrong kind of struct to e.g. a managed
> drmm_connector_init - it really needs to be the drm_device, not a
> panel or bridge or something else.

Fair enough, that makes sense.

> - We could still share the code as a kind of implementation/backend
> library. But it's not much, and with embedding I could use the drm
> device logging stuff which is kinda nice. But if there's more demand
> for this I can definitely see the point in sharing this, as Laurent
> pointed out with the tiny optimization with not allocating a NULL void
> * that I've done (and screwed up) it's not entirely trivial code.

I think moving over time to having this be a backend library is good.
But no rush/issues here with this going in now, it solves a real need
and we can refactor it later on to try to make it more "bus/class"
generic as needed.

thanks,

greg k-h
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [Intel-gfx] [PATCH 03/52] drm: add managed resources tied to drm_device
  2020-02-19 16:53                 ` Daniel Vetter
@ 2020-02-19 17:02                   ` Laurent Pinchart
  -1 siblings, 0 replies; 310+ messages in thread
From: Laurent Pinchart @ 2020-02-19 17:02 UTC (permalink / raw)
  To: Daniel Vetter
  Cc: Rafael J. Wysocki, Greg Kroah-Hartman,
	Intel Graphics Development, Emil Velikov, DRI Development,
	Daniel Vetter

Hi Daniel,

On Wed, Feb 19, 2020 at 05:53:59PM +0100, Daniel Vetter wrote:
> On Wed, Feb 19, 2020 at 5:46 PM Laurent Pinchart wrote:
> > On Wed, Feb 19, 2020 at 05:22:38PM +0100, Daniel Vetter wrote:
> >> On Wed, Feb 19, 2020 at 5:09 PM Emil Velikov wrote:
> >>> On Wed, 19 Feb 2020 at 14:23, Daniel Vetter wrote:
> >>>> On Wed, Feb 19, 2020 at 2:33 PM Greg Kroah-Hartman wrote:
> >>>>> On Wed, Feb 19, 2020 at 03:28:47PM +0200, Laurent Pinchart wrote:
> >>>>>> On Wed, Feb 19, 2020 at 11:20:33AM +0100, Daniel Vetter wrote:
> >>>>>>> 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.
> >>>>>>
> >>>>>> This is all a very good idea ! Many subsystems are plagged by drivers
> >>>>>> using devm_k*alloc to allocate data accessible by userspace. Since the
> >>>>>> introduction of devm_*, we've likely reduced the number of memory leaks,
> >>>>>> but I'm pretty sure we've increased the risk of crashes as I've seen
> >>>>>> some drivers that used .release() callbacks correctly being naively
> >>>>>> converted to incorrect devm_* usage :-(
> >>>>>>
> >>>>>> This leads me to a question: if other subsystems have the same problem,
> >>>>>> could we turn this implementation into something more generic ? It
> >>>>>> doesn't have to be done right away and shouldn't block merging this
> >>>>>> series, but I think it would be very useful.
> >>>>>
> >>>>> It shouldn't be that hard to tie this into a drv_m() type of a thing
> >>>>> (driver_memory?)
> >>>>>
> >>>>> And yes, I think it's much better than devm_* for the obvious reasons of
> >>>>> this being needed here.
> >>>>
> >>>> There's two reasons I went with copypasta instead of trying to share code:
> >>>> - Type checking, I definitely don't want people to mix up devm_ with
> >>>> drmm_. But even if we do a drv_m that subsystems could embed we do
> >>>> have quite a few different types of component drivers (and with
> >>>> drm_panel and drm_bridge even standardized), and I don't want people
> >>>> to be able to pass the wrong kind of struct to e.g. a managed
> >>>> drmm_connector_init - it really needs to be the drm_device, not a
> >>>> panel or bridge or something else.
> >>>>
> >>>> - We could still share the code as a kind of implementation/backend
> >>>> library. But it's not much, and with embedding I could use the drm
> >>>> device logging stuff which is kinda nice. But if there's more demand
> >>>> for this I can definitely see the point in sharing this, as Laurent
> >>>> pointed out with the tiny optimization with not allocating a NULL void
> >>>> * that I've done (and screwed up) it's not entirely trivial code.
> >>>
> >>> My 2c as they say, although closer to a brain dump :-)
> >>>
> >>> On one hand the drm_device has an embedded struct device. On the other
> >>> drm_device preserves state which outlives the embedded struct device.
> >>>
> >>> Would it make sense to keep drm_device better related to the
> >>> underlying device? Effectively moving the $misc state to drm_driver.
> >>> This idea does raise another question - struct drm_driver unlike many
> >>> other struct $foo_driver, does not embedded device_driver :-(
> >>> So if one is to cover the above two, then the embedding concerns will
> >>> be elevated.
> >>
> >> drm_driver isn't a bus device driver in the linux driver model sense,
> >> but an uapi thing that sits on top of some underlying device. So maybe
> >> better to rename drm_driver to drm_interface_driver, and drm_device to
> >> drm_interface. But that would be giantic churn and probably lots of
> >> confusion. We do require a link between drm_device->struct device
> >> nowadays, but that's just to guarantee userspace can find the
> >> drm_device in sysfs somewhere and make sense of what it actually
> >> drives.
> >
> > If we wanted to rename drm_driver to align with the rest of the kernel,
> > it should probably be drm_device_ops, with the non-ops fields being
> > moved to a separate structure.
> >
> > I don't mind churn (but I agree it may not be worth it), but even if we
> > don't rename the structure, I think it would be very useful to remove
> > the non-const fields, in order to allow storing the structure as a
> > global static const struct. Function pointers in non-const memory can be
> > a security issue. As far as I can tell, the only blocker is the
> > legacy_dev_list field.
> 
> Oh man ... we could make the legacy_dev_list depend on
> CONFIG_DRM_LEGACY and the INIT_LIST_HEAD also depend upon
> DRIVER_LEGACY and then at least all the new drivers could make their
> drm_driver structure const. Or something along those lines.

We would however need different function prototypes for drm_dev_init() &
co. that would take const struct drm_driver instead of struct
drm_driver.

> Properly ditching legacy_dev_list is probably not worth it, since
> those drivers tend to be all root exploits anyway :-)

What if we turned the list into a global list in drm_pci.c ?

> >> That's also why the lifetimes for the two things are totally
> >> different. The device driver an all it's resources are tied to the
> >> underlying physical device, and resources can be released when that
> >> driver<->device link is broken (either unbind or hotunplug). That's
> >> what devm_ does. The drm_driver/drm_device otoh is tied to the
> >> userspace api, and can only disappear once all the userspace handles
> >> have been cleaned up and released.
> >
> > And so they're tied to the lifetime of the struct device that models the
> > userspace interface. Shame they're both called device :-)
> >
> >> And we have an enormous amount of those, with all the mmaps, and
> >> shared fd for dma-buf, sync_file, synobj and whatever else. The
> >> drm_device can only be cleaned up once userspace has closed all these
> >> things, or we'll go boom somewhere. The only connection is that the
> >> userspace interface drives the underlying hw (as long as it's still
> >> there) and the hw side holds a reference on the uapi side
> >> (drm_dev_get/put) to make sure the userspace side doesn't go poof and
> >> disappear when no one has the /dev node open :-)
> >>
> >> But aside from these links they're completely separate worlds, and
> >> mixing up the lifetimes results in all kinds of bad things happening.
> >> Ofc normally these two things exist at the same time, but hotunplug
> >> makes things very interesting here. And traditionally we've handled it
> >> badly, if at all in drm.
> >>
> >>> WRT type safety, with the embedded work sorted, one could introduce
> >>> trivial helpers for drmm_connector_init and friends.
> >>>
> >>> In another email you've also raised the question of API diversity and
> >>> reviews, I believe. IMHO one could start with a bare minimum set and
> >>> extend as needed.
> >>> Based on the prompt response from Greg, I suspect review won't be an issue.
> >>
> >> The drmm_ stuff in here is the bare minimum we need to get started. I
> >> expect lots of stuff will be added, but those are all just going to be
> >> convenience functions on top of the drmm_add_action primitive.
> >>
> >>> If people agree with my analysis and considering the size/complexity
> >>> of drm_device <> drm_driver reshuffle, we could add a TODO task.
> >>> I suspect the underlying work will be larger than the current 52 patch
> >>> set, so doing it in one go will be PITA.
> >>
> >> I'm not following what you want to shuffle. drm_driver is entirely
> >> static and kinda global, drm_device is the per-instance structure we
> >> have. And here we mean per-userspace uapi interface instance. So I
> >> guess I'm confused what you want to do?
> >>
> >>> * Based on the following quick greps
> >>> $git grep -W "struct [a-zA-Z0-9-]*_driver {" -- include/ | grep -w
> >>> "struct device_driver\>.*;"  | wc -l
> >>> 56
> >>> $git cgrep "struct [a-zA-Z0-9-]*_driver {" -- include/ | wc -l
> >>> 71

-- 
Regards,

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

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

* Re: [Intel-gfx] [PATCH 03/52] drm: add managed resources tied to drm_device
@ 2020-02-19 17:02                   ` Laurent Pinchart
  0 siblings, 0 replies; 310+ messages in thread
From: Laurent Pinchart @ 2020-02-19 17:02 UTC (permalink / raw)
  To: Daniel Vetter
  Cc: Rafael J. Wysocki, Greg Kroah-Hartman,
	Intel Graphics Development, DRI Development, Daniel Vetter

Hi Daniel,

On Wed, Feb 19, 2020 at 05:53:59PM +0100, Daniel Vetter wrote:
> On Wed, Feb 19, 2020 at 5:46 PM Laurent Pinchart wrote:
> > On Wed, Feb 19, 2020 at 05:22:38PM +0100, Daniel Vetter wrote:
> >> On Wed, Feb 19, 2020 at 5:09 PM Emil Velikov wrote:
> >>> On Wed, 19 Feb 2020 at 14:23, Daniel Vetter wrote:
> >>>> On Wed, Feb 19, 2020 at 2:33 PM Greg Kroah-Hartman wrote:
> >>>>> On Wed, Feb 19, 2020 at 03:28:47PM +0200, Laurent Pinchart wrote:
> >>>>>> On Wed, Feb 19, 2020 at 11:20:33AM +0100, Daniel Vetter wrote:
> >>>>>>> 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.
> >>>>>>
> >>>>>> This is all a very good idea ! Many subsystems are plagged by drivers
> >>>>>> using devm_k*alloc to allocate data accessible by userspace. Since the
> >>>>>> introduction of devm_*, we've likely reduced the number of memory leaks,
> >>>>>> but I'm pretty sure we've increased the risk of crashes as I've seen
> >>>>>> some drivers that used .release() callbacks correctly being naively
> >>>>>> converted to incorrect devm_* usage :-(
> >>>>>>
> >>>>>> This leads me to a question: if other subsystems have the same problem,
> >>>>>> could we turn this implementation into something more generic ? It
> >>>>>> doesn't have to be done right away and shouldn't block merging this
> >>>>>> series, but I think it would be very useful.
> >>>>>
> >>>>> It shouldn't be that hard to tie this into a drv_m() type of a thing
> >>>>> (driver_memory?)
> >>>>>
> >>>>> And yes, I think it's much better than devm_* for the obvious reasons of
> >>>>> this being needed here.
> >>>>
> >>>> There's two reasons I went with copypasta instead of trying to share code:
> >>>> - Type checking, I definitely don't want people to mix up devm_ with
> >>>> drmm_. But even if we do a drv_m that subsystems could embed we do
> >>>> have quite a few different types of component drivers (and with
> >>>> drm_panel and drm_bridge even standardized), and I don't want people
> >>>> to be able to pass the wrong kind of struct to e.g. a managed
> >>>> drmm_connector_init - it really needs to be the drm_device, not a
> >>>> panel or bridge or something else.
> >>>>
> >>>> - We could still share the code as a kind of implementation/backend
> >>>> library. But it's not much, and with embedding I could use the drm
> >>>> device logging stuff which is kinda nice. But if there's more demand
> >>>> for this I can definitely see the point in sharing this, as Laurent
> >>>> pointed out with the tiny optimization with not allocating a NULL void
> >>>> * that I've done (and screwed up) it's not entirely trivial code.
> >>>
> >>> My 2c as they say, although closer to a brain dump :-)
> >>>
> >>> On one hand the drm_device has an embedded struct device. On the other
> >>> drm_device preserves state which outlives the embedded struct device.
> >>>
> >>> Would it make sense to keep drm_device better related to the
> >>> underlying device? Effectively moving the $misc state to drm_driver.
> >>> This idea does raise another question - struct drm_driver unlike many
> >>> other struct $foo_driver, does not embedded device_driver :-(
> >>> So if one is to cover the above two, then the embedding concerns will
> >>> be elevated.
> >>
> >> drm_driver isn't a bus device driver in the linux driver model sense,
> >> but an uapi thing that sits on top of some underlying device. So maybe
> >> better to rename drm_driver to drm_interface_driver, and drm_device to
> >> drm_interface. But that would be giantic churn and probably lots of
> >> confusion. We do require a link between drm_device->struct device
> >> nowadays, but that's just to guarantee userspace can find the
> >> drm_device in sysfs somewhere and make sense of what it actually
> >> drives.
> >
> > If we wanted to rename drm_driver to align with the rest of the kernel,
> > it should probably be drm_device_ops, with the non-ops fields being
> > moved to a separate structure.
> >
> > I don't mind churn (but I agree it may not be worth it), but even if we
> > don't rename the structure, I think it would be very useful to remove
> > the non-const fields, in order to allow storing the structure as a
> > global static const struct. Function pointers in non-const memory can be
> > a security issue. As far as I can tell, the only blocker is the
> > legacy_dev_list field.
> 
> Oh man ... we could make the legacy_dev_list depend on
> CONFIG_DRM_LEGACY and the INIT_LIST_HEAD also depend upon
> DRIVER_LEGACY and then at least all the new drivers could make their
> drm_driver structure const. Or something along those lines.

We would however need different function prototypes for drm_dev_init() &
co. that would take const struct drm_driver instead of struct
drm_driver.

> Properly ditching legacy_dev_list is probably not worth it, since
> those drivers tend to be all root exploits anyway :-)

What if we turned the list into a global list in drm_pci.c ?

> >> That's also why the lifetimes for the two things are totally
> >> different. The device driver an all it's resources are tied to the
> >> underlying physical device, and resources can be released when that
> >> driver<->device link is broken (either unbind or hotunplug). That's
> >> what devm_ does. The drm_driver/drm_device otoh is tied to the
> >> userspace api, and can only disappear once all the userspace handles
> >> have been cleaned up and released.
> >
> > And so they're tied to the lifetime of the struct device that models the
> > userspace interface. Shame they're both called device :-)
> >
> >> And we have an enormous amount of those, with all the mmaps, and
> >> shared fd for dma-buf, sync_file, synobj and whatever else. The
> >> drm_device can only be cleaned up once userspace has closed all these
> >> things, or we'll go boom somewhere. The only connection is that the
> >> userspace interface drives the underlying hw (as long as it's still
> >> there) and the hw side holds a reference on the uapi side
> >> (drm_dev_get/put) to make sure the userspace side doesn't go poof and
> >> disappear when no one has the /dev node open :-)
> >>
> >> But aside from these links they're completely separate worlds, and
> >> mixing up the lifetimes results in all kinds of bad things happening.
> >> Ofc normally these two things exist at the same time, but hotunplug
> >> makes things very interesting here. And traditionally we've handled it
> >> badly, if at all in drm.
> >>
> >>> WRT type safety, with the embedded work sorted, one could introduce
> >>> trivial helpers for drmm_connector_init and friends.
> >>>
> >>> In another email you've also raised the question of API diversity and
> >>> reviews, I believe. IMHO one could start with a bare minimum set and
> >>> extend as needed.
> >>> Based on the prompt response from Greg, I suspect review won't be an issue.
> >>
> >> The drmm_ stuff in here is the bare minimum we need to get started. I
> >> expect lots of stuff will be added, but those are all just going to be
> >> convenience functions on top of the drmm_add_action primitive.
> >>
> >>> If people agree with my analysis and considering the size/complexity
> >>> of drm_device <> drm_driver reshuffle, we could add a TODO task.
> >>> I suspect the underlying work will be larger than the current 52 patch
> >>> set, so doing it in one go will be PITA.
> >>
> >> I'm not following what you want to shuffle. drm_driver is entirely
> >> static and kinda global, drm_device is the per-instance structure we
> >> have. And here we mean per-userspace uapi interface instance. So I
> >> guess I'm confused what you want to do?
> >>
> >>> * Based on the following quick greps
> >>> $git grep -W "struct [a-zA-Z0-9-]*_driver {" -- include/ | grep -w
> >>> "struct device_driver\>.*;"  | wc -l
> >>> 56
> >>> $git cgrep "struct [a-zA-Z0-9-]*_driver {" -- include/ | wc -l
> >>> 71

-- 
Regards,

Laurent Pinchart
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [Intel-gfx] [PATCH 03/52] drm: add managed resources tied to drm_device
  2020-02-19 17:02                   ` Laurent Pinchart
@ 2020-02-19 17:06                     ` Daniel Vetter
  -1 siblings, 0 replies; 310+ messages in thread
From: Daniel Vetter @ 2020-02-19 17:06 UTC (permalink / raw)
  To: Laurent Pinchart
  Cc: Rafael J. Wysocki, Greg Kroah-Hartman,
	Intel Graphics Development, Emil Velikov, DRI Development,
	Daniel Vetter

On Wed, Feb 19, 2020 at 6:02 PM Laurent Pinchart
<laurent.pinchart@ideasonboard.com> wrote:
>
> Hi Daniel,
>
> On Wed, Feb 19, 2020 at 05:53:59PM +0100, Daniel Vetter wrote:
> > On Wed, Feb 19, 2020 at 5:46 PM Laurent Pinchart wrote:
> > > On Wed, Feb 19, 2020 at 05:22:38PM +0100, Daniel Vetter wrote:
> > >> On Wed, Feb 19, 2020 at 5:09 PM Emil Velikov wrote:
> > >>> On Wed, 19 Feb 2020 at 14:23, Daniel Vetter wrote:
> > >>>> On Wed, Feb 19, 2020 at 2:33 PM Greg Kroah-Hartman wrote:
> > >>>>> On Wed, Feb 19, 2020 at 03:28:47PM +0200, Laurent Pinchart wrote:
> > >>>>>> On Wed, Feb 19, 2020 at 11:20:33AM +0100, Daniel Vetter wrote:
> > >>>>>>> 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.
> > >>>>>>
> > >>>>>> This is all a very good idea ! Many subsystems are plagged by drivers
> > >>>>>> using devm_k*alloc to allocate data accessible by userspace. Since the
> > >>>>>> introduction of devm_*, we've likely reduced the number of memory leaks,
> > >>>>>> but I'm pretty sure we've increased the risk of crashes as I've seen
> > >>>>>> some drivers that used .release() callbacks correctly being naively
> > >>>>>> converted to incorrect devm_* usage :-(
> > >>>>>>
> > >>>>>> This leads me to a question: if other subsystems have the same problem,
> > >>>>>> could we turn this implementation into something more generic ? It
> > >>>>>> doesn't have to be done right away and shouldn't block merging this
> > >>>>>> series, but I think it would be very useful.
> > >>>>>
> > >>>>> It shouldn't be that hard to tie this into a drv_m() type of a thing
> > >>>>> (driver_memory?)
> > >>>>>
> > >>>>> And yes, I think it's much better than devm_* for the obvious reasons of
> > >>>>> this being needed here.
> > >>>>
> > >>>> There's two reasons I went with copypasta instead of trying to share code:
> > >>>> - Type checking, I definitely don't want people to mix up devm_ with
> > >>>> drmm_. But even if we do a drv_m that subsystems could embed we do
> > >>>> have quite a few different types of component drivers (and with
> > >>>> drm_panel and drm_bridge even standardized), and I don't want people
> > >>>> to be able to pass the wrong kind of struct to e.g. a managed
> > >>>> drmm_connector_init - it really needs to be the drm_device, not a
> > >>>> panel or bridge or something else.
> > >>>>
> > >>>> - We could still share the code as a kind of implementation/backend
> > >>>> library. But it's not much, and with embedding I could use the drm
> > >>>> device logging stuff which is kinda nice. But if there's more demand
> > >>>> for this I can definitely see the point in sharing this, as Laurent
> > >>>> pointed out with the tiny optimization with not allocating a NULL void
> > >>>> * that I've done (and screwed up) it's not entirely trivial code.
> > >>>
> > >>> My 2c as they say, although closer to a brain dump :-)
> > >>>
> > >>> On one hand the drm_device has an embedded struct device. On the other
> > >>> drm_device preserves state which outlives the embedded struct device.
> > >>>
> > >>> Would it make sense to keep drm_device better related to the
> > >>> underlying device? Effectively moving the $misc state to drm_driver.
> > >>> This idea does raise another question - struct drm_driver unlike many
> > >>> other struct $foo_driver, does not embedded device_driver :-(
> > >>> So if one is to cover the above two, then the embedding concerns will
> > >>> be elevated.
> > >>
> > >> drm_driver isn't a bus device driver in the linux driver model sense,
> > >> but an uapi thing that sits on top of some underlying device. So maybe
> > >> better to rename drm_driver to drm_interface_driver, and drm_device to
> > >> drm_interface. But that would be giantic churn and probably lots of
> > >> confusion. We do require a link between drm_device->struct device
> > >> nowadays, but that's just to guarantee userspace can find the
> > >> drm_device in sysfs somewhere and make sense of what it actually
> > >> drives.
> > >
> > > If we wanted to rename drm_driver to align with the rest of the kernel,
> > > it should probably be drm_device_ops, with the non-ops fields being
> > > moved to a separate structure.
> > >
> > > I don't mind churn (but I agree it may not be worth it), but even if we
> > > don't rename the structure, I think it would be very useful to remove
> > > the non-const fields, in order to allow storing the structure as a
> > > global static const struct. Function pointers in non-const memory can be
> > > a security issue. As far as I can tell, the only blocker is the
> > > legacy_dev_list field.
> >
> > Oh man ... we could make the legacy_dev_list depend on
> > CONFIG_DRM_LEGACY and the INIT_LIST_HEAD also depend upon
> > DRIVER_LEGACY and then at least all the new drivers could make their
> > drm_driver structure const. Or something along those lines.
>
> We would however need different function prototypes for drm_dev_init() &
> co. that would take const struct drm_driver instead of struct
> drm_driver.

Huh right, this would require quite serious amounts of lying. Legacy
drivers only enter this entire thing through drm_legacy_pci_init, so
we could cast there to a const and move the LIST_INIT_HEAD to that
function. All the other list manipulation is also only happening in
drm_pci.c. But would be kinda ugly.

> > Properly ditching legacy_dev_list is probably not worth it, since
> > those drivers tend to be all root exploits anyway :-)
>
> What if we turned the list into a global list in drm_pci.c ?

I guess that would work too.
-Daniel

> > >> That's also why the lifetimes for the two things are totally
> > >> different. The device driver an all it's resources are tied to the
> > >> underlying physical device, and resources can be released when that
> > >> driver<->device link is broken (either unbind or hotunplug). That's
> > >> what devm_ does. The drm_driver/drm_device otoh is tied to the
> > >> userspace api, and can only disappear once all the userspace handles
> > >> have been cleaned up and released.
> > >
> > > And so they're tied to the lifetime of the struct device that models the
> > > userspace interface. Shame they're both called device :-)
> > >
> > >> And we have an enormous amount of those, with all the mmaps, and
> > >> shared fd for dma-buf, sync_file, synobj and whatever else. The
> > >> drm_device can only be cleaned up once userspace has closed all these
> > >> things, or we'll go boom somewhere. The only connection is that the
> > >> userspace interface drives the underlying hw (as long as it's still
> > >> there) and the hw side holds a reference on the uapi side
> > >> (drm_dev_get/put) to make sure the userspace side doesn't go poof and
> > >> disappear when no one has the /dev node open :-)
> > >>
> > >> But aside from these links they're completely separate worlds, and
> > >> mixing up the lifetimes results in all kinds of bad things happening.
> > >> Ofc normally these two things exist at the same time, but hotunplug
> > >> makes things very interesting here. And traditionally we've handled it
> > >> badly, if at all in drm.
> > >>
> > >>> WRT type safety, with the embedded work sorted, one could introduce
> > >>> trivial helpers for drmm_connector_init and friends.
> > >>>
> > >>> In another email you've also raised the question of API diversity and
> > >>> reviews, I believe. IMHO one could start with a bare minimum set and
> > >>> extend as needed.
> > >>> Based on the prompt response from Greg, I suspect review won't be an issue.
> > >>
> > >> The drmm_ stuff in here is the bare minimum we need to get started. I
> > >> expect lots of stuff will be added, but those are all just going to be
> > >> convenience functions on top of the drmm_add_action primitive.
> > >>
> > >>> If people agree with my analysis and considering the size/complexity
> > >>> of drm_device <> drm_driver reshuffle, we could add a TODO task.
> > >>> I suspect the underlying work will be larger than the current 52 patch
> > >>> set, so doing it in one go will be PITA.
> > >>
> > >> I'm not following what you want to shuffle. drm_driver is entirely
> > >> static and kinda global, drm_device is the per-instance structure we
> > >> have. And here we mean per-userspace uapi interface instance. So I
> > >> guess I'm confused what you want to do?
> > >>
> > >>> * Based on the following quick greps
> > >>> $git grep -W "struct [a-zA-Z0-9-]*_driver {" -- include/ | grep -w
> > >>> "struct device_driver\>.*;"  | wc -l
> > >>> 56
> > >>> $git cgrep "struct [a-zA-Z0-9-]*_driver {" -- include/ | wc -l
> > >>> 71
>
> --
> Regards,
>
> Laurent Pinchart



-- 
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] 310+ messages in thread

* Re: [Intel-gfx] [PATCH 03/52] drm: add managed resources tied to drm_device
@ 2020-02-19 17:06                     ` Daniel Vetter
  0 siblings, 0 replies; 310+ messages in thread
From: Daniel Vetter @ 2020-02-19 17:06 UTC (permalink / raw)
  To: Laurent Pinchart
  Cc: Rafael J. Wysocki, Greg Kroah-Hartman,
	Intel Graphics Development, DRI Development, Daniel Vetter

On Wed, Feb 19, 2020 at 6:02 PM Laurent Pinchart
<laurent.pinchart@ideasonboard.com> wrote:
>
> Hi Daniel,
>
> On Wed, Feb 19, 2020 at 05:53:59PM +0100, Daniel Vetter wrote:
> > On Wed, Feb 19, 2020 at 5:46 PM Laurent Pinchart wrote:
> > > On Wed, Feb 19, 2020 at 05:22:38PM +0100, Daniel Vetter wrote:
> > >> On Wed, Feb 19, 2020 at 5:09 PM Emil Velikov wrote:
> > >>> On Wed, 19 Feb 2020 at 14:23, Daniel Vetter wrote:
> > >>>> On Wed, Feb 19, 2020 at 2:33 PM Greg Kroah-Hartman wrote:
> > >>>>> On Wed, Feb 19, 2020 at 03:28:47PM +0200, Laurent Pinchart wrote:
> > >>>>>> On Wed, Feb 19, 2020 at 11:20:33AM +0100, Daniel Vetter wrote:
> > >>>>>>> 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.
> > >>>>>>
> > >>>>>> This is all a very good idea ! Many subsystems are plagged by drivers
> > >>>>>> using devm_k*alloc to allocate data accessible by userspace. Since the
> > >>>>>> introduction of devm_*, we've likely reduced the number of memory leaks,
> > >>>>>> but I'm pretty sure we've increased the risk of crashes as I've seen
> > >>>>>> some drivers that used .release() callbacks correctly being naively
> > >>>>>> converted to incorrect devm_* usage :-(
> > >>>>>>
> > >>>>>> This leads me to a question: if other subsystems have the same problem,
> > >>>>>> could we turn this implementation into something more generic ? It
> > >>>>>> doesn't have to be done right away and shouldn't block merging this
> > >>>>>> series, but I think it would be very useful.
> > >>>>>
> > >>>>> It shouldn't be that hard to tie this into a drv_m() type of a thing
> > >>>>> (driver_memory?)
> > >>>>>
> > >>>>> And yes, I think it's much better than devm_* for the obvious reasons of
> > >>>>> this being needed here.
> > >>>>
> > >>>> There's two reasons I went with copypasta instead of trying to share code:
> > >>>> - Type checking, I definitely don't want people to mix up devm_ with
> > >>>> drmm_. But even if we do a drv_m that subsystems could embed we do
> > >>>> have quite a few different types of component drivers (and with
> > >>>> drm_panel and drm_bridge even standardized), and I don't want people
> > >>>> to be able to pass the wrong kind of struct to e.g. a managed
> > >>>> drmm_connector_init - it really needs to be the drm_device, not a
> > >>>> panel or bridge or something else.
> > >>>>
> > >>>> - We could still share the code as a kind of implementation/backend
> > >>>> library. But it's not much, and with embedding I could use the drm
> > >>>> device logging stuff which is kinda nice. But if there's more demand
> > >>>> for this I can definitely see the point in sharing this, as Laurent
> > >>>> pointed out with the tiny optimization with not allocating a NULL void
> > >>>> * that I've done (and screwed up) it's not entirely trivial code.
> > >>>
> > >>> My 2c as they say, although closer to a brain dump :-)
> > >>>
> > >>> On one hand the drm_device has an embedded struct device. On the other
> > >>> drm_device preserves state which outlives the embedded struct device.
> > >>>
> > >>> Would it make sense to keep drm_device better related to the
> > >>> underlying device? Effectively moving the $misc state to drm_driver.
> > >>> This idea does raise another question - struct drm_driver unlike many
> > >>> other struct $foo_driver, does not embedded device_driver :-(
> > >>> So if one is to cover the above two, then the embedding concerns will
> > >>> be elevated.
> > >>
> > >> drm_driver isn't a bus device driver in the linux driver model sense,
> > >> but an uapi thing that sits on top of some underlying device. So maybe
> > >> better to rename drm_driver to drm_interface_driver, and drm_device to
> > >> drm_interface. But that would be giantic churn and probably lots of
> > >> confusion. We do require a link between drm_device->struct device
> > >> nowadays, but that's just to guarantee userspace can find the
> > >> drm_device in sysfs somewhere and make sense of what it actually
> > >> drives.
> > >
> > > If we wanted to rename drm_driver to align with the rest of the kernel,
> > > it should probably be drm_device_ops, with the non-ops fields being
> > > moved to a separate structure.
> > >
> > > I don't mind churn (but I agree it may not be worth it), but even if we
> > > don't rename the structure, I think it would be very useful to remove
> > > the non-const fields, in order to allow storing the structure as a
> > > global static const struct. Function pointers in non-const memory can be
> > > a security issue. As far as I can tell, the only blocker is the
> > > legacy_dev_list field.
> >
> > Oh man ... we could make the legacy_dev_list depend on
> > CONFIG_DRM_LEGACY and the INIT_LIST_HEAD also depend upon
> > DRIVER_LEGACY and then at least all the new drivers could make their
> > drm_driver structure const. Or something along those lines.
>
> We would however need different function prototypes for drm_dev_init() &
> co. that would take const struct drm_driver instead of struct
> drm_driver.

Huh right, this would require quite serious amounts of lying. Legacy
drivers only enter this entire thing through drm_legacy_pci_init, so
we could cast there to a const and move the LIST_INIT_HEAD to that
function. All the other list manipulation is also only happening in
drm_pci.c. But would be kinda ugly.

> > Properly ditching legacy_dev_list is probably not worth it, since
> > those drivers tend to be all root exploits anyway :-)
>
> What if we turned the list into a global list in drm_pci.c ?

I guess that would work too.
-Daniel

> > >> That's also why the lifetimes for the two things are totally
> > >> different. The device driver an all it's resources are tied to the
> > >> underlying physical device, and resources can be released when that
> > >> driver<->device link is broken (either unbind or hotunplug). That's
> > >> what devm_ does. The drm_driver/drm_device otoh is tied to the
> > >> userspace api, and can only disappear once all the userspace handles
> > >> have been cleaned up and released.
> > >
> > > And so they're tied to the lifetime of the struct device that models the
> > > userspace interface. Shame they're both called device :-)
> > >
> > >> And we have an enormous amount of those, with all the mmaps, and
> > >> shared fd for dma-buf, sync_file, synobj and whatever else. The
> > >> drm_device can only be cleaned up once userspace has closed all these
> > >> things, or we'll go boom somewhere. The only connection is that the
> > >> userspace interface drives the underlying hw (as long as it's still
> > >> there) and the hw side holds a reference on the uapi side
> > >> (drm_dev_get/put) to make sure the userspace side doesn't go poof and
> > >> disappear when no one has the /dev node open :-)
> > >>
> > >> But aside from these links they're completely separate worlds, and
> > >> mixing up the lifetimes results in all kinds of bad things happening.
> > >> Ofc normally these two things exist at the same time, but hotunplug
> > >> makes things very interesting here. And traditionally we've handled it
> > >> badly, if at all in drm.
> > >>
> > >>> WRT type safety, with the embedded work sorted, one could introduce
> > >>> trivial helpers for drmm_connector_init and friends.
> > >>>
> > >>> In another email you've also raised the question of API diversity and
> > >>> reviews, I believe. IMHO one could start with a bare minimum set and
> > >>> extend as needed.
> > >>> Based on the prompt response from Greg, I suspect review won't be an issue.
> > >>
> > >> The drmm_ stuff in here is the bare minimum we need to get started. I
> > >> expect lots of stuff will be added, but those are all just going to be
> > >> convenience functions on top of the drmm_add_action primitive.
> > >>
> > >>> If people agree with my analysis and considering the size/complexity
> > >>> of drm_device <> drm_driver reshuffle, we could add a TODO task.
> > >>> I suspect the underlying work will be larger than the current 52 patch
> > >>> set, so doing it in one go will be PITA.
> > >>
> > >> I'm not following what you want to shuffle. drm_driver is entirely
> > >> static and kinda global, drm_device is the per-instance structure we
> > >> have. And here we mean per-userspace uapi interface instance. So I
> > >> guess I'm confused what you want to do?
> > >>
> > >>> * Based on the following quick greps
> > >>> $git grep -W "struct [a-zA-Z0-9-]*_driver {" -- include/ | grep -w
> > >>> "struct device_driver\>.*;"  | wc -l
> > >>> 56
> > >>> $git cgrep "struct [a-zA-Z0-9-]*_driver {" -- include/ | wc -l
> > >>> 71
>
> --
> Regards,
>
> Laurent Pinchart



-- 
Daniel Vetter
Software Engineer, Intel Corporation
+41 (0) 79 365 57 48 - http://blog.ffwll.ch
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH 27/52] drm: Manage drm_mode_config_init with drmm_
  2020-02-19 16:23           ` [Intel-gfx] " Daniel Vetter
@ 2020-02-19 17:30             ` Noralf Trønnes
  -1 siblings, 0 replies; 310+ messages in thread
From: Noralf Trønnes @ 2020-02-19 17:30 UTC (permalink / raw)
  To: Daniel Vetter, Laurent Pinchart
  Cc: Daniel Vetter, Intel Graphics Development, Sam Ravnborg,
	DRI Development, Thomas Zimmermann



Den 19.02.2020 17.23, skrev Daniel Vetter:
> On Wed, Feb 19, 2020 at 5:08 PM Laurent Pinchart
> <laurent.pinchart@ideasonboard.com> wrote:
>>
>> Hi Daniel,
>>
>> On Wed, Feb 19, 2020 at 04:47:55PM +0100, Daniel Vetter wrote:
>>> On Wed, Feb 19, 2020 at 2:50 PM Laurent Pinchart wrote:
>>>> On Wed, Feb 19, 2020 at 11:20:57AM +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 not 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, so deprecate that hook to discourage future users.
>>>>>
>>>>> v2: Fixup the example in the kerneldoc too.
>>>>>
>>>>> Cc: "Noralf Trønnes" <noralf@tronnes.org>
>>>>> Cc: Sam Ravnborg <sam@ravnborg.org>
>>>>> Cc: Thomas Zimmermann <tzimmermann@suse.de>
>>>>> Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
>>>>> ---

<snip>

>>>>> diff --git a/drivers/gpu/drm/drm_mode_config.c b/drivers/gpu/drm/drm_mode_config.c
>>>>> index 08e6eff6a179..957db1edba0c 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,8 @@ void drm_mode_config_init(struct drm_device *dev)
>>>>>               drm_modeset_acquire_fini(&modeset_ctx);
>>>>>               dma_resv_fini(&resv);
>>>>>       }
>>>>> +
>>>>> +     return drmm_add_action(dev, drm_mode_config_init_release, NULL);
>>>>
>>>> If this fails, shouldn't drm_mode_config_cleanup() be called here ?
>>>
>>> Maybe for ocd reasons, but not for actually cleaning up anything. It's
>>> just a bunch of empty lists that drm_mode_config_cleanup will walk and
>>> do nothing about. Not sure I should add that ...
>>
>> How about the ida init, and the mutex_init() that isn't a no-op when
>> lock debugging is enabled ?
> 
> Hm right, I'll fix this.
> 

You could make a drmm_ version of devm_add_action_or_reset() for this.

Noralf.

> Fun thing is that I've found a pile of missing mutex_destroy and
> ida_cleanup() while reviewing all the code I've read. Not sure I've
> fixed them all up ...
> -Daniel
> 
>>
>>>>>  }
>>>>>  EXPORT_SYMBOL(drm_mode_config_init);
>>>>>
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

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

* Re: [Intel-gfx] [PATCH 27/52] drm: Manage drm_mode_config_init with drmm_
@ 2020-02-19 17:30             ` Noralf Trønnes
  0 siblings, 0 replies; 310+ messages in thread
From: Noralf Trønnes @ 2020-02-19 17:30 UTC (permalink / raw)
  To: Daniel Vetter, Laurent Pinchart
  Cc: Daniel Vetter, Intel Graphics Development, Sam Ravnborg,
	DRI Development, Thomas Zimmermann



Den 19.02.2020 17.23, skrev Daniel Vetter:
> On Wed, Feb 19, 2020 at 5:08 PM Laurent Pinchart
> <laurent.pinchart@ideasonboard.com> wrote:
>>
>> Hi Daniel,
>>
>> On Wed, Feb 19, 2020 at 04:47:55PM +0100, Daniel Vetter wrote:
>>> On Wed, Feb 19, 2020 at 2:50 PM Laurent Pinchart wrote:
>>>> On Wed, Feb 19, 2020 at 11:20:57AM +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 not 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, so deprecate that hook to discourage future users.
>>>>>
>>>>> v2: Fixup the example in the kerneldoc too.
>>>>>
>>>>> Cc: "Noralf Trønnes" <noralf@tronnes.org>
>>>>> Cc: Sam Ravnborg <sam@ravnborg.org>
>>>>> Cc: Thomas Zimmermann <tzimmermann@suse.de>
>>>>> Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
>>>>> ---

<snip>

>>>>> diff --git a/drivers/gpu/drm/drm_mode_config.c b/drivers/gpu/drm/drm_mode_config.c
>>>>> index 08e6eff6a179..957db1edba0c 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,8 @@ void drm_mode_config_init(struct drm_device *dev)
>>>>>               drm_modeset_acquire_fini(&modeset_ctx);
>>>>>               dma_resv_fini(&resv);
>>>>>       }
>>>>> +
>>>>> +     return drmm_add_action(dev, drm_mode_config_init_release, NULL);
>>>>
>>>> If this fails, shouldn't drm_mode_config_cleanup() be called here ?
>>>
>>> Maybe for ocd reasons, but not for actually cleaning up anything. It's
>>> just a bunch of empty lists that drm_mode_config_cleanup will walk and
>>> do nothing about. Not sure I should add that ...
>>
>> How about the ida init, and the mutex_init() that isn't a no-op when
>> lock debugging is enabled ?
> 
> Hm right, I'll fix this.
> 

You could make a drmm_ version of devm_add_action_or_reset() for this.

Noralf.

> Fun thing is that I've found a pile of missing mutex_destroy and
> ida_cleanup() while reviewing all the code I've read. Not sure I've
> fixed them all up ...
> -Daniel
> 
>>
>>>>>  }
>>>>>  EXPORT_SYMBOL(drm_mode_config_init);
>>>>>
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH 03/52] drm: add managed resources tied to drm_device
  2020-02-19 17:00           ` [Intel-gfx] " Greg Kroah-Hartman
@ 2020-02-19 17:36             ` Laurent Pinchart
  -1 siblings, 0 replies; 310+ messages in thread
From: Laurent Pinchart @ 2020-02-19 17:36 UTC (permalink / raw)
  To: Greg Kroah-Hartman
  Cc: Daniel Vetter, Intel Graphics Development, Rafael J. Wysocki,
	DRI Development, Daniel Vetter

Hi Greg,

On Wed, Feb 19, 2020 at 06:00:46PM +0100, Greg Kroah-Hartman wrote:
> On Wed, Feb 19, 2020 at 03:22:49PM +0100, Daniel Vetter wrote:
> > On Wed, Feb 19, 2020 at 2:33 PM Greg Kroah-Hartman wrote:
> > > On Wed, Feb 19, 2020 at 03:28:47PM +0200, Laurent Pinchart wrote:
> > > > On Wed, Feb 19, 2020 at 11:20:33AM +0100, Daniel Vetter wrote:
> > > > > 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.
> > > >
> > > > This is all a very good idea ! Many subsystems are plagged by drivers
> > > > using devm_k*alloc to allocate data accessible by userspace. Since the
> > > > introduction of devm_*, we've likely reduced the number of memory leaks,
> > > > but I'm pretty sure we've increased the risk of crashes as I've seen
> > > > some drivers that used .release() callbacks correctly being naively
> > > > converted to incorrect devm_* usage :-(
> > > >
> > > > This leads me to a question: if other subsystems have the same problem,
> > > > could we turn this implementation into something more generic ? It
> > > > doesn't have to be done right away and shouldn't block merging this
> > > > series, but I think it would be very useful.
> > >
> > > It shouldn't be that hard to tie this into a drv_m() type of a thing
> > > (driver_memory?)
> > >
> > > And yes, I think it's much better than devm_* for the obvious reasons of
> > > this being needed here.
> > 
> > There's two reasons I went with copypasta instead of trying to share code:
> > - Type checking, I definitely don't want people to mix up devm_ with
> > drmm_. But even if we do a drv_m that subsystems could embed we do
> > have quite a few different types of component drivers (and with
> > drm_panel and drm_bridge even standardized), and I don't want people
> > to be able to pass the wrong kind of struct to e.g. a managed
> > drmm_connector_init - it really needs to be the drm_device, not a
> > panel or bridge or something else.
> 
> Fair enough, that makes sense.
> 
> > - We could still share the code as a kind of implementation/backend
> > library. But it's not much, and with embedding I could use the drm
> > device logging stuff which is kinda nice. But if there's more demand
> > for this I can definitely see the point in sharing this, as Laurent
> > pointed out with the tiny optimization with not allocating a NULL void
> > * that I've done (and screwed up) it's not entirely trivial code.
> 
> I think moving over time to having this be a backend library is good.
> But no rush/issues here with this going in now, it solves a real need
> and we can refactor it later on to try to make it more "bus/class"
> generic as needed.

From a type checking point of view, it would then be nice to have a
structure that models a device node, other than just struct device that
is shared by all types of devices. As someone who was involve in the
creation of the device model we have today, and thus know the history,
what's your opinion on that ?

-- 
Regards,

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

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

* Re: [Intel-gfx] [PATCH 03/52] drm: add managed resources tied to drm_device
@ 2020-02-19 17:36             ` Laurent Pinchart
  0 siblings, 0 replies; 310+ messages in thread
From: Laurent Pinchart @ 2020-02-19 17:36 UTC (permalink / raw)
  To: Greg Kroah-Hartman
  Cc: Daniel Vetter, Intel Graphics Development, Rafael J. Wysocki,
	DRI Development, Daniel Vetter

Hi Greg,

On Wed, Feb 19, 2020 at 06:00:46PM +0100, Greg Kroah-Hartman wrote:
> On Wed, Feb 19, 2020 at 03:22:49PM +0100, Daniel Vetter wrote:
> > On Wed, Feb 19, 2020 at 2:33 PM Greg Kroah-Hartman wrote:
> > > On Wed, Feb 19, 2020 at 03:28:47PM +0200, Laurent Pinchart wrote:
> > > > On Wed, Feb 19, 2020 at 11:20:33AM +0100, Daniel Vetter wrote:
> > > > > 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.
> > > >
> > > > This is all a very good idea ! Many subsystems are plagged by drivers
> > > > using devm_k*alloc to allocate data accessible by userspace. Since the
> > > > introduction of devm_*, we've likely reduced the number of memory leaks,
> > > > but I'm pretty sure we've increased the risk of crashes as I've seen
> > > > some drivers that used .release() callbacks correctly being naively
> > > > converted to incorrect devm_* usage :-(
> > > >
> > > > This leads me to a question: if other subsystems have the same problem,
> > > > could we turn this implementation into something more generic ? It
> > > > doesn't have to be done right away and shouldn't block merging this
> > > > series, but I think it would be very useful.
> > >
> > > It shouldn't be that hard to tie this into a drv_m() type of a thing
> > > (driver_memory?)
> > >
> > > And yes, I think it's much better than devm_* for the obvious reasons of
> > > this being needed here.
> > 
> > There's two reasons I went with copypasta instead of trying to share code:
> > - Type checking, I definitely don't want people to mix up devm_ with
> > drmm_. But even if we do a drv_m that subsystems could embed we do
> > have quite a few different types of component drivers (and with
> > drm_panel and drm_bridge even standardized), and I don't want people
> > to be able to pass the wrong kind of struct to e.g. a managed
> > drmm_connector_init - it really needs to be the drm_device, not a
> > panel or bridge or something else.
> 
> Fair enough, that makes sense.
> 
> > - We could still share the code as a kind of implementation/backend
> > library. But it's not much, and with embedding I could use the drm
> > device logging stuff which is kinda nice. But if there's more demand
> > for this I can definitely see the point in sharing this, as Laurent
> > pointed out with the tiny optimization with not allocating a NULL void
> > * that I've done (and screwed up) it's not entirely trivial code.
> 
> I think moving over time to having this be a backend library is good.
> But no rush/issues here with this going in now, it solves a real need
> and we can refactor it later on to try to make it more "bus/class"
> generic as needed.

From a type checking point of view, it would then be nice to have a
structure that models a device node, other than just struct device that
is shared by all types of devices. As someone who was involve in the
creation of the device model we have today, and thus know the history,
what's your opinion on that ?

-- 
Regards,

Laurent Pinchart
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH 27/52] drm: Manage drm_mode_config_init with drmm_
  2020-02-19 17:30             ` [Intel-gfx] " Noralf Trønnes
@ 2020-02-19 18:12               ` Daniel Vetter
  -1 siblings, 0 replies; 310+ messages in thread
From: Daniel Vetter @ 2020-02-19 18:12 UTC (permalink / raw)
  To: Noralf Trønnes
  Cc: Intel Graphics Development, DRI Development, Laurent Pinchart,
	Thomas Zimmermann, Daniel Vetter, Sam Ravnborg

On Wed, Feb 19, 2020 at 6:30 PM Noralf Trønnes <noralf@tronnes.org> wrote:
>
>
>
> Den 19.02.2020 17.23, skrev Daniel Vetter:
> > On Wed, Feb 19, 2020 at 5:08 PM Laurent Pinchart
> > <laurent.pinchart@ideasonboard.com> wrote:
> >>
> >> Hi Daniel,
> >>
> >> On Wed, Feb 19, 2020 at 04:47:55PM +0100, Daniel Vetter wrote:
> >>> On Wed, Feb 19, 2020 at 2:50 PM Laurent Pinchart wrote:
> >>>> On Wed, Feb 19, 2020 at 11:20:57AM +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 not 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, so deprecate that hook to discourage future users.
> >>>>>
> >>>>> v2: Fixup the example in the kerneldoc too.
> >>>>>
> >>>>> Cc: "Noralf Trønnes" <noralf@tronnes.org>
> >>>>> Cc: Sam Ravnborg <sam@ravnborg.org>
> >>>>> Cc: Thomas Zimmermann <tzimmermann@suse.de>
> >>>>> Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
> >>>>> ---
>
> <snip>
>
> >>>>> diff --git a/drivers/gpu/drm/drm_mode_config.c b/drivers/gpu/drm/drm_mode_config.c
> >>>>> index 08e6eff6a179..957db1edba0c 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,8 @@ void drm_mode_config_init(struct drm_device *dev)
> >>>>>               drm_modeset_acquire_fini(&modeset_ctx);
> >>>>>               dma_resv_fini(&resv);
> >>>>>       }
> >>>>> +
> >>>>> +     return drmm_add_action(dev, drm_mode_config_init_release, NULL);
> >>>>
> >>>> If this fails, shouldn't drm_mode_config_cleanup() be called here ?
> >>>
> >>> Maybe for ocd reasons, but not for actually cleaning up anything. It's
> >>> just a bunch of empty lists that drm_mode_config_cleanup will walk and
> >>> do nothing about. Not sure I should add that ...
> >>
> >> How about the ida init, and the mutex_init() that isn't a no-op when
> >> lock debugging is enabled ?
> >
> > Hm right, I'll fix this.
> >
>
> You could make a drmm_ version of devm_add_action_or_reset() for this.

...

How did I not see that in devres.c. In my defense, I've never written
a driver using devm because of all the lifetime bugs that would cause
in drm, but yes this is exactly what we want here.

Thanks a lot for the pointer, I'll go do some typing!

Cheers, Daniel
-- 
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] 310+ messages in thread

* Re: [Intel-gfx] [PATCH 27/52] drm: Manage drm_mode_config_init with drmm_
@ 2020-02-19 18:12               ` Daniel Vetter
  0 siblings, 0 replies; 310+ messages in thread
From: Daniel Vetter @ 2020-02-19 18:12 UTC (permalink / raw)
  To: Noralf Trønnes
  Cc: Intel Graphics Development, DRI Development, Laurent Pinchart,
	Thomas Zimmermann, Daniel Vetter, Sam Ravnborg

On Wed, Feb 19, 2020 at 6:30 PM Noralf Trønnes <noralf@tronnes.org> wrote:
>
>
>
> Den 19.02.2020 17.23, skrev Daniel Vetter:
> > On Wed, Feb 19, 2020 at 5:08 PM Laurent Pinchart
> > <laurent.pinchart@ideasonboard.com> wrote:
> >>
> >> Hi Daniel,
> >>
> >> On Wed, Feb 19, 2020 at 04:47:55PM +0100, Daniel Vetter wrote:
> >>> On Wed, Feb 19, 2020 at 2:50 PM Laurent Pinchart wrote:
> >>>> On Wed, Feb 19, 2020 at 11:20:57AM +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 not 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, so deprecate that hook to discourage future users.
> >>>>>
> >>>>> v2: Fixup the example in the kerneldoc too.
> >>>>>
> >>>>> Cc: "Noralf Trønnes" <noralf@tronnes.org>
> >>>>> Cc: Sam Ravnborg <sam@ravnborg.org>
> >>>>> Cc: Thomas Zimmermann <tzimmermann@suse.de>
> >>>>> Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
> >>>>> ---
>
> <snip>
>
> >>>>> diff --git a/drivers/gpu/drm/drm_mode_config.c b/drivers/gpu/drm/drm_mode_config.c
> >>>>> index 08e6eff6a179..957db1edba0c 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,8 @@ void drm_mode_config_init(struct drm_device *dev)
> >>>>>               drm_modeset_acquire_fini(&modeset_ctx);
> >>>>>               dma_resv_fini(&resv);
> >>>>>       }
> >>>>> +
> >>>>> +     return drmm_add_action(dev, drm_mode_config_init_release, NULL);
> >>>>
> >>>> If this fails, shouldn't drm_mode_config_cleanup() be called here ?
> >>>
> >>> Maybe for ocd reasons, but not for actually cleaning up anything. It's
> >>> just a bunch of empty lists that drm_mode_config_cleanup will walk and
> >>> do nothing about. Not sure I should add that ...
> >>
> >> How about the ida init, and the mutex_init() that isn't a no-op when
> >> lock debugging is enabled ?
> >
> > Hm right, I'll fix this.
> >
>
> You could make a drmm_ version of devm_add_action_or_reset() for this.

...

How did I not see that in devres.c. In my defense, I've never written
a driver using devm because of all the lifetime bugs that would cause
in drm, but yes this is exactly what we want here.

Thanks a lot for the pointer, I'll go do some typing!

Cheers, Daniel
-- 
Daniel Vetter
Software Engineer, Intel Corporation
+41 (0) 79 365 57 48 - http://blog.ffwll.ch
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH 03/52] drm: add managed resources tied to drm_device
  2020-02-19 17:36             ` [Intel-gfx] " Laurent Pinchart
@ 2020-02-19 18:19               ` Greg Kroah-Hartman
  -1 siblings, 0 replies; 310+ messages in thread
From: Greg Kroah-Hartman @ 2020-02-19 18:19 UTC (permalink / raw)
  To: Laurent Pinchart
  Cc: Daniel Vetter, Intel Graphics Development, Rafael J. Wysocki,
	DRI Development, Daniel Vetter

On Wed, Feb 19, 2020 at 07:36:52PM +0200, Laurent Pinchart wrote:
> Hi Greg,
> 
> On Wed, Feb 19, 2020 at 06:00:46PM +0100, Greg Kroah-Hartman wrote:
> > On Wed, Feb 19, 2020 at 03:22:49PM +0100, Daniel Vetter wrote:
> > > On Wed, Feb 19, 2020 at 2:33 PM Greg Kroah-Hartman wrote:
> > > > On Wed, Feb 19, 2020 at 03:28:47PM +0200, Laurent Pinchart wrote:
> > > > > On Wed, Feb 19, 2020 at 11:20:33AM +0100, Daniel Vetter wrote:
> > > > > > 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.
> > > > >
> > > > > This is all a very good idea ! Many subsystems are plagged by drivers
> > > > > using devm_k*alloc to allocate data accessible by userspace. Since the
> > > > > introduction of devm_*, we've likely reduced the number of memory leaks,
> > > > > but I'm pretty sure we've increased the risk of crashes as I've seen
> > > > > some drivers that used .release() callbacks correctly being naively
> > > > > converted to incorrect devm_* usage :-(
> > > > >
> > > > > This leads me to a question: if other subsystems have the same problem,
> > > > > could we turn this implementation into something more generic ? It
> > > > > doesn't have to be done right away and shouldn't block merging this
> > > > > series, but I think it would be very useful.
> > > >
> > > > It shouldn't be that hard to tie this into a drv_m() type of a thing
> > > > (driver_memory?)
> > > >
> > > > And yes, I think it's much better than devm_* for the obvious reasons of
> > > > this being needed here.
> > > 
> > > There's two reasons I went with copypasta instead of trying to share code:
> > > - Type checking, I definitely don't want people to mix up devm_ with
> > > drmm_. But even if we do a drv_m that subsystems could embed we do
> > > have quite a few different types of component drivers (and with
> > > drm_panel and drm_bridge even standardized), and I don't want people
> > > to be able to pass the wrong kind of struct to e.g. a managed
> > > drmm_connector_init - it really needs to be the drm_device, not a
> > > panel or bridge or something else.
> > 
> > Fair enough, that makes sense.
> > 
> > > - We could still share the code as a kind of implementation/backend
> > > library. But it's not much, and with embedding I could use the drm
> > > device logging stuff which is kinda nice. But if there's more demand
> > > for this I can definitely see the point in sharing this, as Laurent
> > > pointed out with the tiny optimization with not allocating a NULL void
> > > * that I've done (and screwed up) it's not entirely trivial code.
> > 
> > I think moving over time to having this be a backend library is good.
> > But no rush/issues here with this going in now, it solves a real need
> > and we can refactor it later on to try to make it more "bus/class"
> > generic as needed.
> 
> >From a type checking point of view, it would then be nice to have a
> structure that models a device node, other than just struct device that
> is shared by all types of devices. As someone who was involve in the
> creation of the device model we have today, and thus know the history,
> what's your opinion on that ?

My opinion is that 'struct device' was created just for that exact
thing.  If "all you want" is a device node, it is trivial to use:
	device_create();
or device_create_varargs() or device_create_with_groups()
and then use device_destroy() when you are done with it.

yes, it can do much more complex things, as needed, but the basics are
there, so use it in a simple way if you want to, no objection from me.

If there are things that are missing with it, please let me know.

But creating a new structure/way for this, no, we do not want to go back
to the 2.4 and older kernel methods where it was all totally disjointed
and messy.

thanks,

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

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

* Re: [Intel-gfx] [PATCH 03/52] drm: add managed resources tied to drm_device
@ 2020-02-19 18:19               ` Greg Kroah-Hartman
  0 siblings, 0 replies; 310+ messages in thread
From: Greg Kroah-Hartman @ 2020-02-19 18:19 UTC (permalink / raw)
  To: Laurent Pinchart
  Cc: Daniel Vetter, Intel Graphics Development, Rafael J. Wysocki,
	DRI Development, Daniel Vetter

On Wed, Feb 19, 2020 at 07:36:52PM +0200, Laurent Pinchart wrote:
> Hi Greg,
> 
> On Wed, Feb 19, 2020 at 06:00:46PM +0100, Greg Kroah-Hartman wrote:
> > On Wed, Feb 19, 2020 at 03:22:49PM +0100, Daniel Vetter wrote:
> > > On Wed, Feb 19, 2020 at 2:33 PM Greg Kroah-Hartman wrote:
> > > > On Wed, Feb 19, 2020 at 03:28:47PM +0200, Laurent Pinchart wrote:
> > > > > On Wed, Feb 19, 2020 at 11:20:33AM +0100, Daniel Vetter wrote:
> > > > > > 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.
> > > > >
> > > > > This is all a very good idea ! Many subsystems are plagged by drivers
> > > > > using devm_k*alloc to allocate data accessible by userspace. Since the
> > > > > introduction of devm_*, we've likely reduced the number of memory leaks,
> > > > > but I'm pretty sure we've increased the risk of crashes as I've seen
> > > > > some drivers that used .release() callbacks correctly being naively
> > > > > converted to incorrect devm_* usage :-(
> > > > >
> > > > > This leads me to a question: if other subsystems have the same problem,
> > > > > could we turn this implementation into something more generic ? It
> > > > > doesn't have to be done right away and shouldn't block merging this
> > > > > series, but I think it would be very useful.
> > > >
> > > > It shouldn't be that hard to tie this into a drv_m() type of a thing
> > > > (driver_memory?)
> > > >
> > > > And yes, I think it's much better than devm_* for the obvious reasons of
> > > > this being needed here.
> > > 
> > > There's two reasons I went with copypasta instead of trying to share code:
> > > - Type checking, I definitely don't want people to mix up devm_ with
> > > drmm_. But even if we do a drv_m that subsystems could embed we do
> > > have quite a few different types of component drivers (and with
> > > drm_panel and drm_bridge even standardized), and I don't want people
> > > to be able to pass the wrong kind of struct to e.g. a managed
> > > drmm_connector_init - it really needs to be the drm_device, not a
> > > panel or bridge or something else.
> > 
> > Fair enough, that makes sense.
> > 
> > > - We could still share the code as a kind of implementation/backend
> > > library. But it's not much, and with embedding I could use the drm
> > > device logging stuff which is kinda nice. But if there's more demand
> > > for this I can definitely see the point in sharing this, as Laurent
> > > pointed out with the tiny optimization with not allocating a NULL void
> > > * that I've done (and screwed up) it's not entirely trivial code.
> > 
> > I think moving over time to having this be a backend library is good.
> > But no rush/issues here with this going in now, it solves a real need
> > and we can refactor it later on to try to make it more "bus/class"
> > generic as needed.
> 
> >From a type checking point of view, it would then be nice to have a
> structure that models a device node, other than just struct device that
> is shared by all types of devices. As someone who was involve in the
> creation of the device model we have today, and thus know the history,
> what's your opinion on that ?

My opinion is that 'struct device' was created just for that exact
thing.  If "all you want" is a device node, it is trivial to use:
	device_create();
or device_create_varargs() or device_create_with_groups()
and then use device_destroy() when you are done with it.

yes, it can do much more complex things, as needed, but the basics are
there, so use it in a simple way if you want to, no objection from me.

If there are things that are missing with it, please let me know.

But creating a new structure/way for this, no, we do not want to go back
to the 2.4 and older kernel methods where it was all totally disjointed
and messy.

thanks,

greg k-h
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH 11/52] drm/v3d: Use drmm_add_final_kfree
  2020-02-19 10:20   ` [Intel-gfx] " Daniel Vetter
@ 2020-02-19 18:43     ` Eric Anholt
  -1 siblings, 0 replies; 310+ messages in thread
From: Eric Anholt @ 2020-02-19 18:43 UTC (permalink / raw)
  To: Daniel Vetter; +Cc: Daniel Vetter, Intel Graphics Development, DRI Development

On Wed, Feb 19, 2020 at 2:21 AM Daniel Vetter <daniel.vetter@ffwll.ch> wrote:
>
> 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.
>
> Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
> Cc: Eric Anholt <eric@anholt.net>

Acked-by: Eric Anholt <eric@anholt.net>
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

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

* Re: [Intel-gfx] [PATCH 11/52] drm/v3d: Use drmm_add_final_kfree
@ 2020-02-19 18:43     ` Eric Anholt
  0 siblings, 0 replies; 310+ messages in thread
From: Eric Anholt @ 2020-02-19 18:43 UTC (permalink / raw)
  To: Daniel Vetter; +Cc: Daniel Vetter, Intel Graphics Development, DRI Development

On Wed, Feb 19, 2020 at 2:21 AM Daniel Vetter <daniel.vetter@ffwll.ch> wrote:
>
> 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.
>
> Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
> Cc: Eric Anholt <eric@anholt.net>

Acked-by: Eric Anholt <eric@anholt.net>
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH 01/52] mm/sl[uo]b: export __kmalloc_track(_node)_caller
  2020-02-19 10:20   ` Daniel Vetter
  (?)
@ 2020-02-19 19:42     ` Andrew Morton
  -1 siblings, 0 replies; 310+ messages in thread
From: Andrew Morton @ 2020-02-19 19:42 UTC (permalink / raw)
  To: Daniel Vetter
  Cc: DRI Development, Intel Graphics Development, Daniel Vetter,
	Christoph Lameter, Pekka Enberg, David Rientjes, Joonsoo Kim,
	linux-mm

On Wed, 19 Feb 2020 11:20:31 +0100 Daniel Vetter <daniel.vetter@ffwll.ch> wrote:

> 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.
> 
> ...
>
> Ack for merging through drm trees very much appreciated.

Acked-by: Andrew Morton <akpm@linux-foundation.org>


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

* Re: [PATCH 01/52] mm/sl[uo]b: export __kmalloc_track(_node)_caller
@ 2020-02-19 19:42     ` Andrew Morton
  0 siblings, 0 replies; 310+ messages in thread
From: Andrew Morton @ 2020-02-19 19:42 UTC (permalink / raw)
  To: Daniel Vetter
  Cc: Intel Graphics Development, DRI Development, Pekka Enberg,
	linux-mm, David Rientjes, Daniel Vetter, Christoph Lameter,
	Joonsoo Kim

On Wed, 19 Feb 2020 11:20:31 +0100 Daniel Vetter <daniel.vetter@ffwll.ch> wrote:

> 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.
> 
> ...
>
> Ack for merging through drm trees very much appreciated.

Acked-by: Andrew Morton <akpm@linux-foundation.org>
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

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

* Re: [Intel-gfx] [PATCH 01/52] mm/sl[uo]b: export __kmalloc_track(_node)_caller
@ 2020-02-19 19:42     ` Andrew Morton
  0 siblings, 0 replies; 310+ messages in thread
From: Andrew Morton @ 2020-02-19 19:42 UTC (permalink / raw)
  To: Daniel Vetter
  Cc: Intel Graphics Development, DRI Development, Pekka Enberg,
	linux-mm, David Rientjes, Daniel Vetter, Christoph Lameter,
	Joonsoo Kim

On Wed, 19 Feb 2020 11:20:31 +0100 Daniel Vetter <daniel.vetter@ffwll.ch> wrote:

> 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.
> 
> ...
>
> Ack for merging through drm trees very much appreciated.

Acked-by: Andrew Morton <akpm@linux-foundation.org>
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH 03/52] drm: add managed resources tied to drm_device
  2020-02-19 18:19               ` [Intel-gfx] " Greg Kroah-Hartman
@ 2020-02-19 19:57                 ` Daniel Vetter
  -1 siblings, 0 replies; 310+ messages in thread
From: Daniel Vetter @ 2020-02-19 19:57 UTC (permalink / raw)
  To: Greg Kroah-Hartman
  Cc: Daniel Vetter, Intel Graphics Development, Laurent Pinchart,
	DRI Development, Rafael J. Wysocki

On Wed, Feb 19, 2020 at 7:19 PM Greg Kroah-Hartman
<gregkh@linuxfoundation.org> wrote:
>
> On Wed, Feb 19, 2020 at 07:36:52PM +0200, Laurent Pinchart wrote:
> > Hi Greg,
> >
> > On Wed, Feb 19, 2020 at 06:00:46PM +0100, Greg Kroah-Hartman wrote:
> > > On Wed, Feb 19, 2020 at 03:22:49PM +0100, Daniel Vetter wrote:
> > > > On Wed, Feb 19, 2020 at 2:33 PM Greg Kroah-Hartman wrote:
> > > > > On Wed, Feb 19, 2020 at 03:28:47PM +0200, Laurent Pinchart wrote:
> > > > > > On Wed, Feb 19, 2020 at 11:20:33AM +0100, Daniel Vetter wrote:
> > > > > > > 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.
> > > > > >
> > > > > > This is all a very good idea ! Many subsystems are plagged by drivers
> > > > > > using devm_k*alloc to allocate data accessible by userspace. Since the
> > > > > > introduction of devm_*, we've likely reduced the number of memory leaks,
> > > > > > but I'm pretty sure we've increased the risk of crashes as I've seen
> > > > > > some drivers that used .release() callbacks correctly being naively
> > > > > > converted to incorrect devm_* usage :-(
> > > > > >
> > > > > > This leads me to a question: if other subsystems have the same problem,
> > > > > > could we turn this implementation into something more generic ? It
> > > > > > doesn't have to be done right away and shouldn't block merging this
> > > > > > series, but I think it would be very useful.
> > > > >
> > > > > It shouldn't be that hard to tie this into a drv_m() type of a thing
> > > > > (driver_memory?)
> > > > >
> > > > > And yes, I think it's much better than devm_* for the obvious reasons of
> > > > > this being needed here.
> > > >
> > > > There's two reasons I went with copypasta instead of trying to share code:
> > > > - Type checking, I definitely don't want people to mix up devm_ with
> > > > drmm_. But even if we do a drv_m that subsystems could embed we do
> > > > have quite a few different types of component drivers (and with
> > > > drm_panel and drm_bridge even standardized), and I don't want people
> > > > to be able to pass the wrong kind of struct to e.g. a managed
> > > > drmm_connector_init - it really needs to be the drm_device, not a
> > > > panel or bridge or something else.
> > >
> > > Fair enough, that makes sense.
> > >
> > > > - We could still share the code as a kind of implementation/backend
> > > > library. But it's not much, and with embedding I could use the drm
> > > > device logging stuff which is kinda nice. But if there's more demand
> > > > for this I can definitely see the point in sharing this, as Laurent
> > > > pointed out with the tiny optimization with not allocating a NULL void
> > > > * that I've done (and screwed up) it's not entirely trivial code.
> > >
> > > I think moving over time to having this be a backend library is good.
> > > But no rush/issues here with this going in now, it solves a real need
> > > and we can refactor it later on to try to make it more "bus/class"
> > > generic as needed.
> >
> > >From a type checking point of view, it would then be nice to have a
> > structure that models a device node, other than just struct device that
> > is shared by all types of devices. As someone who was involve in the
> > creation of the device model we have today, and thus know the history,
> > what's your opinion on that ?
>
> My opinion is that 'struct device' was created just for that exact
> thing.  If "all you want" is a device node, it is trivial to use:
>         device_create();
> or device_create_varargs() or device_create_with_groups()
> and then use device_destroy() when you are done with it.

Yeah I think if we're going to share the backend code with devres.c
then probably the simplest way is to embed a struct device into
drm_device and give it a name like fake_dont_touch_for_drmm_only_dev
or so :-) And then use that internally in the wrappers, with a nice
properly typed interface exposed to drivers. C isn't C++ where you can
instantiate stuff with generics and all that.
-Daniel

> yes, it can do much more complex things, as needed, but the basics are
> there, so use it in a simple way if you want to, no objection from me.
>
> If there are things that are missing with it, please let me know.
>
> But creating a new structure/way for this, no, we do not want to go back
> to the 2.4 and older kernel methods where it was all totally disjointed
> and messy.



-- 
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] 310+ messages in thread

* Re: [Intel-gfx] [PATCH 03/52] drm: add managed resources tied to drm_device
@ 2020-02-19 19:57                 ` Daniel Vetter
  0 siblings, 0 replies; 310+ messages in thread
From: Daniel Vetter @ 2020-02-19 19:57 UTC (permalink / raw)
  To: Greg Kroah-Hartman
  Cc: Daniel Vetter, Intel Graphics Development, Laurent Pinchart,
	DRI Development, Rafael J. Wysocki

On Wed, Feb 19, 2020 at 7:19 PM Greg Kroah-Hartman
<gregkh@linuxfoundation.org> wrote:
>
> On Wed, Feb 19, 2020 at 07:36:52PM +0200, Laurent Pinchart wrote:
> > Hi Greg,
> >
> > On Wed, Feb 19, 2020 at 06:00:46PM +0100, Greg Kroah-Hartman wrote:
> > > On Wed, Feb 19, 2020 at 03:22:49PM +0100, Daniel Vetter wrote:
> > > > On Wed, Feb 19, 2020 at 2:33 PM Greg Kroah-Hartman wrote:
> > > > > On Wed, Feb 19, 2020 at 03:28:47PM +0200, Laurent Pinchart wrote:
> > > > > > On Wed, Feb 19, 2020 at 11:20:33AM +0100, Daniel Vetter wrote:
> > > > > > > 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.
> > > > > >
> > > > > > This is all a very good idea ! Many subsystems are plagged by drivers
> > > > > > using devm_k*alloc to allocate data accessible by userspace. Since the
> > > > > > introduction of devm_*, we've likely reduced the number of memory leaks,
> > > > > > but I'm pretty sure we've increased the risk of crashes as I've seen
> > > > > > some drivers that used .release() callbacks correctly being naively
> > > > > > converted to incorrect devm_* usage :-(
> > > > > >
> > > > > > This leads me to a question: if other subsystems have the same problem,
> > > > > > could we turn this implementation into something more generic ? It
> > > > > > doesn't have to be done right away and shouldn't block merging this
> > > > > > series, but I think it would be very useful.
> > > > >
> > > > > It shouldn't be that hard to tie this into a drv_m() type of a thing
> > > > > (driver_memory?)
> > > > >
> > > > > And yes, I think it's much better than devm_* for the obvious reasons of
> > > > > this being needed here.
> > > >
> > > > There's two reasons I went with copypasta instead of trying to share code:
> > > > - Type checking, I definitely don't want people to mix up devm_ with
> > > > drmm_. But even if we do a drv_m that subsystems could embed we do
> > > > have quite a few different types of component drivers (and with
> > > > drm_panel and drm_bridge even standardized), and I don't want people
> > > > to be able to pass the wrong kind of struct to e.g. a managed
> > > > drmm_connector_init - it really needs to be the drm_device, not a
> > > > panel or bridge or something else.
> > >
> > > Fair enough, that makes sense.
> > >
> > > > - We could still share the code as a kind of implementation/backend
> > > > library. But it's not much, and with embedding I could use the drm
> > > > device logging stuff which is kinda nice. But if there's more demand
> > > > for this I can definitely see the point in sharing this, as Laurent
> > > > pointed out with the tiny optimization with not allocating a NULL void
> > > > * that I've done (and screwed up) it's not entirely trivial code.
> > >
> > > I think moving over time to having this be a backend library is good.
> > > But no rush/issues here with this going in now, it solves a real need
> > > and we can refactor it later on to try to make it more "bus/class"
> > > generic as needed.
> >
> > >From a type checking point of view, it would then be nice to have a
> > structure that models a device node, other than just struct device that
> > is shared by all types of devices. As someone who was involve in the
> > creation of the device model we have today, and thus know the history,
> > what's your opinion on that ?
>
> My opinion is that 'struct device' was created just for that exact
> thing.  If "all you want" is a device node, it is trivial to use:
>         device_create();
> or device_create_varargs() or device_create_with_groups()
> and then use device_destroy() when you are done with it.

Yeah I think if we're going to share the backend code with devres.c
then probably the simplest way is to embed a struct device into
drm_device and give it a name like fake_dont_touch_for_drmm_only_dev
or so :-) And then use that internally in the wrappers, with a nice
properly typed interface exposed to drivers. C isn't C++ where you can
instantiate stuff with generics and all that.
-Daniel

> yes, it can do much more complex things, as needed, but the basics are
> there, so use it in a simple way if you want to, no objection from me.
>
> If there are things that are missing with it, please let me know.
>
> But creating a new structure/way for this, no, we do not want to go back
> to the 2.4 and older kernel methods where it was all totally disjointed
> and messy.



-- 
Daniel Vetter
Software Engineer, Intel Corporation
+41 (0) 79 365 57 48 - http://blog.ffwll.ch
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH 39/52] drm/stm: Drop explicit drm_mode_config_cleanup call
  2020-02-19 10:21   ` Daniel Vetter
  (?)
@ 2020-02-20 14:18     ` Philippe CORNU
  -1 siblings, 0 replies; 310+ messages in thread
From: Philippe CORNU @ 2020-02-20 14:18 UTC (permalink / raw)
  To: Daniel Vetter, DRI Development
  Cc: Benjamin Gaignard, Intel Graphics Development, Yannick FERTRE,
	Maxime Coquelin, Daniel Vetter, Vincent ABRIOU, linux-stm32,
	linux-arm-kernel, Alexandre TORGUE

Hi Daniel,

On 2/19/20 11:21 AM, Daniel Vetter wrote:
> It's right above the drm_dev_put().
> 
> Aside: Another driver with a bit much devm_kzalloc, which should
> probably use drmm_kzalloc instead ...
> 
> 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..5b374531dd8c 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 = drm_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)
> 

Thank you for your patch,
For this stm part,
Acked-by: Philippe Cornu <philippe.cornu@st.com>

note: we will handle devm_kzalloc() asap, thanks.

Philippe :-)
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [PATCH 39/52] drm/stm: Drop explicit drm_mode_config_cleanup call
@ 2020-02-20 14:18     ` Philippe CORNU
  0 siblings, 0 replies; 310+ messages in thread
From: Philippe CORNU @ 2020-02-20 14:18 UTC (permalink / raw)
  To: Daniel Vetter, DRI Development
  Cc: Intel Graphics Development, Yannick FERTRE, Maxime Coquelin,
	Daniel Vetter, Vincent ABRIOU, linux-stm32, linux-arm-kernel,
	Alexandre TORGUE

Hi Daniel,

On 2/19/20 11:21 AM, Daniel Vetter wrote:
> It's right above the drm_dev_put().
> 
> Aside: Another driver with a bit much devm_kzalloc, which should
> probably use drmm_kzalloc instead ...
> 
> 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..5b374531dd8c 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 = drm_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)
> 

Thank you for your patch,
For this stm part,
Acked-by: Philippe Cornu <philippe.cornu@st.com>

note: we will handle devm_kzalloc() asap, thanks.

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

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

* Re: [Intel-gfx] [PATCH 39/52] drm/stm: Drop explicit drm_mode_config_cleanup call
@ 2020-02-20 14:18     ` Philippe CORNU
  0 siblings, 0 replies; 310+ messages in thread
From: Philippe CORNU @ 2020-02-20 14:18 UTC (permalink / raw)
  To: Daniel Vetter, DRI Development
  Cc: Benjamin Gaignard, Intel Graphics Development, Yannick FERTRE,
	Maxime Coquelin, Daniel Vetter, Vincent ABRIOU, linux-stm32,
	linux-arm-kernel, Alexandre TORGUE

Hi Daniel,

On 2/19/20 11:21 AM, Daniel Vetter wrote:
> It's right above the drm_dev_put().
> 
> Aside: Another driver with a bit much devm_kzalloc, which should
> probably use drmm_kzalloc instead ...
> 
> 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..5b374531dd8c 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 = drm_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)
> 

Thank you for your patch,
For this stm part,
Acked-by: Philippe Cornu <philippe.cornu@st.com>

note: we will handle devm_kzalloc() asap, thanks.

Philippe :-)
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH 03/52] drm: add managed resources tied to drm_device
  2020-02-19 18:19               ` [Intel-gfx] " Greg Kroah-Hartman
@ 2020-02-20 14:58                 ` Laurent Pinchart
  -1 siblings, 0 replies; 310+ messages in thread
From: Laurent Pinchart @ 2020-02-20 14:58 UTC (permalink / raw)
  To: Greg Kroah-Hartman
  Cc: Daniel Vetter, Intel Graphics Development, Rafael J. Wysocki,
	DRI Development, Daniel Vetter

Hi Greg,

On Wed, Feb 19, 2020 at 07:19:32PM +0100, Greg Kroah-Hartman wrote:
> On Wed, Feb 19, 2020 at 07:36:52PM +0200, Laurent Pinchart wrote:
> > On Wed, Feb 19, 2020 at 06:00:46PM +0100, Greg Kroah-Hartman wrote:
> >> On Wed, Feb 19, 2020 at 03:22:49PM +0100, Daniel Vetter wrote:
> >>> On Wed, Feb 19, 2020 at 2:33 PM Greg Kroah-Hartman wrote:
> >>>> On Wed, Feb 19, 2020 at 03:28:47PM +0200, Laurent Pinchart wrote:
> >>>>> On Wed, Feb 19, 2020 at 11:20:33AM +0100, Daniel Vetter wrote:
> >>>>>> 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.
> >>>>>
> >>>>> This is all a very good idea ! Many subsystems are plagged by drivers
> >>>>> using devm_k*alloc to allocate data accessible by userspace. Since the
> >>>>> introduction of devm_*, we've likely reduced the number of memory leaks,
> >>>>> but I'm pretty sure we've increased the risk of crashes as I've seen
> >>>>> some drivers that used .release() callbacks correctly being naively
> >>>>> converted to incorrect devm_* usage :-(
> >>>>>
> >>>>> This leads me to a question: if other subsystems have the same problem,
> >>>>> could we turn this implementation into something more generic ? It
> >>>>> doesn't have to be done right away and shouldn't block merging this
> >>>>> series, but I think it would be very useful.
> >>>>
> >>>> It shouldn't be that hard to tie this into a drv_m() type of a thing
> >>>> (driver_memory?)
> >>>>
> >>>> And yes, I think it's much better than devm_* for the obvious reasons of
> >>>> this being needed here.
> >>> 
> >>> There's two reasons I went with copypasta instead of trying to share code:
> >>> - Type checking, I definitely don't want people to mix up devm_ with
> >>> drmm_. But even if we do a drv_m that subsystems could embed we do
> >>> have quite a few different types of component drivers (and with
> >>> drm_panel and drm_bridge even standardized), and I don't want people
> >>> to be able to pass the wrong kind of struct to e.g. a managed
> >>> drmm_connector_init - it really needs to be the drm_device, not a
> >>> panel or bridge or something else.
> >> 
> >> Fair enough, that makes sense.
> >> 
> >>> - We could still share the code as a kind of implementation/backend
> >>> library. But it's not much, and with embedding I could use the drm
> >>> device logging stuff which is kinda nice. But if there's more demand
> >>> for this I can definitely see the point in sharing this, as Laurent
> >>> pointed out with the tiny optimization with not allocating a NULL void
> >>> * that I've done (and screwed up) it's not entirely trivial code.
> >> 
> >> I think moving over time to having this be a backend library is good.
> >> But no rush/issues here with this going in now, it solves a real need
> >> and we can refactor it later on to try to make it more "bus/class"
> >> generic as needed.
> > 
> > >From a type checking point of view, it would then be nice to have a
> > structure that models a device node, other than just struct device that
> > is shared by all types of devices. As someone who was involve in the
> > creation of the device model we have today, and thus know the history,
> > what's your opinion on that ?
> 
> My opinion is that 'struct device' was created just for that exact
> thing.  If "all you want" is a device node, it is trivial to use:
> 	device_create();
> or device_create_varargs() or device_create_with_groups()
> and then use device_destroy() when you are done with it.
> 
> yes, it can do much more complex things, as needed, but the basics are
> there, so use it in a simple way if you want to, no objection from me.
> 
> If there are things that are missing with it, please let me know.

I don't think it's really about anything missing, but about having two
different APIs for driver developers, to associate resources with either
physical devices that can disappear from the system, or with interfaces
exposed to userspace (or other parts of the kernel). The lifetime
constraints are very different, and if both cases are handled with the
devres API and a struct device, it's very easy for driver authors to
pass the wrong struct device to the API, tying the lifetime of a
userspace-facing resource with the physical device (this is what devres
is mostly used for today :-(). Having two different objects would make
it more apparent which API should be used, and would make it easier to
catch incorrect usage during review. I think this is Daniel's main
point, and the reason that prompted him to create a new API instead of
just reusing devres with the struct device that models the userspace
interface.

(On a side node, I wonder if devres shouldn't have been implemented at
the kref level.)

> But creating a new structure/way for this, no, we do not want to go back
> to the 2.4 and older kernel methods where it was all totally disjointed
> and messy.

-- 
Regards,

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

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

* Re: [Intel-gfx] [PATCH 03/52] drm: add managed resources tied to drm_device
@ 2020-02-20 14:58                 ` Laurent Pinchart
  0 siblings, 0 replies; 310+ messages in thread
From: Laurent Pinchart @ 2020-02-20 14:58 UTC (permalink / raw)
  To: Greg Kroah-Hartman
  Cc: Daniel Vetter, Intel Graphics Development, Rafael J. Wysocki,
	DRI Development, Daniel Vetter

Hi Greg,

On Wed, Feb 19, 2020 at 07:19:32PM +0100, Greg Kroah-Hartman wrote:
> On Wed, Feb 19, 2020 at 07:36:52PM +0200, Laurent Pinchart wrote:
> > On Wed, Feb 19, 2020 at 06:00:46PM +0100, Greg Kroah-Hartman wrote:
> >> On Wed, Feb 19, 2020 at 03:22:49PM +0100, Daniel Vetter wrote:
> >>> On Wed, Feb 19, 2020 at 2:33 PM Greg Kroah-Hartman wrote:
> >>>> On Wed, Feb 19, 2020 at 03:28:47PM +0200, Laurent Pinchart wrote:
> >>>>> On Wed, Feb 19, 2020 at 11:20:33AM +0100, Daniel Vetter wrote:
> >>>>>> 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.
> >>>>>
> >>>>> This is all a very good idea ! Many subsystems are plagged by drivers
> >>>>> using devm_k*alloc to allocate data accessible by userspace. Since the
> >>>>> introduction of devm_*, we've likely reduced the number of memory leaks,
> >>>>> but I'm pretty sure we've increased the risk of crashes as I've seen
> >>>>> some drivers that used .release() callbacks correctly being naively
> >>>>> converted to incorrect devm_* usage :-(
> >>>>>
> >>>>> This leads me to a question: if other subsystems have the same problem,
> >>>>> could we turn this implementation into something more generic ? It
> >>>>> doesn't have to be done right away and shouldn't block merging this
> >>>>> series, but I think it would be very useful.
> >>>>
> >>>> It shouldn't be that hard to tie this into a drv_m() type of a thing
> >>>> (driver_memory?)
> >>>>
> >>>> And yes, I think it's much better than devm_* for the obvious reasons of
> >>>> this being needed here.
> >>> 
> >>> There's two reasons I went with copypasta instead of trying to share code:
> >>> - Type checking, I definitely don't want people to mix up devm_ with
> >>> drmm_. But even if we do a drv_m that subsystems could embed we do
> >>> have quite a few different types of component drivers (and with
> >>> drm_panel and drm_bridge even standardized), and I don't want people
> >>> to be able to pass the wrong kind of struct to e.g. a managed
> >>> drmm_connector_init - it really needs to be the drm_device, not a
> >>> panel or bridge or something else.
> >> 
> >> Fair enough, that makes sense.
> >> 
> >>> - We could still share the code as a kind of implementation/backend
> >>> library. But it's not much, and with embedding I could use the drm
> >>> device logging stuff which is kinda nice. But if there's more demand
> >>> for this I can definitely see the point in sharing this, as Laurent
> >>> pointed out with the tiny optimization with not allocating a NULL void
> >>> * that I've done (and screwed up) it's not entirely trivial code.
> >> 
> >> I think moving over time to having this be a backend library is good.
> >> But no rush/issues here with this going in now, it solves a real need
> >> and we can refactor it later on to try to make it more "bus/class"
> >> generic as needed.
> > 
> > >From a type checking point of view, it would then be nice to have a
> > structure that models a device node, other than just struct device that
> > is shared by all types of devices. As someone who was involve in the
> > creation of the device model we have today, and thus know the history,
> > what's your opinion on that ?
> 
> My opinion is that 'struct device' was created just for that exact
> thing.  If "all you want" is a device node, it is trivial to use:
> 	device_create();
> or device_create_varargs() or device_create_with_groups()
> and then use device_destroy() when you are done with it.
> 
> yes, it can do much more complex things, as needed, but the basics are
> there, so use it in a simple way if you want to, no objection from me.
> 
> If there are things that are missing with it, please let me know.

I don't think it's really about anything missing, but about having two
different APIs for driver developers, to associate resources with either
physical devices that can disappear from the system, or with interfaces
exposed to userspace (or other parts of the kernel). The lifetime
constraints are very different, and if both cases are handled with the
devres API and a struct device, it's very easy for driver authors to
pass the wrong struct device to the API, tying the lifetime of a
userspace-facing resource with the physical device (this is what devres
is mostly used for today :-(). Having two different objects would make
it more apparent which API should be used, and would make it easier to
catch incorrect usage during review. I think this is Daniel's main
point, and the reason that prompted him to create a new API instead of
just reusing devres with the struct device that models the userspace
interface.

(On a side node, I wonder if devres shouldn't have been implemented at
the kref level.)

> But creating a new structure/way for this, no, we do not want to go back
> to the 2.4 and older kernel methods where it was all totally disjointed
> and messy.

-- 
Regards,

Laurent Pinchart
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH 39/52] drm/stm: Drop explicit drm_mode_config_cleanup call
  2020-02-20 14:18     ` Philippe CORNU
  (?)
@ 2020-02-20 16:12       ` Daniel Vetter
  -1 siblings, 0 replies; 310+ messages in thread
From: Daniel Vetter @ 2020-02-20 16:12 UTC (permalink / raw)
  To: Philippe CORNU
  Cc: Maxime Coquelin, Intel Graphics Development, DRI Development,
	Yannick FERTRE, Benjamin Gaignard, Daniel Vetter, Vincent ABRIOU,
	linux-stm32, linux-arm-kernel, Alexandre TORGUE

On Thu, Feb 20, 2020 at 3:19 PM Philippe CORNU <philippe.cornu@st.com> wrote:
>
> Hi Daniel,
>
> On 2/19/20 11:21 AM, Daniel Vetter wrote:
> > It's right above the drm_dev_put().
> >
> > Aside: Another driver with a bit much devm_kzalloc, which should
> > probably use drmm_kzalloc instead ...
> >
> > 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..5b374531dd8c 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 = drm_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)
> >
>
> Thank you for your patch,
> For this stm part,
> Acked-by: Philippe Cornu <philippe.cornu@st.com>
>
> note: we will handle devm_kzalloc() asap, thanks.

Note that as-is you can't just blindly switch devm_kzalloc over to
drmm_kzalloc for the structures containing a drm_* object, or you'll
just replace one type of use-after free with another one (and probably
worse, since the new one will hit you on normal driver unload too).
There's a bit more work needed in this area, this here is just the
first steps and a heads up. And removing the devm_kzalloc would result
in lots of code added for a bunch of kfree() all over, not so great
option either.

I'd say wait for the next round :-)
-Daniel
-- 
Daniel Vetter
Software Engineer, Intel Corporation
+41 (0) 79 365 57 48 - http://blog.ffwll.ch

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [PATCH 39/52] drm/stm: Drop explicit drm_mode_config_cleanup call
@ 2020-02-20 16:12       ` Daniel Vetter
  0 siblings, 0 replies; 310+ messages in thread
From: Daniel Vetter @ 2020-02-20 16:12 UTC (permalink / raw)
  To: Philippe CORNU
  Cc: Maxime Coquelin, Intel Graphics Development, DRI Development,
	Yannick FERTRE, Daniel Vetter, Vincent ABRIOU, linux-stm32,
	linux-arm-kernel, Alexandre TORGUE

On Thu, Feb 20, 2020 at 3:19 PM Philippe CORNU <philippe.cornu@st.com> wrote:
>
> Hi Daniel,
>
> On 2/19/20 11:21 AM, Daniel Vetter wrote:
> > It's right above the drm_dev_put().
> >
> > Aside: Another driver with a bit much devm_kzalloc, which should
> > probably use drmm_kzalloc instead ...
> >
> > 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..5b374531dd8c 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 = drm_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)
> >
>
> Thank you for your patch,
> For this stm part,
> Acked-by: Philippe Cornu <philippe.cornu@st.com>
>
> note: we will handle devm_kzalloc() asap, thanks.

Note that as-is you can't just blindly switch devm_kzalloc over to
drmm_kzalloc for the structures containing a drm_* object, or you'll
just replace one type of use-after free with another one (and probably
worse, since the new one will hit you on normal driver unload too).
There's a bit more work needed in this area, this here is just the
first steps and a heads up. And removing the devm_kzalloc would result
in lots of code added for a bunch of kfree() all over, not so great
option either.

I'd say wait for the next round :-)
-Daniel
-- 
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] 310+ messages in thread

* Re: [Intel-gfx] [PATCH 39/52] drm/stm: Drop explicit drm_mode_config_cleanup call
@ 2020-02-20 16:12       ` Daniel Vetter
  0 siblings, 0 replies; 310+ messages in thread
From: Daniel Vetter @ 2020-02-20 16:12 UTC (permalink / raw)
  To: Philippe CORNU
  Cc: Maxime Coquelin, Intel Graphics Development, DRI Development,
	Yannick FERTRE, Benjamin Gaignard, Daniel Vetter, Vincent ABRIOU,
	linux-stm32, linux-arm-kernel, Alexandre TORGUE

On Thu, Feb 20, 2020 at 3:19 PM Philippe CORNU <philippe.cornu@st.com> wrote:
>
> Hi Daniel,
>
> On 2/19/20 11:21 AM, Daniel Vetter wrote:
> > It's right above the drm_dev_put().
> >
> > Aside: Another driver with a bit much devm_kzalloc, which should
> > probably use drmm_kzalloc instead ...
> >
> > 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..5b374531dd8c 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 = drm_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)
> >
>
> Thank you for your patch,
> For this stm part,
> Acked-by: Philippe Cornu <philippe.cornu@st.com>
>
> note: we will handle devm_kzalloc() asap, thanks.

Note that as-is you can't just blindly switch devm_kzalloc over to
drmm_kzalloc for the structures containing a drm_* object, or you'll
just replace one type of use-after free with another one (and probably
worse, since the new one will hit you on normal driver unload too).
There's a bit more work needed in this area, this here is just the
first steps and a heads up. And removing the devm_kzalloc would result
in lots of code added for a bunch of kfree() all over, not so great
option either.

I'd say wait for the next round :-)
-Daniel
-- 
Daniel Vetter
Software Engineer, Intel Corporation
+41 (0) 79 365 57 48 - http://blog.ffwll.ch
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH 05/52] drm/mipi_dbi: Use drmm_add_final_kfree in all drivers
  2020-02-19 10:20   ` [Intel-gfx] " Daniel Vetter
@ 2020-02-20 16:18     ` Noralf Trønnes
  -1 siblings, 0 replies; 310+ messages in thread
From: Noralf Trønnes @ 2020-02-20 16:18 UTC (permalink / raw)
  To: Daniel Vetter, DRI Development
  Cc: Thomas Zimmermann, David Airlie, Intel Graphics Development,
	Daniel Vetter, Kamlesh Gurudasani, Sam Ravnborg, David Lechner



Den 19.02.2020 11.20, skrev Daniel Vetter:
> 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).
> 
> 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>
> ---

I really would have preferred having devm_drm_dev_alloc() in this
series, drmm_add_final_kfree() is rather odd.

But I can wait:
Reviewed-by: Noralf Trønnes <noralf@tronnes.org>

I have tested the whole series on tiny/mi0283qt:
Tested-by: Noralf Trønnes <noralf@tronnes.org>
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

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

* Re: [Intel-gfx] [PATCH 05/52] drm/mipi_dbi: Use drmm_add_final_kfree in all drivers
@ 2020-02-20 16:18     ` Noralf Trønnes
  0 siblings, 0 replies; 310+ messages in thread
From: Noralf Trønnes @ 2020-02-20 16:18 UTC (permalink / raw)
  To: Daniel Vetter, DRI Development
  Cc: Thomas Zimmermann, David Airlie, Intel Graphics Development,
	Maxime Ripard, Eric Anholt, Daniel Vetter, Kamlesh Gurudasani,
	Sam Ravnborg, David Lechner



Den 19.02.2020 11.20, skrev Daniel Vetter:
> 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).
> 
> 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>
> ---

I really would have preferred having devm_drm_dev_alloc() in this
series, drmm_add_final_kfree() is rather odd.

But I can wait:
Reviewed-by: Noralf Trønnes <noralf@tronnes.org>

I have tested the whole series on tiny/mi0283qt:
Tested-by: Noralf Trønnes <noralf@tronnes.org>
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH 16/52] drm/repaper: Use drmm_add_final_kfree
  2020-02-19 10:20   ` [Intel-gfx] " Daniel Vetter
@ 2020-02-20 16:18     ` Noralf Trønnes
  -1 siblings, 0 replies; 310+ messages in thread
From: Noralf Trønnes @ 2020-02-20 16:18 UTC (permalink / raw)
  To: Daniel Vetter, DRI Development; +Cc: Daniel Vetter, Intel Graphics Development



Den 19.02.2020 11.20, skrev Daniel Vetter:
> With this we can drop the final kfree from the release function.
> 
> Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
> Cc: "Noralf Trønnes" <noralf@tronnes.org>
> ---

Reviewed-by: Noralf Trønnes <noralf@tronnes.org>
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

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

* Re: [Intel-gfx] [PATCH 16/52] drm/repaper: Use drmm_add_final_kfree
@ 2020-02-20 16:18     ` Noralf Trønnes
  0 siblings, 0 replies; 310+ messages in thread
From: Noralf Trønnes @ 2020-02-20 16:18 UTC (permalink / raw)
  To: Daniel Vetter, DRI Development; +Cc: Daniel Vetter, Intel Graphics Development



Den 19.02.2020 11.20, skrev Daniel Vetter:
> With this we can drop the final kfree from the release function.
> 
> Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
> Cc: "Noralf Trønnes" <noralf@tronnes.org>
> ---

Reviewed-by: Noralf Trønnes <noralf@tronnes.org>
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH 47/52] drm/repaper: Drop explicit drm_mode_config_cleanup call
  2020-02-19 10:21   ` [Intel-gfx] " Daniel Vetter
@ 2020-02-20 16:21     ` Noralf Trønnes
  -1 siblings, 0 replies; 310+ messages in thread
From: Noralf Trønnes @ 2020-02-20 16:21 UTC (permalink / raw)
  To: Daniel Vetter, DRI Development; +Cc: Daniel Vetter, Intel Graphics Development



Den 19.02.2020 11.21, skrev Daniel Vetter:
> Allows us to drop the drm_driver.release callback.
> 
> Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
> Cc: "Noralf Trønnes" <noralf@tronnes.org>
> ---

Reviewed-by: Noralf Trønnes <noralf@tronnes.org>
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

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

* Re: [Intel-gfx] [PATCH 47/52] drm/repaper: Drop explicit drm_mode_config_cleanup call
@ 2020-02-20 16:21     ` Noralf Trønnes
  0 siblings, 0 replies; 310+ messages in thread
From: Noralf Trønnes @ 2020-02-20 16:21 UTC (permalink / raw)
  To: Daniel Vetter, DRI Development; +Cc: Daniel Vetter, Intel Graphics Development



Den 19.02.2020 11.21, skrev Daniel Vetter:
> Allows us to drop the drm_driver.release callback.
> 
> Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
> Cc: "Noralf Trønnes" <noralf@tronnes.org>
> ---

Reviewed-by: Noralf Trønnes <noralf@tronnes.org>
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH 48/52] drm/mipi-dbi: Move drm_mode_config_init into mipi library
  2020-02-19 10:21   ` [Intel-gfx] " Daniel Vetter
@ 2020-02-20 16:22     ` Noralf Trønnes
  -1 siblings, 0 replies; 310+ messages in thread
From: Noralf Trønnes @ 2020-02-20 16:22 UTC (permalink / raw)
  To: Daniel Vetter, DRI Development; +Cc: Daniel Vetter, Intel Graphics Development


Den 19.02.2020 11.21, skrev Daniel Vetter:
> 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.
> 
> Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
> ---

Reviewed-by: Noralf Trønnes <noralf@tronnes.org>
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

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

* Re: [Intel-gfx] [PATCH 48/52] drm/mipi-dbi: Move drm_mode_config_init into mipi library
@ 2020-02-20 16:22     ` Noralf Trønnes
  0 siblings, 0 replies; 310+ messages in thread
From: Noralf Trønnes @ 2020-02-20 16:22 UTC (permalink / raw)
  To: Daniel Vetter, DRI Development; +Cc: Daniel Vetter, Intel Graphics Development


Den 19.02.2020 11.21, skrev Daniel Vetter:
> 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.
> 
> Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
> ---

Reviewed-by: Noralf Trønnes <noralf@tronnes.org>
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH 49/52] drm/mipi-dbi: Drop explicit drm_mode_config_cleanup call
  2020-02-19 10:21   ` [Intel-gfx] " Daniel Vetter
@ 2020-02-20 16:22     ` Noralf Trønnes
  -1 siblings, 0 replies; 310+ messages in thread
From: Noralf Trønnes @ 2020-02-20 16:22 UTC (permalink / raw)
  To: Daniel Vetter, DRI Development
  Cc: David Airlie, Intel Graphics Development, Thomas Zimmermann,
	Daniel Vetter, Kamlesh Gurudasani, Sam Ravnborg, David Lechner


Den 19.02.2020 11.21, skrev Daniel Vetter:
> Allows us to drop the drm_driver.release callback from all
> drivers, and remove the mipi_dbi_release() function.
> 
> 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>
> ---

Reviewed-by: Noralf Trønnes <noralf@tronnes.org>
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

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

* Re: [Intel-gfx] [PATCH 49/52] drm/mipi-dbi: Drop explicit drm_mode_config_cleanup call
@ 2020-02-20 16:22     ` Noralf Trønnes
  0 siblings, 0 replies; 310+ messages in thread
From: Noralf Trønnes @ 2020-02-20 16:22 UTC (permalink / raw)
  To: Daniel Vetter, DRI Development
  Cc: David Airlie, Intel Graphics Development, Maxime Ripard,
	Eric Anholt, Thomas Zimmermann, Daniel Vetter,
	Kamlesh Gurudasani, Sam Ravnborg, David Lechner


Den 19.02.2020 11.21, skrev Daniel Vetter:
> Allows us to drop the drm_driver.release callback from all
> drivers, and remove the mipi_dbi_release() function.
> 
> 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>
> ---

Reviewed-by: Noralf Trønnes <noralf@tronnes.org>
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* [Intel-gfx] ✗ Fi.CI.IGT: failure for drm_device managed resources
  2020-02-19 10:20 ` [Intel-gfx] " Daniel Vetter
                   ` (55 preceding siblings ...)
  (?)
@ 2020-02-21  1:37 ` Patchwork
  -1 siblings, 0 replies; 310+ messages in thread
From: Patchwork @ 2020-02-21  1:37 UTC (permalink / raw)
  To: Daniel Vetter; +Cc: intel-gfx

== Series Details ==

Series: drm_device managed resources
URL   : https://patchwork.freedesktop.org/series/73633/
State : failure

== Summary ==

CI Bug Log - changes from CI_DRM_7963_full -> Patchwork_16618_full
====================================================

Summary
-------

  **FAILURE**

  Serious unknown changes coming with Patchwork_16618_full absolutely need to be
  verified manually.
  
  If you think the reported changes have nothing to do with the changes
  introduced in Patchwork_16618_full, please notify your bug team to allow them
  to document this new failure mode, which will reduce false positives in CI.

  

Possible new issues
-------------------

  Here are the unknown changes that may have been introduced in Patchwork_16618_full:

### IGT changes ###

#### Possible regressions ####

  * igt@gem_ctx_param@basic-default:
    - shard-hsw:          [PASS][1] -> [FAIL][2] +1 similar issue
   [1]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7963/shard-hsw6/igt@gem_ctx_param@basic-default.html
   [2]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_16618/shard-hsw2/igt@gem_ctx_param@basic-default.html
    - shard-snb:          [PASS][3] -> [FAIL][4] +1 similar issue
   [3]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7963/shard-snb5/igt@gem_ctx_param@basic-default.html
   [4]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_16618/shard-snb1/igt@gem_ctx_param@basic-default.html
    - shard-tglb:         [PASS][5] -> [FAIL][6] +4 similar issues
   [5]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7963/shard-tglb6/igt@gem_ctx_param@basic-default.html
   [6]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_16618/shard-tglb5/igt@gem_ctx_param@basic-default.html

  * igt@gem_ctx_param@root-set-no-zeromap-enabled:
    - shard-glk:          [PASS][7] -> [FAIL][8] +2 similar issues
   [7]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7963/shard-glk7/igt@gem_ctx_param@root-set-no-zeromap-enabled.html
   [8]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_16618/shard-glk7/igt@gem_ctx_param@root-set-no-zeromap-enabled.html
    - shard-iclb:         [PASS][9] -> [FAIL][10] +3 similar issues
   [9]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7963/shard-iclb1/igt@gem_ctx_param@root-set-no-zeromap-enabled.html
   [10]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_16618/shard-iclb5/igt@gem_ctx_param@root-set-no-zeromap-enabled.html
    - shard-apl:          [PASS][11] -> [FAIL][12] +2 similar issues
   [11]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7963/shard-apl6/igt@gem_ctx_param@root-set-no-zeromap-enabled.html
   [12]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_16618/shard-apl7/igt@gem_ctx_param@root-set-no-zeromap-enabled.html

  * igt@gem_render_copy@yf-tiled-ccs-to-y-tiled:
    - shard-kbl:          [PASS][13] -> [FAIL][14] +3 similar issues
   [13]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7963/shard-kbl4/igt@gem_render_copy@yf-tiled-ccs-to-y-tiled.html
   [14]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_16618/shard-kbl2/igt@gem_render_copy@yf-tiled-ccs-to-y-tiled.html
    - shard-skl:          [PASS][15] -> [FAIL][16] +2 similar issues
   [15]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7963/shard-skl8/igt@gem_render_copy@yf-tiled-ccs-to-y-tiled.html
   [16]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_16618/shard-skl10/igt@gem_render_copy@yf-tiled-ccs-to-y-tiled.html

  * igt@i915_selftest@mock_timelines:
    - shard-iclb:         [PASS][17] -> [INCOMPLETE][18]
   [17]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7963/shard-iclb4/igt@i915_selftest@mock_timelines.html
   [18]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_16618/shard-iclb4/igt@i915_selftest@mock_timelines.html
    - shard-skl:          [PASS][19] -> [INCOMPLETE][20]
   [19]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7963/shard-skl7/igt@i915_selftest@mock_timelines.html
   [20]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_16618/shard-skl3/igt@i915_selftest@mock_timelines.html
    - shard-tglb:         [PASS][21] -> [INCOMPLETE][22]
   [21]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7963/shard-tglb8/igt@i915_selftest@mock_timelines.html
   [22]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_16618/shard-tglb2/igt@i915_selftest@mock_timelines.html

  * igt@kms_draw_crc@draw-method-xrgb2101010-render-ytiled:
    - shard-tglb:         [PASS][23] -> [SKIP][24] +16 similar issues
   [23]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7963/shard-tglb5/igt@kms_draw_crc@draw-method-xrgb2101010-render-ytiled.html
   [24]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_16618/shard-tglb2/igt@kms_draw_crc@draw-method-xrgb2101010-render-ytiled.html

  * igt@kms_plane_alpha_blend@pipe-b-alpha-transparant-fb:
    - shard-iclb:         [PASS][25] -> [SKIP][26] +17 similar issues
   [25]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7963/shard-iclb5/igt@kms_plane_alpha_blend@pipe-b-alpha-transparant-fb.html
   [26]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_16618/shard-iclb2/igt@kms_plane_alpha_blend@pipe-b-alpha-transparant-fb.html

  
#### Warnings ####

  * igt@gem_ctx_shared@exec-single-timeline-bsd:
    - shard-tglb:         [SKIP][27] ([fdo#110841]) -> [SKIP][28]
   [27]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7963/shard-tglb5/igt@gem_ctx_shared@exec-single-timeline-bsd.html
   [28]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_16618/shard-tglb2/igt@gem_ctx_shared@exec-single-timeline-bsd.html

  * igt@gem_render_copy@yf-tiled-ccs-to-y-tiled:
    - shard-hsw:          [SKIP][29] ([fdo#109271]) -> [FAIL][30] +1 similar issue
   [29]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7963/shard-hsw6/igt@gem_render_copy@yf-tiled-ccs-to-y-tiled.html
   [30]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_16618/shard-hsw2/igt@gem_render_copy@yf-tiled-ccs-to-y-tiled.html

  * igt@gem_render_copy@yf-tiled-to-vebox-y-tiled:
    - shard-snb:          [SKIP][31] ([fdo#109271]) -> [FAIL][32] +1 similar issue
   [31]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7963/shard-snb1/igt@gem_render_copy@yf-tiled-to-vebox-y-tiled.html
   [32]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_16618/shard-snb1/igt@gem_render_copy@yf-tiled-to-vebox-y-tiled.html
    - shard-kbl:          [SKIP][33] ([fdo#109271]) -> [FAIL][34]
   [33]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7963/shard-kbl3/igt@gem_render_copy@yf-tiled-to-vebox-y-tiled.html
   [34]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_16618/shard-kbl7/igt@gem_render_copy@yf-tiled-to-vebox-y-tiled.html
    - shard-skl:          [SKIP][35] ([fdo#109271]) -> [FAIL][36]
   [35]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7963/shard-skl9/igt@gem_render_copy@yf-tiled-to-vebox-y-tiled.html
   [36]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_16618/shard-skl7/igt@gem_render_copy@yf-tiled-to-vebox-y-tiled.html
    - shard-glk:          [SKIP][37] ([fdo#109271]) -> [FAIL][38]
   [37]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7963/shard-glk8/igt@gem_render_copy@yf-tiled-to-vebox-y-tiled.html
   [38]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_16618/shard-glk9/igt@gem_render_copy@yf-tiled-to-vebox-y-tiled.html
    - shard-apl:          [SKIP][39] ([fdo#109271]) -> [FAIL][40]
   [39]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7963/shard-apl4/igt@gem_render_copy@yf-tiled-to-vebox-y-tiled.html
   [40]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_16618/shard-apl1/igt@gem_render_copy@yf-tiled-to-vebox-y-tiled.html
    - shard-iclb:         [SKIP][41] ([i915#768]) -> [FAIL][42]
   [41]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7963/shard-iclb6/igt@gem_render_copy@yf-tiled-to-vebox-y-tiled.html
   [42]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_16618/shard-iclb2/igt@gem_render_copy@yf-tiled-to-vebox-y-tiled.html

  * igt@kms_atomic_transition@5x-modeset-transitions-nonblocking-fencing:
    - shard-tglb:         [SKIP][43] ([fdo#112025]) -> [SKIP][44]
   [43]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7963/shard-tglb5/igt@kms_atomic_transition@5x-modeset-transitions-nonblocking-fencing.html
   [44]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_16618/shard-tglb2/igt@kms_atomic_transition@5x-modeset-transitions-nonblocking-fencing.html
    - shard-iclb:         [SKIP][45] ([fdo#109278]) -> [SKIP][46]
   [45]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7963/shard-iclb5/igt@kms_atomic_transition@5x-modeset-transitions-nonblocking-fencing.html
   [46]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_16618/shard-iclb2/igt@kms_atomic_transition@5x-modeset-transitions-nonblocking-fencing.html

  * igt@kms_big_fb@yf-tiled-8bpp-rotate-270:
    - shard-iclb:         [SKIP][47] ([fdo#110723]) -> [SKIP][48]
   [47]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7963/shard-iclb5/igt@kms_big_fb@yf-tiled-8bpp-rotate-270.html
   [48]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_16618/shard-iclb2/igt@kms_big_fb@yf-tiled-8bpp-rotate-270.html
    - shard-tglb:         [SKIP][49] ([fdo#111615]) -> [SKIP][50]
   [49]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7963/shard-tglb5/igt@kms_big_fb@yf-tiled-8bpp-rotate-270.html
   [50]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_16618/shard-tglb2/igt@kms_big_fb@yf-tiled-8bpp-rotate-270.html

  * igt@kms_cursor_crc@pipe-c-cursor-512x170-sliding:
    - shard-iclb:         [SKIP][51] ([fdo#109279]) -> [SKIP][52] +1 similar issue
   [51]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7963/shard-iclb5/igt@kms_cursor_crc@pipe-c-cursor-512x170-sliding.html
   [52]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_16618/shard-iclb2/igt@kms_cursor_crc@pipe-c-cursor-512x170-sliding.html
    - shard-tglb:         [SKIP][53] ([fdo#109279]) -> [SKIP][54] +1 similar issue
   [53]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7963/shard-tglb5/igt@kms_cursor_crc@pipe-c-cursor-512x170-sliding.html
   [54]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_16618/shard-tglb2/igt@kms_cursor_crc@pipe-c-cursor-512x170-sliding.html

  * igt@kms_cursor_legacy@cursorb-vs-flipb-atomic:
    - shard-tglb:         [SKIP][55] ([fdo#111825]) -> [SKIP][56] +1 similar issue
   [55]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7963/shard-tglb5/igt@kms_cursor_legacy@cursorb-vs-flipb-atomic.html
   [56]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_16618/shard-tglb2/igt@kms_cursor_legacy@cursorb-vs-flipb-atomic.html
    - shard-iclb:         [SKIP][57] ([fdo#109274]) -> [SKIP][58]
   [57]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7963/shard-iclb5/igt@kms_cursor_legacy@cursorb-vs-flipb-atomic.html
   [58]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_16618/shard-iclb2/igt@kms_cursor_legacy@cursorb-vs-flipb-atomic.html

  * igt@kms_frontbuffer_tracking@fbc-2p-primscrn-pri-shrfb-draw-mmap-wc:
    - shard-iclb:         [SKIP][59] ([fdo#109280]) -> [SKIP][60]
   [59]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7963/shard-iclb5/igt@kms_frontbuffer_tracking@fbc-2p-primscrn-pri-shrfb-draw-mmap-wc.html
   [60]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_16618/shard-iclb2/igt@kms_frontbuffer_tracking@fbc-2p-primscrn-pri-shrfb-draw-mmap-wc.html

  * igt@kms_frontbuffer_tracking@psr-1p-rte:
    - shard-tglb:         [SKIP][61] ([i915#668]) -> [SKIP][62]
   [61]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7963/shard-tglb5/igt@kms_frontbuffer_tracking@psr-1p-rte.html
   [62]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_16618/shard-tglb2/igt@kms_frontbuffer_tracking@psr-1p-rte.html

  * igt@kms_vrr@flip-dpms:
    - shard-iclb:         [SKIP][63] ([fdo#109502]) -> [SKIP][64]
   [63]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7963/shard-iclb5/igt@kms_vrr@flip-dpms.html
   [64]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_16618/shard-iclb2/igt@kms_vrr@flip-dpms.html
    - shard-tglb:         [SKIP][65] ([fdo#109502]) -> [SKIP][66]
   [65]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7963/shard-tglb5/igt@kms_vrr@flip-dpms.html
   [66]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_16618/shard-tglb2/igt@kms_vrr@flip-dpms.html

  * igt@perf_pmu@render-node-busy-idle-vcs1:
    - shard-apl:          [SKIP][67] ([fdo#109271] / [fdo#112080]) -> [FAIL][68]
   [67]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7963/shard-apl6/igt@perf_pmu@render-node-busy-idle-vcs1.html
   [68]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_16618/shard-apl7/igt@perf_pmu@render-node-busy-idle-vcs1.html
    - shard-snb:          [SKIP][69] ([fdo#109271] / [fdo#112080]) -> [FAIL][70]
   [69]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7963/shard-snb5/igt@perf_pmu@render-node-busy-idle-vcs1.html
   [70]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_16618/shard-snb1/igt@perf_pmu@render-node-busy-idle-vcs1.html
    - shard-skl:          [SKIP][71] ([fdo#109271] / [fdo#112080]) -> [FAIL][72]
   [71]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7963/shard-skl8/igt@perf_pmu@render-node-busy-idle-vcs1.html
   [72]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_16618/shard-skl10/igt@perf_pmu@render-node-busy-idle-vcs1.html
    - shard-hsw:          [SKIP][73] ([fdo#109271] / [fdo#112080]) -> [FAIL][74]
   [73]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7963/shard-hsw6/igt@perf_pmu@render-node-busy-idle-vcs1.html
   [74]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_16618/shard-hsw2/igt@perf_pmu@render-node-busy-idle-vcs1.html
    - shard-glk:          [SKIP][75] ([fdo#109271] / [fdo#112080]) -> [FAIL][76]
   [75]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7963/shard-glk7/igt@perf_pmu@render-node-busy-idle-vcs1.html
   [76]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_16618/shard-glk7/igt@perf_pmu@render-node-busy-idle-vcs1.html

  
#### Suppressed ####

  The following results come from untrusted machines, tests, or statuses.
  They do not affect the overall result.

  * {igt@kms_color_chamelium@pipe-a-ctm-0-5}:
    - shard-iclb:         [SKIP][77] ([fdo#109284] / [fdo#111827]) -> [SKIP][78]
   [77]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7963/shard-iclb5/igt@kms_color_chamelium@pipe-a-ctm-0-5.html
   [78]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_16618/shard-iclb2/igt@kms_color_chamelium@pipe-a-ctm-0-5.html
    - shard-tglb:         [SKIP][79] ([fdo#111827]) -> [SKIP][80]
   [79]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7963/shard-tglb5/igt@kms_color_chamelium@pipe-a-ctm-0-5.html
   [80]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_16618/shard-tglb2/igt@kms_color_chamelium@pipe-a-ctm-0-5.html

  
Known issues
------------

  Here are the changes found in Patchwork_16618_full that come from known issues:

### IGT changes ###

#### Issues hit ####

  * igt@gem_busy@busy-vcs1:
    - shard-iclb:         [PASS][81] -> [SKIP][82] ([fdo#112080]) +8 similar issues
   [81]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7963/shard-iclb1/igt@gem_busy@busy-vcs1.html
   [82]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_16618/shard-iclb6/igt@gem_busy@busy-vcs1.html

  * igt@gem_exec_schedule@pi-common-bsd:
    - shard-iclb:         [PASS][83] -> [SKIP][84] ([i915#677]) +1 similar issue
   [83]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7963/shard-iclb7/igt@gem_exec_schedule@pi-common-bsd.html
   [84]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_16618/shard-iclb2/igt@gem_exec_schedule@pi-common-bsd.html

  * igt@gem_exec_schedule@preempt-other-chain-bsd:
    - shard-iclb:         [PASS][85] -> [SKIP][86] ([fdo#112146]) +6 similar issues
   [85]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7963/shard-iclb5/igt@gem_exec_schedule@preempt-other-chain-bsd.html
   [86]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_16618/shard-iclb2/igt@gem_exec_schedule@preempt-other-chain-bsd.html

  * igt@gem_exec_schedule@preempt-queue-bsd1:
    - shard-iclb:         [PASS][87] -> [SKIP][88] ([fdo#109276]) +25 similar issues
   [87]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7963/shard-iclb1/igt@gem_exec_schedule@preempt-queue-bsd1.html
   [88]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_16618/shard-iclb6/igt@gem_exec_schedule@preempt-queue-bsd1.html

  * igt@gem_partial_pwrite_pread@reads:
    - shard-hsw:          [PASS][89] -> [FAIL][90] ([i915#694]) +1 similar issue
   [89]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7963/shard-hsw2/igt@gem_partial_pwrite_pread@reads.html
   [90]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_16618/shard-hsw2/igt@gem_partial_pwrite_pread@reads.html

  * igt@gem_ppgtt@flink-and-close-vma-leak:
    - shard-skl:          [PASS][91] -> [FAIL][92] ([i915#644])
   [91]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7963/shard-skl7/igt@gem_ppgtt@flink-and-close-vma-leak.html
   [92]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_16618/shard-skl2/igt@gem_ppgtt@flink-and-close-vma-leak.html

  * igt@gem_tiled_partial_pwrite_pread@writes:
    - shard-hsw:          [PASS][93] -> [FAIL][94] ([i915#817])
   [93]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7963/shard-hsw1/igt@gem_tiled_partial_pwrite_pread@writes.html
   [94]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_16618/shard-hsw5/igt@gem_tiled_partial_pwrite_pread@writes.html

  * igt@gem_workarounds@suspend-resume-context:
    - shard-apl:          [PASS][95] -> [SKIP][96] ([fdo#109271]) +15 similar issues
   [95]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7963/shard-apl2/igt@gem_workarounds@suspend-resume-context.html
   [96]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_16618/shard-apl3/igt@gem_workarounds@suspend-resume-context.html

  * igt@i915_selftest@mock_timelines:
    - shard-glk:          [PASS][97] -> [INCOMPLETE][98] ([i915#58] / [k.org#198133])
   [97]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7963/shard-glk3/igt@i915_selftest@mock_timelines.html
   [98]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_16618/shard-glk4/igt@i915_selftest@mock_timelines.html
    - shard-hsw:          [PASS][99] -> [INCOMPLETE][100] ([i915#61])
   [99]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7963/shard-hsw5/igt@i915_selftest@mock_timelines.html
   [100]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_16618/shard-hsw6/igt@i915_selftest@mock_timelines.html
    - shard-kbl:          [PASS][101] -> [INCOMPLETE][102] ([fdo#103665])
   [101]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7963/shard-kbl7/igt@i915_selftest@mock_timelines.html
   [102]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_16618/shard-kbl1/igt@i915_selftest@mock_timelines.html
    - shard-snb:          [PASS][103] -> [INCOMPLETE][104] ([i915#82])
   [103]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7963/shard-snb6/igt@i915_selftest@mock_timelines.html
   [104]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_16618/shard-snb5/igt@i915_selftest@mock_timelines.html
    - shard-apl:          [PASS][105] -> [INCOMPLETE][106] ([fdo#103927])
   [105]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7963/shard-apl8/igt@i915_selftest@mock_timelines.html
   [106]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_16618/shard-apl7/igt@i915_selftest@mock_timelines.html

  * igt@kms_ccs@pipe-b-bad-aux-stride:
    - shard-skl:          [PASS][107] -> [SKIP][108] ([fdo#109271]) +15 similar issues
   [107]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7963/shard-skl4/igt@kms_ccs@pipe-b-bad-aux-stride.html
   [108]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_16618/shard-skl1/igt@kms_ccs@pipe-b-bad-aux-stride.html

  * igt@kms_cursor_legacy@cursorb-vs-flipb-atomic:
    - shard-hsw:          [PASS][109] -> [SKIP][110] ([fdo#109271]) +9 similar issues
   [109]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7963/shard-hsw2/igt@kms_cursor_legacy@cursorb-vs-flipb-atomic.html
   [110]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_16618/shard-hsw8/igt@kms_cursor_legacy@cursorb-vs-flipb-atomic.html

  * igt@kms_cursor_legacy@long-nonblocking-modeset-vs-cursor-atomic:
    - shard-skl:          [PASS][111] -> [DMESG-WARN][112] ([i915#88])
   [111]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7963/shard-skl1/igt@kms_cursor_legacy@long-nonblocking-modeset-vs-cursor-atomic.html
   [112]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_16618/shard-skl9/igt@kms_cursor_legacy@long-nonblocking-modeset-vs-cursor-atomic.html

  * igt@kms_cursor_legacy@pipe-c-torture-move:
    - shard-glk:          [PASS][113] -> [DMESG-WARN][114] ([i915#128])
   [113]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7963/shard-glk3/igt@kms_cursor_legacy@pipe-c-torture-move.html
   [114]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_16618/shard-glk2/igt@kms_cursor_legacy@pipe-c-torture-move.html

  * igt@kms_draw_crc@draw-method-xrgb2101010-render-ytiled:
    - shard-kbl:          [PASS][115] -> [SKIP][116] ([fdo#109271]) +14 similar issues
   [115]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7963/shard-kbl2/igt@kms_draw_crc@draw-method-xrgb2101010-render-ytiled.html
   [116]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_16618/shard-kbl4/igt@kms_draw_crc@draw-method-xrgb2101010-render-ytiled.html

  * igt@kms_flip@2x-flip-vs-absolute-wf_vblank-interruptible:
    - shard-glk:          [PASS][117] -> [FAIL][118] ([i915#34])
   [117]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7963/shard-glk6/igt@kms_flip@2x-flip-vs-absolute-wf_vblank-interruptible.html
   [118]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_16618/shard-glk1/igt@kms_flip@2x-flip-vs-absolute-wf_vblank-interruptible.html

  * igt@kms_flip@dpms-vs-vblank-race-interruptible:
    - shard-glk:          [PASS][119] -> [FAIL][120] ([i915#407])
   [119]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7963/shard-glk3/igt@kms_flip@dpms-vs-vblank-race-interruptible.html
   [120]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_16618/shard-glk9/igt@kms_flip@dpms-vs-vblank-race-interruptible.html

  * igt@kms_frontbuffer_tracking@psr-1p-primscrn-spr-indfb-draw-mmap-cpu:
    - shard-skl:          [PASS][121] -> [FAIL][122] ([i915#49])
   [121]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7963/shard-skl1/igt@kms_frontbuffer_tracking@psr-1p-primscrn-spr-indfb-draw-mmap-cpu.html
   [122]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_16618/shard-skl3/igt@kms_frontbuffer_tracking@psr-1p-primscrn-spr-indfb-draw-mmap-cpu.html

  * igt@kms_plane@plane-panning-bottom-right-suspend-pipe-a-planes:
    - shard-apl:          [PASS][123] -> [DMESG-WARN][124] ([i915#180]) +3 similar issues
   [123]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7963/shard-apl6/igt@kms_plane@plane-panning-bottom-right-suspend-pipe-a-planes.html
   [124]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_16618/shard-apl4/igt@kms_plane@plane-panning-bottom-right-suspend-pipe-a-planes.html

  * igt@kms_plane@plane-panning-bottom-right-suspend-pipe-c-planes:
    - shard-kbl:          [PASS][125] -> [DMESG-WARN][126] ([i915#180]) +3 similar issues
   [125]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7963/shard-kbl7/igt@kms_plane@plane-panning-bottom-right-suspend-pipe-c-planes.html
   [126]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_16618/shard-kbl6/igt@kms_plane@plane-panning-bottom-right-suspend-pipe-c-planes.html

  * igt@kms_plane_alpha_blend@pipe-a-constant-alpha-min:
    - shard-skl:          [PASS][127] -> [FAIL][128] ([fdo#108145])
   [127]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7963/shard-skl1/igt@kms_plane_alpha_blend@pipe-a-constant-alpha-min.html
   [128]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_16618/shard-skl3/igt@kms_plane_alpha_blend@pipe-a-constant-alpha-min.html

  * igt@kms_plane_alpha_blend@pipe-b-coverage-7efc:
    - shard-skl:          [PASS][129] -> [FAIL][130] ([fdo#108145] / [i915#265])
   [129]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7963/shard-skl10/igt@kms_plane_alpha_blend@pipe-b-coverage-7efc.html
   [130]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_16618/shard-skl6/igt@kms_plane_alpha_blend@pipe-b-coverage-7efc.html

  * igt@kms_psr@psr2_cursor_mmap_cpu:
    - shard-iclb:         [PASS][131] -> [SKIP][132] ([fdo#109441]) +2 similar issues
   [131]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7963/shard-iclb2/igt@kms_psr@psr2_cursor_mmap_cpu.html
   [132]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_16618/shard-iclb1/igt@kms_psr@psr2_cursor_mmap_cpu.html

  * igt@kms_psr@psr2_sprite_render:
    - shard-tglb:         [PASS][133] -> [SKIP][134] ([i915#668]) +1 similar issue
   [133]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7963/shard-tglb1/igt@kms_psr@psr2_sprite_render.html
   [134]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_16618/shard-tglb2/igt@kms_psr@psr2_sprite_render.html

  * igt@perf@oa-exponents:
    - shard-glk:          [PASS][135] -> [FAIL][136] ([i915#84])
   [135]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7963/shard-glk6/igt@perf@oa-exponents.html
   [136]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_16618/shard-glk8/igt@perf@oa-exponents.html

  
#### Possible fixes ####

  * {igt@gem_ctx_persistence@close-replace-race}:
    - shard-iclb:         [FAIL][137] ([i915#1241]) -> [PASS][138]
   [137]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7963/shard-iclb1/igt@gem_ctx_persistence@close-replace-race.html
   [138]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_16618/shard-iclb5/igt@gem_ctx_persistence@close-replace-race.html
    - shard-apl:          [FAIL][139] ([i915#1241]) -> [PASS][140]
   [139]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7963/shard-apl4/igt@gem_ctx_persistence@close-replace-race.html
   [140]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_16618/shard-apl6/igt@gem_ctx_persistence@close-replace-race.html

  * {igt@gem_ctx_persistence@legacy-engines-mixed-process@vebox}:
    - shard-skl:          [FAIL][141] ([i915#679]) -> [PASS][142]
   [141]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7963/shard-skl8/igt@gem_ctx_persistence@legacy-engines-mixed-process@vebox.html
   [142]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_16618/shard-skl10/igt@gem_ctx_persistence@legacy-engines-mixed-process@vebox.html

  * igt@gem_eio@in-flight-suspend:
    - shard-kbl:          [INCOMPLETE][143] ([fdo#103665]) -> [PASS][144]
   [143]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7963/shard-kbl6/igt@gem_eio@in-flight-suspend.html
   [144]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_16618/shard-kbl7/igt@gem_eio@in-flight-suspend.html

  * {igt@gem_exec_schedule@implicit-both-bsd1}:
    - shard-iclb:         [SKIP][145] ([fdo#109276] / [i915#677]) -> [PASS][146]
   [145]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7963/shard-iclb7/igt@gem_exec_schedule@implicit-both-bsd1.html
   [146]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_16618/shard-iclb2/igt@gem_exec_schedule@implicit-both-bsd1.html

  * igt@gem_exec_schedule@pi-distinct-iova-bsd:
    - shard-iclb:         [SKIP][147] ([i915#677]) -> [PASS][148] +1 similar issue
   [147]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7963/shard-iclb1/igt@gem_exec_schedule@pi-distinct-iova-bsd.html
   [148]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_16618/shard-iclb5/igt@gem_exec_schedule@pi-distinct-iova-bsd.html

  * igt@gem_exec_schedule@preempt-contexts-bsd2:
    - shard-iclb:         [SKIP][149] ([fdo#109276]) -> [PASS][150] +12 similar issues
   [149]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7963/shard-iclb7/igt@gem_exec_schedule@preempt-contexts-bsd2.html
   [150]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_16618/shard-iclb4/igt@gem_exec_schedule@preempt-contexts-bsd2.html

  * igt@gem_exec_schedule@preemptive-hang-bsd:
    - shard-iclb:         [SKIP][151] ([fdo#112146]) -> [PASS][152] +6 similar issues
   [151]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7963/shard-iclb1/igt@gem_exec_schedule@preemptive-hang-bsd.html
   [152]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_16618/shard-iclb5/igt@gem_exec_schedule@preemptive-hang-bsd.html

  * igt@gem_ppgtt@flink-and-close-vma-leak:
    - shard-apl:          [FAIL][153] ([i915#644]) -> [PASS][154]
   [153]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7963/shard-apl1/igt@gem_ppgtt@flink-and-close-vma-leak.html
   [154]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_16618/shard-apl6/igt@gem_ppgtt@flink-and-close-vma-leak.html

  * igt@i915_pm_rps@waitboost:
    - shard-tglb:         [FAIL][155] ([i915#413]) -> [PASS][156]
   [155]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7963/shard-tglb5/igt@i915_pm_rps@waitboost.html
   [156]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_16618/shard-tglb8/igt@i915_pm_rps@waitboost.html

  * igt@kms_cursor_crc@pipe-a-cursor-size-change:
    - shard-snb:          [SKIP][157] ([fdo#109271]) -> [PASS][158] +1 similar issue
   [157]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7963/shard-snb4/igt@kms_cursor_crc@pipe-a-cursor-size-change.html
   [158]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_16618/shard-snb5/igt@kms_cursor_crc@pipe-a-cursor-size-change.html

  * igt@kms_cursor_legacy@2x-long-cursor-vs-flip-legacy:
    - shard-hsw:          [FAIL][159] ([i915#96]) -> [PASS][160]
   [159]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7963/shard-hsw8/igt@kms_cursor_legacy@2x-long-cursor-vs-flip-legacy.html
   [160]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_16618/shard-hsw1/igt@kms_cursor_legacy@2x-long-cursor-vs-flip-legacy.html

  * igt@kms_flip@flip-vs-expired-vblank-interruptible:
    - shard-skl:          [FAIL][161] ([i915#79]) -> [PASS][162]
   [161]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7963/shard-skl5/igt@kms_flip@flip-vs-expired-vblank-interruptible.html
   [162]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_16618/shard-skl8/igt@kms_flip@flip-vs-expired-vblank-interruptible.html

  * igt@kms_plane@plane-panning-bottom-right-suspend-pipe-b-planes:
    - shard-apl:          [DMESG-WARN][163] ([i915#180]) -> [PASS][164] +2 similar issues
   [163]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7963/shard-apl1/igt@kms_plane@plane-panning-bottom-right-su

== Logs ==

For more details see: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_16618/index.html
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH 04/52] drm: Set final_kfree in drm_dev_alloc
  2020-02-19 14:41       ` [Intel-gfx] " Daniel Vetter
  (?)
@ 2020-02-21 19:07         ` Daniel Vetter
  -1 siblings, 0 replies; 310+ messages in thread
From: Daniel Vetter @ 2020-02-21 19:07 UTC (permalink / raw)
  To: Laurent Pinchart
  Cc: Oleksandr Andrushchenko, David Airlie,
	Intel Graphics Development, DRI Development, Gerd Hoffmann,
	Thomas Zimmermann, Daniel Vetter, xen-devel

On Wed, Feb 19, 2020 at 03:41:07PM +0100, Daniel Vetter wrote:
> On Wed, Feb 19, 2020 at 2:39 PM Laurent Pinchart
> <laurent.pinchart@ideasonboard.com> wrote:
> >
> > Hi Daniel,
> >
> > Thank you for the patch.
> >
> > On Wed, Feb 19, 2020 at 11:20:34AM +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.
> >
> > I'd split this patch in two then, with the Xen first coming first, and
> > with an explanation in the commit message of the second patch about why
> > you call drmm_add_final_kfree() in drm_dev_alloc().

Forgot to reply to this I think.

Breaks biscting, so no can't split. It's just a leak, but this entire
series is full of these "would break bisecting because it would introduce
a subtle leak or use-after-free". Still isn't as simple as it looks
unfortunately :-/

> >
> > > 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
> > >
> > > 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 3e5627d6eba6..9e62e28bbc62 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);
> >
> > drmm_add_final_kfree() can only be called once. Does this mean that a
> > driver using drm_dev_alloc() isn't allowed to use drmm_add_final_kfree()
> > to tract its own private structure ?
> 
> There is only _one_ final kfree() for the structure containing
> drm_device. Anything else you can just allocate with drmm_kzalloc, and
> it will be cleaned up before. The chicken/egg doesn't just exist
> around init time with drm_device, but also at cleanup time - the list
> of cleanup actions is stored in drm_device, plus the logging macros
> also need a drm_device. Which means we really, really, really need to
> make sure that the drm_device is the very last thing that goes away.
> Hence this special case. I was semi-tempted to drill through the slab
> debug layer and add a check that the drm_device pointer in the
> final_kfree is actually within the slab allocation block. Just to make
> sure people use this correctly, and not just as a "hey here's a random
> kmalloc block I want you to release, thxokbye". Because doing that
> would cause a few use-after-free (or a leak).

I've added those checks now.
-Daniel


> -Daniel
> 
> >
> > > +
> > >       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;
> >
> > --
> > Regards,
> >
> > Laurent Pinchart
> 
> 
> 
> -- 
> Daniel Vetter
> Software Engineer, Intel Corporation
> +41 (0) 79 365 57 48 - http://blog.ffwll.ch

-- 
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] 310+ messages in thread

* Re: [Intel-gfx] [PATCH 04/52] drm: Set final_kfree in drm_dev_alloc
@ 2020-02-21 19:07         ` Daniel Vetter
  0 siblings, 0 replies; 310+ messages in thread
From: Daniel Vetter @ 2020-02-21 19:07 UTC (permalink / raw)
  To: Laurent Pinchart
  Cc: Oleksandr Andrushchenko, David Airlie,
	Intel Graphics Development, DRI Development, Gerd Hoffmann,
	Thomas Zimmermann, Daniel Vetter, xen-devel

On Wed, Feb 19, 2020 at 03:41:07PM +0100, Daniel Vetter wrote:
> On Wed, Feb 19, 2020 at 2:39 PM Laurent Pinchart
> <laurent.pinchart@ideasonboard.com> wrote:
> >
> > Hi Daniel,
> >
> > Thank you for the patch.
> >
> > On Wed, Feb 19, 2020 at 11:20:34AM +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.
> >
> > I'd split this patch in two then, with the Xen first coming first, and
> > with an explanation in the commit message of the second patch about why
> > you call drmm_add_final_kfree() in drm_dev_alloc().

Forgot to reply to this I think.

Breaks biscting, so no can't split. It's just a leak, but this entire
series is full of these "would break bisecting because it would introduce
a subtle leak or use-after-free". Still isn't as simple as it looks
unfortunately :-/

> >
> > > 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
> > >
> > > 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 3e5627d6eba6..9e62e28bbc62 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);
> >
> > drmm_add_final_kfree() can only be called once. Does this mean that a
> > driver using drm_dev_alloc() isn't allowed to use drmm_add_final_kfree()
> > to tract its own private structure ?
> 
> There is only _one_ final kfree() for the structure containing
> drm_device. Anything else you can just allocate with drmm_kzalloc, and
> it will be cleaned up before. The chicken/egg doesn't just exist
> around init time with drm_device, but also at cleanup time - the list
> of cleanup actions is stored in drm_device, plus the logging macros
> also need a drm_device. Which means we really, really, really need to
> make sure that the drm_device is the very last thing that goes away.
> Hence this special case. I was semi-tempted to drill through the slab
> debug layer and add a check that the drm_device pointer in the
> final_kfree is actually within the slab allocation block. Just to make
> sure people use this correctly, and not just as a "hey here's a random
> kmalloc block I want you to release, thxokbye". Because doing that
> would cause a few use-after-free (or a leak).

I've added those checks now.
-Daniel


> -Daniel
> 
> >
> > > +
> > >       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;
> >
> > --
> > Regards,
> >
> > Laurent Pinchart
> 
> 
> 
> -- 
> Daniel Vetter
> Software Engineer, Intel Corporation
> +41 (0) 79 365 57 48 - http://blog.ffwll.ch

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

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

* Re: [Xen-devel] [PATCH 04/52] drm: Set final_kfree in drm_dev_alloc
@ 2020-02-21 19:07         ` Daniel Vetter
  0 siblings, 0 replies; 310+ messages in thread
From: Daniel Vetter @ 2020-02-21 19:07 UTC (permalink / raw)
  To: Laurent Pinchart
  Cc: Oleksandr Andrushchenko, David Airlie,
	Intel Graphics Development, DRI Development, Gerd Hoffmann,
	Thomas Zimmermann, Daniel Vetter, xen-devel

On Wed, Feb 19, 2020 at 03:41:07PM +0100, Daniel Vetter wrote:
> On Wed, Feb 19, 2020 at 2:39 PM Laurent Pinchart
> <laurent.pinchart@ideasonboard.com> wrote:
> >
> > Hi Daniel,
> >
> > Thank you for the patch.
> >
> > On Wed, Feb 19, 2020 at 11:20:34AM +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.
> >
> > I'd split this patch in two then, with the Xen first coming first, and
> > with an explanation in the commit message of the second patch about why
> > you call drmm_add_final_kfree() in drm_dev_alloc().

Forgot to reply to this I think.

Breaks biscting, so no can't split. It's just a leak, but this entire
series is full of these "would break bisecting because it would introduce
a subtle leak or use-after-free". Still isn't as simple as it looks
unfortunately :-/

> >
> > > 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
> > >
> > > 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 3e5627d6eba6..9e62e28bbc62 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);
> >
> > drmm_add_final_kfree() can only be called once. Does this mean that a
> > driver using drm_dev_alloc() isn't allowed to use drmm_add_final_kfree()
> > to tract its own private structure ?
> 
> There is only _one_ final kfree() for the structure containing
> drm_device. Anything else you can just allocate with drmm_kzalloc, and
> it will be cleaned up before. The chicken/egg doesn't just exist
> around init time with drm_device, but also at cleanup time - the list
> of cleanup actions is stored in drm_device, plus the logging macros
> also need a drm_device. Which means we really, really, really need to
> make sure that the drm_device is the very last thing that goes away.
> Hence this special case. I was semi-tempted to drill through the slab
> debug layer and add a check that the drm_device pointer in the
> final_kfree is actually within the slab allocation block. Just to make
> sure people use this correctly, and not just as a "hey here's a random
> kmalloc block I want you to release, thxokbye". Because doing that
> would cause a few use-after-free (or a leak).

I've added those checks now.
-Daniel


> -Daniel
> 
> >
> > > +
> > >       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;
> >
> > --
> > Regards,
> >
> > Laurent Pinchart
> 
> 
> 
> -- 
> Daniel Vetter
> Software Engineer, Intel Corporation
> +41 (0) 79 365 57 48 - http://blog.ffwll.ch

-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

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

* Re: [PATCH 52/52] drm: Add docs for managed resources
  2020-02-19 10:21   ` [Intel-gfx] " Daniel Vetter
@ 2020-02-21 20:23     ` Sam Ravnborg
  -1 siblings, 0 replies; 310+ messages in thread
From: Sam Ravnborg @ 2020-02-21 20:23 UTC (permalink / raw)
  To: Daniel Vetter; +Cc: Daniel Vetter, Intel Graphics Development, DRI Development

Hi Daniel.

In general I think I could follow the documentation, this is good.
If the overall design is the best possible I cannot say,
but looks sane to me.

I like the drmm_ naming as a counterpart to devm_, each handling
resources with different lifetimes.

What I miss in all of this is how do other subsystems deal
with the different lifetime of their stuff?
Or maybe only drm really has this issue?
Anything we could learn from others?

Some more or less clueless comments in the following. Filter as usual.

And a bikeshedding detail.
"dev" is in my vocalubary a "struct device". So each time I see a "dev"
I think a struct device.
drm or ddev makes me think of struct drm_device - with the former being
my favorite.

	Sam

> + * 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.

Best to use => Maybe "It is recommended to use ..."

> + *
> + * 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().
Maybe this is obvious to others, but maybe add just a bit more about
what is required to be "fully protected". Or maybe this is already
documented somewhere else?
In drm_dev_enter() the term "critical section" is used.
I gues this is the section that is fully protected.

> diff --git a/drivers/gpu/drm/drm_managed.c b/drivers/gpu/drm/drm_managed.c
> index fb44fe65c2cd..7fcbe90d3f46 100644
> --- a/drivers/gpu/drm/drm_managed.c
> +++ b/drivers/gpu/drm/drm_managed.c
> @@ -17,10 +17,22 @@
>  /**
>   * DOC: managed resources
>   *
> - * Inspired by sturct &device managed resources, but tied to the lifetime of
> + * Inspired by struct &device managed resources, but tied to the lifetime of
Maybe fix this when the text is added.

> +/**
> + * drmm_add_final_kfree - add release action for the final kfree()
> + * @dev: DRM device
> + * @data: 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.

Or maybe

Use drmm_add_final_kfree() to record that the allocation must be
released as the last step when the final drm_dev_put() for @dev is
called.


> + */
>  void drmm_add_final_kfree(struct drm_device *dev, void *parent)
>  {
>  	WARN_ON(dev->managed.final_kfree);
> @@ -132,6 +156,14 @@ int __drmm_add_action(struct drm_device *dev,
>  }
>  EXPORT_SYMBOL(__drmm_add_action);
>  
> +/**
> + * drmm_add_action - remave a managed release action to a &drm_device
s/remave/remove/
"action to a &drm_device" => "action from a &drm_device"?

> @@ -160,6 +192,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().

RETURNS: ?

> + */
>  void *drmm_kmalloc(struct drm_device *dev, size_t size, gfp_t gfp)
>  {
>  	struct drmres *dr;
> @@ -175,6 +217,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
> + * @size: 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().

RETURNS: ?
> + */
>  char *drmm_kstrdup(struct drm_device *dev, const char *s, gfp_t gfp)
>  {
>  	size_t size;
> @@ -191,6 +243,15 @@ char *drmm_kstrdup(struct drm_device *dev, const char *s, gfp_t gfp)
>  }
>  EXPORT_SYMBOL_GPL(drmm_kstrdup);
>  


> diff --git a/include/drm/drm_managed.h b/include/drm/drm_managed.h
> index 573cadca4b3d..0e7616bd0858 100644
> --- a/include/drm/drm_managed.h
> +++ b/include/drm/drm_managed.h
> @@ -8,6 +8,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 wwith optional parameter @data to the
s/wwith/with/

> + * 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)
>  
> @@ -22,12 +35,45 @@ 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().

RETURNS: ?

> + */
>  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
> + * @size: 0 terminated string to be duplicated
> + * @gfp: 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().

RETURNS: ?

> + */
>  static inline void *drmm_kmalloc_array(struct drm_device *dev,
>  				       size_t n, size_t size, gfp_t flags)
> +
> +/**
> + * drmm_kcalloc - &drm_device managed kcalloc()
> + * @dev: DRM device
> + * @size: 0 terminated string to be duplicated
> + * @gfp: 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().

RETURNS: ?

> + */
>  {
>  	size_t bytes;
>  
> @@ -41,6 +87,7 @@ static inline void *drmm_kcalloc(struct drm_device *dev,
>  {
>  	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] 310+ messages in thread

* Re: [Intel-gfx] [PATCH 52/52] drm: Add docs for managed resources
@ 2020-02-21 20:23     ` Sam Ravnborg
  0 siblings, 0 replies; 310+ messages in thread
From: Sam Ravnborg @ 2020-02-21 20:23 UTC (permalink / raw)
  To: Daniel Vetter; +Cc: Daniel Vetter, Intel Graphics Development, DRI Development

Hi Daniel.

In general I think I could follow the documentation, this is good.
If the overall design is the best possible I cannot say,
but looks sane to me.

I like the drmm_ naming as a counterpart to devm_, each handling
resources with different lifetimes.

What I miss in all of this is how do other subsystems deal
with the different lifetime of their stuff?
Or maybe only drm really has this issue?
Anything we could learn from others?

Some more or less clueless comments in the following. Filter as usual.

And a bikeshedding detail.
"dev" is in my vocalubary a "struct device". So each time I see a "dev"
I think a struct device.
drm or ddev makes me think of struct drm_device - with the former being
my favorite.

	Sam

> + * 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.

Best to use => Maybe "It is recommended to use ..."

> + *
> + * 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().
Maybe this is obvious to others, but maybe add just a bit more about
what is required to be "fully protected". Or maybe this is already
documented somewhere else?
In drm_dev_enter() the term "critical section" is used.
I gues this is the section that is fully protected.

> diff --git a/drivers/gpu/drm/drm_managed.c b/drivers/gpu/drm/drm_managed.c
> index fb44fe65c2cd..7fcbe90d3f46 100644
> --- a/drivers/gpu/drm/drm_managed.c
> +++ b/drivers/gpu/drm/drm_managed.c
> @@ -17,10 +17,22 @@
>  /**
>   * DOC: managed resources
>   *
> - * Inspired by sturct &device managed resources, but tied to the lifetime of
> + * Inspired by struct &device managed resources, but tied to the lifetime of
Maybe fix this when the text is added.

> +/**
> + * drmm_add_final_kfree - add release action for the final kfree()
> + * @dev: DRM device
> + * @data: 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.

Or maybe

Use drmm_add_final_kfree() to record that the allocation must be
released as the last step when the final drm_dev_put() for @dev is
called.


> + */
>  void drmm_add_final_kfree(struct drm_device *dev, void *parent)
>  {
>  	WARN_ON(dev->managed.final_kfree);
> @@ -132,6 +156,14 @@ int __drmm_add_action(struct drm_device *dev,
>  }
>  EXPORT_SYMBOL(__drmm_add_action);
>  
> +/**
> + * drmm_add_action - remave a managed release action to a &drm_device
s/remave/remove/
"action to a &drm_device" => "action from a &drm_device"?

> @@ -160,6 +192,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().

RETURNS: ?

> + */
>  void *drmm_kmalloc(struct drm_device *dev, size_t size, gfp_t gfp)
>  {
>  	struct drmres *dr;
> @@ -175,6 +217,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
> + * @size: 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().

RETURNS: ?
> + */
>  char *drmm_kstrdup(struct drm_device *dev, const char *s, gfp_t gfp)
>  {
>  	size_t size;
> @@ -191,6 +243,15 @@ char *drmm_kstrdup(struct drm_device *dev, const char *s, gfp_t gfp)
>  }
>  EXPORT_SYMBOL_GPL(drmm_kstrdup);
>  


> diff --git a/include/drm/drm_managed.h b/include/drm/drm_managed.h
> index 573cadca4b3d..0e7616bd0858 100644
> --- a/include/drm/drm_managed.h
> +++ b/include/drm/drm_managed.h
> @@ -8,6 +8,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 wwith optional parameter @data to the
s/wwith/with/

> + * 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)
>  
> @@ -22,12 +35,45 @@ 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().

RETURNS: ?

> + */
>  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
> + * @size: 0 terminated string to be duplicated
> + * @gfp: 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().

RETURNS: ?

> + */
>  static inline void *drmm_kmalloc_array(struct drm_device *dev,
>  				       size_t n, size_t size, gfp_t flags)
> +
> +/**
> + * drmm_kcalloc - &drm_device managed kcalloc()
> + * @dev: DRM device
> + * @size: 0 terminated string to be duplicated
> + * @gfp: 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().

RETURNS: ?

> + */
>  {
>  	size_t bytes;
>  
> @@ -41,6 +87,7 @@ static inline void *drmm_kcalloc(struct drm_device *dev,
>  {
>  	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
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH 52/52] drm: Add docs for managed resources
  2020-02-21 20:23     ` [Intel-gfx] " Sam Ravnborg
@ 2020-02-21 21:13       ` Sam Ravnborg
  -1 siblings, 0 replies; 310+ messages in thread
From: Sam Ravnborg @ 2020-02-21 21:13 UTC (permalink / raw)
  To: Daniel Vetter; +Cc: Daniel Vetter, Intel Graphics Development, DRI Development

Hi Daniel.

> What I miss in all of this is how do other subsystems deal
> with the different lifetime of their stuff?
> Or maybe only drm really has this issue?
> Anything we could learn from others?
Reading through the thread - this is all covered in more than sufficient
details in other mails. So forget this comment.

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

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

* Re: [Intel-gfx] [PATCH 52/52] drm: Add docs for managed resources
@ 2020-02-21 21:13       ` Sam Ravnborg
  0 siblings, 0 replies; 310+ messages in thread
From: Sam Ravnborg @ 2020-02-21 21:13 UTC (permalink / raw)
  To: Daniel Vetter; +Cc: Daniel Vetter, Intel Graphics Development, DRI Development

Hi Daniel.

> What I miss in all of this is how do other subsystems deal
> with the different lifetime of their stuff?
> Or maybe only drm really has this issue?
> Anything we could learn from others?
Reading through the thread - this is all covered in more than sufficient
details in other mails. So forget this comment.

	Sam
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH 01/52] mm/sl[uo]b: export __kmalloc_track(_node)_caller
  2020-02-19 10:20   ` Daniel Vetter
  (?)
@ 2020-02-22  3:42     ` Christopher Lameter
  -1 siblings, 0 replies; 310+ messages in thread
From: Christopher Lameter @ 2020-02-22  3:42 UTC (permalink / raw)
  To: Daniel Vetter
  Cc: DRI Development, Intel Graphics Development, Daniel Vetter,
	Pekka Enberg, David Rientjes, Joonsoo Kim, Andrew Morton,
	linux-mm

On Wed, 19 Feb 2020, Daniel Vetter wrote:

> 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.


Would be better to export it without underscores.

But ok.

Acked-by: Christoph Lameter <cl@linux.com>


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

* Re: [PATCH 01/52] mm/sl[uo]b: export __kmalloc_track(_node)_caller
@ 2020-02-22  3:42     ` Christopher Lameter
  0 siblings, 0 replies; 310+ messages in thread
From: Christopher Lameter @ 2020-02-22  3:42 UTC (permalink / raw)
  To: Daniel Vetter
  Cc: Intel Graphics Development, DRI Development, Pekka Enberg,
	linux-mm, David Rientjes, Daniel Vetter, Joonsoo Kim,
	Andrew Morton

On Wed, 19 Feb 2020, Daniel Vetter wrote:

> 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.


Would be better to export it without underscores.

But ok.

Acked-by: Christoph Lameter <cl@linux.com>
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

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

* Re: [Intel-gfx] [PATCH 01/52] mm/sl[uo]b: export __kmalloc_track(_node)_caller
@ 2020-02-22  3:42     ` Christopher Lameter
  0 siblings, 0 replies; 310+ messages in thread
From: Christopher Lameter @ 2020-02-22  3:42 UTC (permalink / raw)
  To: Daniel Vetter
  Cc: Intel Graphics Development, DRI Development, Pekka Enberg,
	linux-mm, David Rientjes, Daniel Vetter, Joonsoo Kim,
	Andrew Morton

On Wed, 19 Feb 2020, Daniel Vetter wrote:

> 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.


Would be better to export it without underscores.

But ok.

Acked-by: Christoph Lameter <cl@linux.com>
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH 10/52] drm/cirrus: Use drmm_add_final_kfree
  2020-02-19 10:20   ` Daniel Vetter
  (?)
@ 2020-02-24  8:13     ` Gerd Hoffmann
  -1 siblings, 0 replies; 310+ messages in thread
From: Gerd Hoffmann @ 2020-02-24  8:13 UTC (permalink / raw)
  To: Daniel Vetter
  Cc: Intel Graphics Development, DRI Development, virtualization,
	Noralf Trønnes, Thomas Zimmermann, Dave Airlie,
	Daniel Vetter, Sam Ravnborg, Linus Walleij

On Wed, Feb 19, 2020 at 11:20:40AM +0100, Daniel Vetter wrote:
> 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: Gerd Hoffmann <kraxel@redhat.com>

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

* Re: [PATCH 10/52] drm/cirrus: Use drmm_add_final_kfree
@ 2020-02-24  8:13     ` Gerd Hoffmann
  0 siblings, 0 replies; 310+ messages in thread
From: Gerd Hoffmann @ 2020-02-24  8:13 UTC (permalink / raw)
  To: Daniel Vetter
  Cc: Intel Graphics Development, DRI Development, virtualization,
	Thomas Zimmermann, Dave Airlie, Daniel Vetter, Sam Ravnborg

On Wed, Feb 19, 2020 at 11:20:40AM +0100, Daniel Vetter wrote:
> 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: 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] 310+ messages in thread

* Re: [Intel-gfx] [PATCH 10/52] drm/cirrus: Use drmm_add_final_kfree
@ 2020-02-24  8:13     ` Gerd Hoffmann
  0 siblings, 0 replies; 310+ messages in thread
From: Gerd Hoffmann @ 2020-02-24  8:13 UTC (permalink / raw)
  To: Daniel Vetter
  Cc: Intel Graphics Development, DRI Development, virtualization,
	Noralf Trønnes, Thomas Zimmermann, Dave Airlie,
	Daniel Vetter, Sam Ravnborg, Linus Walleij

On Wed, Feb 19, 2020 at 11:20:40AM +0100, Daniel Vetter wrote:
> 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: Gerd Hoffmann <kraxel@redhat.com>

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH 28/52] drm/bochs: Remove leftover drm_atomic_helper_shutdown
  2020-02-19 10:20   ` [Intel-gfx] " Daniel Vetter
@ 2020-02-24  8:14     ` Gerd Hoffmann
  -1 siblings, 0 replies; 310+ messages in thread
From: Gerd Hoffmann @ 2020-02-24  8:14 UTC (permalink / raw)
  To: Daniel Vetter; +Cc: Daniel Vetter, Intel Graphics Development, DRI Development

On Wed, Feb 19, 2020 at 11:20:58AM +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>

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

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

* Re: [Intel-gfx] [PATCH 28/52] drm/bochs: Remove leftover drm_atomic_helper_shutdown
@ 2020-02-24  8:14     ` Gerd Hoffmann
  0 siblings, 0 replies; 310+ messages in thread
From: Gerd Hoffmann @ 2020-02-24  8:14 UTC (permalink / raw)
  To: Daniel Vetter; +Cc: Daniel Vetter, Intel Graphics Development, DRI Development

On Wed, Feb 19, 2020 at 11:20:58AM +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>

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH 29/52] drm/bochs: Drop explicit drm_mode_config_cleanup
  2020-02-19 10:20   ` Daniel Vetter
  (?)
@ 2020-02-24  8:15     ` Gerd Hoffmann
  -1 siblings, 0 replies; 310+ messages in thread
From: Gerd Hoffmann @ 2020-02-24  8:15 UTC (permalink / raw)
  To: Daniel Vetter
  Cc: Daniel Vetter, Intel Graphics Development, DRI Development,
	virtualization

On Wed, Feb 19, 2020 at 11:20:59AM +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.
> 
> Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
> Cc: Gerd Hoffmann <kraxel@redhat.com>
> Cc: virtualization@lists.linux-foundation.org

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

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

* Re: [PATCH 29/52] drm/bochs: Drop explicit drm_mode_config_cleanup
@ 2020-02-24  8:15     ` Gerd Hoffmann
  0 siblings, 0 replies; 310+ messages in thread
From: Gerd Hoffmann @ 2020-02-24  8:15 UTC (permalink / raw)
  To: Daniel Vetter
  Cc: Daniel Vetter, Intel Graphics Development, DRI Development,
	virtualization

On Wed, Feb 19, 2020 at 11:20:59AM +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.
> 
> Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
> Cc: Gerd Hoffmann <kraxel@redhat.com>
> Cc: virtualization@lists.linux-foundation.org

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] 310+ messages in thread

* Re: [Intel-gfx] [PATCH 29/52] drm/bochs: Drop explicit drm_mode_config_cleanup
@ 2020-02-24  8:15     ` Gerd Hoffmann
  0 siblings, 0 replies; 310+ messages in thread
From: Gerd Hoffmann @ 2020-02-24  8:15 UTC (permalink / raw)
  To: Daniel Vetter
  Cc: Daniel Vetter, Intel Graphics Development, DRI Development,
	virtualization

On Wed, Feb 19, 2020 at 11:20:59AM +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.
> 
> Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
> Cc: Gerd Hoffmann <kraxel@redhat.com>
> Cc: virtualization@lists.linux-foundation.org

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

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH 30/52] drm/cirrus: Drop explicit drm_mode_config_cleanup call
  2020-02-19 10:21   ` Daniel Vetter
  (?)
@ 2020-02-24  8:16     ` Gerd Hoffmann
  -1 siblings, 0 replies; 310+ messages in thread
From: Gerd Hoffmann @ 2020-02-24  8:16 UTC (permalink / raw)
  To: Daniel Vetter
  Cc: Intel Graphics Development, DRI Development, virtualization,
	Noralf Trønnes, Thomas Zimmermann, Dave Airlie,
	Daniel Vetter, Sam Ravnborg

On Wed, Feb 19, 2020 at 11:21:00AM +0100, Daniel Vetter wrote:
> We can even delete the drm_driver.release hook now!
> 
> 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

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

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

* Re: [PATCH 30/52] drm/cirrus: Drop explicit drm_mode_config_cleanup call
@ 2020-02-24  8:16     ` Gerd Hoffmann
  0 siblings, 0 replies; 310+ messages in thread
From: Gerd Hoffmann @ 2020-02-24  8:16 UTC (permalink / raw)
  To: Daniel Vetter
  Cc: Intel Graphics Development, DRI Development, virtualization,
	Thomas Zimmermann, Dave Airlie, Daniel Vetter, Sam Ravnborg

On Wed, Feb 19, 2020 at 11:21:00AM +0100, Daniel Vetter wrote:
> We can even delete the drm_driver.release hook now!
> 
> 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

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] 310+ messages in thread

* Re: [Intel-gfx] [PATCH 30/52] drm/cirrus: Drop explicit drm_mode_config_cleanup call
@ 2020-02-24  8:16     ` Gerd Hoffmann
  0 siblings, 0 replies; 310+ messages in thread
From: Gerd Hoffmann @ 2020-02-24  8:16 UTC (permalink / raw)
  To: Daniel Vetter
  Cc: Intel Graphics Development, DRI Development, virtualization,
	Noralf Trønnes, Thomas Zimmermann, Dave Airlie,
	Daniel Vetter, Sam Ravnborg

On Wed, Feb 19, 2020 at 11:21:00AM +0100, Daniel Vetter wrote:
> We can even delete the drm_driver.release hook now!
> 
> 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

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

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH 31/52] drm/cirrus: Fully embrace devm_
  2020-02-19 10:21   ` Daniel Vetter
  (?)
@ 2020-02-24  8:18     ` Gerd Hoffmann
  -1 siblings, 0 replies; 310+ messages in thread
From: Gerd Hoffmann @ 2020-02-24  8:18 UTC (permalink / raw)
  To: Daniel Vetter
  Cc: Intel Graphics Development, DRI Development, virtualization,
	Noralf Trønnes, Thomas Zimmermann, Dave Airlie,
	Daniel Vetter, Emil Velikov

On Wed, Feb 19, 2020 at 11:21:01AM +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.
> 
> 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

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

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

* Re: [PATCH 31/52] drm/cirrus: Fully embrace devm_
@ 2020-02-24  8:18     ` Gerd Hoffmann
  0 siblings, 0 replies; 310+ messages in thread
From: Gerd Hoffmann @ 2020-02-24  8:18 UTC (permalink / raw)
  To: Daniel Vetter
  Cc: Intel Graphics Development, DRI Development, virtualization,
	Thomas Zimmermann, Dave Airlie, Daniel Vetter, Emil Velikov

On Wed, Feb 19, 2020 at 11:21:01AM +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.
> 
> 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

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] 310+ messages in thread

* Re: [Intel-gfx] [PATCH 31/52] drm/cirrus: Fully embrace devm_
@ 2020-02-24  8:18     ` Gerd Hoffmann
  0 siblings, 0 replies; 310+ messages in thread
From: Gerd Hoffmann @ 2020-02-24  8:18 UTC (permalink / raw)
  To: Daniel Vetter
  Cc: Intel Graphics Development, DRI Development, virtualization,
	Noralf Trønnes, Thomas Zimmermann, Dave Airlie,
	Daniel Vetter, Emil Velikov

On Wed, Feb 19, 2020 at 11:21:01AM +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.
> 
> 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

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

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

end of thread, other threads:[~2020-02-24  9:21 UTC | newest]

Thread overview: 310+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-02-19 10:20 [PATCH 00/52] drm_device managed resources Daniel Vetter
2020-02-19 10:20 ` [Intel-gfx] " Daniel Vetter
2020-02-19 10:20 ` [PATCH 01/52] mm/sl[uo]b: export __kmalloc_track(_node)_caller Daniel Vetter
2020-02-19 10:20   ` [Intel-gfx] " Daniel Vetter
2020-02-19 10:20   ` Daniel Vetter
2020-02-19 19:42   ` Andrew Morton
2020-02-19 19:42     ` [Intel-gfx] " Andrew Morton
2020-02-19 19:42     ` Andrew Morton
2020-02-22  3:42   ` Christopher Lameter
2020-02-22  3:42     ` [Intel-gfx] " Christopher Lameter
2020-02-22  3:42     ` Christopher Lameter
2020-02-19 10:20 ` [PATCH 02/52] drm/i915: Don't clear drvdata in ->release Daniel Vetter
2020-02-19 10:20   ` [Intel-gfx] " Daniel Vetter
2020-02-19 10:20 ` [PATCH 03/52] drm: add managed resources tied to drm_device Daniel Vetter
2020-02-19 10:20   ` [Intel-gfx] " Daniel Vetter
2020-02-19 12:31   ` Neil Armstrong
2020-02-19 12:31     ` [Intel-gfx] " Neil Armstrong
2020-02-19 13:24     ` Daniel Vetter
2020-02-19 13:24       ` [Intel-gfx] " Daniel Vetter
2020-02-19 13:28   ` Laurent Pinchart
2020-02-19 13:28     ` [Intel-gfx] " Laurent Pinchart
2020-02-19 13:33     ` Greg Kroah-Hartman
2020-02-19 13:33       ` [Intel-gfx] " Greg Kroah-Hartman
2020-02-19 14:22       ` Daniel Vetter
2020-02-19 14:22         ` [Intel-gfx] " Daniel Vetter
2020-02-19 16:09         ` Emil Velikov
2020-02-19 16:09           ` Emil Velikov
2020-02-19 16:22           ` Daniel Vetter
2020-02-19 16:22             ` Daniel Vetter
2020-02-19 16:41             ` Emil Velikov
2020-02-19 16:41               ` Emil Velikov
2020-02-19 16:46             ` Laurent Pinchart
2020-02-19 16:46               ` Laurent Pinchart
2020-02-19 16:53               ` Daniel Vetter
2020-02-19 16:53                 ` Daniel Vetter
2020-02-19 17:02                 ` Laurent Pinchart
2020-02-19 17:02                   ` Laurent Pinchart
2020-02-19 17:06                   ` Daniel Vetter
2020-02-19 17:06                     ` Daniel Vetter
2020-02-19 17:00         ` Greg Kroah-Hartman
2020-02-19 17:00           ` [Intel-gfx] " Greg Kroah-Hartman
2020-02-19 17:36           ` Laurent Pinchart
2020-02-19 17:36             ` [Intel-gfx] " Laurent Pinchart
2020-02-19 18:19             ` Greg Kroah-Hartman
2020-02-19 18:19               ` [Intel-gfx] " Greg Kroah-Hartman
2020-02-19 19:57               ` Daniel Vetter
2020-02-19 19:57                 ` [Intel-gfx] " Daniel Vetter
2020-02-20 14:58               ` Laurent Pinchart
2020-02-20 14:58                 ` [Intel-gfx] " Laurent Pinchart
2020-02-19 13:57     ` Daniel Vetter
2020-02-19 13:57       ` [Intel-gfx] " Daniel Vetter
2020-02-19 10:20 ` [PATCH 04/52] drm: Set final_kfree in drm_dev_alloc Daniel Vetter
2020-02-19 10:20   ` [Xen-devel] " Daniel Vetter
2020-02-19 10:20   ` [Intel-gfx] " Daniel Vetter
2020-02-19 12:03   ` Oleksandr Andrushchenko
2020-02-19 12:03     ` [Xen-devel] " Oleksandr Andrushchenko
2020-02-19 12:03     ` [Intel-gfx] " Oleksandr Andrushchenko
2020-02-19 13:39   ` Laurent Pinchart
2020-02-19 13:39     ` [Xen-devel] " Laurent Pinchart
2020-02-19 13:39     ` [Intel-gfx] " Laurent Pinchart
2020-02-19 14:41     ` Daniel Vetter
2020-02-19 14:41       ` [Xen-devel] " Daniel Vetter
2020-02-19 14:41       ` [Intel-gfx] " Daniel Vetter
2020-02-21 19:07       ` Daniel Vetter
2020-02-21 19:07         ` [Xen-devel] " Daniel Vetter
2020-02-21 19:07         ` [Intel-gfx] " Daniel Vetter
2020-02-19 10:20 ` [PATCH 05/52] drm/mipi_dbi: Use drmm_add_final_kfree in all drivers Daniel Vetter
2020-02-19 10:20   ` [Intel-gfx] " Daniel Vetter
2020-02-19 11:47   ` Thomas Zimmermann
2020-02-19 11:47     ` [Intel-gfx] " Thomas Zimmermann
2020-02-19 12:45     ` Thomas Zimmermann
2020-02-19 12:45       ` [Intel-gfx] " Thomas Zimmermann
2020-02-19 13:23     ` Daniel Vetter
2020-02-19 13:23       ` [Intel-gfx] " Daniel Vetter
2020-02-19 13:29       ` Thomas Zimmermann
2020-02-19 13:29         ` [Intel-gfx] " Thomas Zimmermann
2020-02-19 14:32         ` Daniel Vetter
2020-02-19 14:32           ` [Intel-gfx] " Daniel Vetter
2020-02-20 16:18   ` Noralf Trønnes
2020-02-20 16:18     ` [Intel-gfx] " Noralf Trønnes
2020-02-19 10:20 ` [PATCH 06/52] drm/udl: Use drmm_add_final_kfree Daniel Vetter
2020-02-19 10:20   ` [Intel-gfx] " Daniel Vetter
2020-02-19 10:20 ` [PATCH 07/52] " Daniel Vetter
2020-02-19 10:20   ` [Intel-gfx] " Daniel Vetter
2020-02-19 13:42   ` Laurent Pinchart
2020-02-19 13:42     ` [Intel-gfx] " Laurent Pinchart
2020-02-19 14:43     ` Daniel Vetter
2020-02-19 14:43       ` [Intel-gfx] " Daniel Vetter
2020-02-19 10:20 ` [PATCH 08/52] drm/qxl: " Daniel Vetter
2020-02-19 10:20   ` [Intel-gfx] " Daniel Vetter
2020-02-19 10:20   ` Daniel Vetter
2020-02-19 10:20 ` [PATCH 09/52] drm/i915: " Daniel Vetter
2020-02-19 10:20   ` [Intel-gfx] " Daniel Vetter
2020-02-19 10:20 ` [PATCH 10/52] drm/cirrus: " Daniel Vetter
2020-02-19 10:20   ` [Intel-gfx] " Daniel Vetter
2020-02-19 10:20   ` Daniel Vetter
2020-02-24  8:13   ` Gerd Hoffmann
2020-02-24  8:13     ` [Intel-gfx] " Gerd Hoffmann
2020-02-24  8:13     ` Gerd Hoffmann
2020-02-19 10:20 ` [PATCH 11/52] drm/v3d: " Daniel Vetter
2020-02-19 10:20   ` [Intel-gfx] " Daniel Vetter
2020-02-19 18:43   ` Eric Anholt
2020-02-19 18:43     ` [Intel-gfx] " Eric Anholt
2020-02-19 10:20 ` [PATCH 12/52] drm/tidss: " Daniel Vetter
2020-02-19 10:20   ` [Intel-gfx] " Daniel Vetter
2020-02-19 10:20 ` [PATCH 13/52] drm/mcde: " Daniel Vetter
2020-02-19 10:20   ` [Intel-gfx] " Daniel Vetter
2020-02-19 16:12   ` Linus Walleij
2020-02-19 16:12     ` [Intel-gfx] " Linus Walleij
2020-02-19 10:20 ` [PATCH 14/52] drm/vgem: " Daniel Vetter
2020-02-19 10:20   ` [Intel-gfx] " Daniel Vetter
2020-02-19 10:20 ` [PATCH 15/52] drm/vkms: " Daniel Vetter
2020-02-19 10:20   ` [Intel-gfx] " Daniel Vetter
2020-02-19 10:20 ` [PATCH 16/52] drm/repaper: " Daniel Vetter
2020-02-19 10:20   ` [Intel-gfx] " Daniel Vetter
2020-02-20 16:18   ` Noralf Trønnes
2020-02-20 16:18     ` [Intel-gfx] " Noralf Trønnes
2020-02-19 10:20 ` [PATCH 17/52] drm/inigenic: " Daniel Vetter
2020-02-19 10:20   ` [Intel-gfx] " Daniel Vetter
2020-02-19 10:20 ` [PATCH 18/52] drm/gm12u320: " Daniel Vetter
2020-02-19 10:20   ` [Intel-gfx] " Daniel Vetter
2020-02-19 10:20 ` [PATCH 19/52] drm/<drivers>: " Daniel Vetter
2020-02-19 10:20   ` [Intel-gfx] " Daniel Vetter
2020-02-19 14:11   ` Laurent Pinchart
2020-02-19 14:11     ` [Intel-gfx] " Laurent Pinchart
2020-02-19 14:30     ` Daniel Vetter
2020-02-19 14:30       ` [Intel-gfx] " Daniel Vetter
2020-02-19 14:39       ` Laurent Pinchart
2020-02-19 14:39         ` [Intel-gfx] " Laurent Pinchart
2020-02-19 15:29         ` Daniel Vetter
2020-02-19 15:29           ` [Intel-gfx] " Daniel Vetter
2020-02-19 10:20 ` [PATCH 20/52] drm: Cleanups after drmm_add_final_kfree rollout Daniel Vetter
2020-02-19 10:20   ` [Intel-gfx] " Daniel Vetter
2020-02-19 10:20 ` [PATCH 21/52] drm: Handle dev->unique with drmm_ Daniel Vetter
2020-02-19 10:20   ` [Intel-gfx] " Daniel Vetter
2020-02-19 14:28   ` Laurent Pinchart
2020-02-19 14:28     ` [Intel-gfx] " Laurent Pinchart
2020-02-19 15:24     ` Daniel Vetter
2020-02-19 15:24       ` [Intel-gfx] " Daniel Vetter
2020-02-19 10:20 ` [PATCH 22/52] drm: Use drmm_ for drm_dev_init cleanup Daniel Vetter
2020-02-19 10:20   ` [Intel-gfx] " Daniel Vetter
2020-02-19 14:35   ` Laurent Pinchart
2020-02-19 14:35     ` [Intel-gfx] " Laurent Pinchart
2020-02-19 15:27     ` Daniel Vetter
2020-02-19 15:27       ` [Intel-gfx] " Daniel Vetter
2020-02-19 15:37       ` Laurent Pinchart
2020-02-19 15:37         ` [Intel-gfx] " Laurent Pinchart
2020-02-19 15:44         ` Daniel Vetter
2020-02-19 15:44           ` [Intel-gfx] " Daniel Vetter
2020-02-19 10:20 ` [PATCH 23/52] drm: manage drm_minor cleanup with drmm_ Daniel Vetter
2020-02-19 10:20   ` [Intel-gfx] " Daniel Vetter
2020-02-19 14:47   ` Laurent Pinchart
2020-02-19 14:47     ` [Intel-gfx] " Laurent Pinchart
2020-02-19 15:34     ` Daniel Vetter
2020-02-19 15:34       ` [Intel-gfx] " Daniel Vetter
2020-02-19 10:20 ` [PATCH 24/52] drm: Manage drm_gem_init " Daniel Vetter
2020-02-19 10:20   ` [Intel-gfx] " Daniel Vetter
2020-02-19 14:22   ` Laurent Pinchart
2020-02-19 14:22     ` [Intel-gfx] " Laurent Pinchart
2020-02-19 14:37     ` Daniel Vetter
2020-02-19 14:37       ` [Intel-gfx] " Daniel Vetter
2020-02-19 14:52       ` Laurent Pinchart
2020-02-19 14:52         ` [Intel-gfx] " Laurent Pinchart
2020-02-19 14:56         ` Daniel Vetter
2020-02-19 14:56           ` [Intel-gfx] " Daniel Vetter
2020-02-19 10:20 ` [PATCH 25/52] drm: Manage drm_vblank_cleanup " Daniel Vetter
2020-02-19 10:20   ` [Intel-gfx] " Daniel Vetter
2020-02-19 10:20 ` [PATCH 26/52] drm: Garbage collect drm_dev_fini Daniel Vetter
2020-02-19 10:20   ` [Intel-gfx] " Daniel Vetter
2020-02-19 10:20 ` [PATCH 27/52] drm: Manage drm_mode_config_init with drmm_ Daniel Vetter
2020-02-19 10:20   ` [Intel-gfx] " Daniel Vetter
2020-02-19 13:49   ` Laurent Pinchart
2020-02-19 13:49     ` [Intel-gfx] " Laurent Pinchart
2020-02-19 15:47     ` Daniel Vetter
2020-02-19 15:47       ` [Intel-gfx] " Daniel Vetter
2020-02-19 16:07       ` Laurent Pinchart
2020-02-19 16:07         ` [Intel-gfx] " Laurent Pinchart
2020-02-19 16:23         ` Daniel Vetter
2020-02-19 16:23           ` [Intel-gfx] " Daniel Vetter
2020-02-19 17:30           ` Noralf Trønnes
2020-02-19 17:30             ` [Intel-gfx] " Noralf Trønnes
2020-02-19 18:12             ` Daniel Vetter
2020-02-19 18:12               ` [Intel-gfx] " Daniel Vetter
2020-02-19 10:20 ` [PATCH 28/52] drm/bochs: Remove leftover drm_atomic_helper_shutdown Daniel Vetter
2020-02-19 10:20   ` [Intel-gfx] " Daniel Vetter
2020-02-24  8:14   ` Gerd Hoffmann
2020-02-24  8:14     ` [Intel-gfx] " Gerd Hoffmann
2020-02-19 10:20 ` [PATCH 29/52] drm/bochs: Drop explicit drm_mode_config_cleanup Daniel Vetter
2020-02-19 10:20   ` [Intel-gfx] " Daniel Vetter
2020-02-19 10:20   ` Daniel Vetter
2020-02-24  8:15   ` Gerd Hoffmann
2020-02-24  8:15     ` [Intel-gfx] " Gerd Hoffmann
2020-02-24  8:15     ` Gerd Hoffmann
2020-02-19 10:21 ` [PATCH 30/52] drm/cirrus: Drop explicit drm_mode_config_cleanup call Daniel Vetter
2020-02-19 10:21   ` [Intel-gfx] " Daniel Vetter
2020-02-19 10:21   ` Daniel Vetter
2020-02-24  8:16   ` Gerd Hoffmann
2020-02-24  8:16     ` [Intel-gfx] " Gerd Hoffmann
2020-02-24  8:16     ` Gerd Hoffmann
2020-02-19 10:21 ` [PATCH 31/52] drm/cirrus: Fully embrace devm_ Daniel Vetter
2020-02-19 10:21   ` [Intel-gfx] " Daniel Vetter
2020-02-19 10:21   ` Daniel Vetter
2020-02-24  8:18   ` Gerd Hoffmann
2020-02-24  8:18     ` [Intel-gfx] " Gerd Hoffmann
2020-02-24  8:18     ` Gerd Hoffmann
2020-02-19 10:21 ` [PATCH 32/52] drm/ingenic: Drop explicit drm_mode_config_cleanup call Daniel Vetter
2020-02-19 10:21   ` [Intel-gfx] " Daniel Vetter
2020-02-19 10:21 ` [PATCH 33/52] drm/mcde: " Daniel Vetter
2020-02-19 10:21   ` [Intel-gfx] " Daniel Vetter
2020-02-19 16:12   ` Linus Walleij
2020-02-19 16:12     ` [Intel-gfx] " Linus Walleij
2020-02-19 10:21 ` [PATCH 34/52] drm/mcde: More devm_drm_dev_init Daniel Vetter
2020-02-19 10:21   ` [Intel-gfx] " Daniel Vetter
2020-02-19 16:13   ` Linus Walleij
2020-02-19 16:13     ` [Intel-gfx] " Linus Walleij
2020-02-19 10:21 ` [PATCH 35/52] drm/meson: Drop explicit drm_mode_config_cleanup call Daniel Vetter
2020-02-19 10:21   ` Daniel Vetter
2020-02-19 10:21   ` [Intel-gfx] " Daniel Vetter
2020-02-19 10:21   ` Daniel Vetter
2020-02-19 10:39   ` Neil Armstrong
2020-02-19 10:39     ` Neil Armstrong
2020-02-19 10:39     ` [Intel-gfx] " Neil Armstrong
2020-02-19 10:39     ` Neil Armstrong
2020-02-19 10:21 ` [PATCH 36/52] drm/pl111: " Daniel Vetter
2020-02-19 10:21   ` [Intel-gfx] " Daniel Vetter
2020-02-19 10:21 ` [PATCH 37/52] drm/rcar-du: " Daniel Vetter
2020-02-19 10:21   ` [Intel-gfx] " Daniel Vetter
2020-02-19 10:21   ` Daniel Vetter
2020-02-19 10:30   ` Geert Uytterhoeven
2020-02-19 10:30     ` [Intel-gfx] " Geert Uytterhoeven
2020-02-19 10:30     ` Geert Uytterhoeven
2020-02-19 10:56     ` Daniel Vetter
2020-02-19 10:56       ` [Intel-gfx] " Daniel Vetter
2020-02-19 10:56       ` Daniel Vetter
2020-02-19 11:10       ` Geert Uytterhoeven
2020-02-19 11:10         ` [Intel-gfx] " Geert Uytterhoeven
2020-02-19 11:10         ` Geert Uytterhoeven
2020-02-19 12:17         ` Laurent Pinchart
2020-02-19 12:17           ` [Intel-gfx] " Laurent Pinchart
2020-02-19 12:17           ` Laurent Pinchart
2020-02-19 12:40           ` Daniel Vetter
2020-02-19 12:40             ` [Intel-gfx] " Daniel Vetter
2020-02-19 12:40             ` Daniel Vetter
2020-02-19 13:53   ` Laurent Pinchart
2020-02-19 13:53     ` [Intel-gfx] " Laurent Pinchart
2020-02-19 13:53     ` Laurent Pinchart
2020-02-19 14:29     ` Daniel Vetter
2020-02-19 14:29       ` [Intel-gfx] " Daniel Vetter
2020-02-19 14:29       ` Daniel Vetter
     [not found] ` <20200219102122.1607365-1-daniel.vetter-/w4YWyX8dFk@public.gmane.org>
2020-02-19 10:21   ` [PATCH 38/52] drm/rockchip: " Daniel Vetter
2020-02-19 10:21     ` [Intel-gfx] " Daniel Vetter
2020-02-19 10:21     ` Daniel Vetter
2020-02-19 10:21     ` Daniel Vetter
2020-02-19 10:21 ` [PATCH 39/52] drm/stm: " Daniel Vetter
2020-02-19 10:21   ` [Intel-gfx] " Daniel Vetter
2020-02-19 10:21   ` Daniel Vetter
2020-02-20 14:18   ` Philippe CORNU
2020-02-20 14:18     ` [Intel-gfx] " Philippe CORNU
2020-02-20 14:18     ` Philippe CORNU
2020-02-20 16:12     ` Daniel Vetter
2020-02-20 16:12       ` [Intel-gfx] " Daniel Vetter
2020-02-20 16:12       ` Daniel Vetter
2020-02-19 10:21 ` [PATCH 40/52] drm/shmob: " Daniel Vetter
2020-02-19 10:21   ` [Intel-gfx] " Daniel Vetter
2020-02-19 10:21   ` Daniel Vetter
2020-02-19 13:57   ` Laurent Pinchart
2020-02-19 13:57     ` [Intel-gfx] " Laurent Pinchart
2020-02-19 13:57     ` Laurent Pinchart
2020-02-19 10:21 ` [PATCH 41/52] drm/mtk: " Daniel Vetter
2020-02-19 10:21   ` [Intel-gfx] " Daniel Vetter
2020-02-19 10:21 ` [PATCH 42/52] drm/tidss: " Daniel Vetter
2020-02-19 10:21   ` [Intel-gfx] " Daniel Vetter
2020-02-19 10:21 ` [PATCH 43/52] drm/gm12u320: More drmm_ Daniel Vetter
2020-02-19 10:21   ` [Intel-gfx] " Daniel Vetter
2020-02-19 10:21 ` [PATCH 44/52] drm/gm12u320: Use devm_drm_dev_init Daniel Vetter
2020-02-19 10:21   ` [Intel-gfx] " Daniel Vetter
2020-02-19 10:21 ` [PATCH 45/52] drm/gm12u320: Use helpers for shutdown/suspend/resume Daniel Vetter
2020-02-19 10:21   ` [Intel-gfx] " Daniel Vetter
2020-02-19 10:21 ` [PATCH 46/52] drm/gm12u320: Simplify upload work Daniel Vetter
2020-02-19 10:21   ` [Intel-gfx] " Daniel Vetter
2020-02-19 10:21 ` [PATCH 47/52] drm/repaper: Drop explicit drm_mode_config_cleanup call Daniel Vetter
2020-02-19 10:21   ` [Intel-gfx] " Daniel Vetter
2020-02-20 16:21   ` Noralf Trønnes
2020-02-20 16:21     ` [Intel-gfx] " Noralf Trønnes
2020-02-19 10:21 ` [PATCH 48/52] drm/mipi-dbi: Move drm_mode_config_init into mipi library Daniel Vetter
2020-02-19 10:21   ` [Intel-gfx] " Daniel Vetter
2020-02-20 16:22   ` Noralf Trønnes
2020-02-20 16:22     ` [Intel-gfx] " Noralf Trønnes
2020-02-19 10:21 ` [PATCH 49/52] drm/mipi-dbi: Drop explicit drm_mode_config_cleanup call Daniel Vetter
2020-02-19 10:21   ` [Intel-gfx] " Daniel Vetter
2020-02-20 16:22   ` Noralf Trønnes
2020-02-20 16:22     ` [Intel-gfx] " Noralf Trønnes
2020-02-19 10:21 ` [PATCH 50/52] drm/udl: " Daniel Vetter
2020-02-19 10:21   ` [Intel-gfx] " Daniel Vetter
2020-02-19 10:21 ` [PATCH 51/52] drm/udl: drop drm_driver.release hook Daniel Vetter
2020-02-19 10:21   ` [Intel-gfx] " Daniel Vetter
2020-02-19 10:21 ` [PATCH 52/52] drm: Add docs for managed resources Daniel Vetter
2020-02-19 10:21   ` [Intel-gfx] " Daniel Vetter
2020-02-19 15:08   ` Laurent Pinchart
2020-02-19 15:08     ` [Intel-gfx] " Laurent Pinchart
2020-02-19 15:40     ` Daniel Vetter
2020-02-19 15:40       ` [Intel-gfx] " Daniel Vetter
2020-02-21 20:23   ` Sam Ravnborg
2020-02-21 20:23     ` [Intel-gfx] " Sam Ravnborg
2020-02-21 21:13     ` Sam Ravnborg
2020-02-21 21:13       ` [Intel-gfx] " Sam Ravnborg
2020-02-19 11:30 ` [Intel-gfx] ✗ Fi.CI.CHECKPATCH: warning for drm_device " Patchwork
2020-02-19 11:32 ` [Intel-gfx] ✗ Fi.CI.SPARSE: " Patchwork
2020-02-19 11:54 ` [Intel-gfx] ✓ Fi.CI.BAT: success " Patchwork
2020-02-21  1:37 ` [Intel-gfx] ✗ Fi.CI.IGT: failure " Patchwork

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.