All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 00/15] Share TTM code among framebuffer drivers
@ 2019-04-08  9:21 Thomas Zimmermann
  2019-04-08  9:21 ` [PATCH 01/15] drm: Add |struct drm_gem_ttm_object| and helpers Thomas Zimmermann
                   ` (16 more replies)
  0 siblings, 17 replies; 43+ messages in thread
From: Thomas Zimmermann @ 2019-04-08  9:21 UTC (permalink / raw)
  To: daniel, airlied, kraxel, christian.koenig, ray.huang,
	Jerry.Zhang, hdegoede, z.liuxinliang, zourongrong,
	kong.kongxinwei, puck.chen
  Cc: Thomas Zimmermann, dri-devel, virtualization

Several simple framebuffer drivers copy most of the TTM code from each
other. The implementation is always the same; except for the name of
some data structures.

As recently discussed, this patch set provides generic TTM memory-
management code for framebuffers with dedicated video memory. It further
converts the respective drivers to the generic code. The shared code
is basically the same implementation as the one copied among individual
drivers.

The patch set contains two major changes: first, it introduces
|struct drm_gem_ttm_object| and helpers. It's a GEM object that is
backed by TTM-managed memory. The type's purpose is somewhat similar
to |struct drm_gem_{cma, shmem}_object|. Second, the patch set
introduces |struct drm_simple_ttm| (for the lack of a better name) and
helpers. It's an implementation of a basic TTM-based memory manager.

Both, GEM TTM and Simple TTM, support VRAM and SYSTEM placements. Support
for TT could probably be added if necessary. Both can be used independedly
from each other if desired by the DRM driver.

Currently ast, bochs, mgag200, vboxvideo and hisilicon/hibmc can use
these helpers. Cirrus would also be a candidate, but as it's being
rewrtten from scratch, I didn't bother doing the conversion.

Future directions: with these changes, the respective drivers can also
share some of their mode-setting or fbdev code. GEM TTM could implement
PRIME helpers, which would allow for using the generic fbcon.

The patch set is against a recent drm-tip.

Thomas Zimmermann (15):
  drm: Add |struct drm_gem_ttm_object| and helpers
  drm: Add |struct drm_gem_ttm_object| callbacks for |struct
    ttm_bo_driver|
  drm: Add |struct drm_gem_ttm_object| callbacks for |struct drm_driver|
  drm: Add drm_gem_ttm_fill_create_dumb() to create dumb buffers
  drm: Add Simple TTM, a memory manager for dedicated VRAM
  drm/ast: Convert AST driver to |struct drm_gem_ttm_object|
  drm/ast: Convert AST driver to Simple TTM
  drm/bochs: Convert Bochs driver to |struct drm_gem_ttm_object|
  drm/bochs: Convert Bochs driver to Simple TTM
  drm/mgag200: Convert mgag200 driver to |struct drm_gem_ttm_object|
  drm/mgag200: Convert mgag200 driver to Simple TTM
  drm/vboxvideo: Convert vboxvideo driver to |struct drm_gem_ttm_object|
  drm/vboxvideo: Convert vboxvideo driver to Simple TTM
  drm/hisilicon: Convert hibmc-drm driver to |struct drm_gem_ttm_object|
  drm/hisilicon: Convert hibmc-drm driver to Simple TTM

 Documentation/gpu/drm-mm.rst                  |  23 +
 drivers/gpu/drm/Kconfig                       |  20 +
 drivers/gpu/drm/Makefile                      |   5 +
 drivers/gpu/drm/ast/Kconfig                   |   3 +-
 drivers/gpu/drm/ast/ast_drv.c                 |   4 +-
 drivers/gpu/drm/ast/ast_drv.h                 |  58 +-
 drivers/gpu/drm/ast/ast_fb.c                  |  18 +-
 drivers/gpu/drm/ast/ast_main.c                |  74 +--
 drivers/gpu/drm/ast/ast_mode.c                |  78 +--
 drivers/gpu/drm/ast/ast_ttm.c                 | 290 +---------
 drivers/gpu/drm/bochs/Kconfig                 |   2 +
 drivers/gpu/drm/bochs/bochs.h                 |  42 +-
 drivers/gpu/drm/bochs/bochs_drv.c             |   4 +-
 drivers/gpu/drm/bochs/bochs_kms.c             |  18 +-
 drivers/gpu/drm/bochs/bochs_mm.c              | 392 +-------------
 drivers/gpu/drm/drm_gem_ttm_helper.c          | 507 ++++++++++++++++++
 drivers/gpu/drm/drm_simple_ttm_helper.c       | 191 +++++++
 drivers/gpu/drm/drm_ttm_helper_common.c       |   6 +
 drivers/gpu/drm/hisilicon/hibmc/Kconfig       |   2 +
 .../gpu/drm/hisilicon/hibmc/hibmc_drm_de.c    |  19 +-
 .../gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c   |   4 +-
 .../gpu/drm/hisilicon/hibmc/hibmc_drm_drv.h   |  28 +-
 .../gpu/drm/hisilicon/hibmc/hibmc_drm_fbdev.c |  30 +-
 drivers/gpu/drm/hisilicon/hibmc/hibmc_ttm.c   | 328 +----------
 drivers/gpu/drm/mgag200/Kconfig               |   2 +
 drivers/gpu/drm/mgag200/mgag200_cursor.c      |  61 ++-
 drivers/gpu/drm/mgag200/mgag200_drv.c         |   4 +-
 drivers/gpu/drm/mgag200/mgag200_drv.h         |  68 +--
 drivers/gpu/drm/mgag200/mgag200_fb.c          |  18 +-
 drivers/gpu/drm/mgag200/mgag200_main.c        |  84 +--
 drivers/gpu/drm/mgag200/mgag200_mode.c        |  45 +-
 drivers/gpu/drm/mgag200/mgag200_ttm.c         | 290 +---------
 drivers/gpu/drm/vboxvideo/Kconfig             |   2 +
 drivers/gpu/drm/vboxvideo/vbox_drv.c          |   5 +-
 drivers/gpu/drm/vboxvideo/vbox_drv.h          |  64 +--
 drivers/gpu/drm/vboxvideo/vbox_fb.c           |  22 +-
 drivers/gpu/drm/vboxvideo/vbox_main.c         |  70 +--
 drivers/gpu/drm/vboxvideo/vbox_mode.c         |  36 +-
 drivers/gpu/drm/vboxvideo/vbox_ttm.c          | 344 +-----------
 include/drm/drm_gem_ttm_helper.h              | 119 ++++
 include/drm/drm_simple_ttm_helper.h           |  74 +++
 41 files changed, 1292 insertions(+), 2162 deletions(-)
 create mode 100644 drivers/gpu/drm/drm_gem_ttm_helper.c
 create mode 100644 drivers/gpu/drm/drm_simple_ttm_helper.c
 create mode 100644 drivers/gpu/drm/drm_ttm_helper_common.c
 create mode 100644 include/drm/drm_gem_ttm_helper.h
 create mode 100644 include/drm/drm_simple_ttm_helper.h

--
2.21.0

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

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

* [PATCH 01/15] drm: Add |struct drm_gem_ttm_object| and helpers
  2019-04-08  9:21 [PATCH 00/15] Share TTM code among framebuffer drivers Thomas Zimmermann
@ 2019-04-08  9:21 ` Thomas Zimmermann
  2019-04-08  9:21 ` [PATCH 02/15] drm: Add |struct drm_gem_ttm_object| callbacks for |struct ttm_bo_driver| Thomas Zimmermann
                   ` (15 subsequent siblings)
  16 siblings, 0 replies; 43+ messages in thread
From: Thomas Zimmermann @ 2019-04-08  9:21 UTC (permalink / raw)
  To: daniel, airlied, kraxel, christian.koenig, ray.huang,
	Jerry.Zhang, hdegoede, z.liuxinliang, zourongrong,
	kong.kongxinwei, puck.chen
  Cc: Thomas Zimmermann, dri-devel, virtualization

The type |struct drm_gem_ttm_object| implements a TTM buffer object
for simple framebuffer devices with dedicated video memory. The BO
is either located in VRAM or system memory. The implementation has
been created from the respective code in ast, bochs and mgag200. These
drivers copy their implementation from each other; except for the
names of several data types.

Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
---
 Documentation/gpu/drm-mm.rst            |  12 +
 drivers/gpu/drm/Kconfig                 |  13 +
 drivers/gpu/drm/Makefile                |   4 +
 drivers/gpu/drm/drm_gem_ttm_helper.c    | 367 ++++++++++++++++++++++++
 drivers/gpu/drm/drm_ttm_helper_common.c |   6 +
 include/drm/drm_gem_ttm_helper.h        |  91 ++++++
 6 files changed, 493 insertions(+)
 create mode 100644 drivers/gpu/drm/drm_gem_ttm_helper.c
 create mode 100644 drivers/gpu/drm/drm_ttm_helper_common.c
 create mode 100644 include/drm/drm_gem_ttm_helper.h

diff --git a/Documentation/gpu/drm-mm.rst b/Documentation/gpu/drm-mm.rst
index 54a696d961a7..596e5f15f459 100644
--- a/Documentation/gpu/drm-mm.rst
+++ b/Documentation/gpu/drm-mm.rst
@@ -380,6 +380,18 @@ GEM CMA Helper Functions Reference
 .. kernel-doc:: drivers/gpu/drm/drm_gem_cma_helper.c
    :export:
 
+GEM TTM Helper Functions Reference
+----------------------------------
+
+.. kernel-doc:: drivers/gpu/drm/drm_gem_ttm_helper.c
+   :doc: overview
+
+.. kernel-doc:: include/drm/drm_gem_ttm_helper.h
+   :internal:
+
+.. kernel-doc:: drivers/gpu/drm/drm_gem_ttm_helper.c
+   :export:
+
 VMA Offset Manager
 ==================
 
diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig
index bcbc4234893a..684bd327eb07 100644
--- a/drivers/gpu/drm/Kconfig
+++ b/drivers/gpu/drm/Kconfig
@@ -160,6 +160,12 @@ config DRM_TTM
 	  GPU memory types. Will be enabled automatically if a device driver
 	  uses it.
 
+config DRM_TTM_HELPER
+	tristate
+	depends on DRM && DRM_TTM
+	help
+	  Helpers for TTM-based memory management
+
 config DRM_GEM_CMA_HELPER
 	bool
 	depends on DRM
@@ -179,6 +185,13 @@ config DRM_GEM_SHMEM_HELPER
 	help
 	  Choose this if you need the GEM shmem helper functions
 
+config DRM_GEM_TTM_HELPER
+	bool
+	depends on DRM
+	select DRM_TTM_HELPER
+	help
+	  Choose this if you need the GEM TTM helper functions
+
 config DRM_VM
 	bool
 	depends on DRM && MMU
diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile
index d97c0a3a8cfc..acd0f3e4f079 100644
--- a/drivers/gpu/drm/Makefile
+++ b/drivers/gpu/drm/Makefile
@@ -33,6 +33,10 @@ drm-$(CONFIG_AGP) += drm_agpsupport.o
 drm-$(CONFIG_DEBUG_FS) += drm_debugfs.o drm_debugfs_crc.o
 drm-$(CONFIG_DRM_LOAD_EDID_FIRMWARE) += drm_edid_load.o
 
+drm_ttm_helper-y := drm_ttm_helper_common.o
+drm_ttm_helper-$(CONFIG_DRM_GEM_TTM_HELPER) += drm_gem_ttm_helper.o
+obj-$(CONFIG_DRM_TTM_HELPER) += drm_ttm_helper.o
+
 drm_kms_helper-y := drm_crtc_helper.o drm_dp_helper.o drm_dsc.o drm_probe_helper.o \
 		drm_plane_helper.o drm_dp_mst_topology.o drm_atomic_helper.o \
 		drm_kms_helper_common.o drm_dp_dual_mode_helper.o \
diff --git a/drivers/gpu/drm/drm_gem_ttm_helper.c b/drivers/gpu/drm/drm_gem_ttm_helper.c
new file mode 100644
index 000000000000..d52d3c439917
--- /dev/null
+++ b/drivers/gpu/drm/drm_gem_ttm_helper.c
@@ -0,0 +1,367 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+#include <drm/drm_gem_ttm_helper.h>
+#include <drm/ttm/ttm_page_alloc.h>
+
+/**
+ * DOC: overview
+ *
+ * This library provides a GEM object that is backed by TTM-managed
+ * memory. It can be used for simple framebuffer devices with dedicated
+ * memory.
+ */
+
+/*
+ * Buffer-objects helpers
+ */
+
+static void drm_gem_ttm_cleanup(struct drm_gem_ttm_object *gbo)
+{
+	/* We got here via ttm_bo_put(), which means that the
+	 * TTM buffer object in 'bo' has already been cleaned
+	 * up; only release the GEM object. */
+	drm_gem_object_release(&gbo->gem);
+}
+
+static void drm_gem_ttm_destroy(struct drm_gem_ttm_object *gbo)
+{
+	drm_gem_ttm_cleanup(gbo);
+	kfree(gbo);
+}
+
+static void ttm_buffer_object_destroy(struct ttm_buffer_object *bo)
+{
+	struct drm_gem_ttm_object *gbo = drm_gem_ttm_of_bo(bo);
+	drm_gem_ttm_destroy(gbo);
+}
+
+static void drm_gem_ttm_placement(struct drm_gem_ttm_object *gbo, int pl_flag)
+{
+	unsigned int i;
+	unsigned int c = 0;
+
+	gbo->placement.placement = gbo->placements;
+	gbo->placement.busy_placement = gbo->placements;
+
+	if (pl_flag & TTM_PL_FLAG_VRAM)
+		gbo->placements[c++].flags = TTM_PL_FLAG_WC |
+					     TTM_PL_FLAG_UNCACHED |
+					     TTM_PL_FLAG_VRAM;
+
+	if (pl_flag & TTM_PL_FLAG_SYSTEM)
+		gbo->placements[c++].flags = TTM_PL_MASK_CACHING |
+					     TTM_PL_FLAG_SYSTEM;
+
+	if (!c)
+		gbo->placements[c++].flags = TTM_PL_MASK_CACHING |
+					     TTM_PL_FLAG_SYSTEM;
+
+	gbo->placement.num_placement = c;
+	gbo->placement.num_busy_placement = c;
+
+	for (i = 0; i < c; ++i) {
+		gbo->placements[i].fpfn = 0;
+		gbo->placements[i].lpfn = 0;
+	}
+}
+
+static int drm_gem_ttm_init(struct drm_device *dev,
+			    struct ttm_bo_device *bdev,
+			    struct drm_gem_ttm_object *gbo,
+			    unsigned long size, uint32_t pg_align,
+			    bool interruptible)
+{
+	int ret;
+	size_t acc_size;
+
+	ret = drm_gem_object_init(dev, &gbo->gem, size);
+	if (ret)
+		return ret;
+
+	acc_size = ttm_bo_dma_acc_size(bdev, size, sizeof(*gbo));
+
+	gbo->bo.bdev = bdev;
+	drm_gem_ttm_placement(gbo, TTM_PL_FLAG_VRAM | TTM_PL_FLAG_SYSTEM);
+
+	ret = ttm_bo_init(bdev, &gbo->bo, size, ttm_bo_type_device,
+			  &gbo->placement, pg_align, interruptible, acc_size,
+			  NULL, NULL, ttm_buffer_object_destroy);
+	if (ret)
+		goto err_drm_gem_object_release;
+
+	return 0;
+
+err_drm_gem_object_release:
+	drm_gem_object_release(&gbo->gem);
+	return ret;
+}
+
+/**
+ * drm_gem_ttm_create() - Creates a TTM-backed GEM object
+ * @dev:		the DRM device
+ * @bdev:		the TTM BO device backing the object
+ * @size:		the buffer size in bytes
+ * @pg_align:		the buffer's alignment in multiples of the page size
+ * @interruptible:	sleep interruptible if waiting for memory
+ *
+ * Returns:
+ * A new instance of struct_gem_ttm_object on success, or
+ * an ERR_PTR-encoded error code otherwise.
+ */
+struct drm_gem_ttm_object* drm_gem_ttm_create(struct drm_device *dev,
+					      struct ttm_bo_device *bdev,
+					      unsigned long size,
+					      uint32_t pg_align,
+					      bool interruptible)
+{
+	struct drm_gem_ttm_object *gbo;
+	int ret;
+
+	gbo = kzalloc(sizeof(*gbo), GFP_KERNEL);
+	if (!gbo)
+		return ERR_PTR(-ENOMEM);
+
+	ret = drm_gem_ttm_init(dev, bdev, gbo, size, pg_align, interruptible);
+	if (ret < 0)
+		goto err_kfree;
+
+	return gbo;
+
+err_kfree:
+	kfree(gbo);
+	return ERR_PTR(ret);
+}
+EXPORT_SYMBOL(drm_gem_ttm_create);
+
+/**
+ * drm_gem_ttm_put() - Releases a reference to a TTM-backed GEM object
+ * @gbo:	the GEM-TTM object
+ *
+ * See ttm_bo_put() for more information.
+ */
+void drm_gem_ttm_put(struct drm_gem_ttm_object *gbo)
+{
+	ttm_bo_put(&gbo->bo);
+}
+EXPORT_SYMBOL(drm_gem_ttm_put);
+
+/**
+ * drm_gem_ttm_reserve() - Reserves a TTM-backed GEM object
+ * @gbo:	the GEM-TTM object
+ * @no_wait:	don't wait for buffer object to become available
+ *
+ * See ttm_bo_reserve() for more information.
+ *
+ * Returns:
+ * 0 on success, or
+ * a negative error code otherwise
+ */
+int drm_gem_ttm_reserve(struct drm_gem_ttm_object *gbo, bool no_wait)
+{
+	return ttm_bo_reserve(&gbo->bo, true, no_wait, NULL);
+}
+EXPORT_SYMBOL(drm_gem_ttm_reserve);
+
+/**
+ * drm_gem_ttm_unreserve() - Release a reservation acquired by drm_gem_ttm_reserve
+ * @gbo:	the GEM TTM object
+ *
+ * See ttm_bo_unreserve() for more information.
+ */
+void drm_gem_ttm_unreserve(struct drm_gem_ttm_object *gbo)
+{
+	ttm_bo_unreserve(&gbo->bo);
+}
+EXPORT_SYMBOL(drm_gem_ttm_unreserve);
+
+/**
+ * drm_gem_ttm_mmap_offset() - Returns a GEM TTM object's mmap offset
+ * @gbo:	the GEM TTM object
+ *
+ * See drm_vma_node_offset_addr() for more information.
+ *
+ * Returns:
+ * The buffer object's offset for userspace mappings on success, or
+ * 0 if no offset is allocated.
+ */
+u64 drm_gem_ttm_mmap_offset(struct drm_gem_ttm_object *gbo)
+{
+	return drm_vma_node_offset_addr(&gbo->bo.vma_node);
+}
+EXPORT_SYMBOL(drm_gem_ttm_mmap_offset);
+
+/**
+ * drm_gem_ttm_vram_offset() - Returns a GEM-TTM object's offset in video memory
+ * @gbo:	the GEM TTM object
+ *
+ * This function returns the buffer object's offset in the device's video
+ * memory. The buffer object has to be pinned to TT_PL_VRAM.
+ *
+ * Returns:
+ * The buffer object's offset in video memory on success, or
+ * a negative error code otherwise.
+ */
+s64 drm_gem_ttm_vram_offset(struct drm_gem_ttm_object *gbo)
+{
+	if (!gbo->pin_count)
+		return (s64)-ENODEV;
+	return gbo->bo.offset;
+}
+EXPORT_SYMBOL(drm_gem_ttm_vram_offset);
+
+/**
+ * drm_gem_ttm_pin() - Pins a GEM-TTM object in a region
+ * @gbo:	the GEM TTM object
+ * @pl_flag:	a bitmask of possible memory regions
+ *
+ * Pinning a buffer object ensures that it is not evicted from
+ * a memory region. A pinned buffer object has to be unpinned before
+ * it can be pinned to another region.
+ *
+ * Returns:
+ * 0 on success, or
+ * a negative error code otherwise.
+ */
+int drm_gem_ttm_pin(struct drm_gem_ttm_object *gbo, u32 pl_flag)
+{
+	int i, ret;
+	struct ttm_operation_ctx ctx = { false, false };
+
+	if (gbo->pin_count) {
+		++gbo->pin_count;
+		return 0;
+	}
+
+	drm_gem_ttm_placement(gbo, pl_flag);
+	for (i = 0; i < gbo->placement.num_placement; ++i)
+		gbo->placements[i].flags |= TTM_PL_FLAG_NO_EVICT;
+
+	ret = ttm_bo_validate(&gbo->bo, &gbo->placement, &ctx);
+	if (ret < 0)
+		return ret;
+
+	gbo->pin_count = 1;
+
+	return 0;
+}
+EXPORT_SYMBOL(drm_gem_ttm_pin);
+
+/**
+ * drm_gem_ttm_unpin() - Unpins a GEM-TTM object
+ * @gbo:	the GEM TTM object
+ *
+ * Returns:
+ * 0 on success, or
+ * a negative error code otherwise.
+ */
+int drm_gem_ttm_unpin(struct drm_gem_ttm_object *gbo)
+{
+	int i, ret;
+	struct ttm_operation_ctx ctx = { false, false };
+
+	if (!gbo->pin_count)
+		return 0;
+
+	--gbo->pin_count;
+	if (gbo->pin_count)
+		return 0;
+
+	for (i = 0; i < gbo->placement.num_placement ; ++i)
+		gbo->placements[i].flags &= ~TTM_PL_FLAG_NO_EVICT;
+
+	ret = ttm_bo_validate(&gbo->bo, &gbo->placement, &ctx);
+	if (ret < 0)
+		return ret;
+
+	return 0;
+}
+EXPORT_SYMBOL(drm_gem_ttm_unpin);
+
+/**
+ * drm_gem_ttm_push_to_system() - \
+	Unpins a GEM TTM object and moves it to system memory
+ * @gbo:	the GEM TTM object
+ *
+ * This operation only works if the caller holds the final pin on the
+ * buffer object.
+ *
+ * Returns:
+ * 0 on success, or
+ * a negative error code otherwise.
+ */
+int drm_gem_ttm_push_to_system(struct drm_gem_ttm_object *gbo)
+{
+	int i, ret;
+	struct ttm_operation_ctx ctx = { false, false };
+
+	if (!gbo->pin_count)
+		return 0;
+
+	--gbo->pin_count;
+	if (gbo->pin_count)
+		return 0;
+
+	if (gbo->kmap.virtual)
+		ttm_bo_kunmap(&gbo->kmap);
+
+	drm_gem_ttm_placement(gbo, TTM_PL_FLAG_SYSTEM);
+	for (i = 0; i < gbo->placement.num_placement ; ++i)
+		gbo->placements[i].flags |= TTM_PL_FLAG_NO_EVICT;
+
+	ret = ttm_bo_validate(&gbo->bo, &gbo->placement, &ctx);
+	if (ret)
+		return ret;
+
+	return 0;
+}
+EXPORT_SYMBOL(drm_gem_ttm_push_to_system);
+
+/**
+ * drm_gem_ttm_kmap() - Maps a GEM TTM object into kernel address space.
+ * @gbo:	the GEM TTM object
+ * @map:	establish a mapping if necessary
+ *
+ * This function maps the buffer object into the kernel's address space
+ * or returns the current mapping. If the parameter map is false, the
+ * function only queries the current mapping, but does not establish a
+ * new one.
+ *
+ * Returns:
+ * The buffers virtual address if mapped, or
+ * NULL is not mapped, or
+ * an ERR_PTR()-encoded error code otherwise.
+ */
+void* drm_gem_ttm_kmap(struct drm_gem_ttm_object *gbo, bool map)
+{
+	int ret;
+
+	if (gbo->kmap.virtual || !map)
+		return gbo->kmap.virtual;
+
+	ret = ttm_bo_kmap(&gbo->bo, 0, gbo->bo.num_pages, &gbo->kmap);
+	if (ret)
+		return ERR_PTR(ret);
+
+	return gbo->kmap.virtual;
+}
+EXPORT_SYMBOL(drm_gem_ttm_kmap);
+
+/**
+ * drm_gem_ttm_kunmap() - Unmaps a GEM TTM object.
+ * @gbo:	the GEM TTM object
+ */
+void drm_gem_ttm_kunmap(struct drm_gem_ttm_object *gbo)
+{
+	if (!gbo->kmap.virtual)
+		return;
+
+	ttm_bo_kunmap(&gbo->kmap);
+	gbo->kmap.virtual = NULL;
+}
+EXPORT_SYMBOL(drm_gem_ttm_kunmap);
+
+bool drm_is_gem_ttm(struct ttm_buffer_object *bo)
+{
+	return (bo->destroy == ttm_buffer_object_destroy);
+}
+EXPORT_SYMBOL(drm_is_gem_ttm);
diff --git a/drivers/gpu/drm/drm_ttm_helper_common.c b/drivers/gpu/drm/drm_ttm_helper_common.c
new file mode 100644
index 000000000000..cacd0f69facc
--- /dev/null
+++ b/drivers/gpu/drm/drm_ttm_helper_common.c
@@ -0,0 +1,6 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+#include <linux/module.h>
+
+MODULE_DESCRIPTION("DRM TTM memory-management helpers");
+MODULE_LICENSE("GPL");
diff --git a/include/drm/drm_gem_ttm_helper.h b/include/drm/drm_gem_ttm_helper.h
new file mode 100644
index 000000000000..662dcb8d4770
--- /dev/null
+++ b/include/drm/drm_gem_ttm_helper.h
@@ -0,0 +1,91 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+#ifndef DRM_GEM_TTM_HELPER_H
+#define DRM_GEM_TTM_HELPER_H
+
+#include <drm/drm_gem.h>
+#include <drm/ttm/ttm_bo_api.h>
+#include <drm/ttm/ttm_placement.h>
+#include <linux/kernel.h> /* for container_of() */
+
+struct filp;
+
+/*
+ * Buffer-object helpers
+ */
+
+/**
+ * struct drm_gem_ttm_object - GEM object backed by TTM-managed memory
+ *
+ * The type struct drm_gem_ttm_object represents a GEM object that is
+ * backed by TTM-managed memory. It can be used for simple frambuffer
+ * devices with dedicated memory. Current supported memory regions are
+ * TTM_PL_SYSTEM and TTM_PL_VRAM. TTM_PL_TT could probably be added if
+ * necessary.
+ */
+struct drm_gem_ttm_object {
+	/**
+	 * GEM object
+	 */
+        struct drm_gem_object gem;
+
+	/**
+	 * TTM buffer object
+	 */
+        struct ttm_buffer_object bo;
+
+	/**
+	 * Mapping information for bo
+	 */
+        struct ttm_bo_kmap_obj kmap;
+
+	/* Supported placements are VRAM and SYSTEM */
+        struct ttm_placement placement;
+        struct ttm_place placements[3];
+
+        int pin_count;
+};
+
+/**
+ * Returns the container of type struct drm_gem_ttm_object
+ * for field bo.
+ * @bo:		the TTM buffer object
+ * Returns:	The containing GEM-TTM object
+ */
+static inline struct drm_gem_ttm_object* drm_gem_ttm_of_bo(
+	struct ttm_buffer_object *bo)
+{
+	return container_of(bo, struct drm_gem_ttm_object, bo);
+}
+
+/**
+ * Returns the container of type struct drm_gem_ttm_object
+ * for field gem.
+ * @gem:	the GEM object
+ * Returns:	The containing GEM-TTM object
+ */
+static inline struct drm_gem_ttm_object* drm_gem_ttm_of_gem(
+	struct drm_gem_object *gem)
+{
+	return container_of(gem, struct drm_gem_ttm_object, gem);
+}
+
+struct drm_gem_ttm_object* drm_gem_ttm_create(struct drm_device *dev,
+					      struct ttm_bo_device* bdev,
+					      unsigned long size,
+					      uint32_t pg_align,
+					      bool interruptible);
+void drm_gem_ttm_put(struct drm_gem_ttm_object *gbo);
+int drm_gem_ttm_reserve(struct drm_gem_ttm_object *gbo, bool no_wait);
+void drm_gem_ttm_unreserve(struct drm_gem_ttm_object *gbo);
+u64 drm_gem_ttm_mmap_offset(struct drm_gem_ttm_object *gbo);
+s64 drm_gem_ttm_vram_offset(struct drm_gem_ttm_object *gbo);
+int drm_gem_ttm_pin(struct drm_gem_ttm_object *gbo, u32 pl_flag);
+int drm_gem_ttm_unpin(struct drm_gem_ttm_object *gbo);
+int drm_gem_ttm_push_to_system(struct drm_gem_ttm_object *gbo);
+void* drm_gem_ttm_kmap(struct drm_gem_ttm_object *gbo, bool map);
+void drm_gem_ttm_kunmap(struct drm_gem_ttm_object *gbo);
+
+bool drm_is_gem_ttm(struct ttm_buffer_object *bo);
+
+#endif
-- 
2.21.0

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

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

* [PATCH 02/15] drm: Add |struct drm_gem_ttm_object| callbacks for |struct ttm_bo_driver|
  2019-04-08  9:21 [PATCH 00/15] Share TTM code among framebuffer drivers Thomas Zimmermann
  2019-04-08  9:21 ` [PATCH 01/15] drm: Add |struct drm_gem_ttm_object| and helpers Thomas Zimmermann
@ 2019-04-08  9:21 ` Thomas Zimmermann
  2019-04-08  9:21 ` [PATCH 03/15] drm: Add |struct drm_gem_ttm_object| callbacks for |struct drm_driver| Thomas Zimmermann
                   ` (14 subsequent siblings)
  16 siblings, 0 replies; 43+ messages in thread
From: Thomas Zimmermann @ 2019-04-08  9:21 UTC (permalink / raw)
  To: daniel, airlied, kraxel, christian.koenig, ray.huang,
	Jerry.Zhang, hdegoede, z.liuxinliang, zourongrong,
	kong.kongxinwei, puck.chen
  Cc: Thomas Zimmermann, dri-devel, virtualization

The provided helpers can be used for the respective callback functions
in |struct ttm_bo_driver|.

Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
---
 drivers/gpu/drm/drm_gem_ttm_helper.c | 39 ++++++++++++++++++++++++++++
 include/drm/drm_gem_ttm_helper.h     | 10 +++++++
 2 files changed, 49 insertions(+)

diff --git a/drivers/gpu/drm/drm_gem_ttm_helper.c b/drivers/gpu/drm/drm_gem_ttm_helper.c
index d52d3c439917..af3487137822 100644
--- a/drivers/gpu/drm/drm_gem_ttm_helper.c
+++ b/drivers/gpu/drm/drm_gem_ttm_helper.c
@@ -365,3 +365,42 @@ bool drm_is_gem_ttm(struct ttm_buffer_object *bo)
 	return (bo->destroy == ttm_buffer_object_destroy);
 }
 EXPORT_SYMBOL(drm_is_gem_ttm);
+
+/*
+ * Helpers for struct ttm_bo_driver
+ */
+
+/**
+ * drm_gem_ttm_bo_driver_evict_flags - \
+	Implements struct ttm_bo_driver.evict_flags
+ */
+void drm_gem_ttm_bo_driver_evict_flags(struct ttm_buffer_object *bo,
+				       struct ttm_placement *pl)
+{
+	struct drm_gem_ttm_object *gbo;
+
+	/* TODO: This test used to be performed by drivers, but can
+	 * this actually happen? If so, should we put the check into
+	 * drm_gem_ttm_of_gem()? */
+	if (!drm_is_gem_ttm(bo))
+		return;
+
+	gbo = drm_gem_ttm_of_bo(bo);
+	drm_gem_ttm_placement(gbo, TTM_PL_FLAG_SYSTEM);
+	*pl = gbo->placement;
+}
+EXPORT_SYMBOL(drm_gem_ttm_bo_driver_evict_flags);
+
+/**
+ * drm_gem_ttm_bo_driver_verify_access - \
+	Implements struct ttm_bo_driver.verify_access
+ */
+int drm_gem_ttm_bo_driver_verify_access(struct ttm_buffer_object *bo,
+					struct file *filp)
+{
+	struct drm_gem_ttm_object *gbo = drm_gem_ttm_of_bo(bo);
+
+	return drm_vma_node_verify_access(&gbo->gem.vma_node,
+					  filp->private_data);
+}
+EXPORT_SYMBOL(drm_gem_ttm_bo_driver_verify_access);
diff --git a/include/drm/drm_gem_ttm_helper.h b/include/drm/drm_gem_ttm_helper.h
index 662dcb8d4770..c1c4bd757f4b 100644
--- a/include/drm/drm_gem_ttm_helper.h
+++ b/include/drm/drm_gem_ttm_helper.h
@@ -88,4 +88,14 @@ void drm_gem_ttm_kunmap(struct drm_gem_ttm_object *gbo);
 
 bool drm_is_gem_ttm(struct ttm_buffer_object *bo);
 
+/*
+ * Helpers for struct ttm_bo_driver
+ */
+
+void drm_gem_ttm_bo_driver_evict_flags(struct ttm_buffer_object *bo,
+				       struct ttm_placement *pl);
+
+int drm_gem_ttm_bo_driver_verify_access(struct ttm_buffer_object *bo,
+					struct file *filp);
+
 #endif
-- 
2.21.0

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

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

* [PATCH 03/15] drm: Add |struct drm_gem_ttm_object| callbacks for |struct drm_driver|
  2019-04-08  9:21 [PATCH 00/15] Share TTM code among framebuffer drivers Thomas Zimmermann
  2019-04-08  9:21 ` [PATCH 01/15] drm: Add |struct drm_gem_ttm_object| and helpers Thomas Zimmermann
  2019-04-08  9:21 ` [PATCH 02/15] drm: Add |struct drm_gem_ttm_object| callbacks for |struct ttm_bo_driver| Thomas Zimmermann
@ 2019-04-08  9:21 ` Thomas Zimmermann
  2019-04-08  9:21 ` [PATCH 04/15] drm: Add drm_gem_ttm_fill_create_dumb() to create dumb buffers Thomas Zimmermann
                   ` (13 subsequent siblings)
  16 siblings, 0 replies; 43+ messages in thread
From: Thomas Zimmermann @ 2019-04-08  9:21 UTC (permalink / raw)
  To: daniel, airlied, kraxel, christian.koenig, ray.huang,
	Jerry.Zhang, hdegoede, z.liuxinliang, zourongrong,
	kong.kongxinwei, puck.chen
  Cc: Thomas Zimmermann, dri-devel, virtualization

The provided helpers can be used for the respective callback functions
in |struct drm_driver|.

Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
---
 drivers/gpu/drm/drm_gem_ttm_helper.c | 39 ++++++++++++++++++++++++++++
 include/drm/drm_gem_ttm_helper.h     | 10 +++++++
 2 files changed, 49 insertions(+)

diff --git a/drivers/gpu/drm/drm_gem_ttm_helper.c b/drivers/gpu/drm/drm_gem_ttm_helper.c
index af3487137822..d4950517e357 100644
--- a/drivers/gpu/drm/drm_gem_ttm_helper.c
+++ b/drivers/gpu/drm/drm_gem_ttm_helper.c
@@ -404,3 +404,42 @@ int drm_gem_ttm_bo_driver_verify_access(struct ttm_buffer_object *bo,
 					  filp->private_data);
 }
 EXPORT_SYMBOL(drm_gem_ttm_bo_driver_verify_access);
+
+/*
+ * Helpers for struct drm_driver
+ */
+
+/**
+ * drm_gem_ttm_driver_gem_free_object_unlocked() - \
+	Implements struct drm_driver.gem_free_object_unlocked
+ */
+void drm_gem_ttm_driver_gem_free_object_unlocked(struct drm_gem_object *gem)
+{
+	struct drm_gem_ttm_object *gbo = drm_gem_ttm_of_gem(gem);
+	drm_gem_ttm_put(gbo);
+}
+EXPORT_SYMBOL(drm_gem_ttm_driver_gem_free_object_unlocked);
+
+/**
+ * drm_gem_ttm_driver_dumb_mmap_offset() - \
+	Implements struct drm_driver.dumb_mmap_offset
+ */
+int drm_gem_ttm_driver_dumb_mmap_offset(struct drm_file *file,
+					struct drm_device *dev,
+		     			uint32_t handle, uint64_t *offset)
+{
+	struct drm_gem_object *gem;
+	struct drm_gem_ttm_object *gbo;
+
+	gem = drm_gem_object_lookup(file, handle);
+	if (!gem)
+		return -ENOENT;
+
+	gbo = drm_gem_ttm_of_gem(gem);
+	*offset = drm_gem_ttm_mmap_offset(gbo);
+
+	drm_gem_object_put_unlocked(gem);
+
+	return 0;
+}
+EXPORT_SYMBOL(drm_gem_ttm_driver_dumb_mmap_offset);
diff --git a/include/drm/drm_gem_ttm_helper.h b/include/drm/drm_gem_ttm_helper.h
index c1c4bd757f4b..edc2093588ff 100644
--- a/include/drm/drm_gem_ttm_helper.h
+++ b/include/drm/drm_gem_ttm_helper.h
@@ -98,4 +98,14 @@ void drm_gem_ttm_bo_driver_evict_flags(struct ttm_buffer_object *bo,
 int drm_gem_ttm_bo_driver_verify_access(struct ttm_buffer_object *bo,
 					struct file *filp);
 
+/*
+ * Helpers for struct drm_driver
+ */
+
+void drm_gem_ttm_driver_gem_free_object_unlocked(struct drm_gem_object *gem);
+
+int drm_gem_ttm_driver_dumb_mmap_offset(struct drm_file *file,
+					struct drm_device *dev,
+		     			uint32_t handle, uint64_t *offset);
+
 #endif
-- 
2.21.0

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

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

* [PATCH 04/15] drm: Add drm_gem_ttm_fill_create_dumb() to create dumb buffers
  2019-04-08  9:21 [PATCH 00/15] Share TTM code among framebuffer drivers Thomas Zimmermann
                   ` (2 preceding siblings ...)
  2019-04-08  9:21 ` [PATCH 03/15] drm: Add |struct drm_gem_ttm_object| callbacks for |struct drm_driver| Thomas Zimmermann
@ 2019-04-08  9:21 ` Thomas Zimmermann
  2019-04-08  9:21 ` [PATCH 05/15] drm: Add Simple TTM, a memory manager for dedicated VRAM Thomas Zimmermann
                   ` (12 subsequent siblings)
  16 siblings, 0 replies; 43+ messages in thread
From: Thomas Zimmermann @ 2019-04-08  9:21 UTC (permalink / raw)
  To: daniel, airlied, kraxel, christian.koenig, ray.huang,
	Jerry.Zhang, hdegoede, z.liuxinliang, zourongrong,
	kong.kongxinwei, puck.chen
  Cc: Thomas Zimmermann, dri-devel, virtualization

The helper function drm_gem_ttm_fill_create_dumb() implements most of
struct drm_driver.dumb_create() for GEM TTM buffer objects. It's not a
full implemenation of the callback, as several driver-specific parameters
are still required.

Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
---
 drivers/gpu/drm/drm_gem_ttm_helper.c | 62 ++++++++++++++++++++++++++++
 include/drm/drm_gem_ttm_helper.h     |  8 ++++
 2 files changed, 70 insertions(+)

diff --git a/drivers/gpu/drm/drm_gem_ttm_helper.c b/drivers/gpu/drm/drm_gem_ttm_helper.c
index d4950517e357..a2306e27db13 100644
--- a/drivers/gpu/drm/drm_gem_ttm_helper.c
+++ b/drivers/gpu/drm/drm_gem_ttm_helper.c
@@ -1,6 +1,7 @@
 /* SPDX-License-Identifier: GPL-2.0-or-later */
 
 #include <drm/drm_gem_ttm_helper.h>
+#include <drm/drm_mode.h>
 #include <drm/ttm/ttm_page_alloc.h>
 
 /**
@@ -366,6 +367,67 @@ bool drm_is_gem_ttm(struct ttm_buffer_object *bo)
 }
 EXPORT_SYMBOL(drm_is_gem_ttm);
 
+/**
+ * drm_gem_ttm_fill_create_dumb() - \
+	Helper for implementing struct drm_driver.dumb_create
+ * @file:		the DRM file
+ * @dev:		the DRM device
+ * @bdev:		the TTM BO device managing the buffer object
+ * @pg_align:		the buffer's alignment in multiples of the page size
+ * @interruptible:	sleep interruptible if waiting for memory
+ * @args:		the arguments as provided to \
+				struct drm_driver.dumb_create
+ *
+ * This helper function fills struct drm_mode_create_dumb, which is used
+ * by struct drm_driver.dumb_create. Implementations of this interface
+ * should forwards their arguments to this helper; plus the driver-specific
+ * parameters.
+ *
+ * Returns:
+ * 0 on success, or
+ * a negative error code otherwise.
+ */
+int drm_gem_ttm_fill_create_dumb(struct drm_file *file,
+				 struct drm_device *dev,
+				 struct ttm_bo_device *bdev,
+				 uint32_t pg_align,
+				 bool interruptible,
+				 struct drm_mode_create_dumb *args)
+{
+	size_t pitch, size;
+	struct drm_gem_ttm_object *gbo;
+	int ret;
+	u32 handle;
+
+	pitch = args->width * ((args->bpp + 7) / 8);
+	size = pitch * args->height;
+
+	size = roundup(size, PAGE_SIZE);
+	if (!size)
+		return -EINVAL;
+
+	gbo = drm_gem_ttm_create(dev, bdev, size, pg_align, interruptible);
+	if (IS_ERR(gbo))
+		return PTR_ERR(gbo);
+
+	ret = drm_gem_handle_create(file, &gbo->gem, &handle);
+	if (ret)
+		goto err_drm_gem_object_put_unlocked;
+
+	drm_gem_object_put_unlocked(&gbo->gem);
+
+	args->pitch = pitch;
+	args->size = size;
+	args->handle = handle;
+
+	return 0;
+
+err_drm_gem_object_put_unlocked:
+	drm_gem_object_put_unlocked(&gbo->gem);
+	return ret;
+}
+EXPORT_SYMBOL(drm_gem_ttm_fill_create_dumb);
+
 /*
  * Helpers for struct ttm_bo_driver
  */
diff --git a/include/drm/drm_gem_ttm_helper.h b/include/drm/drm_gem_ttm_helper.h
index edc2093588ff..3918dfca1d58 100644
--- a/include/drm/drm_gem_ttm_helper.h
+++ b/include/drm/drm_gem_ttm_helper.h
@@ -8,6 +8,7 @@
 #include <drm/ttm/ttm_placement.h>
 #include <linux/kernel.h> /* for container_of() */
 
+struct drm_mode_create_dumb;
 struct filp;
 
 /*
@@ -88,6 +89,13 @@ void drm_gem_ttm_kunmap(struct drm_gem_ttm_object *gbo);
 
 bool drm_is_gem_ttm(struct ttm_buffer_object *bo);
 
+int drm_gem_ttm_fill_create_dumb(struct drm_file *file,
+				 struct drm_device *dev,
+				 struct ttm_bo_device *bdev,
+				 uint32_t pg_align,
+				 bool interruptible,
+				 struct drm_mode_create_dumb *args);
+
 /*
  * Helpers for struct ttm_bo_driver
  */
-- 
2.21.0

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

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

* [PATCH 05/15] drm: Add Simple TTM, a memory manager for dedicated VRAM
  2019-04-08  9:21 [PATCH 00/15] Share TTM code among framebuffer drivers Thomas Zimmermann
                   ` (3 preceding siblings ...)
  2019-04-08  9:21 ` [PATCH 04/15] drm: Add drm_gem_ttm_fill_create_dumb() to create dumb buffers Thomas Zimmermann
@ 2019-04-08  9:21 ` Thomas Zimmermann
  2019-04-08  9:21 ` [PATCH 06/15] drm/ast: Convert AST driver to |struct drm_gem_ttm_object| Thomas Zimmermann
                   ` (11 subsequent siblings)
  16 siblings, 0 replies; 43+ messages in thread
From: Thomas Zimmermann @ 2019-04-08  9:21 UTC (permalink / raw)
  To: daniel, airlied, kraxel, christian.koenig, ray.huang,
	Jerry.Zhang, hdegoede, z.liuxinliang, zourongrong,
	kong.kongxinwei, puck.chen
  Cc: Thomas Zimmermann, dri-devel, virtualization

The Simple TTM memory manager is a helper library that manages dedicated
video memory of simple framebuffer devices. The implementation is based on
the respective code from ast, bochs, and mgag200. These drivers share the
exact same implementation execept for type names.

Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
---
 Documentation/gpu/drm-mm.rst            |  11 ++
 drivers/gpu/drm/Kconfig                 |   7 +
 drivers/gpu/drm/Makefile                |   1 +
 drivers/gpu/drm/drm_simple_ttm_helper.c | 191 ++++++++++++++++++++++++
 include/drm/drm_simple_ttm_helper.h     |  74 +++++++++
 5 files changed, 284 insertions(+)
 create mode 100644 drivers/gpu/drm/drm_simple_ttm_helper.c
 create mode 100644 include/drm/drm_simple_ttm_helper.h

diff --git a/Documentation/gpu/drm-mm.rst b/Documentation/gpu/drm-mm.rst
index 596e5f15f459..94e8afaa55d2 100644
--- a/Documentation/gpu/drm-mm.rst
+++ b/Documentation/gpu/drm-mm.rst
@@ -79,6 +79,17 @@ count for the TTM, which will call your initialization function.
 
 See the radeon_ttm.c file for an example of usage.
 
+Simple TTM Helper Functions Reference
+-------------------------------------
+
+.. kernel-doc:: drivers/gpu/drm/drm_simple_ttm_helper.c
+   :doc: overview
+
+.. kernel-doc:: include/drm/drm_simple_ttm_helper.h
+   :internal:
+
+.. kernel-doc:: drivers/gpu/drm/drm_simple_ttm_helper.c
+   :export:
 
 The Graphics Execution Manager (GEM)
 ====================================
diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig
index 684bd327eb07..fb84ab61fee3 100644
--- a/drivers/gpu/drm/Kconfig
+++ b/drivers/gpu/drm/Kconfig
@@ -166,6 +166,13 @@ config DRM_TTM_HELPER
 	help
 	  Helpers for TTM-based memory management
 
+config DRM_SIMPLE_TTM_HELPER
+	tristate
+	depends on DRM && DRM_TTM
+	select DRM_TTM_HELPER
+	help
+	  Choose this if you need the Simple TTM helper functions
+
 config DRM_GEM_CMA_HELPER
 	bool
 	depends on DRM
diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile
index acd0f3e4f079..54b128ba0b8e 100644
--- a/drivers/gpu/drm/Makefile
+++ b/drivers/gpu/drm/Makefile
@@ -35,6 +35,7 @@ drm-$(CONFIG_DRM_LOAD_EDID_FIRMWARE) += drm_edid_load.o
 
 drm_ttm_helper-y := drm_ttm_helper_common.o
 drm_ttm_helper-$(CONFIG_DRM_GEM_TTM_HELPER) += drm_gem_ttm_helper.o
+drm_ttm_helper-$(CONFIG_DRM_SIMPLE_TTM_HELPER) += drm_simple_ttm_helper.o
 obj-$(CONFIG_DRM_TTM_HELPER) += drm_ttm_helper.o
 
 drm_kms_helper-y := drm_crtc_helper.o drm_dp_helper.o drm_dsc.o drm_probe_helper.o \
diff --git a/drivers/gpu/drm/drm_simple_ttm_helper.c b/drivers/gpu/drm/drm_simple_ttm_helper.c
new file mode 100644
index 000000000000..52471f150f63
--- /dev/null
+++ b/drivers/gpu/drm/drm_simple_ttm_helper.c
@@ -0,0 +1,191 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+#include <drm/drm_simple_ttm_helper.h>
+#include <drm/drmP.h>
+#include <drm/ttm/ttm_page_alloc.h>
+
+/**
+ * DOC: overview
+ *
+ * Simple TTM implements a TTM memory manager for framebuffer devices with
+ * dedicated video memory. It currently support memory regions TTM_PL_VRAM
+ * and TTM_PL_SYSTEM. Support for TTM_PL_TT could probably be added if
+ * necessary.
+ */
+
+/*
+ * TTM TT
+ */
+
+static void backend_func_destroy(struct ttm_tt *tt)
+{
+	ttm_tt_fini(tt);
+	kfree(tt);
+}
+
+static struct ttm_backend_func backend_func = {
+	.destroy = backend_func_destroy
+};
+
+/*
+ * TTM BO device
+ */
+
+static struct ttm_tt *bo_driver_ttm_tt_create(struct ttm_buffer_object *bo,
+					      uint32_t page_flags)
+{
+	struct ttm_tt *tt;
+	int ret;
+
+	tt = kzalloc(sizeof(*tt), GFP_KERNEL);
+	if (!tt)
+		return NULL;
+
+	tt->func = &backend_func;
+
+	ret = ttm_tt_init(tt, bo, page_flags);
+	if (ret < 0)
+		goto err_ttm_tt_init;
+
+	return tt;
+
+err_ttm_tt_init:
+	kfree(tt);
+	return NULL;
+}
+
+static int bo_driver_init_mem_type(struct ttm_bo_device *bdev, uint32_t type,
+				   struct ttm_mem_type_manager *man)
+{
+	switch (type) {
+	case TTM_PL_SYSTEM:
+		man->flags = TTM_MEMTYPE_FLAG_MAPPABLE;
+		man->available_caching = TTM_PL_MASK_CACHING;
+		man->default_caching = TTM_PL_FLAG_CACHED;
+		break;
+	case TTM_PL_VRAM:
+		man->func = &ttm_bo_manager_func;
+		man->flags = TTM_MEMTYPE_FLAG_FIXED |
+			     TTM_MEMTYPE_FLAG_MAPPABLE;
+		man->available_caching = TTM_PL_FLAG_UNCACHED |
+					 TTM_PL_FLAG_WC;
+		man->default_caching = TTM_PL_FLAG_WC;
+		break;
+	default:
+		return -EINVAL;
+	}
+	return 0;
+}
+
+static void bo_driver_evict_flags(struct ttm_buffer_object *bo, struct ttm_placement *placement)
+{
+	struct drm_simple_ttm *ttm = drm_simple_ttm_of_bdev(bo->bdev);
+
+	if (ttm->funcs && ttm->funcs->evict_flags)
+		ttm->funcs->evict_flags(bo, placement);
+}
+
+static int bo_driver_verify_access(struct ttm_buffer_object *bo, struct file *filp)
+{
+	struct drm_simple_ttm *ttm = drm_simple_ttm_of_bdev(bo->bdev);
+
+	if (!ttm->funcs || !ttm->funcs->verify_access)
+		return 0;
+	return ttm->funcs->verify_access(bo, filp);
+}
+
+static int bo_driver_io_mem_reserve(struct ttm_bo_device *bdev,
+				    struct ttm_mem_reg *mem)
+{
+	struct ttm_mem_type_manager *man = bdev->man + mem->mem_type;
+	struct drm_simple_ttm *ttm = drm_simple_ttm_of_bdev(bdev);
+
+	if (!(man->flags & TTM_MEMTYPE_FLAG_MAPPABLE))
+		return -EINVAL;
+
+	mem->bus.addr = NULL;
+	mem->bus.size = mem->num_pages << PAGE_SHIFT;
+
+	switch (mem->mem_type) {
+	case TTM_PL_SYSTEM:	/* nothing to do */
+		mem->bus.offset = 0;
+		mem->bus.base = 0;
+		mem->bus.is_iomem = false;
+		break;
+	case TTM_PL_VRAM:
+		mem->bus.offset = mem->start << PAGE_SHIFT;
+		mem->bus.base = ttm->vram_base;
+		mem->bus.is_iomem = true;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static void bo_driver_io_mem_free(struct ttm_bo_device *bdev,
+				  struct ttm_mem_reg *mem)
+{ }
+
+static struct ttm_bo_driver bo_driver = {
+	.ttm_tt_create = bo_driver_ttm_tt_create,
+	.ttm_tt_populate = ttm_pool_populate,
+	.ttm_tt_unpopulate = ttm_pool_unpopulate,
+	.init_mem_type = bo_driver_init_mem_type,
+	.eviction_valuable = ttm_bo_eviction_valuable,
+	.evict_flags = bo_driver_evict_flags,
+	.verify_access = bo_driver_verify_access,
+	.io_mem_reserve = bo_driver_io_mem_reserve,
+	.io_mem_free = bo_driver_io_mem_free,
+};
+
+/*
+ * struct drm_simple_ttm
+ */
+
+/**
+ * drm_simple_ttm_init() - Initialize an instance of Simple TTM.
+ * @ttm:	the Simple TTM instance to initialize
+ * @dev:	the DRM device
+ * @vram_base:	the base address of the video memory
+ * @vram_size:	the size of the video memory in bytes
+ * @funcs:	callback functions for buffer objects
+ *
+ * Returns:
+ * 0 on success, or
+ * a negative error code otherwise.
+ */
+int drm_simple_ttm_init(struct drm_simple_ttm *ttm, struct drm_device *dev,
+			u64 vram_base, unsigned long vram_size,
+			const struct drm_simple_ttm_funcs* funcs)
+{
+	int ret;
+
+	ttm->vram_base = vram_base;
+	ttm->vram_size = vram_size;
+	ttm->funcs = funcs;
+
+	ret = ttm_bo_device_init(&ttm->bdev, &bo_driver,
+				 dev->anon_inode->i_mapping,
+				 true);
+	if (ret)
+		return ret;
+
+	ret = ttm_bo_init_mm(&ttm->bdev, TTM_PL_VRAM, vram_size >> PAGE_SHIFT);
+	if (ret)
+		return ret;
+
+	return 0;
+}
+EXPORT_SYMBOL(drm_simple_ttm_init);
+
+/**
+ * drm_simple_ttm_cleanup() - Cleans up an initialized instance of Simple TTM.
+ * @ttm:	the Simple TTM instance to clean up
+ */
+void drm_simple_ttm_cleanup(struct drm_simple_ttm *ttm)
+{
+	ttm_bo_device_release(&ttm->bdev);
+}
+EXPORT_SYMBOL(drm_simple_ttm_cleanup);
diff --git a/include/drm/drm_simple_ttm_helper.h b/include/drm/drm_simple_ttm_helper.h
new file mode 100644
index 000000000000..eaf507dfc7fe
--- /dev/null
+++ b/include/drm/drm_simple_ttm_helper.h
@@ -0,0 +1,74 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+#ifndef DRM_SIMPLE_TTM_HELPER_H
+#define DRM_SIMPLE_TTM_HELPER_H
+
+#include <drm/ttm/ttm_bo_driver.h>
+
+struct drm_device;
+
+/**
+ * struct drm_simple_ttm_funcs - Callback functions for struct drm_simple_ttm
+ *
+ * These callback function integrate Simple TTM with TTM buffer objects. New
+ * functions can be added if necessary.
+ */
+struct drm_simple_ttm_funcs {
+	/**
+	 * Provides an implementation for struct ttm_bo_driver.evict_flags.
+	 */
+        void (*evict_flags)(struct ttm_buffer_object *bo,
+                            struct ttm_placement *placement);
+
+	/**
+	 * Provides an implementation for struct ttm_bo_driver.verify_access.
+	 */
+	int (*verify_access)(struct ttm_buffer_object *bo, struct file *filp);
+};
+
+/**
+ * struct drm_simple_ttm - An instance of Simple TTM
+ *
+ * The fields struct drm_simple_ttm.vram_base and
+ * struct drm_simple_ttm.vrm_size are managed by Simple TTM,
+ * but available for public read access. Use the field
+ * struct drm_simple_ttm.bdev to access the TTM BO device.
+ */
+struct drm_simple_ttm {
+	/**
+	 * Base address of the managed video memory
+	 */
+	u64 vram_base;
+
+	/**
+	 * Size of the managed video memory in bytes
+	 */
+	unsigned long vram_size;
+
+	/**
+	 * The TTM BO device.
+	 */
+	struct ttm_bo_device bdev;
+
+	/* TTM BO functions */
+	const struct drm_simple_ttm_funcs *funcs;
+};
+
+/**
+ * Returns the container of type struct ttm_bo_device
+ * for field bdev.
+ * @bdev:	the TTM BO device
+ * Returns:	The containing Simple TTM instance
+ */
+static inline struct drm_simple_ttm* drm_simple_ttm_of_bdev(
+	struct ttm_bo_device *bdev)
+{
+	return container_of(bdev, struct drm_simple_ttm, bdev);
+}
+
+int drm_simple_ttm_init(struct drm_simple_ttm *ttm, struct drm_device *dev,
+			u64 vram_base, unsigned long vram_size,
+			const struct drm_simple_ttm_funcs* funcs);
+void drm_simple_ttm_cleanup(struct drm_simple_ttm *ttm);
+
+#endif
-- 
2.21.0

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

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

* [PATCH 06/15] drm/ast: Convert AST driver to |struct drm_gem_ttm_object|
  2019-04-08  9:21 [PATCH 00/15] Share TTM code among framebuffer drivers Thomas Zimmermann
                   ` (4 preceding siblings ...)
  2019-04-08  9:21 ` [PATCH 05/15] drm: Add Simple TTM, a memory manager for dedicated VRAM Thomas Zimmermann
@ 2019-04-08  9:21 ` Thomas Zimmermann
  2019-04-08  9:21 ` [PATCH 07/15] drm/ast: Convert AST driver to Simple TTM Thomas Zimmermann
                   ` (10 subsequent siblings)
  16 siblings, 0 replies; 43+ messages in thread
From: Thomas Zimmermann @ 2019-04-08  9:21 UTC (permalink / raw)
  To: daniel, airlied, kraxel, christian.koenig, ray.huang,
	Jerry.Zhang, hdegoede, z.liuxinliang, zourongrong,
	kong.kongxinwei, puck.chen
  Cc: Thomas Zimmermann, dri-devel, virtualization

Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
---
 drivers/gpu/drm/ast/Kconfig    |   2 +-
 drivers/gpu/drm/ast/ast_drv.c  |   4 +-
 drivers/gpu/drm/ast/ast_drv.h  |  52 +---------
 drivers/gpu/drm/ast/ast_fb.c   |  18 ++--
 drivers/gpu/drm/ast/ast_main.c |  74 ++------------
 drivers/gpu/drm/ast/ast_mode.c |  78 +++++++++------
 drivers/gpu/drm/ast/ast_ttm.c  | 172 +--------------------------------
 7 files changed, 70 insertions(+), 330 deletions(-)

diff --git a/drivers/gpu/drm/ast/Kconfig b/drivers/gpu/drm/ast/Kconfig
index 9647e1f07088..8d90c5b231c7 100644
--- a/drivers/gpu/drm/ast/Kconfig
+++ b/drivers/gpu/drm/ast/Kconfig
@@ -3,7 +3,7 @@ config DRM_AST
 	depends on DRM && PCI && MMU
 	select DRM_TTM
 	select DRM_KMS_HELPER
-	select DRM_TTM
+	select DRM_GEM_TTM_HELPER
 	help
 	 Say yes for experimental AST GPU driver. Do not enable
 	 this driver without having a working -modesetting,
diff --git a/drivers/gpu/drm/ast/ast_drv.c b/drivers/gpu/drm/ast/ast_drv.c
index 3871b39d4dea..b820eb1c8312 100644
--- a/drivers/gpu/drm/ast/ast_drv.c
+++ b/drivers/gpu/drm/ast/ast_drv.c
@@ -228,9 +228,9 @@ static struct drm_driver driver = {
 	.minor = DRIVER_MINOR,
 	.patchlevel = DRIVER_PATCHLEVEL,
 
-	.gem_free_object_unlocked = ast_gem_free_object,
+	.gem_free_object_unlocked = drm_gem_ttm_driver_gem_free_object_unlocked,
 	.dumb_create = ast_dumb_create,
-	.dumb_map_offset = ast_dumb_mmap_offset,
+	.dumb_map_offset = drm_gem_ttm_driver_dumb_mmap_offset,
 
 };
 
diff --git a/drivers/gpu/drm/ast/ast_drv.h b/drivers/gpu/drm/ast/ast_drv.h
index 1cf0c75e411d..939acac4cc4a 100644
--- a/drivers/gpu/drm/ast/ast_drv.h
+++ b/drivers/gpu/drm/ast/ast_drv.h
@@ -38,6 +38,7 @@
 #include <drm/ttm/ttm_module.h>
 
 #include <drm/drm_gem.h>
+#include <drm/drm_gem_ttm_helper.h>
 
 #include <linux/i2c.h>
 #include <linux/i2c-algo-bit.h>
@@ -321,25 +322,6 @@ void ast_fbdev_fini(struct drm_device *dev);
 void ast_fbdev_set_suspend(struct drm_device *dev, int state);
 void ast_fbdev_set_base(struct ast_private *ast, unsigned long gpu_addr);
 
-struct ast_bo {
-	struct ttm_buffer_object bo;
-	struct ttm_placement placement;
-	struct ttm_bo_kmap_obj kmap;
-	struct drm_gem_object gem;
-	struct ttm_place placements[3];
-	int pin_count;
-};
-#define gem_to_ast_bo(gobj) container_of((gobj), struct ast_bo, gem)
-
-static inline struct ast_bo *
-ast_bo(struct ttm_buffer_object *bo)
-{
-	return container_of(bo, struct ast_bo, bo);
-}
-
-
-#define to_ast_obj(x) container_of(x, struct ast_gem_object, base)
-
 #define AST_MM_ALIGN_SHIFT 4
 #define AST_MM_ALIGN_MASK ((1 << AST_MM_ALIGN_SHIFT) - 1)
 
@@ -347,45 +329,13 @@ extern int ast_dumb_create(struct drm_file *file,
 			   struct drm_device *dev,
 			   struct drm_mode_create_dumb *args);
 
-extern void ast_gem_free_object(struct drm_gem_object *obj);
-extern int ast_dumb_mmap_offset(struct drm_file *file,
-				struct drm_device *dev,
-				uint32_t handle,
-				uint64_t *offset);
-
 int ast_mm_init(struct ast_private *ast);
 void ast_mm_fini(struct ast_private *ast);
 
-int ast_bo_create(struct drm_device *dev, int size, int align,
-		  uint32_t flags, struct ast_bo **pastbo);
-
 int ast_gem_create(struct drm_device *dev,
 		   u32 size, bool iskernel,
 		   struct drm_gem_object **obj);
 
-int ast_bo_pin(struct ast_bo *bo, u32 pl_flag, u64 *gpu_addr);
-int ast_bo_unpin(struct ast_bo *bo);
-
-static inline int ast_bo_reserve(struct ast_bo *bo, bool no_wait)
-{
-	int ret;
-
-	ret = ttm_bo_reserve(&bo->bo, true, no_wait, NULL);
-	if (ret) {
-		if (ret != -ERESTARTSYS && ret != -EBUSY)
-			DRM_ERROR("reserve failed %p\n", bo);
-		return ret;
-	}
-	return 0;
-}
-
-static inline void ast_bo_unreserve(struct ast_bo *bo)
-{
-	ttm_bo_unreserve(&bo->bo);
-}
-
-void ast_ttm_placement(struct ast_bo *bo, int domain);
-int ast_bo_push_sysram(struct ast_bo *bo);
 int ast_mmap(struct file *filp, struct vm_area_struct *vma);
 
 /* ast post */
diff --git a/drivers/gpu/drm/ast/ast_fb.c b/drivers/gpu/drm/ast/ast_fb.c
index e718d0f60d6b..097501451cb2 100644
--- a/drivers/gpu/drm/ast/ast_fb.c
+++ b/drivers/gpu/drm/ast/ast_fb.c
@@ -49,7 +49,7 @@ static void ast_dirty_update(struct ast_fbdev *afbdev,
 {
 	int i;
 	struct drm_gem_object *obj;
-	struct ast_bo *bo;
+	struct drm_gem_ttm_object *gbo;
 	int src_offset, dst_offset;
 	int bpp = afbdev->afb.base.format->cpp[0];
 	int ret = -EBUSY;
@@ -59,7 +59,7 @@ static void ast_dirty_update(struct ast_fbdev *afbdev,
 	unsigned long flags;
 
 	obj = afbdev->afb.obj;
-	bo = gem_to_ast_bo(obj);
+	gbo = drm_gem_ttm_of_gem(obj);
 
 	/*
 	 * try and reserve the BO, if we fail with busy
@@ -67,7 +67,7 @@ static void ast_dirty_update(struct ast_fbdev *afbdev,
 	 * store up the damage until later.
 	 */
 	if (drm_can_sleep())
-		ret = ast_bo_reserve(bo, true);
+		ret = drm_gem_ttm_reserve(gbo, true);
 	if (ret) {
 		if (ret != -EBUSY)
 			return;
@@ -101,11 +101,11 @@ static void ast_dirty_update(struct ast_fbdev *afbdev,
 	afbdev->x2 = afbdev->y2 = 0;
 	spin_unlock_irqrestore(&afbdev->dirty_lock, flags);
 
-	if (!bo->kmap.virtual) {
-		ret = ttm_bo_kmap(&bo->bo, 0, bo->bo.num_pages, &bo->kmap);
+	if (!gbo->kmap.virtual) {
+		ret = ttm_bo_kmap(&gbo->bo, 0, gbo->bo.num_pages, &gbo->kmap);
 		if (ret) {
 			DRM_ERROR("failed to kmap fb updates\n");
-			ast_bo_unreserve(bo);
+			drm_gem_ttm_unreserve(gbo);
 			return;
 		}
 		unmap = true;
@@ -113,13 +113,13 @@ static void ast_dirty_update(struct ast_fbdev *afbdev,
 	for (i = y; i <= y2; i++) {
 		/* assume equal stride for now */
 		src_offset = dst_offset = i * afbdev->afb.base.pitches[0] + (x * bpp);
-		memcpy_toio(bo->kmap.virtual + src_offset, afbdev->sysram + src_offset, (x2 - x + 1) * bpp);
+		memcpy_toio(gbo->kmap.virtual + src_offset, afbdev->sysram + src_offset, (x2 - x + 1) * bpp);
 
 	}
 	if (unmap)
-		ttm_bo_kunmap(&bo->kmap);
+		ttm_bo_kunmap(&gbo->kmap);
 
-	ast_bo_unreserve(bo);
+	drm_gem_ttm_unreserve(gbo);
 }
 
 static void ast_fillrect(struct fb_info *info,
diff --git a/drivers/gpu/drm/ast/ast_main.c b/drivers/gpu/drm/ast/ast_main.c
index 2854399856ba..3dd15d021ac5 100644
--- a/drivers/gpu/drm/ast/ast_main.c
+++ b/drivers/gpu/drm/ast/ast_main.c
@@ -593,7 +593,8 @@ int ast_gem_create(struct drm_device *dev,
 		   u32 size, bool iskernel,
 		   struct drm_gem_object **obj)
 {
-	struct ast_bo *astbo;
+	struct ast_private *ast = dev->dev_private;
+	struct drm_gem_ttm_object *gbo;
 	int ret;
 
 	*obj = NULL;
@@ -602,13 +603,14 @@ int ast_gem_create(struct drm_device *dev,
 	if (size == 0)
 		return -EINVAL;
 
-	ret = ast_bo_create(dev, size, 0, 0, &astbo);
-	if (ret) {
+	gbo = drm_gem_ttm_create(dev, &ast->ttm.bdev, size, 0, false);
+	if (IS_ERR(gbo)) {
+		ret = PTR_ERR(gbo);
 		if (ret != -ERESTARTSYS)
 			DRM_ERROR("failed to allocate GEM object\n");
 		return ret;
 	}
-	*obj = &astbo->gem;
+	*obj = &gbo->gem;
 	return 0;
 }
 
@@ -616,66 +618,8 @@ int ast_dumb_create(struct drm_file *file,
 		    struct drm_device *dev,
 		    struct drm_mode_create_dumb *args)
 {
-	int ret;
-	struct drm_gem_object *gobj;
-	u32 handle;
-
-	args->pitch = args->width * ((args->bpp + 7) / 8);
-	args->size = args->pitch * args->height;
-
-	ret = ast_gem_create(dev, args->size, false,
-			     &gobj);
-	if (ret)
-		return ret;
-
-	ret = drm_gem_handle_create(file, gobj, &handle);
-	drm_gem_object_put_unlocked(gobj);
-	if (ret)
-		return ret;
-
-	args->handle = handle;
-	return 0;
-}
-
-static void ast_bo_unref(struct ast_bo **bo)
-{
-	if ((*bo) == NULL)
-		return;
-	ttm_bo_put(&((*bo)->bo));
-	*bo = NULL;
-}
-
-void ast_gem_free_object(struct drm_gem_object *obj)
-{
-	struct ast_bo *ast_bo = gem_to_ast_bo(obj);
-
-	ast_bo_unref(&ast_bo);
-}
-
-
-static inline u64 ast_bo_mmap_offset(struct ast_bo *bo)
-{
-	return drm_vma_node_offset_addr(&bo->bo.vma_node);
-}
-int
-ast_dumb_mmap_offset(struct drm_file *file,
-		     struct drm_device *dev,
-		     uint32_t handle,
-		     uint64_t *offset)
-{
-	struct drm_gem_object *obj;
-	struct ast_bo *bo;
-
-	obj = drm_gem_object_lookup(file, handle);
-	if (obj == NULL)
-		return -ENOENT;
-
-	bo = gem_to_ast_bo(obj);
-	*offset = ast_bo_mmap_offset(bo);
-
-	drm_gem_object_put_unlocked(obj);
-
-	return 0;
+	struct ast_private *ast = dev->dev_private;
 
+	return drm_gem_ttm_fill_create_dumb(file, dev, &ast->ttm.bdev, 0,
+					    false, args);
 }
-
diff --git a/drivers/gpu/drm/ast/ast_mode.c b/drivers/gpu/drm/ast/ast_mode.c
index 97fed0627d1c..a49fe6618d73 100644
--- a/drivers/gpu/drm/ast/ast_mode.c
+++ b/drivers/gpu/drm/ast/ast_mode.c
@@ -529,50 +529,59 @@ static int ast_crtc_do_set_base(struct drm_crtc *crtc,
 	struct ast_private *ast = crtc->dev->dev_private;
 	struct drm_gem_object *obj;
 	struct ast_framebuffer *ast_fb;
-	struct ast_bo *bo;
+	struct drm_gem_ttm_object *gbo;
 	int ret;
-	u64 gpu_addr;
+	s64 gpu_addr;
 
 	/* push the previous fb to system ram */
 	if (!atomic && fb) {
 		ast_fb = to_ast_framebuffer(fb);
 		obj = ast_fb->obj;
-		bo = gem_to_ast_bo(obj);
-		ret = ast_bo_reserve(bo, false);
+		gbo = drm_gem_ttm_of_gem(obj);
+		ret = drm_gem_ttm_reserve(gbo, false);
 		if (ret)
 			return ret;
-		ast_bo_push_sysram(bo);
-		ast_bo_unreserve(bo);
+		drm_gem_ttm_push_to_system(gbo);
+		drm_gem_ttm_unreserve(gbo);
 	}
 
 	ast_fb = to_ast_framebuffer(crtc->primary->fb);
 	obj = ast_fb->obj;
-	bo = gem_to_ast_bo(obj);
+	gbo = drm_gem_ttm_of_gem(obj);
 
-	ret = ast_bo_reserve(bo, false);
+	ret = drm_gem_ttm_reserve(gbo, false);
 	if (ret)
 		return ret;
 
-	ret = ast_bo_pin(bo, TTM_PL_FLAG_VRAM, &gpu_addr);
-	if (ret) {
-		ast_bo_unreserve(bo);
-		return ret;
+	ret = drm_gem_ttm_pin(gbo, TTM_PL_FLAG_VRAM);
+	if (ret)
+		goto err_drm_gem_ttm_unreserve;
+	gpu_addr = drm_gem_ttm_vram_offset(gbo);
+	if (gpu_addr < 0) {
+		ret = (int)gpu_addr;
+		goto err_drm_gem_ttm_unpin;
 	}
 
 	if (&ast->fbdev->afb == ast_fb) {
 		/* if pushing console in kmap it */
-		ret = ttm_bo_kmap(&bo->bo, 0, bo->bo.num_pages, &bo->kmap);
+		ret = ttm_bo_kmap(&gbo->bo, 0, gbo->bo.num_pages, &gbo->kmap);
 		if (ret)
 			DRM_ERROR("failed to kmap fbcon\n");
 		else
 			ast_fbdev_set_base(ast, gpu_addr);
 	}
-	ast_bo_unreserve(bo);
+	drm_gem_ttm_unreserve(gbo);
 
 	ast_set_offset_reg(crtc);
 	ast_set_start_address_crt1(crtc, (u32)gpu_addr);
 
 	return 0;
+
+err_drm_gem_ttm_unpin:
+	drm_gem_ttm_unpin(gbo);
+err_drm_gem_ttm_unreserve:
+	drm_gem_ttm_unreserve(gbo);
+	return ret;
 }
 
 static int ast_crtc_mode_set_base(struct drm_crtc *crtc, int x, int y,
@@ -625,14 +634,13 @@ static void ast_crtc_disable(struct drm_crtc *crtc)
 	if (crtc->primary->fb) {
 		struct ast_framebuffer *ast_fb = to_ast_framebuffer(crtc->primary->fb);
 		struct drm_gem_object *obj = ast_fb->obj;
-		struct ast_bo *bo = gem_to_ast_bo(obj);
+		struct drm_gem_ttm_object *gbo = drm_gem_ttm_of_gem(obj);
 
-		ret = ast_bo_reserve(bo, false);
+		ret = drm_gem_ttm_reserve(gbo, false);
 		if (ret)
 			return;
-
-		ast_bo_push_sysram(bo);
-		ast_bo_unreserve(bo);
+		drm_gem_ttm_push_to_system(gbo);
+		drm_gem_ttm_unreserve(gbo);
 	}
 	crtc->primary->fb = NULL;
 }
@@ -918,26 +926,32 @@ static int ast_cursor_init(struct drm_device *dev)
 	int size;
 	int ret;
 	struct drm_gem_object *obj;
-	struct ast_bo *bo;
-	uint64_t gpu_addr;
+	struct drm_gem_ttm_object *gbo;
+	s64 gpu_addr;
 
 	size = (AST_HWC_SIZE + AST_HWC_SIGNATURE_SIZE) * AST_DEFAULT_HWC_NUM;
 
 	ret = ast_gem_create(dev, size, true, &obj);
 	if (ret)
 		return ret;
-	bo = gem_to_ast_bo(obj);
-	ret = ast_bo_reserve(bo, false);
+	gbo = drm_gem_ttm_of_gem(obj);
+	ret = drm_gem_ttm_reserve(gbo, false);
 	if (unlikely(ret != 0))
 		goto fail;
 
-	ret = ast_bo_pin(bo, TTM_PL_FLAG_VRAM, &gpu_addr);
-	ast_bo_unreserve(bo);
+	ret = drm_gem_ttm_pin(gbo, TTM_PL_FLAG_VRAM);
+	drm_gem_ttm_unreserve(gbo);
 	if (ret)
 		goto fail;
+	gpu_addr = drm_gem_ttm_vram_offset(gbo);
+	if (gpu_addr < 0) {
+		drm_gem_ttm_unpin(gbo);
+		ret = (int)gpu_addr;
+		goto fail;
+	}
 
 	/* kmap the object */
-	ret = ttm_bo_kmap(&bo->bo, 0, bo->bo.num_pages, &ast->cache_kmap);
+	ret = ttm_bo_kmap(&gbo->bo, 0, gbo->bo.num_pages, &ast->cache_kmap);
 	if (ret)
 		goto fail;
 
@@ -1173,8 +1187,8 @@ static int ast_cursor_set(struct drm_crtc *crtc,
 	struct ast_private *ast = crtc->dev->dev_private;
 	struct ast_crtc *ast_crtc = to_ast_crtc(crtc);
 	struct drm_gem_object *obj;
-	struct ast_bo *bo;
-	uint64_t gpu_addr;
+	struct drm_gem_ttm_object *gbo;
+	s64 gpu_addr;
 	u32 csum;
 	int ret;
 	struct ttm_bo_kmap_obj uobj_map;
@@ -1193,13 +1207,13 @@ static int ast_cursor_set(struct drm_crtc *crtc,
 		DRM_ERROR("Cannot find cursor object %x for crtc\n", handle);
 		return -ENOENT;
 	}
-	bo = gem_to_ast_bo(obj);
+	gbo = drm_gem_ttm_of_gem(obj);
 
-	ret = ast_bo_reserve(bo, false);
+	ret = drm_gem_ttm_reserve(gbo, false);
 	if (ret)
 		goto fail;
 
-	ret = ttm_bo_kmap(&bo->bo, 0, bo->bo.num_pages, &uobj_map);
+	ret = ttm_bo_kmap(&gbo->bo, 0, gbo->bo.num_pages, &uobj_map);
 
 	src = ttm_kmap_obj_virtual(&uobj_map, &src_isiomem);
 	dst = ttm_kmap_obj_virtual(&ast->cache_kmap, &dst_isiomem);
@@ -1216,7 +1230,7 @@ static int ast_cursor_set(struct drm_crtc *crtc,
 
 	/* write checksum + signature */
 	ttm_bo_kunmap(&uobj_map);
-	ast_bo_unreserve(bo);
+	drm_gem_ttm_unreserve(gbo);
 	{
 		u8 *dst = (u8 *)ast->cache_kmap.virtual + (AST_HWC_SIZE + AST_HWC_SIGNATURE_SIZE)*ast->next_cursor + AST_HWC_SIZE;
 		writel(csum, dst);
diff --git a/drivers/gpu/drm/ast/ast_ttm.c b/drivers/gpu/drm/ast/ast_ttm.c
index 75d477b37854..fd587c8fb8f7 100644
--- a/drivers/gpu/drm/ast/ast_ttm.c
+++ b/drivers/gpu/drm/ast/ast_ttm.c
@@ -36,23 +36,6 @@ ast_bdev(struct ttm_bo_device *bd)
 	return container_of(bd, struct ast_private, ttm.bdev);
 }
 
-static void ast_bo_ttm_destroy(struct ttm_buffer_object *tbo)
-{
-	struct ast_bo *bo;
-
-	bo = container_of(tbo, struct ast_bo, bo);
-
-	drm_gem_object_release(&bo->gem);
-	kfree(bo);
-}
-
-static bool ast_ttm_bo_is_ast_bo(struct ttm_buffer_object *bo)
-{
-	if (bo->destroy == &ast_bo_ttm_destroy)
-		return true;
-	return false;
-}
-
 static int
 ast_bo_init_mem_type(struct ttm_bo_device *bdev, uint32_t type,
 		     struct ttm_mem_type_manager *man)
@@ -78,26 +61,6 @@ ast_bo_init_mem_type(struct ttm_bo_device *bdev, uint32_t type,
 	return 0;
 }
 
-static void
-ast_bo_evict_flags(struct ttm_buffer_object *bo, struct ttm_placement *pl)
-{
-	struct ast_bo *astbo = ast_bo(bo);
-
-	if (!ast_ttm_bo_is_ast_bo(bo))
-		return;
-
-	ast_ttm_placement(astbo, TTM_PL_FLAG_SYSTEM);
-	*pl = astbo->placement;
-}
-
-static int ast_bo_verify_access(struct ttm_buffer_object *bo, struct file *filp)
-{
-	struct ast_bo *astbo = ast_bo(bo);
-
-	return drm_vma_node_verify_access(&astbo->gem.vma_node,
-					  filp->private_data);
-}
-
 static int ast_ttm_io_mem_reserve(struct ttm_bo_device *bdev,
 				  struct ttm_mem_reg *mem)
 {
@@ -162,9 +125,9 @@ struct ttm_bo_driver ast_bo_driver = {
 	.ttm_tt_create = ast_ttm_tt_create,
 	.init_mem_type = ast_bo_init_mem_type,
 	.eviction_valuable = ttm_bo_eviction_valuable,
-	.evict_flags = ast_bo_evict_flags,
+	.evict_flags = drm_gem_ttm_bo_driver_evict_flags,
 	.move = NULL,
-	.verify_access = ast_bo_verify_access,
+	.verify_access = drm_gem_ttm_bo_driver_verify_access,
 	.io_mem_reserve = &ast_ttm_io_mem_reserve,
 	.io_mem_free = &ast_ttm_io_mem_free,
 };
@@ -210,137 +173,6 @@ void ast_mm_fini(struct ast_private *ast)
 				pci_resource_len(dev->pdev, 0));
 }
 
-void ast_ttm_placement(struct ast_bo *bo, int domain)
-{
-	u32 c = 0;
-	unsigned i;
-
-	bo->placement.placement = bo->placements;
-	bo->placement.busy_placement = bo->placements;
-	if (domain & TTM_PL_FLAG_VRAM)
-		bo->placements[c++].flags = TTM_PL_FLAG_WC | TTM_PL_FLAG_UNCACHED | TTM_PL_FLAG_VRAM;
-	if (domain & TTM_PL_FLAG_SYSTEM)
-		bo->placements[c++].flags = TTM_PL_FLAG_CACHED | TTM_PL_FLAG_SYSTEM;
-	if (!c)
-		bo->placements[c++].flags = TTM_PL_FLAG_CACHED | TTM_PL_FLAG_SYSTEM;
-	bo->placement.num_placement = c;
-	bo->placement.num_busy_placement = c;
-	for (i = 0; i < c; ++i) {
-		bo->placements[i].fpfn = 0;
-		bo->placements[i].lpfn = 0;
-	}
-}
-
-int ast_bo_create(struct drm_device *dev, int size, int align,
-		  uint32_t flags, struct ast_bo **pastbo)
-{
-	struct ast_private *ast = dev->dev_private;
-	struct ast_bo *astbo;
-	size_t acc_size;
-	int ret;
-
-	astbo = kzalloc(sizeof(struct ast_bo), GFP_KERNEL);
-	if (!astbo)
-		return -ENOMEM;
-
-	ret = drm_gem_object_init(dev, &astbo->gem, size);
-	if (ret)
-		goto error;
-
-	astbo->bo.bdev = &ast->ttm.bdev;
-
-	ast_ttm_placement(astbo, TTM_PL_FLAG_VRAM | TTM_PL_FLAG_SYSTEM);
-
-	acc_size = ttm_bo_dma_acc_size(&ast->ttm.bdev, size,
-				       sizeof(struct ast_bo));
-
-	ret = ttm_bo_init(&ast->ttm.bdev, &astbo->bo, size,
-			  ttm_bo_type_device, &astbo->placement,
-			  align >> PAGE_SHIFT, false, acc_size,
-			  NULL, NULL, ast_bo_ttm_destroy);
-	if (ret)
-		goto error;
-
-	*pastbo = astbo;
-	return 0;
-error:
-	kfree(astbo);
-	return ret;
-}
-
-static inline u64 ast_bo_gpu_offset(struct ast_bo *bo)
-{
-	return bo->bo.offset;
-}
-
-int ast_bo_pin(struct ast_bo *bo, u32 pl_flag, u64 *gpu_addr)
-{
-	struct ttm_operation_ctx ctx = { false, false };
-	int i, ret;
-
-	if (bo->pin_count) {
-		bo->pin_count++;
-		if (gpu_addr)
-			*gpu_addr = ast_bo_gpu_offset(bo);
-	}
-
-	ast_ttm_placement(bo, pl_flag);
-	for (i = 0; i < bo->placement.num_placement; i++)
-		bo->placements[i].flags |= TTM_PL_FLAG_NO_EVICT;
-	ret = ttm_bo_validate(&bo->bo, &bo->placement, &ctx);
-	if (ret)
-		return ret;
-
-	bo->pin_count = 1;
-	if (gpu_addr)
-		*gpu_addr = ast_bo_gpu_offset(bo);
-	return 0;
-}
-
-int ast_bo_unpin(struct ast_bo *bo)
-{
-	struct ttm_operation_ctx ctx = { false, false };
-	int i;
-	if (!bo->pin_count) {
-		DRM_ERROR("unpin bad %p\n", bo);
-		return 0;
-	}
-	bo->pin_count--;
-	if (bo->pin_count)
-		return 0;
-
-	for (i = 0; i < bo->placement.num_placement ; i++)
-		bo->placements[i].flags &= ~TTM_PL_FLAG_NO_EVICT;
-	return ttm_bo_validate(&bo->bo, &bo->placement, &ctx);
-}
-
-int ast_bo_push_sysram(struct ast_bo *bo)
-{
-	struct ttm_operation_ctx ctx = { false, false };
-	int i, ret;
-	if (!bo->pin_count) {
-		DRM_ERROR("unpin bad %p\n", bo);
-		return 0;
-	}
-	bo->pin_count--;
-	if (bo->pin_count)
-		return 0;
-
-	if (bo->kmap.virtual)
-		ttm_bo_kunmap(&bo->kmap);
-
-	ast_ttm_placement(bo, TTM_PL_FLAG_SYSTEM);
-	for (i = 0; i < bo->placement.num_placement ; i++)
-		bo->placements[i].flags |= TTM_PL_FLAG_NO_EVICT;
-
-	ret = ttm_bo_validate(&bo->bo, &bo->placement, &ctx);
-	if (ret) {
-		DRM_ERROR("pushing to VRAM failed\n");
-		return ret;
-	}
-	return 0;
-}
-
 int ast_mmap(struct file *filp, struct vm_area_struct *vma)
 {
 	struct drm_file *file_priv = filp->private_data;
-- 
2.21.0

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

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

* [PATCH 07/15] drm/ast: Convert AST driver to Simple TTM
  2019-04-08  9:21 [PATCH 00/15] Share TTM code among framebuffer drivers Thomas Zimmermann
                   ` (5 preceding siblings ...)
  2019-04-08  9:21 ` [PATCH 06/15] drm/ast: Convert AST driver to |struct drm_gem_ttm_object| Thomas Zimmermann
@ 2019-04-08  9:21 ` Thomas Zimmermann
  2019-04-08  9:21 ` [PATCH 08/15] drm/bochs: Convert Bochs driver to |struct drm_gem_ttm_object| Thomas Zimmermann
                   ` (9 subsequent siblings)
  16 siblings, 0 replies; 43+ messages in thread
From: Thomas Zimmermann @ 2019-04-08  9:21 UTC (permalink / raw)
  To: daniel, airlied, kraxel, christian.koenig, ray.huang,
	Jerry.Zhang, hdegoede, z.liuxinliang, zourongrong,
	kong.kongxinwei, puck.chen
  Cc: Thomas Zimmermann, dri-devel, virtualization

Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
---
 drivers/gpu/drm/ast/Kconfig   |   1 +
 drivers/gpu/drm/ast/ast_drv.h |   6 +-
 drivers/gpu/drm/ast/ast_ttm.c | 120 ++--------------------------------
 3 files changed, 11 insertions(+), 116 deletions(-)

diff --git a/drivers/gpu/drm/ast/Kconfig b/drivers/gpu/drm/ast/Kconfig
index 8d90c5b231c7..bf158b556a84 100644
--- a/drivers/gpu/drm/ast/Kconfig
+++ b/drivers/gpu/drm/ast/Kconfig
@@ -4,6 +4,7 @@ config DRM_AST
 	select DRM_TTM
 	select DRM_KMS_HELPER
 	select DRM_GEM_TTM_HELPER
+	select DRM_SIMPLE_TTM_HELPER
 	help
 	 Say yes for experimental AST GPU driver. Do not enable
 	 this driver without having a working -modesetting,
diff --git a/drivers/gpu/drm/ast/ast_drv.h b/drivers/gpu/drm/ast/ast_drv.h
index 939acac4cc4a..1ed2af255022 100644
--- a/drivers/gpu/drm/ast/ast_drv.h
+++ b/drivers/gpu/drm/ast/ast_drv.h
@@ -40,6 +40,8 @@
 #include <drm/drm_gem.h>
 #include <drm/drm_gem_ttm_helper.h>
 
+#include <drm/drm_simple_ttm_helper.h>
+
 #include <linux/i2c.h>
 #include <linux/i2c-algo-bit.h>
 
@@ -104,9 +106,7 @@ struct ast_private {
 
 	int fb_mtrr;
 
-	struct {
-		struct ttm_bo_device bdev;
-	} ttm;
+	struct drm_simple_ttm ttm;
 
 	struct drm_gem_object *cursor_cache;
 	uint64_t cursor_cache_gpu_addr;
diff --git a/drivers/gpu/drm/ast/ast_ttm.c b/drivers/gpu/drm/ast/ast_ttm.c
index fd587c8fb8f7..58e0ec4a7392 100644
--- a/drivers/gpu/drm/ast/ast_ttm.c
+++ b/drivers/gpu/drm/ast/ast_ttm.c
@@ -30,127 +30,21 @@
 
 #include "ast_drv.h"
 
-static inline struct ast_private *
-ast_bdev(struct ttm_bo_device *bd)
-{
-	return container_of(bd, struct ast_private, ttm.bdev);
-}
-
-static int
-ast_bo_init_mem_type(struct ttm_bo_device *bdev, uint32_t type,
-		     struct ttm_mem_type_manager *man)
-{
-	switch (type) {
-	case TTM_PL_SYSTEM:
-		man->flags = TTM_MEMTYPE_FLAG_MAPPABLE;
-		man->available_caching = TTM_PL_MASK_CACHING;
-		man->default_caching = TTM_PL_FLAG_CACHED;
-		break;
-	case TTM_PL_VRAM:
-		man->func = &ttm_bo_manager_func;
-		man->flags = TTM_MEMTYPE_FLAG_FIXED |
-			TTM_MEMTYPE_FLAG_MAPPABLE;
-		man->available_caching = TTM_PL_FLAG_UNCACHED |
-			TTM_PL_FLAG_WC;
-		man->default_caching = TTM_PL_FLAG_WC;
-		break;
-	default:
-		DRM_ERROR("Unsupported memory type %u\n", (unsigned)type);
-		return -EINVAL;
-	}
-	return 0;
-}
-
-static int ast_ttm_io_mem_reserve(struct ttm_bo_device *bdev,
-				  struct ttm_mem_reg *mem)
-{
-	struct ttm_mem_type_manager *man = &bdev->man[mem->mem_type];
-	struct ast_private *ast = ast_bdev(bdev);
-
-	mem->bus.addr = NULL;
-	mem->bus.offset = 0;
-	mem->bus.size = mem->num_pages << PAGE_SHIFT;
-	mem->bus.base = 0;
-	mem->bus.is_iomem = false;
-	if (!(man->flags & TTM_MEMTYPE_FLAG_MAPPABLE))
-		return -EINVAL;
-	switch (mem->mem_type) {
-	case TTM_PL_SYSTEM:
-		/* system memory */
-		return 0;
-	case TTM_PL_VRAM:
-		mem->bus.offset = mem->start << PAGE_SHIFT;
-		mem->bus.base = pci_resource_start(ast->dev->pdev, 0);
-		mem->bus.is_iomem = true;
-		break;
-	default:
-		return -EINVAL;
-		break;
-	}
-	return 0;
-}
-
-static void ast_ttm_io_mem_free(struct ttm_bo_device *bdev, struct ttm_mem_reg *mem)
-{
-}
-
-static void ast_ttm_backend_destroy(struct ttm_tt *tt)
-{
-	ttm_tt_fini(tt);
-	kfree(tt);
-}
-
-static struct ttm_backend_func ast_tt_backend_func = {
-	.destroy = &ast_ttm_backend_destroy,
-};
-
-
-static struct ttm_tt *ast_ttm_tt_create(struct ttm_buffer_object *bo,
-					uint32_t page_flags)
-{
-	struct ttm_tt *tt;
-
-	tt = kzalloc(sizeof(struct ttm_tt), GFP_KERNEL);
-	if (tt == NULL)
-		return NULL;
-	tt->func = &ast_tt_backend_func;
-	if (ttm_tt_init(tt, bo, page_flags)) {
-		kfree(tt);
-		return NULL;
-	}
-	return tt;
-}
-
-struct ttm_bo_driver ast_bo_driver = {
-	.ttm_tt_create = ast_ttm_tt_create,
-	.init_mem_type = ast_bo_init_mem_type,
-	.eviction_valuable = ttm_bo_eviction_valuable,
+static const struct drm_simple_ttm_funcs ast_simple_ttm_funcs = {
 	.evict_flags = drm_gem_ttm_bo_driver_evict_flags,
-	.move = NULL,
-	.verify_access = drm_gem_ttm_bo_driver_verify_access,
-	.io_mem_reserve = &ast_ttm_io_mem_reserve,
-	.io_mem_free = &ast_ttm_io_mem_free,
+	.verify_access = drm_gem_ttm_bo_driver_verify_access
 };
 
 int ast_mm_init(struct ast_private *ast)
 {
 	int ret;
 	struct drm_device *dev = ast->dev;
-	struct ttm_bo_device *bdev = &ast->ttm.bdev;
-
-	ret = ttm_bo_device_init(&ast->ttm.bdev,
-				 &ast_bo_driver,
-				 dev->anon_inode->i_mapping,
-				 true);
-	if (ret) {
-		DRM_ERROR("Error initialising bo driver; %d\n", ret);
-		return ret;
-	}
 
-	ret = ttm_bo_init_mm(bdev, TTM_PL_VRAM,
-			     ast->vram_size >> PAGE_SHIFT);
+	ret = drm_simple_ttm_init(&ast->ttm, dev,
+				  pci_resource_start(dev->pdev, 0),
+				  ast->vram_size, &ast_simple_ttm_funcs);
 	if (ret) {
-		DRM_ERROR("Failed ttm VRAM init: %d\n", ret);
+		DRM_ERROR("Error initializing Simple TTM; %d\n", ret);
 		return ret;
 	}
 
@@ -166,7 +60,7 @@ void ast_mm_fini(struct ast_private *ast)
 {
 	struct drm_device *dev = ast->dev;
 
-	ttm_bo_device_release(&ast->ttm.bdev);
+	drm_simple_ttm_cleanup(&ast->ttm);
 
 	arch_phys_wc_del(ast->fb_mtrr);
 	arch_io_free_memtype_wc(pci_resource_start(dev->pdev, 0),
-- 
2.21.0

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

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

* [PATCH 08/15] drm/bochs: Convert Bochs driver to |struct drm_gem_ttm_object|
  2019-04-08  9:21 [PATCH 00/15] Share TTM code among framebuffer drivers Thomas Zimmermann
                   ` (6 preceding siblings ...)
  2019-04-08  9:21 ` [PATCH 07/15] drm/ast: Convert AST driver to Simple TTM Thomas Zimmermann
@ 2019-04-08  9:21 ` Thomas Zimmermann
  2019-04-08  9:21 ` [PATCH 09/15] drm/bochs: Convert Bochs driver to Simple TTM Thomas Zimmermann
                   ` (8 subsequent siblings)
  16 siblings, 0 replies; 43+ messages in thread
From: Thomas Zimmermann @ 2019-04-08  9:21 UTC (permalink / raw)
  To: daniel, airlied, kraxel, christian.koenig, ray.huang,
	Jerry.Zhang, hdegoede, z.liuxinliang, zourongrong,
	kong.kongxinwei, puck.chen
  Cc: Thomas Zimmermann, dri-devel, virtualization

Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
---
 drivers/gpu/drm/bochs/Kconfig     |   1 +
 drivers/gpu/drm/bochs/bochs.h     |  34 +---
 drivers/gpu/drm/bochs/bochs_drv.c |   4 +-
 drivers/gpu/drm/bochs/bochs_kms.c |  18 +-
 drivers/gpu/drm/bochs/bochs_mm.c  | 269 +++---------------------------
 5 files changed, 34 insertions(+), 292 deletions(-)

diff --git a/drivers/gpu/drm/bochs/Kconfig b/drivers/gpu/drm/bochs/Kconfig
index bd2718015cdb..40c487b89757 100644
--- a/drivers/gpu/drm/bochs/Kconfig
+++ b/drivers/gpu/drm/bochs/Kconfig
@@ -3,6 +3,7 @@ config DRM_BOCHS
 	depends on DRM && PCI && MMU
 	select DRM_KMS_HELPER
 	select DRM_TTM
+	select DRM_GEM_TTM_HELPER
 	help
 	  Choose this option for qemu.
 	  If M is selected the module will be called bochs-drm.
diff --git a/drivers/gpu/drm/bochs/bochs.h b/drivers/gpu/drm/bochs/bochs.h
index 049d058571d4..438bba0b565e 100644
--- a/drivers/gpu/drm/bochs/bochs.h
+++ b/drivers/gpu/drm/bochs/bochs.h
@@ -9,6 +9,7 @@
 #include <drm/drm_fb_helper.h>
 
 #include <drm/drm_gem.h>
+#include <drm/drm_gem_ttm_helper.h>
 
 #include <drm/ttm/ttm_bo_driver.h>
 #include <drm/ttm/ttm_page_alloc.h>
@@ -81,30 +82,6 @@ struct bochs_device {
 	} ttm;
 };
 
-struct bochs_bo {
-	struct ttm_buffer_object bo;
-	struct ttm_placement placement;
-	struct ttm_bo_kmap_obj kmap;
-	struct drm_gem_object gem;
-	struct ttm_place placements[3];
-	int pin_count;
-};
-
-static inline struct bochs_bo *bochs_bo(struct ttm_buffer_object *bo)
-{
-	return container_of(bo, struct bochs_bo, bo);
-}
-
-static inline struct bochs_bo *gem_to_bochs_bo(struct drm_gem_object *gem)
-{
-	return container_of(gem, struct bochs_bo, gem);
-}
-
-static inline u64 bochs_bo_mmap_offset(struct bochs_bo *bo)
-{
-	return drm_vma_node_offset_addr(&bo->bo.vma_node);
-}
-
 /* ---------------------------------------------------------------------- */
 
 /* bochs_hw.c */
@@ -124,17 +101,8 @@ int bochs_mm_init(struct bochs_device *bochs);
 void bochs_mm_fini(struct bochs_device *bochs);
 int bochs_mmap(struct file *filp, struct vm_area_struct *vma);
 
-int bochs_gem_create(struct drm_device *dev, u32 size, bool iskernel,
-		     struct drm_gem_object **obj);
-int bochs_gem_init_object(struct drm_gem_object *obj);
-void bochs_gem_free_object(struct drm_gem_object *obj);
 int bochs_dumb_create(struct drm_file *file, struct drm_device *dev,
 		      struct drm_mode_create_dumb *args);
-int bochs_dumb_mmap_offset(struct drm_file *file, struct drm_device *dev,
-			   uint32_t handle, uint64_t *offset);
-
-int bochs_bo_pin(struct bochs_bo *bo, u32 pl_flag);
-int bochs_bo_unpin(struct bochs_bo *bo);
 
 int bochs_gem_prime_pin(struct drm_gem_object *obj);
 void bochs_gem_prime_unpin(struct drm_gem_object *obj);
diff --git a/drivers/gpu/drm/bochs/bochs_drv.c b/drivers/gpu/drm/bochs/bochs_drv.c
index 6b6e037258c3..798dd98d7216 100644
--- a/drivers/gpu/drm/bochs/bochs_drv.c
+++ b/drivers/gpu/drm/bochs/bochs_drv.c
@@ -82,9 +82,9 @@ static struct drm_driver bochs_driver = {
 	.date			= "20130925",
 	.major			= 1,
 	.minor			= 0,
-	.gem_free_object_unlocked = bochs_gem_free_object,
+	.gem_free_object_unlocked = drm_gem_ttm_driver_gem_free_object_unlocked,
 	.dumb_create            = bochs_dumb_create,
-	.dumb_map_offset        = bochs_dumb_mmap_offset,
+	.dumb_map_offset        = drm_gem_ttm_driver_dumb_mmap_offset,
 
 	.gem_prime_export = drm_gem_prime_export,
 	.gem_prime_import = drm_gem_prime_import,
diff --git a/drivers/gpu/drm/bochs/bochs_kms.c b/drivers/gpu/drm/bochs/bochs_kms.c
index 485f9cf05e8b..b7c4168ba40a 100644
--- a/drivers/gpu/drm/bochs/bochs_kms.c
+++ b/drivers/gpu/drm/bochs/bochs_kms.c
@@ -78,38 +78,38 @@ static void bochs_plane_atomic_update(struct drm_plane *plane,
 				      struct drm_plane_state *old_state)
 {
 	struct bochs_device *bochs = plane->dev->dev_private;
-	struct bochs_bo *bo;
+	struct drm_gem_ttm_object *gbo;
 
 	if (!plane->state->fb)
 		return;
-	bo = gem_to_bochs_bo(plane->state->fb->obj[0]);
+	gbo = drm_gem_ttm_of_gem(plane->state->fb->obj[0]);
 	bochs_hw_setbase(bochs,
 			 plane->state->crtc_x,
 			 plane->state->crtc_y,
-			 bo->bo.offset);
+			 gbo->bo.offset);
 	bochs_hw_setformat(bochs, plane->state->fb->format);
 }
 
 static int bochs_plane_prepare_fb(struct drm_plane *plane,
 				struct drm_plane_state *new_state)
 {
-	struct bochs_bo *bo;
+	struct drm_gem_ttm_object *gbo;
 
 	if (!new_state->fb)
 		return 0;
-	bo = gem_to_bochs_bo(new_state->fb->obj[0]);
-	return bochs_bo_pin(bo, TTM_PL_FLAG_VRAM);
+	gbo = drm_gem_ttm_of_gem(new_state->fb->obj[0]);
+	return drm_gem_ttm_pin(gbo, TTM_PL_FLAG_VRAM);
 }
 
 static void bochs_plane_cleanup_fb(struct drm_plane *plane,
 				   struct drm_plane_state *old_state)
 {
-	struct bochs_bo *bo;
+	struct drm_gem_ttm_object *gbo;
 
 	if (!old_state->fb)
 		return;
-	bo = gem_to_bochs_bo(old_state->fb->obj[0]);
-	bochs_bo_unpin(bo);
+	gbo = drm_gem_ttm_of_gem(old_state->fb->obj[0]);
+	drm_gem_ttm_unpin(gbo);
 }
 
 static const struct drm_plane_helper_funcs bochs_plane_helper_funcs = {
diff --git a/drivers/gpu/drm/bochs/bochs_mm.c b/drivers/gpu/drm/bochs/bochs_mm.c
index 4a40308169c4..6554fd11676b 100644
--- a/drivers/gpu/drm/bochs/bochs_mm.c
+++ b/drivers/gpu/drm/bochs/bochs_mm.c
@@ -7,8 +7,6 @@
 
 #include "bochs.h"
 
-static void bochs_ttm_placement(struct bochs_bo *bo, int domain);
-
 /* ---------------------------------------------------------------------- */
 
 static inline struct bochs_device *bochs_bdev(struct ttm_bo_device *bd)
@@ -16,22 +14,6 @@ static inline struct bochs_device *bochs_bdev(struct ttm_bo_device *bd)
 	return container_of(bd, struct bochs_device, ttm.bdev);
 }
 
-static void bochs_bo_ttm_destroy(struct ttm_buffer_object *tbo)
-{
-	struct bochs_bo *bo;
-
-	bo = container_of(tbo, struct bochs_bo, bo);
-	drm_gem_object_release(&bo->gem);
-	kfree(bo);
-}
-
-static bool bochs_ttm_bo_is_bochs_bo(struct ttm_buffer_object *bo)
-{
-	if (bo->destroy == &bochs_bo_ttm_destroy)
-		return true;
-	return false;
-}
-
 static int bochs_bo_init_mem_type(struct ttm_bo_device *bdev, uint32_t type,
 				  struct ttm_mem_type_manager *man)
 {
@@ -56,27 +38,6 @@ static int bochs_bo_init_mem_type(struct ttm_bo_device *bdev, uint32_t type,
 	return 0;
 }
 
-static void
-bochs_bo_evict_flags(struct ttm_buffer_object *bo, struct ttm_placement *pl)
-{
-	struct bochs_bo *bochsbo = bochs_bo(bo);
-
-	if (!bochs_ttm_bo_is_bochs_bo(bo))
-		return;
-
-	bochs_ttm_placement(bochsbo, TTM_PL_FLAG_SYSTEM);
-	*pl = bochsbo->placement;
-}
-
-static int bochs_bo_verify_access(struct ttm_buffer_object *bo,
-				  struct file *filp)
-{
-	struct bochs_bo *bochsbo = bochs_bo(bo);
-
-	return drm_vma_node_verify_access(&bochsbo->gem.vma_node,
-					  filp->private_data);
-}
-
 static int bochs_ttm_io_mem_reserve(struct ttm_bo_device *bdev,
 				    struct ttm_mem_reg *mem)
 {
@@ -141,9 +102,9 @@ static struct ttm_bo_driver bochs_bo_driver = {
 	.ttm_tt_create = bochs_ttm_tt_create,
 	.init_mem_type = bochs_bo_init_mem_type,
 	.eviction_valuable = ttm_bo_eviction_valuable,
-	.evict_flags = bochs_bo_evict_flags,
+	.evict_flags = drm_gem_ttm_bo_driver_evict_flags,
 	.move = NULL,
-	.verify_access = bochs_bo_verify_access,
+	.verify_access = drm_gem_ttm_bo_driver_verify_access,
 	.io_mem_reserve = &bochs_ttm_io_mem_reserve,
 	.io_mem_free = &bochs_ttm_io_mem_free,
 };
@@ -182,85 +143,6 @@ void bochs_mm_fini(struct bochs_device *bochs)
 	bochs->ttm.initialized = false;
 }
 
-static void bochs_ttm_placement(struct bochs_bo *bo, int domain)
-{
-	unsigned i;
-	u32 c = 0;
-	bo->placement.placement = bo->placements;
-	bo->placement.busy_placement = bo->placements;
-	if (domain & TTM_PL_FLAG_VRAM) {
-		bo->placements[c++].flags = TTM_PL_FLAG_WC
-			| TTM_PL_FLAG_UNCACHED
-			| TTM_PL_FLAG_VRAM;
-	}
-	if (domain & TTM_PL_FLAG_SYSTEM) {
-		bo->placements[c++].flags = TTM_PL_MASK_CACHING
-			| TTM_PL_FLAG_SYSTEM;
-	}
-	if (!c) {
-		bo->placements[c++].flags = TTM_PL_MASK_CACHING
-			| TTM_PL_FLAG_SYSTEM;
-	}
-	for (i = 0; i < c; ++i) {
-		bo->placements[i].fpfn = 0;
-		bo->placements[i].lpfn = 0;
-	}
-	bo->placement.num_placement = c;
-	bo->placement.num_busy_placement = c;
-}
-
-int bochs_bo_pin(struct bochs_bo *bo, u32 pl_flag)
-{
-	struct ttm_operation_ctx ctx = { false, false };
-	int i, ret;
-
-	if (bo->pin_count) {
-		bo->pin_count++;
-		return 0;
-	}
-
-	bochs_ttm_placement(bo, pl_flag);
-	for (i = 0; i < bo->placement.num_placement; i++)
-		bo->placements[i].flags |= TTM_PL_FLAG_NO_EVICT;
-	ret = ttm_bo_reserve(&bo->bo, true, false, NULL);
-	if (ret)
-		return ret;
-	ret = ttm_bo_validate(&bo->bo, &bo->placement, &ctx);
-	ttm_bo_unreserve(&bo->bo);
-	if (ret)
-		return ret;
-
-	bo->pin_count = 1;
-	return 0;
-}
-
-int bochs_bo_unpin(struct bochs_bo *bo)
-{
-	struct ttm_operation_ctx ctx = { false, false };
-	int i, ret;
-
-	if (!bo->pin_count) {
-		DRM_ERROR("unpin bad %p\n", bo);
-		return 0;
-	}
-	bo->pin_count--;
-
-	if (bo->pin_count)
-		return 0;
-
-	for (i = 0; i < bo->placement.num_placement; i++)
-		bo->placements[i].flags &= ~TTM_PL_FLAG_NO_EVICT;
-	ret = ttm_bo_reserve(&bo->bo, true, false, NULL);
-	if (ret)
-		return ret;
-	ret = ttm_bo_validate(&bo->bo, &bo->placement, &ctx);
-	ttm_bo_unreserve(&bo->bo);
-	if (ret)
-		return ret;
-
-	return 0;
-}
-
 int bochs_mmap(struct file *filp, struct vm_area_struct *vma)
 {
 	struct drm_file *file_priv = filp->private_data;
@@ -271,171 +153,62 @@ int bochs_mmap(struct file *filp, struct vm_area_struct *vma)
 
 /* ---------------------------------------------------------------------- */
 
-static int bochs_bo_create(struct drm_device *dev, int size, int align,
-			   uint32_t flags, struct bochs_bo **pbochsbo)
-{
-	struct bochs_device *bochs = dev->dev_private;
-	struct bochs_bo *bochsbo;
-	size_t acc_size;
-	int ret;
-
-	bochsbo = kzalloc(sizeof(struct bochs_bo), GFP_KERNEL);
-	if (!bochsbo)
-		return -ENOMEM;
-
-	ret = drm_gem_object_init(dev, &bochsbo->gem, size);
-	if (ret) {
-		kfree(bochsbo);
-		return ret;
-	}
-
-	bochsbo->bo.bdev = &bochs->ttm.bdev;
-	bochsbo->bo.bdev->dev_mapping = dev->anon_inode->i_mapping;
-
-	bochs_ttm_placement(bochsbo, TTM_PL_FLAG_VRAM | TTM_PL_FLAG_SYSTEM);
-
-	acc_size = ttm_bo_dma_acc_size(&bochs->ttm.bdev, size,
-				       sizeof(struct bochs_bo));
-
-	ret = ttm_bo_init(&bochs->ttm.bdev, &bochsbo->bo, size,
-			  ttm_bo_type_device, &bochsbo->placement,
-			  align >> PAGE_SHIFT, false, acc_size,
-			  NULL, NULL, bochs_bo_ttm_destroy);
-	if (ret)
-		return ret;
-
-	*pbochsbo = bochsbo;
-	return 0;
-}
-
-int bochs_gem_create(struct drm_device *dev, u32 size, bool iskernel,
-		     struct drm_gem_object **obj)
-{
-	struct bochs_bo *bochsbo;
-	int ret;
-
-	*obj = NULL;
-
-	size = PAGE_ALIGN(size);
-	if (size == 0)
-		return -EINVAL;
-
-	ret = bochs_bo_create(dev, size, 0, 0, &bochsbo);
-	if (ret) {
-		if (ret != -ERESTARTSYS)
-			DRM_ERROR("failed to allocate GEM object\n");
-		return ret;
-	}
-	*obj = &bochsbo->gem;
-	return 0;
-}
-
 int bochs_dumb_create(struct drm_file *file, struct drm_device *dev,
 		      struct drm_mode_create_dumb *args)
 {
-	struct drm_gem_object *gobj;
-	u32 handle;
-	int ret;
-
-	args->pitch = args->width * ((args->bpp + 7) / 8);
-	args->size = args->pitch * args->height;
-
-	ret = bochs_gem_create(dev, args->size, false,
-			       &gobj);
-	if (ret)
-		return ret;
-
-	ret = drm_gem_handle_create(file, gobj, &handle);
-	drm_gem_object_put_unlocked(gobj);
-	if (ret)
-		return ret;
-
-	args->handle = handle;
-	return 0;
-}
-
-static void bochs_bo_unref(struct bochs_bo **bo)
-{
-	struct ttm_buffer_object *tbo;
-
-	if ((*bo) == NULL)
-		return;
-
-	tbo = &((*bo)->bo);
-	ttm_bo_put(tbo);
-	*bo = NULL;
-}
-
-void bochs_gem_free_object(struct drm_gem_object *obj)
-{
-	struct bochs_bo *bochs_bo = gem_to_bochs_bo(obj);
-
-	bochs_bo_unref(&bochs_bo);
-}
-
-int bochs_dumb_mmap_offset(struct drm_file *file, struct drm_device *dev,
-			   uint32_t handle, uint64_t *offset)
-{
-	struct drm_gem_object *obj;
-	struct bochs_bo *bo;
-
-	obj = drm_gem_object_lookup(file, handle);
-	if (obj == NULL)
-		return -ENOENT;
-
-	bo = gem_to_bochs_bo(obj);
-	*offset = bochs_bo_mmap_offset(bo);
+	struct bochs_device *bochs = dev->dev_private;
 
-	drm_gem_object_put_unlocked(obj);
-	return 0;
+	return drm_gem_ttm_fill_create_dumb(file, dev, &bochs->ttm.bdev, 0,
+					    false, args);
 }
 
 /* ---------------------------------------------------------------------- */
 
 int bochs_gem_prime_pin(struct drm_gem_object *obj)
 {
-	struct bochs_bo *bo = gem_to_bochs_bo(obj);
+	struct drm_gem_ttm_object *gbo = drm_gem_ttm_of_gem(obj);
 
-	return bochs_bo_pin(bo, TTM_PL_FLAG_VRAM);
+	return drm_gem_ttm_pin(gbo, TTM_PL_FLAG_VRAM);
 }
 
 void bochs_gem_prime_unpin(struct drm_gem_object *obj)
 {
-	struct bochs_bo *bo = gem_to_bochs_bo(obj);
+	struct drm_gem_ttm_object *gbo = drm_gem_ttm_of_gem(obj);
 
-	bochs_bo_unpin(bo);
+	drm_gem_ttm_unpin(gbo);
 }
 
 void *bochs_gem_prime_vmap(struct drm_gem_object *obj)
 {
-	struct bochs_bo *bo = gem_to_bochs_bo(obj);
+	struct drm_gem_ttm_object *gbo = drm_gem_ttm_of_gem(obj);
 	bool is_iomem;
 	int ret;
+	void* base;
 
-	ret = bochs_bo_pin(bo, TTM_PL_FLAG_VRAM);
+	ret = drm_gem_ttm_pin(gbo, TTM_PL_FLAG_VRAM);
 	if (ret)
 		return NULL;
-	ret = ttm_bo_kmap(&bo->bo, 0, bo->bo.num_pages, &bo->kmap);
-	if (ret) {
-		bochs_bo_unpin(bo);
+	base = drm_gem_ttm_kmap(gbo, true);
+	if (IS_ERR(base)) {
+		drm_gem_ttm_unpin(gbo);
 		return NULL;
 	}
-	return ttm_kmap_obj_virtual(&bo->kmap, &is_iomem);
+	return ttm_kmap_obj_virtual(&gbo->kmap, &is_iomem);
 }
 
 void bochs_gem_prime_vunmap(struct drm_gem_object *obj, void *vaddr)
 {
-	struct bochs_bo *bo = gem_to_bochs_bo(obj);
+	struct drm_gem_ttm_object *gbo = drm_gem_ttm_of_gem(obj);
 
-	ttm_bo_kunmap(&bo->kmap);
-	bochs_bo_unpin(bo);
+	drm_gem_ttm_kunmap(gbo);
+	drm_gem_ttm_unpin(gbo);
 }
 
 int bochs_gem_prime_mmap(struct drm_gem_object *obj,
 			 struct vm_area_struct *vma)
 {
-	struct bochs_bo *bo = gem_to_bochs_bo(obj);
+	struct drm_gem_ttm_object *gbo = drm_gem_ttm_of_gem(obj);
 
-	bo->gem.vma_node.vm_node.start = bo->bo.vma_node.vm_node.start;
+	gbo->gem.vma_node.vm_node.start = gbo->bo.vma_node.vm_node.start;
 	return drm_gem_prime_mmap(obj, vma);
 }
-- 
2.21.0

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

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

* [PATCH 09/15] drm/bochs: Convert Bochs driver to Simple TTM
  2019-04-08  9:21 [PATCH 00/15] Share TTM code among framebuffer drivers Thomas Zimmermann
                   ` (7 preceding siblings ...)
  2019-04-08  9:21 ` [PATCH 08/15] drm/bochs: Convert Bochs driver to |struct drm_gem_ttm_object| Thomas Zimmermann
@ 2019-04-08  9:21 ` Thomas Zimmermann
  2019-04-08  9:21 ` [PATCH 10/15] drm/mgag200: Convert mgag200 driver to |struct drm_gem_ttm_object| Thomas Zimmermann
                   ` (7 subsequent siblings)
  16 siblings, 0 replies; 43+ messages in thread
From: Thomas Zimmermann @ 2019-04-08  9:21 UTC (permalink / raw)
  To: daniel, airlied, kraxel, christian.koenig, ray.huang,
	Jerry.Zhang, hdegoede, z.liuxinliang, zourongrong,
	kong.kongxinwei, puck.chen
  Cc: Thomas Zimmermann, dri-devel, virtualization

Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
---
 drivers/gpu/drm/bochs/Kconfig    |   1 +
 drivers/gpu/drm/bochs/bochs.h    |   8 +-
 drivers/gpu/drm/bochs/bochs_mm.c | 125 +++----------------------------
 3 files changed, 14 insertions(+), 120 deletions(-)

diff --git a/drivers/gpu/drm/bochs/Kconfig b/drivers/gpu/drm/bochs/Kconfig
index 40c487b89757..fdf95b7dcac7 100644
--- a/drivers/gpu/drm/bochs/Kconfig
+++ b/drivers/gpu/drm/bochs/Kconfig
@@ -4,6 +4,7 @@ config DRM_BOCHS
 	select DRM_KMS_HELPER
 	select DRM_TTM
 	select DRM_GEM_TTM_HELPER
+	select DRM_SIMPLE_TTM_HELPER
 	help
 	  Choose this option for qemu.
 	  If M is selected the module will be called bochs-drm.
diff --git a/drivers/gpu/drm/bochs/bochs.h b/drivers/gpu/drm/bochs/bochs.h
index 438bba0b565e..7fbb9ae45e7d 100644
--- a/drivers/gpu/drm/bochs/bochs.h
+++ b/drivers/gpu/drm/bochs/bochs.h
@@ -11,6 +11,8 @@
 #include <drm/drm_gem.h>
 #include <drm/drm_gem_ttm_helper.h>
 
+#include <drm/drm_simple_ttm_helper.h>
+
 #include <drm/ttm/ttm_bo_driver.h>
 #include <drm/ttm/ttm_page_alloc.h>
 
@@ -76,10 +78,8 @@ struct bochs_device {
 	struct drm_connector connector;
 
 	/* ttm */
-	struct {
-		struct ttm_bo_device bdev;
-		bool initialized;
-	} ttm;
+	struct drm_simple_ttm ttm;
+	bool ttm_initialized;
 };
 
 /* ---------------------------------------------------------------------- */
diff --git a/drivers/gpu/drm/bochs/bochs_mm.c b/drivers/gpu/drm/bochs/bochs_mm.c
index 6554fd11676b..c7668ead40bd 100644
--- a/drivers/gpu/drm/bochs/bochs_mm.c
+++ b/drivers/gpu/drm/bochs/bochs_mm.c
@@ -9,138 +9,31 @@
 
 /* ---------------------------------------------------------------------- */
 
-static inline struct bochs_device *bochs_bdev(struct ttm_bo_device *bd)
-{
-	return container_of(bd, struct bochs_device, ttm.bdev);
-}
-
-static int bochs_bo_init_mem_type(struct ttm_bo_device *bdev, uint32_t type,
-				  struct ttm_mem_type_manager *man)
-{
-	switch (type) {
-	case TTM_PL_SYSTEM:
-		man->flags = TTM_MEMTYPE_FLAG_MAPPABLE;
-		man->available_caching = TTM_PL_MASK_CACHING;
-		man->default_caching = TTM_PL_FLAG_CACHED;
-		break;
-	case TTM_PL_VRAM:
-		man->func = &ttm_bo_manager_func;
-		man->flags = TTM_MEMTYPE_FLAG_FIXED |
-			TTM_MEMTYPE_FLAG_MAPPABLE;
-		man->available_caching = TTM_PL_FLAG_UNCACHED |
-			TTM_PL_FLAG_WC;
-		man->default_caching = TTM_PL_FLAG_WC;
-		break;
-	default:
-		DRM_ERROR("Unsupported memory type %u\n", (unsigned)type);
-		return -EINVAL;
-	}
-	return 0;
-}
-
-static int bochs_ttm_io_mem_reserve(struct ttm_bo_device *bdev,
-				    struct ttm_mem_reg *mem)
-{
-	struct ttm_mem_type_manager *man = &bdev->man[mem->mem_type];
-	struct bochs_device *bochs = bochs_bdev(bdev);
-
-	mem->bus.addr = NULL;
-	mem->bus.offset = 0;
-	mem->bus.size = mem->num_pages << PAGE_SHIFT;
-	mem->bus.base = 0;
-	mem->bus.is_iomem = false;
-	if (!(man->flags & TTM_MEMTYPE_FLAG_MAPPABLE))
-		return -EINVAL;
-	switch (mem->mem_type) {
-	case TTM_PL_SYSTEM:
-		/* system memory */
-		return 0;
-	case TTM_PL_VRAM:
-		mem->bus.offset = mem->start << PAGE_SHIFT;
-		mem->bus.base = bochs->fb_base;
-		mem->bus.is_iomem = true;
-		break;
-	default:
-		return -EINVAL;
-		break;
-	}
-	return 0;
-}
-
-static void bochs_ttm_io_mem_free(struct ttm_bo_device *bdev,
-				  struct ttm_mem_reg *mem)
-{
-}
-
-static void bochs_ttm_backend_destroy(struct ttm_tt *tt)
-{
-	ttm_tt_fini(tt);
-	kfree(tt);
-}
-
-static struct ttm_backend_func bochs_tt_backend_func = {
-	.destroy = &bochs_ttm_backend_destroy,
-};
-
-static struct ttm_tt *bochs_ttm_tt_create(struct ttm_buffer_object *bo,
-					  uint32_t page_flags)
-{
-	struct ttm_tt *tt;
-
-	tt = kzalloc(sizeof(struct ttm_tt), GFP_KERNEL);
-	if (tt == NULL)
-		return NULL;
-	tt->func = &bochs_tt_backend_func;
-	if (ttm_tt_init(tt, bo, page_flags)) {
-		kfree(tt);
-		return NULL;
-	}
-	return tt;
-}
-
-static struct ttm_bo_driver bochs_bo_driver = {
-	.ttm_tt_create = bochs_ttm_tt_create,
-	.init_mem_type = bochs_bo_init_mem_type,
-	.eviction_valuable = ttm_bo_eviction_valuable,
+static const struct drm_simple_ttm_funcs bochs_simple_ttm_funcs = {
 	.evict_flags = drm_gem_ttm_bo_driver_evict_flags,
-	.move = NULL,
-	.verify_access = drm_gem_ttm_bo_driver_verify_access,
-	.io_mem_reserve = &bochs_ttm_io_mem_reserve,
-	.io_mem_free = &bochs_ttm_io_mem_free,
+	.verify_access = drm_gem_ttm_bo_driver_verify_access
 };
 
 int bochs_mm_init(struct bochs_device *bochs)
 {
-	struct ttm_bo_device *bdev = &bochs->ttm.bdev;
-	int ret;
-
-	ret = ttm_bo_device_init(&bochs->ttm.bdev,
-				 &bochs_bo_driver,
-				 bochs->dev->anon_inode->i_mapping,
-				 true);
-	if (ret) {
-		DRM_ERROR("Error initialising bo driver; %d\n", ret);
-		return ret;
-	}
-
-	ret = ttm_bo_init_mm(bdev, TTM_PL_VRAM,
-			     bochs->fb_size >> PAGE_SHIFT);
+	int ret = drm_simple_ttm_init(&bochs->ttm, bochs->dev, bochs->fb_base,
+				      bochs->fb_size, &bochs_simple_ttm_funcs);
 	if (ret) {
-		DRM_ERROR("Failed ttm VRAM init: %d\n", ret);
+		DRM_ERROR("Error initializing Simple TTM; %d\n", ret);
 		return ret;
 	}
 
-	bochs->ttm.initialized = true;
+	bochs->ttm_initialized = true;
 	return 0;
 }
 
 void bochs_mm_fini(struct bochs_device *bochs)
 {
-	if (!bochs->ttm.initialized)
+	if (!bochs->ttm_initialized)
 		return;
 
-	ttm_bo_device_release(&bochs->ttm.bdev);
-	bochs->ttm.initialized = false;
+	drm_simple_ttm_cleanup(&bochs->ttm);
+	bochs->ttm_initialized = false;
 }
 
 int bochs_mmap(struct file *filp, struct vm_area_struct *vma)
-- 
2.21.0

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

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

* [PATCH 10/15] drm/mgag200: Convert mgag200 driver to |struct drm_gem_ttm_object|
  2019-04-08  9:21 [PATCH 00/15] Share TTM code among framebuffer drivers Thomas Zimmermann
                   ` (8 preceding siblings ...)
  2019-04-08  9:21 ` [PATCH 09/15] drm/bochs: Convert Bochs driver to Simple TTM Thomas Zimmermann
@ 2019-04-08  9:21 ` Thomas Zimmermann
  2019-04-08  9:21 ` [PATCH 11/15] drm/mgag200: Convert mgag200 driver to Simple TTM Thomas Zimmermann
                   ` (6 subsequent siblings)
  16 siblings, 0 replies; 43+ messages in thread
From: Thomas Zimmermann @ 2019-04-08  9:21 UTC (permalink / raw)
  To: daniel, airlied, kraxel, christian.koenig, ray.huang,
	Jerry.Zhang, hdegoede, z.liuxinliang, zourongrong,
	kong.kongxinwei, puck.chen
  Cc: Thomas Zimmermann, dri-devel, virtualization

Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
---
 drivers/gpu/drm/mgag200/Kconfig          |   1 +
 drivers/gpu/drm/mgag200/mgag200_cursor.c |  61 ++++----
 drivers/gpu/drm/mgag200/mgag200_drv.c    |   4 +-
 drivers/gpu/drm/mgag200/mgag200_drv.h    |  62 ++------
 drivers/gpu/drm/mgag200/mgag200_fb.c     |  18 +--
 drivers/gpu/drm/mgag200/mgag200_main.c   |  84 +++--------
 drivers/gpu/drm/mgag200/mgag200_mode.c   |  45 +++---
 drivers/gpu/drm/mgag200/mgag200_ttm.c    | 172 +----------------------
 8 files changed, 101 insertions(+), 346 deletions(-)

diff --git a/drivers/gpu/drm/mgag200/Kconfig b/drivers/gpu/drm/mgag200/Kconfig
index db58578719d2..b5eed4e0e452 100644
--- a/drivers/gpu/drm/mgag200/Kconfig
+++ b/drivers/gpu/drm/mgag200/Kconfig
@@ -3,6 +3,7 @@ config DRM_MGAG200
 	depends on DRM && PCI && MMU
 	select DRM_KMS_HELPER
 	select DRM_TTM
+	select DRM_GEM_TTM_HELPER
 	help
 	 This is a KMS driver for the MGA G200 server chips, it
          does not support the original MGA G200 or any of the desktop
diff --git a/drivers/gpu/drm/mgag200/mgag200_cursor.c b/drivers/gpu/drm/mgag200/mgag200_cursor.c
index 968e20379d54..7e8e9f92486b 100644
--- a/drivers/gpu/drm/mgag200/mgag200_cursor.c
+++ b/drivers/gpu/drm/mgag200/mgag200_cursor.c
@@ -23,9 +23,9 @@ static void mga_hide_cursor(struct mga_device *mdev)
 	WREG8(MGA_CURPOSXL, 0);
 	WREG8(MGA_CURPOSXH, 0);
 	if (mdev->cursor.pixels_1->pin_count)
-		mgag200_bo_unpin(mdev->cursor.pixels_1);
+		drm_gem_ttm_unpin(mdev->cursor.pixels_1);
 	if (mdev->cursor.pixels_2->pin_count)
-		mgag200_bo_unpin(mdev->cursor.pixels_2);
+		drm_gem_ttm_unpin(mdev->cursor.pixels_2);
 }
 
 int mga_crtc_cursor_set(struct drm_crtc *crtc,
@@ -36,12 +36,12 @@ int mga_crtc_cursor_set(struct drm_crtc *crtc,
 {
 	struct drm_device *dev = crtc->dev;
 	struct mga_device *mdev = (struct mga_device *)dev->dev_private;
-	struct mgag200_bo *pixels_1 = mdev->cursor.pixels_1;
-	struct mgag200_bo *pixels_2 = mdev->cursor.pixels_2;
-	struct mgag200_bo *pixels_current = mdev->cursor.pixels_current;
-	struct mgag200_bo *pixels_prev = mdev->cursor.pixels_prev;
+	struct drm_gem_ttm_object *pixels_1 = mdev->cursor.pixels_1;
+	struct drm_gem_ttm_object *pixels_2 = mdev->cursor.pixels_2;
+	struct drm_gem_ttm_object *pixels_current = mdev->cursor.pixels_current;
+	struct drm_gem_ttm_object *pixels_prev = mdev->cursor.pixels_prev;
 	struct drm_gem_object *obj;
-	struct mgag200_bo *bo = NULL;
+	struct drm_gem_ttm_object *gbo = NULL;
 	int ret = 0;
 	unsigned int i, row, col;
 	uint32_t colour_set[16];
@@ -79,44 +79,55 @@ int mga_crtc_cursor_set(struct drm_crtc *crtc,
 	if (!obj)
 		return -ENOENT;
 
-	ret = mgag200_bo_reserve(pixels_1, true);
+	ret = drm_gem_ttm_reserve(pixels_1, true);
 	if (ret) {
 		WREG8(MGA_CURPOSXL, 0);
 		WREG8(MGA_CURPOSXH, 0);
 		goto out_unref;
 	}
-	ret = mgag200_bo_reserve(pixels_2, true);
+	ret = drm_gem_ttm_reserve(pixels_2, true);
 	if (ret) {
 		WREG8(MGA_CURPOSXL, 0);
 		WREG8(MGA_CURPOSXH, 0);
-		mgag200_bo_unreserve(pixels_1);
+		drm_gem_ttm_unreserve(pixels_1);
 		goto out_unreserve1;
 	}
 
 	/* Move cursor buffers into VRAM if they aren't already */
 	if (!pixels_1->pin_count) {
-		ret = mgag200_bo_pin(pixels_1, TTM_PL_FLAG_VRAM,
-				     &mdev->cursor.pixels_1_gpu_addr);
+		ret = drm_gem_ttm_pin(pixels_1, TTM_PL_FLAG_VRAM);
 		if (ret)
 			goto out1;
+		gpu_addr = drm_gem_ttm_vram_offset(pixels_1);
+		if (gpu_addr < 0) {
+			drm_gem_ttm_unpin(pixels_1);
+			goto out1;
+		}
+		mdev->cursor.pixels_1_gpu_addr = gpu_addr;
 	}
 	if (!pixels_2->pin_count) {
-		ret = mgag200_bo_pin(pixels_2, TTM_PL_FLAG_VRAM,
-				     &mdev->cursor.pixels_2_gpu_addr);
+		ret = drm_gem_ttm_pin(pixels_2, TTM_PL_FLAG_VRAM);
 		if (ret) {
-			mgag200_bo_unpin(pixels_1);
+			drm_gem_ttm_unpin(pixels_1);
+			goto out1;
+		}
+		gpu_addr = drm_gem_ttm_vram_offset(pixels_2);
+		if (gpu_addr < 0) {
+			drm_gem_ttm_unpin(pixels_1);
+			drm_gem_ttm_unpin(pixels_2);
 			goto out1;
 		}
+		mdev->cursor.pixels_2_gpu_addr = gpu_addr;
 	}
 
-	bo = gem_to_mga_bo(obj);
-	ret = mgag200_bo_reserve(bo, true);
+	gbo = drm_gem_ttm_of_gem(obj);
+	ret = drm_gem_ttm_reserve(gbo, true);
 	if (ret) {
 		dev_err(&dev->pdev->dev, "failed to reserve user bo\n");
 		goto out1;
 	}
-	if (!bo->kmap.virtual) {
-		ret = ttm_bo_kmap(&bo->bo, 0, bo->bo.num_pages, &bo->kmap);
+	if (!gbo->kmap.virtual) {
+		ret = ttm_bo_kmap(&gbo->bo, 0, gbo->bo.num_pages, &gbo->kmap);
 		if (ret) {
 			dev_err(&dev->pdev->dev, "failed to kmap user buffer updates\n");
 			goto out2;
@@ -126,7 +137,7 @@ int mga_crtc_cursor_set(struct drm_crtc *crtc,
 	memset(&colour_set[0], 0, sizeof(uint32_t)*16);
 	/* width*height*4 = 16384 */
 	for (i = 0; i < 16384; i += 4) {
-		this_colour = ioread32(bo->kmap.virtual + i);
+		this_colour = ioread32(gbo->kmap.virtual + i);
 		/* No transparency */
 		if (this_colour>>24 != 0xff &&
 			this_colour>>24 != 0x0) {
@@ -192,7 +203,7 @@ int mga_crtc_cursor_set(struct drm_crtc *crtc,
 	for (row = 0; row < 64; row++) {
 		memset(&this_row[0], 0, 48);
 		for (col = 0; col < 64; col++) {
-			this_colour = ioread32(bo->kmap.virtual + 4*(col + 64*row));
+			this_colour = ioread32(gbo->kmap.virtual + 4*(col + 64*row));
 			/* write transparent pixels */
 			if (this_colour>>24 == 0x0) {
 				this_row[47 - col/8] |= 0x80>>(col%8);
@@ -238,15 +249,15 @@ int mga_crtc_cursor_set(struct drm_crtc *crtc,
 
 	ttm_bo_kunmap(&pixels_prev->kmap);
  out3:
-	ttm_bo_kunmap(&bo->kmap);
+	ttm_bo_kunmap(&gbo->kmap);
  out2:
-	mgag200_bo_unreserve(bo);
+	drm_gem_ttm_unreserve(gbo);
  out1:
 	if (ret)
 		mga_hide_cursor(mdev);
-	mgag200_bo_unreserve(pixels_1);
+	drm_gem_ttm_unreserve(pixels_1);
 out_unreserve1:
-	mgag200_bo_unreserve(pixels_2);
+	drm_gem_ttm_unreserve(pixels_2);
 out_unref:
 	drm_gem_object_put_unlocked(obj);
 
diff --git a/drivers/gpu/drm/mgag200/mgag200_drv.c b/drivers/gpu/drm/mgag200/mgag200_drv.c
index ac6af4bd9df6..1fa52c36d78f 100644
--- a/drivers/gpu/drm/mgag200/mgag200_drv.c
+++ b/drivers/gpu/drm/mgag200/mgag200_drv.c
@@ -80,9 +80,9 @@ static struct drm_driver driver = {
 	.minor = DRIVER_MINOR,
 	.patchlevel = DRIVER_PATCHLEVEL,
 
-	.gem_free_object_unlocked = mgag200_gem_free_object,
+	.gem_free_object_unlocked = drm_gem_ttm_driver_gem_free_object_unlocked,
 	.dumb_create = mgag200_dumb_create,
-	.dumb_map_offset = mgag200_dumb_mmap_offset,
+	.dumb_map_offset = drm_gem_ttm_driver_dumb_mmap_offset,
 };
 
 static struct pci_driver mgag200_pci_driver = {
diff --git a/drivers/gpu/drm/mgag200/mgag200_drv.h b/drivers/gpu/drm/mgag200/mgag200_drv.h
index 8c31e4422cae..a3110a0066b9 100644
--- a/drivers/gpu/drm/mgag200/mgag200_drv.h
+++ b/drivers/gpu/drm/mgag200/mgag200_drv.h
@@ -1,6 +1,6 @@
 /*
  * Copyright 2010 Matt Turner.
- * Copyright 2012 Red Hat 
+ * Copyright 2012 Red Hat
  *
  * This file is subject to the terms and conditions of the GNU General
  * Public License version 2. See the file COPYING in the main
@@ -24,6 +24,7 @@
 #include <drm/ttm/ttm_module.h>
 
 #include <drm/drm_gem.h>
+#include <drm/drm_gem_ttm_helper.h>
 
 #include <linux/i2c.h>
 #include <linux/i2c-algo-bit.h>
@@ -159,13 +160,13 @@ struct mga_cursor {
 	   If either of these is NULL, then don't do hardware cursors, and
 	   fall back to software.
 	*/
-	struct mgag200_bo *pixels_1;
-	struct mgag200_bo *pixels_2;
+	struct drm_gem_ttm_object *pixels_1;
+	struct drm_gem_ttm_object *pixels_2;
 	u64 pixels_1_gpu_addr, pixels_2_gpu_addr;
 	/* The currently displayed icon, this points to one of pixels_1, or pixels_2 */
-	struct mgag200_bo *pixels_current;
+	struct drm_gem_ttm_object *pixels_current;
 	/* The previously displayed icon */
-	struct mgag200_bo *pixels_prev;
+	struct drm_gem_ttm_object *pixels_prev;
 };
 
 struct mga_mc {
@@ -219,23 +220,6 @@ struct mga_device {
 	u32 unique_rev_id;
 };
 
-
-struct mgag200_bo {
-	struct ttm_buffer_object bo;
-	struct ttm_placement placement;
-	struct ttm_bo_kmap_obj kmap;
-	struct drm_gem_object gem;
-	struct ttm_place placements[3];
-	int pin_count;
-};
-#define gem_to_mga_bo(gobj) container_of((gobj), struct mgag200_bo, gem)
-
-static inline struct mgag200_bo *
-mgag200_bo(struct ttm_buffer_object *bo)
-{
-	return container_of(bo, struct mgag200_bo, bo);
-}
-
 				/* mgag200_mode.c */
 int mgag200_modeset_init(struct mga_device *mdev);
 void mgag200_modeset_fini(struct mga_device *mdev);
@@ -259,45 +243,15 @@ int mgag200_gem_create(struct drm_device *dev,
 int mgag200_dumb_create(struct drm_file *file,
 			struct drm_device *dev,
 			struct drm_mode_create_dumb *args);
-void mgag200_gem_free_object(struct drm_gem_object *obj);
-int
-mgag200_dumb_mmap_offset(struct drm_file *file,
-			 struct drm_device *dev,
-			 uint32_t handle,
-			 uint64_t *offset);
+
 				/* mgag200_i2c.c */
 struct mga_i2c_chan *mgag200_i2c_create(struct drm_device *dev);
 void mgag200_i2c_destroy(struct mga_i2c_chan *i2c);
 
-void mgag200_ttm_placement(struct mgag200_bo *bo, int domain);
-
-static inline int mgag200_bo_reserve(struct mgag200_bo *bo, bool no_wait)
-{
-	int ret;
-
-	ret = ttm_bo_reserve(&bo->bo, true, no_wait, NULL);
-	if (ret) {
-		if (ret != -ERESTARTSYS && ret != -EBUSY)
-			DRM_ERROR("reserve failed %p\n", bo);
-		return ret;
-	}
-	return 0;
-}
-
-static inline void mgag200_bo_unreserve(struct mgag200_bo *bo)
-{
-	ttm_bo_unreserve(&bo->bo);
-}
-
-int mgag200_bo_create(struct drm_device *dev, int size, int align,
-		      uint32_t flags, struct mgag200_bo **pastbo);
 int mgag200_mm_init(struct mga_device *mdev);
 void mgag200_mm_fini(struct mga_device *mdev);
 int mgag200_mmap(struct file *filp, struct vm_area_struct *vma);
-int mgag200_bo_pin(struct mgag200_bo *bo, u32 pl_flag, u64 *gpu_addr);
-int mgag200_bo_unpin(struct mgag200_bo *bo);
-int mgag200_bo_push_sysram(struct mgag200_bo *bo);
-			   /* mgag200_cursor.c */
+
 int mga_crtc_cursor_set(struct drm_crtc *crtc, struct drm_file *file_priv,
 						uint32_t handle, uint32_t width, uint32_t height);
 int mga_crtc_cursor_move(struct drm_crtc *crtc, int x, int y);
diff --git a/drivers/gpu/drm/mgag200/mgag200_fb.c b/drivers/gpu/drm/mgag200/mgag200_fb.c
index 5b7e64cac004..302c5b7eff2a 100644
--- a/drivers/gpu/drm/mgag200/mgag200_fb.c
+++ b/drivers/gpu/drm/mgag200/mgag200_fb.c
@@ -23,7 +23,7 @@ static void mga_dirty_update(struct mga_fbdev *mfbdev,
 {
 	int i;
 	struct drm_gem_object *obj;
-	struct mgag200_bo *bo;
+	struct drm_gem_ttm_object *gbo;
 	int src_offset, dst_offset;
 	int bpp = mfbdev->mfb.base.format->cpp[0];
 	int ret = -EBUSY;
@@ -33,7 +33,7 @@ static void mga_dirty_update(struct mga_fbdev *mfbdev,
 	unsigned long flags;
 
 	obj = mfbdev->mfb.obj;
-	bo = gem_to_mga_bo(obj);
+	gbo = drm_gem_ttm_of_gem(obj);
 
 	/*
 	 * try and reserve the BO, if we fail with busy
@@ -41,7 +41,7 @@ static void mga_dirty_update(struct mga_fbdev *mfbdev,
 	 * store up the damage until later.
 	 */
 	if (drm_can_sleep())
-		ret = mgag200_bo_reserve(bo, true);
+		ret = drm_gem_ttm_reserve(gbo, true);
 	if (ret) {
 		if (ret != -EBUSY)
 			return;
@@ -75,11 +75,11 @@ static void mga_dirty_update(struct mga_fbdev *mfbdev,
 	mfbdev->x2 = mfbdev->y2 = 0;
 	spin_unlock_irqrestore(&mfbdev->dirty_lock, flags);
 
-	if (!bo->kmap.virtual) {
-		ret = ttm_bo_kmap(&bo->bo, 0, bo->bo.num_pages, &bo->kmap);
+	if (!gbo->kmap.virtual) {
+		ret = ttm_bo_kmap(&gbo->bo, 0, gbo->bo.num_pages, &gbo->kmap);
 		if (ret) {
 			DRM_ERROR("failed to kmap fb updates\n");
-			mgag200_bo_unreserve(bo);
+			drm_gem_ttm_unreserve(gbo);
 			return;
 		}
 		unmap = true;
@@ -87,13 +87,13 @@ static void mga_dirty_update(struct mga_fbdev *mfbdev,
 	for (i = y; i <= y2; i++) {
 		/* assume equal stride for now */
 		src_offset = dst_offset = i * mfbdev->mfb.base.pitches[0] + (x * bpp);
-		memcpy_toio(bo->kmap.virtual + src_offset, mfbdev->sysram + src_offset, (x2 - x + 1) * bpp);
+		memcpy_toio(gbo->kmap.virtual + src_offset, mfbdev->sysram + src_offset, (x2 - x + 1) * bpp);
 
 	}
 	if (unmap)
-		ttm_bo_kunmap(&bo->kmap);
+		ttm_bo_kunmap(&gbo->kmap);
 
-	mgag200_bo_unreserve(bo);
+	drm_gem_ttm_unreserve(gbo);
 }
 
 static void mga_fillrect(struct fb_info *info,
diff --git a/drivers/gpu/drm/mgag200/mgag200_main.c b/drivers/gpu/drm/mgag200/mgag200_main.c
index 163255099779..9a9f6a8dbc9d 100644
--- a/drivers/gpu/drm/mgag200/mgag200_main.c
+++ b/drivers/gpu/drm/mgag200/mgag200_main.c
@@ -230,11 +230,13 @@ int mgag200_driver_load(struct drm_device *dev, unsigned long flags)
 	}
 
 	/* Make small buffers to store a hardware cursor (double buffered icon updates) */
-	mgag200_bo_create(dev, roundup(48*64, PAGE_SIZE), 0, 0,
-					  &mdev->cursor.pixels_1);
-	mgag200_bo_create(dev, roundup(48*64, PAGE_SIZE), 0, 0,
-					  &mdev->cursor.pixels_2);
-	if (!mdev->cursor.pixels_2 || !mdev->cursor.pixels_1) {
+	mdev->cursor.pixels_1 = drm_gem_ttm_create(dev, &mdev->ttm.bdev,
+						   roundup(48*64, PAGE_SIZE),
+						   0, 0);
+	mdev->cursor.pixels_2 = drm_gem_ttm_create(dev, &mdev->ttm.bdev,
+						   roundup(48*64, PAGE_SIZE),
+						   0, 0);
+	if (IS_ERR(mdev->cursor.pixels_2) || IS_ERR(mdev->cursor.pixels_1)) {
 		mdev->cursor.pixels_1 = NULL;
 		mdev->cursor.pixels_2 = NULL;
 		dev_warn(&dev->pdev->dev,
@@ -272,7 +274,8 @@ int mgag200_gem_create(struct drm_device *dev,
 		   u32 size, bool iskernel,
 		   struct drm_gem_object **obj)
 {
-	struct mgag200_bo *astbo;
+	struct mga_device *mdev = dev->dev_private;
+	struct drm_gem_ttm_object *gbo;
 	int ret;
 
 	*obj = NULL;
@@ -281,13 +284,14 @@ int mgag200_gem_create(struct drm_device *dev,
 	if (size == 0)
 		return -EINVAL;
 
-	ret = mgag200_bo_create(dev, size, 0, 0, &astbo);
-	if (ret) {
+	gbo = drm_gem_ttm_create(dev, &mdev->ttm.bdev, size, 0, false);
+	if (IS_ERR(gbo)) {
+		ret = PTR_ERR(gbo);
 		if (ret != -ERESTARTSYS)
 			DRM_ERROR("failed to allocate GEM object\n");
 		return ret;
 	}
-	*obj = &astbo->gem;
+	*obj = &gbo->gem;
 	return 0;
 }
 
@@ -295,64 +299,8 @@ int mgag200_dumb_create(struct drm_file *file,
 		    struct drm_device *dev,
 		    struct drm_mode_create_dumb *args)
 {
-	int ret;
-	struct drm_gem_object *gobj;
-	u32 handle;
-
-	args->pitch = args->width * ((args->bpp + 7) / 8);
-	args->size = args->pitch * args->height;
-
-	ret = mgag200_gem_create(dev, args->size, false,
-			     &gobj);
-	if (ret)
-		return ret;
-
-	ret = drm_gem_handle_create(file, gobj, &handle);
-	drm_gem_object_put_unlocked(gobj);
-	if (ret)
-		return ret;
-
-	args->handle = handle;
-	return 0;
-}
-
-static void mgag200_bo_unref(struct mgag200_bo **bo)
-{
-	if ((*bo) == NULL)
-		return;
-	ttm_bo_put(&((*bo)->bo));
-	*bo = NULL;
-}
-
-void mgag200_gem_free_object(struct drm_gem_object *obj)
-{
-	struct mgag200_bo *mgag200_bo = gem_to_mga_bo(obj);
-
-	mgag200_bo_unref(&mgag200_bo);
-}
-
-
-static inline u64 mgag200_bo_mmap_offset(struct mgag200_bo *bo)
-{
-	return drm_vma_node_offset_addr(&bo->bo.vma_node);
-}
-
-int
-mgag200_dumb_mmap_offset(struct drm_file *file,
-		     struct drm_device *dev,
-		     uint32_t handle,
-		     uint64_t *offset)
-{
-	struct drm_gem_object *obj;
-	struct mgag200_bo *bo;
-
-	obj = drm_gem_object_lookup(file, handle);
-	if (obj == NULL)
-		return -ENOENT;
-
-	bo = gem_to_mga_bo(obj);
-	*offset = mgag200_bo_mmap_offset(bo);
+	struct mga_device *mdev = dev->dev_private;
 
-	drm_gem_object_put_unlocked(obj);
-	return 0;
+	return drm_gem_ttm_fill_create_dumb(file, dev, &mdev->ttm.bdev, 0,
+					    false, args);
 }
diff --git a/drivers/gpu/drm/mgag200/mgag200_mode.c b/drivers/gpu/drm/mgag200/mgag200_mode.c
index 7481a3d556ad..4d3e34523607 100644
--- a/drivers/gpu/drm/mgag200/mgag200_mode.c
+++ b/drivers/gpu/drm/mgag200/mgag200_mode.c
@@ -867,48 +867,57 @@ static int mga_crtc_do_set_base(struct drm_crtc *crtc,
 	struct mga_device *mdev = crtc->dev->dev_private;
 	struct drm_gem_object *obj;
 	struct mga_framebuffer *mga_fb;
-	struct mgag200_bo *bo;
+	struct drm_gem_ttm_object *gbo;
 	int ret;
-	u64 gpu_addr;
+	s64 gpu_addr;
 
 	/* push the previous fb to system ram */
 	if (!atomic && fb) {
 		mga_fb = to_mga_framebuffer(fb);
 		obj = mga_fb->obj;
-		bo = gem_to_mga_bo(obj);
-		ret = mgag200_bo_reserve(bo, false);
+		gbo = drm_gem_ttm_of_gem(obj);
+		ret = drm_gem_ttm_reserve(gbo, false);
 		if (ret)
 			return ret;
-		mgag200_bo_push_sysram(bo);
-		mgag200_bo_unreserve(bo);
+		drm_gem_ttm_push_to_system(gbo);
+		drm_gem_ttm_unreserve(gbo);
 	}
 
 	mga_fb = to_mga_framebuffer(crtc->primary->fb);
 	obj = mga_fb->obj;
-	bo = gem_to_mga_bo(obj);
+	gbo = drm_gem_ttm_of_gem(obj);
 
-	ret = mgag200_bo_reserve(bo, false);
+	ret = drm_gem_ttm_reserve(gbo, false);
 	if (ret)
 		return ret;
 
-	ret = mgag200_bo_pin(bo, TTM_PL_FLAG_VRAM, &gpu_addr);
-	if (ret) {
-		mgag200_bo_unreserve(bo);
-		return ret;
+	ret = drm_gem_ttm_pin(gbo, TTM_PL_FLAG_VRAM);
+	if (ret)
+		goto err_drm_gem_ttm_unreserve;
+	gpu_addr = drm_gem_ttm_vram_offset(gbo);
+	if (gpu_addr < 0) {
+		ret = (int)gpu_addr;
+		goto err_drm_gem_ttm_unpin;
 	}
 
 	if (&mdev->mfbdev->mfb == mga_fb) {
 		/* if pushing console in kmap it */
-		ret = ttm_bo_kmap(&bo->bo, 0, bo->bo.num_pages, &bo->kmap);
+		ret = ttm_bo_kmap(&gbo->bo, 0, gbo->bo.num_pages, &gbo->kmap);
 		if (ret)
 			DRM_ERROR("failed to kmap fbcon\n");
 
 	}
-	mgag200_bo_unreserve(bo);
+	drm_gem_ttm_unreserve(gbo);
 
 	mga_set_start_address(crtc, (u32)gpu_addr);
 
 	return 0;
+
+err_drm_gem_ttm_unpin:
+	drm_gem_ttm_unpin(gbo);
+err_drm_gem_ttm_unreserve:
+	drm_gem_ttm_unreserve(gbo);
+	return ret;
 }
 
 static int mga_crtc_mode_set_base(struct drm_crtc *crtc, int x, int y,
@@ -1428,12 +1437,12 @@ static void mga_crtc_disable(struct drm_crtc *crtc)
 	if (crtc->primary->fb) {
 		struct mga_framebuffer *mga_fb = to_mga_framebuffer(crtc->primary->fb);
 		struct drm_gem_object *obj = mga_fb->obj;
-		struct mgag200_bo *bo = gem_to_mga_bo(obj);
-		ret = mgag200_bo_reserve(bo, false);
+		struct drm_gem_ttm_object *gbo = drm_gem_ttm_of_gem(obj);
+		ret = drm_gem_ttm_reserve(gbo, false);
 		if (ret)
 			return;
-		mgag200_bo_push_sysram(bo);
-		mgag200_bo_unreserve(bo);
+		drm_gem_ttm_push_to_system(gbo);
+		drm_gem_ttm_unreserve(gbo);
 	}
 	crtc->primary->fb = NULL;
 }
diff --git a/drivers/gpu/drm/mgag200/mgag200_ttm.c b/drivers/gpu/drm/mgag200/mgag200_ttm.c
index bd42365a8aa8..34a5c58bde68 100644
--- a/drivers/gpu/drm/mgag200/mgag200_ttm.c
+++ b/drivers/gpu/drm/mgag200/mgag200_ttm.c
@@ -36,23 +36,6 @@ mgag200_bdev(struct ttm_bo_device *bd)
 	return container_of(bd, struct mga_device, ttm.bdev);
 }
 
-static void mgag200_bo_ttm_destroy(struct ttm_buffer_object *tbo)
-{
-	struct mgag200_bo *bo;
-
-	bo = container_of(tbo, struct mgag200_bo, bo);
-
-	drm_gem_object_release(&bo->gem);
-	kfree(bo);
-}
-
-static bool mgag200_ttm_bo_is_mgag200_bo(struct ttm_buffer_object *bo)
-{
-	if (bo->destroy == &mgag200_bo_ttm_destroy)
-		return true;
-	return false;
-}
-
 static int
 mgag200_bo_init_mem_type(struct ttm_bo_device *bdev, uint32_t type,
 		     struct ttm_mem_type_manager *man)
@@ -78,26 +61,6 @@ mgag200_bo_init_mem_type(struct ttm_bo_device *bdev, uint32_t type,
 	return 0;
 }
 
-static void
-mgag200_bo_evict_flags(struct ttm_buffer_object *bo, struct ttm_placement *pl)
-{
-	struct mgag200_bo *mgabo = mgag200_bo(bo);
-
-	if (!mgag200_ttm_bo_is_mgag200_bo(bo))
-		return;
-
-	mgag200_ttm_placement(mgabo, TTM_PL_FLAG_SYSTEM);
-	*pl = mgabo->placement;
-}
-
-static int mgag200_bo_verify_access(struct ttm_buffer_object *bo, struct file *filp)
-{
-	struct mgag200_bo *mgabo = mgag200_bo(bo);
-
-	return drm_vma_node_verify_access(&mgabo->gem.vma_node,
-					  filp->private_data);
-}
-
 static int mgag200_ttm_io_mem_reserve(struct ttm_bo_device *bdev,
 				  struct ttm_mem_reg *mem)
 {
@@ -162,9 +125,9 @@ struct ttm_bo_driver mgag200_bo_driver = {
 	.ttm_tt_create = mgag200_ttm_tt_create,
 	.init_mem_type = mgag200_bo_init_mem_type,
 	.eviction_valuable = ttm_bo_eviction_valuable,
-	.evict_flags = mgag200_bo_evict_flags,
+	.evict_flags = drm_gem_ttm_bo_driver_evict_flags,
 	.move = NULL,
-	.verify_access = mgag200_bo_verify_access,
+	.verify_access = drm_gem_ttm_bo_driver_verify_access,
 	.io_mem_reserve = &mgag200_ttm_io_mem_reserve,
 	.io_mem_free = &mgag200_ttm_io_mem_free,
 };
@@ -211,137 +174,6 @@ void mgag200_mm_fini(struct mga_device *mdev)
 	mdev->fb_mtrr = 0;
 }
 
-void mgag200_ttm_placement(struct mgag200_bo *bo, int domain)
-{
-	u32 c = 0;
-	unsigned i;
-
-	bo->placement.placement = bo->placements;
-	bo->placement.busy_placement = bo->placements;
-	if (domain & TTM_PL_FLAG_VRAM)
-		bo->placements[c++].flags = TTM_PL_FLAG_WC | TTM_PL_FLAG_UNCACHED | TTM_PL_FLAG_VRAM;
-	if (domain & TTM_PL_FLAG_SYSTEM)
-		bo->placements[c++].flags = TTM_PL_MASK_CACHING | TTM_PL_FLAG_SYSTEM;
-	if (!c)
-		bo->placements[c++].flags = TTM_PL_MASK_CACHING | TTM_PL_FLAG_SYSTEM;
-	bo->placement.num_placement = c;
-	bo->placement.num_busy_placement = c;
-	for (i = 0; i < c; ++i) {
-		bo->placements[i].fpfn = 0;
-		bo->placements[i].lpfn = 0;
-	}
-}
-
-int mgag200_bo_create(struct drm_device *dev, int size, int align,
-		  uint32_t flags, struct mgag200_bo **pmgabo)
-{
-	struct mga_device *mdev = dev->dev_private;
-	struct mgag200_bo *mgabo;
-	size_t acc_size;
-	int ret;
-
-	mgabo = kzalloc(sizeof(struct mgag200_bo), GFP_KERNEL);
-	if (!mgabo)
-		return -ENOMEM;
-
-	ret = drm_gem_object_init(dev, &mgabo->gem, size);
-	if (ret) {
-		kfree(mgabo);
-		return ret;
-	}
-
-	mgabo->bo.bdev = &mdev->ttm.bdev;
-
-	mgag200_ttm_placement(mgabo, TTM_PL_FLAG_VRAM | TTM_PL_FLAG_SYSTEM);
-
-	acc_size = ttm_bo_dma_acc_size(&mdev->ttm.bdev, size,
-				       sizeof(struct mgag200_bo));
-
-	ret = ttm_bo_init(&mdev->ttm.bdev, &mgabo->bo, size,
-			  ttm_bo_type_device, &mgabo->placement,
-			  align >> PAGE_SHIFT, false, acc_size,
-			  NULL, NULL, mgag200_bo_ttm_destroy);
-	if (ret)
-		return ret;
-
-	*pmgabo = mgabo;
-	return 0;
-}
-
-static inline u64 mgag200_bo_gpu_offset(struct mgag200_bo *bo)
-{
-	return bo->bo.offset;
-}
-
-int mgag200_bo_pin(struct mgag200_bo *bo, u32 pl_flag, u64 *gpu_addr)
-{
-	struct ttm_operation_ctx ctx = { false, false };
-	int i, ret;
-
-	if (bo->pin_count) {
-		bo->pin_count++;
-		if (gpu_addr)
-			*gpu_addr = mgag200_bo_gpu_offset(bo);
-		return 0;
-	}
-
-	mgag200_ttm_placement(bo, pl_flag);
-	for (i = 0; i < bo->placement.num_placement; i++)
-		bo->placements[i].flags |= TTM_PL_FLAG_NO_EVICT;
-	ret = ttm_bo_validate(&bo->bo, &bo->placement, &ctx);
-	if (ret)
-		return ret;
-
-	bo->pin_count = 1;
-	if (gpu_addr)
-		*gpu_addr = mgag200_bo_gpu_offset(bo);
-	return 0;
-}
-
-int mgag200_bo_unpin(struct mgag200_bo *bo)
-{
-	struct ttm_operation_ctx ctx = { false, false };
-	int i;
-	if (!bo->pin_count) {
-		DRM_ERROR("unpin bad %p\n", bo);
-		return 0;
-	}
-	bo->pin_count--;
-	if (bo->pin_count)
-		return 0;
-
-	for (i = 0; i < bo->placement.num_placement ; i++)
-		bo->placements[i].flags &= ~TTM_PL_FLAG_NO_EVICT;
-	return ttm_bo_validate(&bo->bo, &bo->placement, &ctx);
-}
-
-int mgag200_bo_push_sysram(struct mgag200_bo *bo)
-{
-	struct ttm_operation_ctx ctx = { false, false };
-	int i, ret;
-	if (!bo->pin_count) {
-		DRM_ERROR("unpin bad %p\n", bo);
-		return 0;
-	}
-	bo->pin_count--;
-	if (bo->pin_count)
-		return 0;
-
-	if (bo->kmap.virtual)
-		ttm_bo_kunmap(&bo->kmap);
-
-	mgag200_ttm_placement(bo, TTM_PL_FLAG_SYSTEM);
-	for (i = 0; i < bo->placement.num_placement ; i++)
-		bo->placements[i].flags |= TTM_PL_FLAG_NO_EVICT;
-
-	ret = ttm_bo_validate(&bo->bo, &bo->placement, &ctx);
-	if (ret) {
-		DRM_ERROR("pushing to VRAM failed\n");
-		return ret;
-	}
-	return 0;
-}
-
 int mgag200_mmap(struct file *filp, struct vm_area_struct *vma)
 {
 	struct drm_file *file_priv = filp->private_data;
-- 
2.21.0

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

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

* [PATCH 11/15] drm/mgag200: Convert mgag200 driver to Simple TTM
  2019-04-08  9:21 [PATCH 00/15] Share TTM code among framebuffer drivers Thomas Zimmermann
                   ` (9 preceding siblings ...)
  2019-04-08  9:21 ` [PATCH 10/15] drm/mgag200: Convert mgag200 driver to |struct drm_gem_ttm_object| Thomas Zimmermann
@ 2019-04-08  9:21 ` Thomas Zimmermann
  2019-04-08  9:21 ` [PATCH 12/15] drm/vboxvideo: Convert vboxvideo driver to |struct drm_gem_ttm_object| Thomas Zimmermann
                   ` (5 subsequent siblings)
  16 siblings, 0 replies; 43+ messages in thread
From: Thomas Zimmermann @ 2019-04-08  9:21 UTC (permalink / raw)
  To: daniel, airlied, kraxel, christian.koenig, ray.huang,
	Jerry.Zhang, hdegoede, z.liuxinliang, zourongrong,
	kong.kongxinwei, puck.chen
  Cc: Thomas Zimmermann, dri-devel, virtualization

Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
---
 drivers/gpu/drm/mgag200/Kconfig       |   1 +
 drivers/gpu/drm/mgag200/mgag200_drv.h |   6 +-
 drivers/gpu/drm/mgag200/mgag200_ttm.c | 120 ++------------------------
 3 files changed, 12 insertions(+), 115 deletions(-)

diff --git a/drivers/gpu/drm/mgag200/Kconfig b/drivers/gpu/drm/mgag200/Kconfig
index b5eed4e0e452..6d2c45147caa 100644
--- a/drivers/gpu/drm/mgag200/Kconfig
+++ b/drivers/gpu/drm/mgag200/Kconfig
@@ -4,6 +4,7 @@ config DRM_MGAG200
 	select DRM_KMS_HELPER
 	select DRM_TTM
 	select DRM_GEM_TTM_HELPER
+	select DRM_SIMPLE_TTM_HELPER
 	help
 	 This is a KMS driver for the MGA G200 server chips, it
          does not support the original MGA G200 or any of the desktop
diff --git a/drivers/gpu/drm/mgag200/mgag200_drv.h b/drivers/gpu/drm/mgag200/mgag200_drv.h
index a3110a0066b9..228c433fd151 100644
--- a/drivers/gpu/drm/mgag200/mgag200_drv.h
+++ b/drivers/gpu/drm/mgag200/mgag200_drv.h
@@ -26,6 +26,8 @@
 #include <drm/drm_gem.h>
 #include <drm/drm_gem_ttm_helper.h>
 
+#include <drm/drm_simple_ttm_helper.h>
+
 #include <linux/i2c.h>
 #include <linux/i2c-algo-bit.h>
 
@@ -212,9 +214,7 @@ struct mga_device {
 
 	int fb_mtrr;
 
-	struct {
-		struct ttm_bo_device bdev;
-	} ttm;
+	struct drm_simple_ttm ttm;
 
 	/* SE model number stored in reg 0x1e24 */
 	u32 unique_rev_id;
diff --git a/drivers/gpu/drm/mgag200/mgag200_ttm.c b/drivers/gpu/drm/mgag200/mgag200_ttm.c
index 34a5c58bde68..ffb2c340f6f8 100644
--- a/drivers/gpu/drm/mgag200/mgag200_ttm.c
+++ b/drivers/gpu/drm/mgag200/mgag200_ttm.c
@@ -30,126 +30,22 @@
 
 #include "mgag200_drv.h"
 
-static inline struct mga_device *
-mgag200_bdev(struct ttm_bo_device *bd)
-{
-	return container_of(bd, struct mga_device, ttm.bdev);
-}
-
-static int
-mgag200_bo_init_mem_type(struct ttm_bo_device *bdev, uint32_t type,
-		     struct ttm_mem_type_manager *man)
-{
-	switch (type) {
-	case TTM_PL_SYSTEM:
-		man->flags = TTM_MEMTYPE_FLAG_MAPPABLE;
-		man->available_caching = TTM_PL_MASK_CACHING;
-		man->default_caching = TTM_PL_FLAG_CACHED;
-		break;
-	case TTM_PL_VRAM:
-		man->func = &ttm_bo_manager_func;
-		man->flags = TTM_MEMTYPE_FLAG_FIXED |
-			TTM_MEMTYPE_FLAG_MAPPABLE;
-		man->available_caching = TTM_PL_FLAG_UNCACHED |
-			TTM_PL_FLAG_WC;
-		man->default_caching = TTM_PL_FLAG_WC;
-		break;
-	default:
-		DRM_ERROR("Unsupported memory type %u\n", (unsigned)type);
-		return -EINVAL;
-	}
-	return 0;
-}
-
-static int mgag200_ttm_io_mem_reserve(struct ttm_bo_device *bdev,
-				  struct ttm_mem_reg *mem)
-{
-	struct ttm_mem_type_manager *man = &bdev->man[mem->mem_type];
-	struct mga_device *mdev = mgag200_bdev(bdev);
-
-	mem->bus.addr = NULL;
-	mem->bus.offset = 0;
-	mem->bus.size = mem->num_pages << PAGE_SHIFT;
-	mem->bus.base = 0;
-	mem->bus.is_iomem = false;
-	if (!(man->flags & TTM_MEMTYPE_FLAG_MAPPABLE))
-		return -EINVAL;
-	switch (mem->mem_type) {
-	case TTM_PL_SYSTEM:
-		/* system memory */
-		return 0;
-	case TTM_PL_VRAM:
-		mem->bus.offset = mem->start << PAGE_SHIFT;
-		mem->bus.base = pci_resource_start(mdev->dev->pdev, 0);
-		mem->bus.is_iomem = true;
-		break;
-	default:
-		return -EINVAL;
-		break;
-	}
-	return 0;
-}
-
-static void mgag200_ttm_io_mem_free(struct ttm_bo_device *bdev, struct ttm_mem_reg *mem)
-{
-}
-
-static void mgag200_ttm_backend_destroy(struct ttm_tt *tt)
-{
-	ttm_tt_fini(tt);
-	kfree(tt);
-}
-
-static struct ttm_backend_func mgag200_tt_backend_func = {
-	.destroy = &mgag200_ttm_backend_destroy,
-};
-
-
-static struct ttm_tt *mgag200_ttm_tt_create(struct ttm_buffer_object *bo,
-					    uint32_t page_flags)
-{
-	struct ttm_tt *tt;
-
-	tt = kzalloc(sizeof(struct ttm_tt), GFP_KERNEL);
-	if (tt == NULL)
-		return NULL;
-	tt->func = &mgag200_tt_backend_func;
-	if (ttm_tt_init(tt, bo, page_flags)) {
-		kfree(tt);
-		return NULL;
-	}
-	return tt;
-}
-
-struct ttm_bo_driver mgag200_bo_driver = {
-	.ttm_tt_create = mgag200_ttm_tt_create,
-	.init_mem_type = mgag200_bo_init_mem_type,
-	.eviction_valuable = ttm_bo_eviction_valuable,
+static const struct drm_simple_ttm_funcs mgag200_simple_ttm_funcs = {
 	.evict_flags = drm_gem_ttm_bo_driver_evict_flags,
-	.move = NULL,
-	.verify_access = drm_gem_ttm_bo_driver_verify_access,
-	.io_mem_reserve = &mgag200_ttm_io_mem_reserve,
-	.io_mem_free = &mgag200_ttm_io_mem_free,
+	.verify_access = drm_gem_ttm_bo_driver_verify_access
 };
 
 int mgag200_mm_init(struct mga_device *mdev)
 {
 	int ret;
 	struct drm_device *dev = mdev->dev;
-	struct ttm_bo_device *bdev = &mdev->ttm.bdev;
-
-	ret = ttm_bo_device_init(&mdev->ttm.bdev,
-				 &mgag200_bo_driver,
-				 dev->anon_inode->i_mapping,
-				 true);
-	if (ret) {
-		DRM_ERROR("Error initialising bo driver; %d\n", ret);
-		return ret;
-	}
 
-	ret = ttm_bo_init_mm(bdev, TTM_PL_VRAM, mdev->mc.vram_size >> PAGE_SHIFT);
+	ret = drm_simple_ttm_init(&mdev->ttm, dev,
+				  pci_resource_start(dev->pdev, 0),
+				  mdev->mc.vram_size,
+				  &mgag200_simple_ttm_funcs);
 	if (ret) {
-		DRM_ERROR("Failed ttm VRAM init: %d\n", ret);
+		DRM_ERROR("Error initializing Simple TTM; %d\n", ret);
 		return ret;
 	}
 
@@ -166,7 +62,7 @@ void mgag200_mm_fini(struct mga_device *mdev)
 {
 	struct drm_device *dev = mdev->dev;
 
-	ttm_bo_device_release(&mdev->ttm.bdev);
+	drm_simple_ttm_cleanup(&mdev->ttm);
 
 	arch_io_free_memtype_wc(pci_resource_start(dev->pdev, 0),
 				pci_resource_len(dev->pdev, 0));
-- 
2.21.0

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

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

* [PATCH 12/15] drm/vboxvideo: Convert vboxvideo driver to |struct drm_gem_ttm_object|
  2019-04-08  9:21 [PATCH 00/15] Share TTM code among framebuffer drivers Thomas Zimmermann
                   ` (10 preceding siblings ...)
  2019-04-08  9:21 ` [PATCH 11/15] drm/mgag200: Convert mgag200 driver to Simple TTM Thomas Zimmermann
@ 2019-04-08  9:21 ` Thomas Zimmermann
  2019-04-09  7:09   ` Hans de Goede
  2019-04-09  7:09   ` Hans de Goede
  2019-04-08  9:21 ` [PATCH 13/15] drm/vboxvideo: Convert vboxvideo driver to Simple TTM Thomas Zimmermann
                   ` (4 subsequent siblings)
  16 siblings, 2 replies; 43+ messages in thread
From: Thomas Zimmermann @ 2019-04-08  9:21 UTC (permalink / raw)
  To: daniel, airlied, kraxel, christian.koenig, ray.huang,
	Jerry.Zhang, hdegoede, z.liuxinliang, zourongrong,
	kong.kongxinwei, puck.chen
  Cc: Thomas Zimmermann, dri-devel, virtualization

This patch replaces |struct vbox_bo| and its helpers with the generic
implementation of |struct drm_gem_ttm_object|. The only change in
semantics is that &ttm_bo_driver.verify_access() now does the actual
verification.

Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
---
 drivers/gpu/drm/vboxvideo/Kconfig     |   1 +
 drivers/gpu/drm/vboxvideo/vbox_drv.c  |   5 +-
 drivers/gpu/drm/vboxvideo/vbox_drv.h  |  58 +------
 drivers/gpu/drm/vboxvideo/vbox_fb.c   |  22 +--
 drivers/gpu/drm/vboxvideo/vbox_main.c |  70 +-------
 drivers/gpu/drm/vboxvideo/vbox_mode.c |  36 +++--
 drivers/gpu/drm/vboxvideo/vbox_ttm.c  | 223 +-------------------------
 7 files changed, 45 insertions(+), 370 deletions(-)

diff --git a/drivers/gpu/drm/vboxvideo/Kconfig b/drivers/gpu/drm/vboxvideo/Kconfig
index 1f4182e2e980..c1ca87df81df 100644
--- a/drivers/gpu/drm/vboxvideo/Kconfig
+++ b/drivers/gpu/drm/vboxvideo/Kconfig
@@ -3,6 +3,7 @@ config DRM_VBOXVIDEO
 	depends on DRM && X86 && PCI
 	select DRM_KMS_HELPER
 	select DRM_TTM
+	select DRM_GEM_TTM_HELPER
 	select GENERIC_ALLOCATOR
 	help
 	  This is a KMS driver for the virtual Graphics Card used in
diff --git a/drivers/gpu/drm/vboxvideo/vbox_drv.c b/drivers/gpu/drm/vboxvideo/vbox_drv.c
index fb6a0f0b8167..75b165386935 100644
--- a/drivers/gpu/drm/vboxvideo/vbox_drv.c
+++ b/drivers/gpu/drm/vboxvideo/vbox_drv.c
@@ -215,9 +215,10 @@ static struct drm_driver driver = {
 	.minor = DRIVER_MINOR,
 	.patchlevel = DRIVER_PATCHLEVEL,
 
-	.gem_free_object_unlocked = vbox_gem_free_object,
+	.gem_free_object_unlocked =
+		drm_gem_ttm_driver_gem_free_object_unlocked,
 	.dumb_create = vbox_dumb_create,
-	.dumb_map_offset = vbox_dumb_mmap_offset,
+	.dumb_map_offset = drm_gem_ttm_driver_dumb_mmap_offset,
 	.prime_handle_to_fd = drm_gem_prime_handle_to_fd,
 	.prime_fd_to_handle = drm_gem_prime_fd_to_handle,
 	.gem_prime_export = drm_gem_prime_export,
diff --git a/drivers/gpu/drm/vboxvideo/vbox_drv.h b/drivers/gpu/drm/vboxvideo/vbox_drv.h
index ece31f395540..7db4e961805d 100644
--- a/drivers/gpu/drm/vboxvideo/vbox_drv.h
+++ b/drivers/gpu/drm/vboxvideo/vbox_drv.h
@@ -18,6 +18,7 @@
 #include <drm/drm_encoder.h>
 #include <drm/drm_fb_helper.h>
 #include <drm/drm_gem.h>
+#include <drm/drm_gem_ttm_helper.h>
 
 #include <drm/ttm/ttm_bo_api.h>
 #include <drm/ttm/ttm_bo_driver.h>
@@ -170,73 +171,16 @@ int vboxfb_create(struct drm_fb_helper *helper,
 		  struct drm_fb_helper_surface_size *sizes);
 void vbox_fbdev_fini(struct vbox_private *vbox);
 
-struct vbox_bo {
-	struct ttm_buffer_object bo;
-	struct ttm_placement placement;
-	struct ttm_bo_kmap_obj kmap;
-	struct drm_gem_object gem;
-	struct ttm_place placements[3];
-	int pin_count;
-};
-
-#define gem_to_vbox_bo(gobj) container_of((gobj), struct vbox_bo, gem)
-
-static inline struct vbox_bo *vbox_bo(struct ttm_buffer_object *bo)
-{
-	return container_of(bo, struct vbox_bo, bo);
-}
-
-#define to_vbox_obj(x) container_of(x, struct vbox_gem_object, base)
-
-static inline u64 vbox_bo_gpu_offset(struct vbox_bo *bo)
-{
-	return bo->bo.offset;
-}
-
 int vbox_dumb_create(struct drm_file *file,
 		     struct drm_device *dev,
 		     struct drm_mode_create_dumb *args);
 
-void vbox_gem_free_object(struct drm_gem_object *obj);
-int vbox_dumb_mmap_offset(struct drm_file *file,
-			  struct drm_device *dev,
-			  u32 handle, u64 *offset);
-
 int vbox_mm_init(struct vbox_private *vbox);
 void vbox_mm_fini(struct vbox_private *vbox);
 
-int vbox_bo_create(struct vbox_private *vbox, int size, int align,
-		   u32 flags, struct vbox_bo **pvboxbo);
-
 int vbox_gem_create(struct vbox_private *vbox,
 		    u32 size, bool iskernel, struct drm_gem_object **obj);
-
-int vbox_bo_pin(struct vbox_bo *bo, u32 pl_flag);
-int vbox_bo_unpin(struct vbox_bo *bo);
-
-static inline int vbox_bo_reserve(struct vbox_bo *bo, bool no_wait)
-{
-	int ret;
-
-	ret = ttm_bo_reserve(&bo->bo, true, no_wait, NULL);
-	if (ret) {
-		if (ret != -ERESTARTSYS && ret != -EBUSY)
-			DRM_ERROR("reserve failed %p\n", bo);
-		return ret;
-	}
-	return 0;
-}
-
-static inline void vbox_bo_unreserve(struct vbox_bo *bo)
-{
-	ttm_bo_unreserve(&bo->bo);
-}
-
-void vbox_ttm_placement(struct vbox_bo *bo, int domain);
-int vbox_bo_push_sysram(struct vbox_bo *bo);
 int vbox_mmap(struct file *filp, struct vm_area_struct *vma);
-void *vbox_bo_kmap(struct vbox_bo *bo);
-void vbox_bo_kunmap(struct vbox_bo *bo);
 
 /* vbox_prime.c */
 int vbox_gem_prime_pin(struct drm_gem_object *obj);
diff --git a/drivers/gpu/drm/vboxvideo/vbox_fb.c b/drivers/gpu/drm/vboxvideo/vbox_fb.c
index b724fe7c0c30..1cf0c6bd58b9 100644
--- a/drivers/gpu/drm/vboxvideo/vbox_fb.c
+++ b/drivers/gpu/drm/vboxvideo/vbox_fb.c
@@ -51,9 +51,9 @@ int vboxfb_create(struct drm_fb_helper *helper,
 	struct drm_framebuffer *fb;
 	struct fb_info *info;
 	struct drm_gem_object *gobj;
-	struct vbox_bo *bo;
+	struct drm_gem_ttm_object *gbo;
 	int size, ret;
-	u64 gpu_addr;
+	s64 gpu_addr;
 	u32 pitch;
 
 	mode_cmd.width = sizes->surface_width;
@@ -75,9 +75,9 @@ int vboxfb_create(struct drm_fb_helper *helper,
 	if (ret)
 		return ret;
 
-	bo = gem_to_vbox_bo(gobj);
+	gbo = drm_gem_ttm_of_gem(gobj);
 
-	ret = vbox_bo_pin(bo, TTM_PL_FLAG_VRAM);
+	ret = drm_gem_ttm_pin(gbo, TTM_PL_FLAG_VRAM);
 	if (ret)
 		return ret;
 
@@ -86,7 +86,7 @@ int vboxfb_create(struct drm_fb_helper *helper,
 		return PTR_ERR(info);
 
 	info->screen_size = size;
-	info->screen_base = (char __iomem *)vbox_bo_kmap(bo);
+	info->screen_base = (char __iomem *)drm_gem_ttm_kmap(gbo, true);
 	if (IS_ERR(info->screen_base))
 		return PTR_ERR(info->screen_base);
 
@@ -104,7 +104,9 @@ int vboxfb_create(struct drm_fb_helper *helper,
 
 	drm_fb_helper_fill_info(info, helper, sizes);
 
-	gpu_addr = vbox_bo_gpu_offset(bo);
+	gpu_addr = drm_gem_ttm_vram_offset(gbo);
+	if (gpu_addr < 0)
+		return (int)gpu_addr;
 	info->fix.smem_start = info->apertures->ranges[0].base + gpu_addr;
 	info->fix.smem_len = vbox->available_vram_size - gpu_addr;
 
@@ -132,12 +134,10 @@ void vbox_fbdev_fini(struct vbox_private *vbox)
 	drm_fb_helper_unregister_fbi(&vbox->fb_helper);
 
 	if (afb->obj) {
-		struct vbox_bo *bo = gem_to_vbox_bo(afb->obj);
+		struct drm_gem_ttm_object *gbo = drm_gem_ttm_of_gem(afb->obj);
 
-		vbox_bo_kunmap(bo);
-
-		if (bo->pin_count)
-			vbox_bo_unpin(bo);
+		drm_gem_ttm_kunmap(gbo);
+		drm_gem_ttm_unpin(gbo);
 
 		drm_gem_object_put_unlocked(afb->obj);
 		afb->obj = NULL;
diff --git a/drivers/gpu/drm/vboxvideo/vbox_main.c b/drivers/gpu/drm/vboxvideo/vbox_main.c
index f4d02de5518a..0c3ede058f2b 100644
--- a/drivers/gpu/drm/vboxvideo/vbox_main.c
+++ b/drivers/gpu/drm/vboxvideo/vbox_main.c
@@ -274,7 +274,7 @@ void vbox_hw_fini(struct vbox_private *vbox)
 int vbox_gem_create(struct vbox_private *vbox,
 		    u32 size, bool iskernel, struct drm_gem_object **obj)
 {
-	struct vbox_bo *vboxbo;
+	struct drm_gem_ttm_object *gbo;
 	int ret;
 
 	*obj = NULL;
@@ -283,14 +283,15 @@ int vbox_gem_create(struct vbox_private *vbox,
 	if (size == 0)
 		return -EINVAL;
 
-	ret = vbox_bo_create(vbox, size, 0, 0, &vboxbo);
-	if (ret) {
+	gbo = drm_gem_ttm_create(&vbox->ddev, &vbox->ttm.bdev, size, 0, false);
+	if (IS_ERR(gbo)) {
+		ret = PTR_ERR(gbo);
 		if (ret != -ERESTARTSYS)
 			DRM_ERROR("failed to allocate GEM object\n");
 		return ret;
 	}
 
-	*obj = &vboxbo->gem;
+	*obj = &gbo->gem;
 
 	return 0;
 }
@@ -298,64 +299,9 @@ int vbox_gem_create(struct vbox_private *vbox,
 int vbox_dumb_create(struct drm_file *file,
 		     struct drm_device *dev, struct drm_mode_create_dumb *args)
 {
-	struct vbox_private *vbox =
-		container_of(dev, struct vbox_private, ddev);
-	struct drm_gem_object *gobj;
-	u32 handle;
-	int ret;
-
-	args->pitch = args->width * ((args->bpp + 7) / 8);
-	args->size = args->pitch * args->height;
-
-	ret = vbox_gem_create(vbox, args->size, false, &gobj);
-	if (ret)
-		return ret;
-
-	ret = drm_gem_handle_create(file, gobj, &handle);
-	drm_gem_object_put_unlocked(gobj);
-	if (ret)
-		return ret;
+	struct vbox_private *vbox = dev->dev_private;
 
-	args->handle = handle;
-
-	return 0;
-}
-
-void vbox_gem_free_object(struct drm_gem_object *obj)
-{
-	struct vbox_bo *vbox_bo = gem_to_vbox_bo(obj);
+	return drm_gem_ttm_fill_create_dumb(file, dev, &vbox->ttm.bdev, 0,
+					    false, args);
 
-	ttm_bo_put(&vbox_bo->bo);
-}
-
-static inline u64 vbox_bo_mmap_offset(struct vbox_bo *bo)
-{
-	return drm_vma_node_offset_addr(&bo->bo.vma_node);
-}
-
-int
-vbox_dumb_mmap_offset(struct drm_file *file,
-		      struct drm_device *dev,
-		      u32 handle, u64 *offset)
-{
-	struct drm_gem_object *obj;
-	int ret;
-	struct vbox_bo *bo;
-
-	mutex_lock(&dev->struct_mutex);
-	obj = drm_gem_object_lookup(file, handle);
-	if (!obj) {
-		ret = -ENOENT;
-		goto out_unlock;
-	}
-
-	bo = gem_to_vbox_bo(obj);
-	*offset = vbox_bo_mmap_offset(bo);
-
-	drm_gem_object_put(obj);
-	ret = 0;
-
-out_unlock:
-	mutex_unlock(&dev->struct_mutex);
-	return ret;
 }
diff --git a/drivers/gpu/drm/vboxvideo/vbox_mode.c b/drivers/gpu/drm/vboxvideo/vbox_mode.c
index 620a6e38f71f..faabf2801739 100644
--- a/drivers/gpu/drm/vboxvideo/vbox_mode.c
+++ b/drivers/gpu/drm/vboxvideo/vbox_mode.c
@@ -173,7 +173,8 @@ static void vbox_crtc_set_base_and_mode(struct drm_crtc *crtc,
 					struct drm_framebuffer *fb,
 					int x, int y)
 {
-	struct vbox_bo *bo = gem_to_vbox_bo(to_vbox_framebuffer(fb)->obj);
+	struct drm_gem_ttm_object *gbo =
+		drm_gem_ttm_of_gem(to_vbox_framebuffer(fb)->obj);
 	struct vbox_private *vbox = crtc->dev->dev_private;
 	struct vbox_crtc *vbox_crtc = to_vbox_crtc(crtc);
 	bool needs_modeset = drm_atomic_crtc_needs_modeset(crtc->state);
@@ -187,7 +188,7 @@ static void vbox_crtc_set_base_and_mode(struct drm_crtc *crtc,
 
 	vbox_crtc->x = x;
 	vbox_crtc->y = y;
-	vbox_crtc->fb_offset = vbox_bo_gpu_offset(bo);
+	vbox_crtc->fb_offset = drm_gem_ttm_vram_offset(gbo);
 
 	/* vbox_do_modeset() checks vbox->single_framebuffer so update it now */
 	if (needs_modeset && vbox_set_up_input_mapping(vbox)) {
@@ -303,14 +304,14 @@ static void vbox_primary_atomic_disable(struct drm_plane *plane,
 static int vbox_primary_prepare_fb(struct drm_plane *plane,
 				   struct drm_plane_state *new_state)
 {
-	struct vbox_bo *bo;
+	struct drm_gem_ttm_object *gbo;
 	int ret;
 
 	if (!new_state->fb)
 		return 0;
 
-	bo = gem_to_vbox_bo(to_vbox_framebuffer(new_state->fb)->obj);
-	ret = vbox_bo_pin(bo, TTM_PL_FLAG_VRAM);
+	gbo = drm_gem_ttm_of_gem(to_vbox_framebuffer(new_state->fb)->obj);
+	ret = drm_gem_ttm_pin(gbo, TTM_PL_FLAG_VRAM);
 	if (ret)
 		DRM_WARN("Error %d pinning new fb, out of video mem?\n", ret);
 
@@ -320,13 +321,13 @@ static int vbox_primary_prepare_fb(struct drm_plane *plane,
 static void vbox_primary_cleanup_fb(struct drm_plane *plane,
 				    struct drm_plane_state *old_state)
 {
-	struct vbox_bo *bo;
+	struct drm_gem_ttm_object *gbo;
 
 	if (!old_state->fb)
 		return;
 
-	bo = gem_to_vbox_bo(to_vbox_framebuffer(old_state->fb)->obj);
-	vbox_bo_unpin(bo);
+	gbo = drm_gem_ttm_of_gem(to_vbox_framebuffer(old_state->fb)->obj);
+	drm_gem_ttm_unpin(gbo);
 }
 
 static int vbox_cursor_atomic_check(struct drm_plane *plane,
@@ -386,7 +387,8 @@ static void vbox_cursor_atomic_update(struct drm_plane *plane,
 		container_of(plane->dev, struct vbox_private, ddev);
 	struct vbox_crtc *vbox_crtc = to_vbox_crtc(plane->state->crtc);
 	struct drm_framebuffer *fb = plane->state->fb;
-	struct vbox_bo *bo = gem_to_vbox_bo(to_vbox_framebuffer(fb)->obj);
+	struct drm_gem_ttm_object *gbo =
+		drm_gem_ttm_of_gem(to_vbox_framebuffer(fb)->obj);
 	u32 width = plane->state->crtc_w;
 	u32 height = plane->state->crtc_h;
 	size_t data_size, mask_size;
@@ -405,7 +407,7 @@ static void vbox_cursor_atomic_update(struct drm_plane *plane,
 	vbox_crtc->cursor_enabled = true;
 
 	/* pinning is done in prepare/cleanup framebuffer */
-	src = vbox_bo_kmap(bo);
+	src = drm_gem_ttm_kmap(gbo, true);
 	if (IS_ERR(src)) {
 		mutex_unlock(&vbox->hw_mutex);
 		DRM_WARN("Could not kmap cursor bo, skipping update\n");
@@ -421,7 +423,7 @@ static void vbox_cursor_atomic_update(struct drm_plane *plane,
 	data_size = width * height * 4 + mask_size;
 
 	copy_cursor_image(src, vbox->cursor_data, width, height, mask_size);
-	vbox_bo_kunmap(bo);
+	drm_gem_ttm_kunmap(gbo);
 
 	flags = VBOX_MOUSE_POINTER_VISIBLE | VBOX_MOUSE_POINTER_SHAPE |
 		VBOX_MOUSE_POINTER_ALPHA;
@@ -461,25 +463,25 @@ static void vbox_cursor_atomic_disable(struct drm_plane *plane,
 static int vbox_cursor_prepare_fb(struct drm_plane *plane,
 				  struct drm_plane_state *new_state)
 {
-	struct vbox_bo *bo;
+	struct drm_gem_ttm_object *gbo;
 
 	if (!new_state->fb)
 		return 0;
 
-	bo = gem_to_vbox_bo(to_vbox_framebuffer(new_state->fb)->obj);
-	return vbox_bo_pin(bo, TTM_PL_FLAG_SYSTEM);
+	gbo = drm_gem_ttm_of_gem(to_vbox_framebuffer(new_state->fb)->obj);
+	return drm_gem_ttm_pin(gbo, TTM_PL_FLAG_SYSTEM);
 }
 
 static void vbox_cursor_cleanup_fb(struct drm_plane *plane,
 				   struct drm_plane_state *old_state)
 {
-	struct vbox_bo *bo;
+	struct drm_gem_ttm_object *gbo;
 
 	if (!plane->state->fb)
 		return;
 
-	bo = gem_to_vbox_bo(to_vbox_framebuffer(plane->state->fb)->obj);
-	vbox_bo_unpin(bo);
+	gbo = drm_gem_ttm_of_gem(to_vbox_framebuffer(plane->state->fb)->obj);
+	drm_gem_ttm_unpin(gbo);
 }
 
 static const u32 vbox_cursor_plane_formats[] = {
diff --git a/drivers/gpu/drm/vboxvideo/vbox_ttm.c b/drivers/gpu/drm/vboxvideo/vbox_ttm.c
index 9d78438c2877..a1d64e1ea90c 100644
--- a/drivers/gpu/drm/vboxvideo/vbox_ttm.c
+++ b/drivers/gpu/drm/vboxvideo/vbox_ttm.c
@@ -16,24 +16,6 @@ static inline struct vbox_private *vbox_bdev(struct ttm_bo_device *bd)
 	return container_of(bd, struct vbox_private, ttm.bdev);
 }
 
-static void vbox_bo_ttm_destroy(struct ttm_buffer_object *tbo)
-{
-	struct vbox_bo *bo;
-
-	bo = container_of(tbo, struct vbox_bo, bo);
-
-	drm_gem_object_release(&bo->gem);
-	kfree(bo);
-}
-
-static bool vbox_ttm_bo_is_vbox_bo(struct ttm_buffer_object *bo)
-{
-	if (bo->destroy == &vbox_bo_ttm_destroy)
-		return true;
-
-	return false;
-}
-
 static int
 vbox_bo_init_mem_type(struct ttm_bo_device *bdev, u32 type,
 		      struct ttm_mem_type_manager *man)
@@ -58,24 +40,6 @@ vbox_bo_init_mem_type(struct ttm_bo_device *bdev, u32 type,
 	return 0;
 }
 
-static void
-vbox_bo_evict_flags(struct ttm_buffer_object *bo, struct ttm_placement *pl)
-{
-	struct vbox_bo *vboxbo = vbox_bo(bo);
-
-	if (!vbox_ttm_bo_is_vbox_bo(bo))
-		return;
-
-	vbox_ttm_placement(vboxbo, TTM_PL_FLAG_SYSTEM);
-	*pl = vboxbo->placement;
-}
-
-static int vbox_bo_verify_access(struct ttm_buffer_object *bo,
-				 struct file *filp)
-{
-	return 0;
-}
-
 static int vbox_ttm_io_mem_reserve(struct ttm_bo_device *bdev,
 				   struct ttm_mem_reg *mem)
 {
@@ -141,8 +105,8 @@ static struct ttm_bo_driver vbox_bo_driver = {
 	.ttm_tt_create = vbox_ttm_tt_create,
 	.init_mem_type = vbox_bo_init_mem_type,
 	.eviction_valuable = ttm_bo_eviction_valuable,
-	.evict_flags = vbox_bo_evict_flags,
-	.verify_access = vbox_bo_verify_access,
+	.evict_flags = drm_gem_ttm_bo_driver_evict_flags,
+	.verify_access = drm_gem_ttm_bo_driver_verify_access,
 	.io_mem_reserve = &vbox_ttm_io_mem_reserve,
 	.io_mem_free = &vbox_ttm_io_mem_free,
 };
@@ -196,165 +160,6 @@ void vbox_mm_fini(struct vbox_private *vbox)
 	ttm_bo_device_release(&vbox->ttm.bdev);
 }
 
-void vbox_ttm_placement(struct vbox_bo *bo, int domain)
-{
-	unsigned int i;
-	u32 c = 0;
-
-	bo->placement.placement = bo->placements;
-	bo->placement.busy_placement = bo->placements;
-
-	if (domain & TTM_PL_FLAG_VRAM)
-		bo->placements[c++].flags =
-		    TTM_PL_FLAG_WC | TTM_PL_FLAG_UNCACHED | TTM_PL_FLAG_VRAM;
-	if (domain & TTM_PL_FLAG_SYSTEM)
-		bo->placements[c++].flags =
-		    TTM_PL_MASK_CACHING | TTM_PL_FLAG_SYSTEM;
-	if (!c)
-		bo->placements[c++].flags =
-		    TTM_PL_MASK_CACHING | TTM_PL_FLAG_SYSTEM;
-
-	bo->placement.num_placement = c;
-	bo->placement.num_busy_placement = c;
-
-	for (i = 0; i < c; ++i) {
-		bo->placements[i].fpfn = 0;
-		bo->placements[i].lpfn = 0;
-	}
-}
-
-int vbox_bo_create(struct vbox_private *vbox, int size, int align,
-		   u32 flags, struct vbox_bo **pvboxbo)
-{
-	struct vbox_bo *vboxbo;
-	size_t acc_size;
-	int ret;
-
-	vboxbo = kzalloc(sizeof(*vboxbo), GFP_KERNEL);
-	if (!vboxbo)
-		return -ENOMEM;
-
-	ret = drm_gem_object_init(&vbox->ddev, &vboxbo->gem, size);
-	if (ret)
-		goto err_free_vboxbo;
-
-	vboxbo->bo.bdev = &vbox->ttm.bdev;
-
-	vbox_ttm_placement(vboxbo, TTM_PL_FLAG_VRAM | TTM_PL_FLAG_SYSTEM);
-
-	acc_size = ttm_bo_dma_acc_size(&vbox->ttm.bdev, size,
-				       sizeof(struct vbox_bo));
-
-	ret = ttm_bo_init(&vbox->ttm.bdev, &vboxbo->bo, size,
-			  ttm_bo_type_device, &vboxbo->placement,
-			  align >> PAGE_SHIFT, false, acc_size,
-			  NULL, NULL, vbox_bo_ttm_destroy);
-	if (ret)
-		goto err_free_vboxbo;
-
-	*pvboxbo = vboxbo;
-
-	return 0;
-
-err_free_vboxbo:
-	kfree(vboxbo);
-	return ret;
-}
-
-int vbox_bo_pin(struct vbox_bo *bo, u32 pl_flag)
-{
-	struct ttm_operation_ctx ctx = { false, false };
-	int i, ret;
-
-	if (bo->pin_count) {
-		bo->pin_count++;
-		return 0;
-	}
-
-	ret = vbox_bo_reserve(bo, false);
-	if (ret)
-		return ret;
-
-	vbox_ttm_placement(bo, pl_flag);
-
-	for (i = 0; i < bo->placement.num_placement; i++)
-		bo->placements[i].flags |= TTM_PL_FLAG_NO_EVICT;
-
-	ret = ttm_bo_validate(&bo->bo, &bo->placement, &ctx);
-	if (ret == 0)
-		bo->pin_count = 1;
-
-	vbox_bo_unreserve(bo);
-
-	return ret;
-}
-
-int vbox_bo_unpin(struct vbox_bo *bo)
-{
-	struct ttm_operation_ctx ctx = { false, false };
-	int i, ret;
-
-	if (!bo->pin_count) {
-		DRM_ERROR("unpin bad %p\n", bo);
-		return 0;
-	}
-	bo->pin_count--;
-	if (bo->pin_count)
-		return 0;
-
-	ret = vbox_bo_reserve(bo, false);
-	if (ret) {
-		DRM_ERROR("Error %d reserving bo, leaving it pinned\n", ret);
-		return ret;
-	}
-
-	for (i = 0; i < bo->placement.num_placement; i++)
-		bo->placements[i].flags &= ~TTM_PL_FLAG_NO_EVICT;
-
-	ret = ttm_bo_validate(&bo->bo, &bo->placement, &ctx);
-
-	vbox_bo_unreserve(bo);
-
-	return ret;
-}
-
-/*
- * Move a vbox-owned buffer object to system memory if no one else has it
- * pinned.  The caller must have pinned it previously, and this call will
- * release the caller's pin.
- */
-int vbox_bo_push_sysram(struct vbox_bo *bo)
-{
-	struct ttm_operation_ctx ctx = { false, false };
-	int i, ret;
-
-	if (!bo->pin_count) {
-		DRM_ERROR("unpin bad %p\n", bo);
-		return 0;
-	}
-	bo->pin_count--;
-	if (bo->pin_count)
-		return 0;
-
-	if (bo->kmap.virtual) {
-		ttm_bo_kunmap(&bo->kmap);
-		bo->kmap.virtual = NULL;
-	}
-
-	vbox_ttm_placement(bo, TTM_PL_FLAG_SYSTEM);
-
-	for (i = 0; i < bo->placement.num_placement; i++)
-		bo->placements[i].flags |= TTM_PL_FLAG_NO_EVICT;
-
-	ret = ttm_bo_validate(&bo->bo, &bo->placement, &ctx);
-	if (ret) {
-		DRM_ERROR("pushing to VRAM failed\n");
-		return ret;
-	}
-
-	return 0;
-}
-
 int vbox_mmap(struct file *filp, struct vm_area_struct *vma)
 {
 	struct drm_file *file_priv = filp->private_data;
@@ -362,27 +167,3 @@ int vbox_mmap(struct file *filp, struct vm_area_struct *vma)
 
 	return ttm_bo_mmap(filp, vma, &vbox->ttm.bdev);
 }
-
-void *vbox_bo_kmap(struct vbox_bo *bo)
-{
-	int ret;
-
-	if (bo->kmap.virtual)
-		return bo->kmap.virtual;
-
-	ret = ttm_bo_kmap(&bo->bo, 0, bo->bo.num_pages, &bo->kmap);
-	if (ret) {
-		DRM_ERROR("Error kmapping bo: %d\n", ret);
-		return NULL;
-	}
-
-	return bo->kmap.virtual;
-}
-
-void vbox_bo_kunmap(struct vbox_bo *bo)
-{
-	if (bo->kmap.virtual) {
-		ttm_bo_kunmap(&bo->kmap);
-		bo->kmap.virtual = NULL;
-	}
-}
-- 
2.21.0

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

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

* [PATCH 13/15] drm/vboxvideo: Convert vboxvideo driver to Simple TTM
  2019-04-08  9:21 [PATCH 00/15] Share TTM code among framebuffer drivers Thomas Zimmermann
                   ` (11 preceding siblings ...)
  2019-04-08  9:21 ` [PATCH 12/15] drm/vboxvideo: Convert vboxvideo driver to |struct drm_gem_ttm_object| Thomas Zimmermann
@ 2019-04-08  9:21 ` Thomas Zimmermann
  2019-04-09  7:09   ` Hans de Goede
  2019-04-09  7:09   ` Hans de Goede
  2019-04-08  9:21 ` [PATCH 14/15] drm/hisilicon: Convert hibmc-drm driver to |struct drm_gem_ttm_object| Thomas Zimmermann
                   ` (3 subsequent siblings)
  16 siblings, 2 replies; 43+ messages in thread
From: Thomas Zimmermann @ 2019-04-08  9:21 UTC (permalink / raw)
  To: daniel, airlied, kraxel, christian.koenig, ray.huang,
	Jerry.Zhang, hdegoede, z.liuxinliang, zourongrong,
	kong.kongxinwei, puck.chen
  Cc: Thomas Zimmermann, dri-devel, virtualization

Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
---
 drivers/gpu/drm/vboxvideo/Kconfig    |   1 +
 drivers/gpu/drm/vboxvideo/vbox_drv.h |   6 +-
 drivers/gpu/drm/vboxvideo/vbox_ttm.c | 123 ++-------------------------
 3 files changed, 12 insertions(+), 118 deletions(-)

diff --git a/drivers/gpu/drm/vboxvideo/Kconfig b/drivers/gpu/drm/vboxvideo/Kconfig
index c1ca87df81df..e29df360978d 100644
--- a/drivers/gpu/drm/vboxvideo/Kconfig
+++ b/drivers/gpu/drm/vboxvideo/Kconfig
@@ -4,6 +4,7 @@ config DRM_VBOXVIDEO
 	select DRM_KMS_HELPER
 	select DRM_TTM
 	select DRM_GEM_TTM_HELPER
+	select DRM_SIMPLE_TTM_HELPER
 	select GENERIC_ALLOCATOR
 	help
 	  This is a KMS driver for the virtual Graphics Card used in
diff --git a/drivers/gpu/drm/vboxvideo/vbox_drv.h b/drivers/gpu/drm/vboxvideo/vbox_drv.h
index 7db4e961805d..d4cfcc6339ef 100644
--- a/drivers/gpu/drm/vboxvideo/vbox_drv.h
+++ b/drivers/gpu/drm/vboxvideo/vbox_drv.h
@@ -20,6 +20,8 @@
 #include <drm/drm_gem.h>
 #include <drm/drm_gem_ttm_helper.h>
 
+#include <drm/drm_simple_ttm_helper.h>
+
 #include <drm/ttm/ttm_bo_api.h>
 #include <drm/ttm/ttm_bo_driver.h>
 #include <drm/ttm/ttm_placement.h>
@@ -78,9 +80,7 @@ struct vbox_private {
 
 	int fb_mtrr;
 
-	struct {
-		struct ttm_bo_device bdev;
-	} ttm;
+	struct drm_simple_ttm ttm;
 
 	struct mutex hw_mutex; /* protects modeset and accel/vbva accesses */
 	struct work_struct hotplug_work;
diff --git a/drivers/gpu/drm/vboxvideo/vbox_ttm.c b/drivers/gpu/drm/vboxvideo/vbox_ttm.c
index a1d64e1ea90c..115ec44636ab 100644
--- a/drivers/gpu/drm/vboxvideo/vbox_ttm.c
+++ b/drivers/gpu/drm/vboxvideo/vbox_ttm.c
@@ -11,128 +11,25 @@
 #include <drm/ttm/ttm_page_alloc.h>
 #include "vbox_drv.h"
 
-static inline struct vbox_private *vbox_bdev(struct ttm_bo_device *bd)
-{
-	return container_of(bd, struct vbox_private, ttm.bdev);
-}
-
-static int
-vbox_bo_init_mem_type(struct ttm_bo_device *bdev, u32 type,
-		      struct ttm_mem_type_manager *man)
-{
-	switch (type) {
-	case TTM_PL_SYSTEM:
-		man->flags = TTM_MEMTYPE_FLAG_MAPPABLE;
-		man->available_caching = TTM_PL_MASK_CACHING;
-		man->default_caching = TTM_PL_FLAG_CACHED;
-		break;
-	case TTM_PL_VRAM:
-		man->func = &ttm_bo_manager_func;
-		man->flags = TTM_MEMTYPE_FLAG_FIXED | TTM_MEMTYPE_FLAG_MAPPABLE;
-		man->available_caching = TTM_PL_FLAG_UNCACHED | TTM_PL_FLAG_WC;
-		man->default_caching = TTM_PL_FLAG_WC;
-		break;
-	default:
-		DRM_ERROR("Unsupported memory type %u\n", (unsigned int)type);
-		return -EINVAL;
-	}
-
-	return 0;
-}
-
-static int vbox_ttm_io_mem_reserve(struct ttm_bo_device *bdev,
-				   struct ttm_mem_reg *mem)
-{
-	struct ttm_mem_type_manager *man = &bdev->man[mem->mem_type];
-	struct vbox_private *vbox = vbox_bdev(bdev);
-
-	mem->bus.addr = NULL;
-	mem->bus.offset = 0;
-	mem->bus.size = mem->num_pages << PAGE_SHIFT;
-	mem->bus.base = 0;
-	mem->bus.is_iomem = false;
-	if (!(man->flags & TTM_MEMTYPE_FLAG_MAPPABLE))
-		return -EINVAL;
-	switch (mem->mem_type) {
-	case TTM_PL_SYSTEM:
-		/* system memory */
-		return 0;
-	case TTM_PL_VRAM:
-		mem->bus.offset = mem->start << PAGE_SHIFT;
-		mem->bus.base = pci_resource_start(vbox->ddev.pdev, 0);
-		mem->bus.is_iomem = true;
-		break;
-	default:
-		return -EINVAL;
-	}
-	return 0;
-}
-
-static void vbox_ttm_io_mem_free(struct ttm_bo_device *bdev,
-				 struct ttm_mem_reg *mem)
-{
-}
-
-static void vbox_ttm_backend_destroy(struct ttm_tt *tt)
-{
-	ttm_tt_fini(tt);
-	kfree(tt);
-}
-
-static struct ttm_backend_func vbox_tt_backend_func = {
-	.destroy = &vbox_ttm_backend_destroy,
-};
-
-static struct ttm_tt *vbox_ttm_tt_create(struct ttm_buffer_object *bo,
-					 u32 page_flags)
-{
-	struct ttm_tt *tt;
-
-	tt = kzalloc(sizeof(*tt), GFP_KERNEL);
-	if (!tt)
-		return NULL;
-
-	tt->func = &vbox_tt_backend_func;
-	if (ttm_tt_init(tt, bo, page_flags)) {
-		kfree(tt);
-		return NULL;
-	}
-
-	return tt;
-}
-
-static struct ttm_bo_driver vbox_bo_driver = {
-	.ttm_tt_create = vbox_ttm_tt_create,
-	.init_mem_type = vbox_bo_init_mem_type,
-	.eviction_valuable = ttm_bo_eviction_valuable,
+static const struct drm_simple_ttm_funcs vbox_simple_ttm_funcs = {
 	.evict_flags = drm_gem_ttm_bo_driver_evict_flags,
-	.verify_access = drm_gem_ttm_bo_driver_verify_access,
-	.io_mem_reserve = &vbox_ttm_io_mem_reserve,
-	.io_mem_free = &vbox_ttm_io_mem_free,
+	.verify_access = drm_gem_ttm_bo_driver_verify_access
 };
 
 int vbox_mm_init(struct vbox_private *vbox)
 {
 	int ret;
 	struct drm_device *dev = &vbox->ddev;
-	struct ttm_bo_device *bdev = &vbox->ttm.bdev;
 
-	ret = ttm_bo_device_init(&vbox->ttm.bdev,
-				 &vbox_bo_driver,
-				 dev->anon_inode->i_mapping,
-				 true);
+	ret = drm_simple_ttm_init(&vbox->ttm, dev,
+				  pci_resource_start(dev->pdev, 0),
+				  vbox->available_vram_size,
+				  &vbox_simple_ttm_funcs);
 	if (ret) {
-		DRM_ERROR("Error initialising bo driver; %d\n", ret);
+		DRM_ERROR("Error initializing Simple TTM; %d\n", ret);
 		return ret;
 	}
 
-	ret = ttm_bo_init_mm(bdev, TTM_PL_VRAM,
-			     vbox->available_vram_size >> PAGE_SHIFT);
-	if (ret) {
-		DRM_ERROR("Failed ttm VRAM init: %d\n", ret);
-		goto err_device_release;
-	}
-
 #ifdef DRM_MTRR_WC
 	vbox->fb_mtrr = drm_mtrr_add(pci_resource_start(dev->pdev, 0),
 				     pci_resource_len(dev->pdev, 0),
@@ -142,10 +39,6 @@ int vbox_mm_init(struct vbox_private *vbox)
 					 pci_resource_len(dev->pdev, 0));
 #endif
 	return 0;
-
-err_device_release:
-	ttm_bo_device_release(&vbox->ttm.bdev);
-	return ret;
 }
 
 void vbox_mm_fini(struct vbox_private *vbox)
@@ -157,7 +50,7 @@ void vbox_mm_fini(struct vbox_private *vbox)
 #else
 	arch_phys_wc_del(vbox->fb_mtrr);
 #endif
-	ttm_bo_device_release(&vbox->ttm.bdev);
+	drm_simple_ttm_cleanup(&vbox->ttm);
 }
 
 int vbox_mmap(struct file *filp, struct vm_area_struct *vma)
-- 
2.21.0

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

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

* [PATCH 14/15] drm/hisilicon: Convert hibmc-drm driver to |struct drm_gem_ttm_object|
  2019-04-08  9:21 [PATCH 00/15] Share TTM code among framebuffer drivers Thomas Zimmermann
                   ` (12 preceding siblings ...)
  2019-04-08  9:21 ` [PATCH 13/15] drm/vboxvideo: Convert vboxvideo driver to Simple TTM Thomas Zimmermann
@ 2019-04-08  9:21 ` Thomas Zimmermann
  2019-04-08  9:21 ` [PATCH 15/15] drm/hisilicon: Convert hibmc-drm driver to Simple TTM Thomas Zimmermann
                   ` (2 subsequent siblings)
  16 siblings, 0 replies; 43+ messages in thread
From: Thomas Zimmermann @ 2019-04-08  9:21 UTC (permalink / raw)
  To: daniel, airlied, kraxel, christian.koenig, ray.huang,
	Jerry.Zhang, hdegoede, z.liuxinliang, zourongrong,
	kong.kongxinwei, puck.chen
  Cc: Thomas Zimmermann, dri-devel, virtualization

Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
---
 drivers/gpu/drm/hisilicon/hibmc/Kconfig       |   1 +
 .../gpu/drm/hisilicon/hibmc/hibmc_drm_de.c    |  19 +-
 .../gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c   |   4 +-
 .../gpu/drm/hisilicon/hibmc/hibmc_drm_drv.h   |  25 +--
 .../gpu/drm/hisilicon/hibmc/hibmc_drm_fbdev.c |  30 +--
 drivers/gpu/drm/hisilicon/hibmc/hibmc_ttm.c   | 210 +-----------------
 6 files changed, 42 insertions(+), 247 deletions(-)

diff --git a/drivers/gpu/drm/hisilicon/hibmc/Kconfig b/drivers/gpu/drm/hisilicon/hibmc/Kconfig
index c7129dc3bdfc..98fc7d546d2a 100644
--- a/drivers/gpu/drm/hisilicon/hibmc/Kconfig
+++ b/drivers/gpu/drm/hisilicon/hibmc/Kconfig
@@ -3,6 +3,7 @@ config DRM_HISI_HIBMC
 	depends on DRM && PCI && MMU
 	select DRM_KMS_HELPER
 	select DRM_TTM
+	select DRM_GEM_TTM_HELPER
 
 	help
 	  Choose this option if you have a Hisilicon Hibmc soc chipset.
diff --git a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_de.c b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_de.c
index 9316b724e7a2..86951de4aa12 100644
--- a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_de.c
+++ b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_de.c
@@ -96,27 +96,32 @@ static void hibmc_plane_atomic_update(struct drm_plane *plane,
 	struct drm_plane_state	*state	= plane->state;
 	u32 reg;
 	int ret;
-	u64 gpu_addr = 0;
+	s64 gpu_addr = 0;
 	unsigned int line_l;
 	struct hibmc_drm_private *priv = plane->dev->dev_private;
 	struct hibmc_framebuffer *hibmc_fb;
-	struct hibmc_bo *bo;
+	struct drm_gem_ttm_object *gbo;
 
 	if (!state->fb)
 		return;
 
 	hibmc_fb = to_hibmc_framebuffer(state->fb);
-	bo = gem_to_hibmc_bo(hibmc_fb->obj);
-	ret = ttm_bo_reserve(&bo->bo, true, false, NULL);
+	gbo = drm_gem_ttm_of_gem(hibmc_fb->obj);
+	ret = drm_gem_ttm_reserve(gbo, false);
 	if (ret) {
 		DRM_ERROR("failed to reserve ttm_bo: %d", ret);
 		return;
 	}
 
-	ret = hibmc_bo_pin(bo, TTM_PL_FLAG_VRAM, &gpu_addr);
-	ttm_bo_unreserve(&bo->bo);
+	ret = drm_gem_ttm_pin(gbo, TTM_PL_FLAG_VRAM);
+	drm_gem_ttm_unreserve(gbo);
 	if (ret) {
-		DRM_ERROR("failed to pin hibmc_bo: %d", ret);
+		DRM_ERROR("failed to pin bo: %d", ret);
+		return;
+	}
+	gpu_addr = drm_gem_ttm_vram_offset(gbo);
+	if (gpu_addr < 0) {
+		drm_gem_ttm_unpin(gbo);
 		return;
 	}
 
diff --git a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c
index 8ed94fcd42a7..cc6ab66ec9d1 100644
--- a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c
+++ b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c
@@ -63,9 +63,9 @@ static struct drm_driver hibmc_driver = {
 	.desc			= "hibmc drm driver",
 	.major			= 1,
 	.minor			= 0,
-	.gem_free_object_unlocked = hibmc_gem_free_object,
+	.gem_free_object_unlocked = drm_gem_ttm_driver_gem_free_object_unlocked,
 	.dumb_create            = hibmc_dumb_create,
-	.dumb_map_offset        = hibmc_dumb_mmap_offset,
+	.dumb_map_offset        = drm_gem_ttm_driver_dumb_mmap_offset,
 	.irq_handler		= hibmc_drm_interrupt,
 };
 
diff --git a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.h b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.h
index 0a381c22de26..a46fa0474b59 100644
--- a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.h
+++ b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.h
@@ -23,6 +23,7 @@
 #include <drm/drm_atomic.h>
 #include <drm/drm_fb_helper.h>
 #include <drm/drm_gem.h>
+#include <drm/drm_gem_ttm_helper.h>
 #include <drm/ttm/ttm_bo_driver.h>
 
 struct hibmc_framebuffer {
@@ -59,25 +60,6 @@ struct hibmc_drm_private {
 
 #define to_hibmc_framebuffer(x) container_of(x, struct hibmc_framebuffer, fb)
 
-struct hibmc_bo {
-	struct ttm_buffer_object bo;
-	struct ttm_placement placement;
-	struct ttm_bo_kmap_obj kmap;
-	struct drm_gem_object gem;
-	struct ttm_place placements[3];
-	int pin_count;
-};
-
-static inline struct hibmc_bo *hibmc_bo(struct ttm_buffer_object *bo)
-{
-	return container_of(bo, struct hibmc_bo, bo);
-}
-
-static inline struct hibmc_bo *gem_to_hibmc_bo(struct drm_gem_object *gem)
-{
-	return container_of(gem, struct hibmc_bo, gem);
-}
-
 void hibmc_set_power_mode(struct hibmc_drm_private *priv,
 			  unsigned int power_mode);
 void hibmc_set_current_gate(struct hibmc_drm_private *priv,
@@ -97,13 +79,8 @@ hibmc_framebuffer_init(struct drm_device *dev,
 
 int hibmc_mm_init(struct hibmc_drm_private *hibmc);
 void hibmc_mm_fini(struct hibmc_drm_private *hibmc);
-int hibmc_bo_pin(struct hibmc_bo *bo, u32 pl_flag, u64 *gpu_addr);
-int hibmc_bo_unpin(struct hibmc_bo *bo);
-void hibmc_gem_free_object(struct drm_gem_object *obj);
 int hibmc_dumb_create(struct drm_file *file, struct drm_device *dev,
 		      struct drm_mode_create_dumb *args);
-int hibmc_dumb_mmap_offset(struct drm_file *file, struct drm_device *dev,
-			   u32 handle, u64 *offset);
 int hibmc_mmap(struct file *filp, struct vm_area_struct *vma);
 
 extern const struct drm_mode_config_funcs hibmc_mode_funcs;
diff --git a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_fbdev.c b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_fbdev.c
index 8026859aa07d..452e2b820821 100644
--- a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_fbdev.c
+++ b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_fbdev.c
@@ -66,7 +66,8 @@ static int hibmc_drm_fb_create(struct drm_fb_helper *helper,
 	int ret1;
 	size_t size;
 	unsigned int bytes_per_pixel;
-	struct hibmc_bo *bo = NULL;
+	struct drm_gem_ttm_object *gbo = NULL;
+	void *base;
 
 	DRM_DEBUG_DRIVER("surface width(%d), height(%d) and bpp(%d)\n",
 			 sizes->surface_width, sizes->surface_height,
@@ -88,26 +89,27 @@ static int hibmc_drm_fb_create(struct drm_fb_helper *helper,
 		return -ENOMEM;
 	}
 
-	bo = gem_to_hibmc_bo(gobj);
+	gbo = drm_gem_ttm_of_gem(gobj);
 
-	ret = ttm_bo_reserve(&bo->bo, true, false, NULL);
+	ret = drm_gem_ttm_reserve(gbo, false);
 	if (ret) {
-		DRM_ERROR("failed to reserve ttm_bo: %d\n", ret);
+		DRM_ERROR("failed to reserve bo: %d\n", ret);
 		goto out_unref_gem;
 	}
 
-	ret = hibmc_bo_pin(bo, TTM_PL_FLAG_VRAM, NULL);
+	ret = drm_gem_ttm_pin(gbo, TTM_PL_FLAG_VRAM);
 	if (ret) {
 		DRM_ERROR("failed to pin fbcon: %d\n", ret);
 		goto out_unreserve_ttm_bo;
 	}
 
-	ret = ttm_bo_kmap(&bo->bo, 0, bo->bo.num_pages, &bo->kmap);
-	if (ret) {
+	base = drm_gem_ttm_kmap(gbo, true);
+	if (IS_ERR(base)) {
+		ret = ERR_PTR(base);
 		DRM_ERROR("failed to kmap fbcon: %d\n", ret);
 		goto out_unpin_bo;
 	}
-	ttm_bo_unreserve(&bo->bo);
+	drm_gem_ttm_unreserve(gbo);
 
 	info = drm_fb_helper_alloc_fbi(helper);
 	if (IS_ERR(info)) {
@@ -131,24 +133,24 @@ static int hibmc_drm_fb_create(struct drm_fb_helper *helper,
 
 	drm_fb_helper_fill_info(info, &priv->fbdev->helper, sizes);
 
-	info->screen_base = bo->kmap.virtual;
+	info->screen_base = base;
 	info->screen_size = size;
 
-	info->fix.smem_start = bo->bo.mem.bus.offset + bo->bo.mem.bus.base;
+	info->fix.smem_start = gbo->bo.mem.bus.offset + gbo->bo.mem.bus.base;
 	info->fix.smem_len = size;
 	return 0;
 
 out_release_fbi:
-	ret1 = ttm_bo_reserve(&bo->bo, true, false, NULL);
+	ret1 = drm_gem_ttm_reserve(gbo, false);
 	if (ret1) {
 		DRM_ERROR("failed to rsv ttm_bo when release fbi: %d\n", ret1);
 		goto out_unref_gem;
 	}
-	ttm_bo_kunmap(&bo->kmap);
+	drm_gem_ttm_kunmap(gbo);
 out_unpin_bo:
-	hibmc_bo_unpin(bo);
+	drm_gem_ttm_unpin(gbo);
 out_unreserve_ttm_bo:
-	ttm_bo_unreserve(&bo->bo);
+	drm_gem_ttm_unreserve(gbo);
 out_unref_gem:
 	drm_gem_object_put_unlocked(gobj);
 
diff --git a/drivers/gpu/drm/hisilicon/hibmc/hibmc_ttm.c b/drivers/gpu/drm/hisilicon/hibmc/hibmc_ttm.c
index 6093c421daff..cbe42a4f3f08 100644
--- a/drivers/gpu/drm/hisilicon/hibmc/hibmc_ttm.c
+++ b/drivers/gpu/drm/hisilicon/hibmc/hibmc_ttm.c
@@ -27,19 +27,6 @@ hibmc_bdev(struct ttm_bo_device *bd)
 	return container_of(bd, struct hibmc_drm_private, bdev);
 }
 
-static void hibmc_bo_ttm_destroy(struct ttm_buffer_object *tbo)
-{
-	struct hibmc_bo *bo = container_of(tbo, struct hibmc_bo, bo);
-
-	drm_gem_object_release(&bo->gem);
-	kfree(bo);
-}
-
-static bool hibmc_ttm_bo_is_hibmc_bo(struct ttm_buffer_object *bo)
-{
-	return bo->destroy == &hibmc_bo_ttm_destroy;
-}
-
 static int
 hibmc_bo_init_mem_type(struct ttm_bo_device *bdev, u32 type,
 		       struct ttm_mem_type_manager *man)
@@ -65,52 +52,6 @@ hibmc_bo_init_mem_type(struct ttm_bo_device *bdev, u32 type,
 	return 0;
 }
 
-void hibmc_ttm_placement(struct hibmc_bo *bo, int domain)
-{
-	u32 count = 0;
-	u32 i;
-
-	bo->placement.placement = bo->placements;
-	bo->placement.busy_placement = bo->placements;
-	if (domain & TTM_PL_FLAG_VRAM)
-		bo->placements[count++].flags = TTM_PL_FLAG_WC |
-			TTM_PL_FLAG_UNCACHED | TTM_PL_FLAG_VRAM;
-	if (domain & TTM_PL_FLAG_SYSTEM)
-		bo->placements[count++].flags = TTM_PL_MASK_CACHING |
-			TTM_PL_FLAG_SYSTEM;
-	if (!count)
-		bo->placements[count++].flags = TTM_PL_MASK_CACHING |
-			TTM_PL_FLAG_SYSTEM;
-
-	bo->placement.num_placement = count;
-	bo->placement.num_busy_placement = count;
-	for (i = 0; i < count; i++) {
-		bo->placements[i].fpfn = 0;
-		bo->placements[i].lpfn = 0;
-	}
-}
-
-static void
-hibmc_bo_evict_flags(struct ttm_buffer_object *bo, struct ttm_placement *pl)
-{
-	struct hibmc_bo *hibmcbo = hibmc_bo(bo);
-
-	if (!hibmc_ttm_bo_is_hibmc_bo(bo))
-		return;
-
-	hibmc_ttm_placement(hibmcbo, TTM_PL_FLAG_SYSTEM);
-	*pl = hibmcbo->placement;
-}
-
-static int hibmc_bo_verify_access(struct ttm_buffer_object *bo,
-				  struct file *filp)
-{
-	struct hibmc_bo *hibmcbo = hibmc_bo(bo);
-
-	return drm_vma_node_verify_access(&hibmcbo->gem.vma_node,
-					  filp->private_data);
-}
-
 static int hibmc_ttm_io_mem_reserve(struct ttm_bo_device *bdev,
 				    struct ttm_mem_reg *mem)
 {
@@ -173,9 +114,9 @@ static struct ttm_tt *hibmc_ttm_tt_create(struct ttm_buffer_object *bo,
 struct ttm_bo_driver hibmc_bo_driver = {
 	.ttm_tt_create		= hibmc_ttm_tt_create,
 	.init_mem_type		= hibmc_bo_init_mem_type,
-	.evict_flags		= hibmc_bo_evict_flags,
+	.evict_flags		= drm_gem_ttm_bo_driver_evict_flags,
 	.move			= NULL,
-	.verify_access		= hibmc_bo_verify_access,
+	.verify_access		= drm_gem_ttm_bo_driver_verify_access,
 	.io_mem_reserve		= &hibmc_ttm_io_mem_reserve,
 	.io_mem_free		= NULL,
 };
@@ -215,108 +156,6 @@ void hibmc_mm_fini(struct hibmc_drm_private *hibmc)
 	hibmc->mm_inited = false;
 }
 
-static void hibmc_bo_unref(struct hibmc_bo **bo)
-{
-	struct ttm_buffer_object *tbo;
-
-	if ((*bo) == NULL)
-		return;
-
-	tbo = &((*bo)->bo);
-	ttm_bo_put(tbo);
-	*bo = NULL;
-}
-
-int hibmc_bo_create(struct drm_device *dev, int size, int align,
-		    u32 flags, struct hibmc_bo **phibmcbo)
-{
-	struct hibmc_drm_private *hibmc = dev->dev_private;
-	struct hibmc_bo *hibmcbo;
-	size_t acc_size;
-	int ret;
-
-	hibmcbo = kzalloc(sizeof(*hibmcbo), GFP_KERNEL);
-	if (!hibmcbo) {
-		DRM_ERROR("failed to allocate hibmcbo\n");
-		return -ENOMEM;
-	}
-	ret = drm_gem_object_init(dev, &hibmcbo->gem, size);
-	if (ret) {
-		DRM_ERROR("failed to initialize drm gem object: %d\n", ret);
-		kfree(hibmcbo);
-		return ret;
-	}
-
-	hibmcbo->bo.bdev = &hibmc->bdev;
-
-	hibmc_ttm_placement(hibmcbo, TTM_PL_FLAG_VRAM | TTM_PL_FLAG_SYSTEM);
-
-	acc_size = ttm_bo_dma_acc_size(&hibmc->bdev, size,
-				       sizeof(struct hibmc_bo));
-
-	ret = ttm_bo_init(&hibmc->bdev, &hibmcbo->bo, size,
-			  ttm_bo_type_device, &hibmcbo->placement,
-			  align >> PAGE_SHIFT, false, acc_size,
-			  NULL, NULL, hibmc_bo_ttm_destroy);
-	if (ret) {
-		hibmc_bo_unref(&hibmcbo);
-		DRM_ERROR("failed to initialize ttm_bo: %d\n", ret);
-		return ret;
-	}
-
-	*phibmcbo = hibmcbo;
-	return 0;
-}
-
-int hibmc_bo_pin(struct hibmc_bo *bo, u32 pl_flag, u64 *gpu_addr)
-{
-	struct ttm_operation_ctx ctx = { false, false };
-	int i, ret;
-
-	if (bo->pin_count) {
-		bo->pin_count++;
-		if (gpu_addr)
-			*gpu_addr = bo->bo.offset;
-		return 0;
-	}
-
-	hibmc_ttm_placement(bo, pl_flag);
-	for (i = 0; i < bo->placement.num_placement; i++)
-		bo->placements[i].flags |= TTM_PL_FLAG_NO_EVICT;
-	ret = ttm_bo_validate(&bo->bo, &bo->placement, &ctx);
-	if (ret)
-		return ret;
-
-	bo->pin_count = 1;
-	if (gpu_addr)
-		*gpu_addr = bo->bo.offset;
-	return 0;
-}
-
-int hibmc_bo_unpin(struct hibmc_bo *bo)
-{
-	struct ttm_operation_ctx ctx = { false, false };
-	int i, ret;
-
-	if (!bo->pin_count) {
-		DRM_ERROR("unpin bad %p\n", bo);
-		return 0;
-	}
-	bo->pin_count--;
-	if (bo->pin_count)
-		return 0;
-
-	for (i = 0; i < bo->placement.num_placement ; i++)
-		bo->placements[i].flags &= ~TTM_PL_FLAG_NO_EVICT;
-	ret = ttm_bo_validate(&bo->bo, &bo->placement, &ctx);
-	if (ret) {
-		DRM_ERROR("validate failed for unpin: %d\n", ret);
-		return ret;
-	}
-
-	return 0;
-}
-
 int hibmc_mmap(struct file *filp, struct vm_area_struct *vma)
 {
 	struct drm_file *file_priv = filp->private_data;
@@ -328,24 +167,24 @@ int hibmc_mmap(struct file *filp, struct vm_area_struct *vma)
 int hibmc_gem_create(struct drm_device *dev, u32 size, bool iskernel,
 		     struct drm_gem_object **obj)
 {
-	struct hibmc_bo *hibmcbo;
+	struct hibmc_drm_private *hibmc = dev->dev_private;
+	struct drm_gem_ttm_object *gbo;
 	int ret;
 
 	*obj = NULL;
 
-	size = PAGE_ALIGN(size);
-	if (size == 0) {
-		DRM_ERROR("error: zero size\n");
+	size = roundup(size, PAGE_SIZE);
+	if (size == 0)
 		return -EINVAL;
-	}
 
-	ret = hibmc_bo_create(dev, size, 0, 0, &hibmcbo);
-	if (ret) {
+	gbo = drm_gem_ttm_create(dev, &hibmc->bdev, size, 0, false);
+	if (IS_ERR(gbo)) {
+		ret = PTR_ERR(gbo);
 		if (ret != -ERESTARTSYS)
 			DRM_ERROR("failed to allocate GEM object: %d\n", ret);
 		return ret;
 	}
-	*obj = &hibmcbo->gem;
+	*obj = &gbo->gem;
 	return 0;
 }
 
@@ -377,35 +216,6 @@ int hibmc_dumb_create(struct drm_file *file, struct drm_device *dev,
 	return 0;
 }
 
-void hibmc_gem_free_object(struct drm_gem_object *obj)
-{
-	struct hibmc_bo *hibmcbo = gem_to_hibmc_bo(obj);
-
-	hibmc_bo_unref(&hibmcbo);
-}
-
-static u64 hibmc_bo_mmap_offset(struct hibmc_bo *bo)
-{
-	return drm_vma_node_offset_addr(&bo->bo.vma_node);
-}
-
-int hibmc_dumb_mmap_offset(struct drm_file *file, struct drm_device *dev,
-			   u32 handle, u64 *offset)
-{
-	struct drm_gem_object *obj;
-	struct hibmc_bo *bo;
-
-	obj = drm_gem_object_lookup(file, handle);
-	if (!obj)
-		return -ENOENT;
-
-	bo = gem_to_hibmc_bo(obj);
-	*offset = hibmc_bo_mmap_offset(bo);
-
-	drm_gem_object_put_unlocked(obj);
-	return 0;
-}
-
 static void hibmc_user_framebuffer_destroy(struct drm_framebuffer *fb)
 {
 	struct hibmc_framebuffer *hibmc_fb = to_hibmc_framebuffer(fb);
-- 
2.21.0

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

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

* [PATCH 15/15] drm/hisilicon: Convert hibmc-drm driver to Simple TTM
  2019-04-08  9:21 [PATCH 00/15] Share TTM code among framebuffer drivers Thomas Zimmermann
                   ` (13 preceding siblings ...)
  2019-04-08  9:21 ` [PATCH 14/15] drm/hisilicon: Convert hibmc-drm driver to |struct drm_gem_ttm_object| Thomas Zimmermann
@ 2019-04-08  9:21 ` Thomas Zimmermann
  2019-04-08 11:10 ` [PATCH 00/15] Share TTM code among framebuffer drivers Koenig, Christian
  2019-04-08 11:10 ` Koenig, Christian
  16 siblings, 0 replies; 43+ messages in thread
From: Thomas Zimmermann @ 2019-04-08  9:21 UTC (permalink / raw)
  To: daniel, airlied, kraxel, christian.koenig, ray.huang,
	Jerry.Zhang, hdegoede, z.liuxinliang, zourongrong,
	kong.kongxinwei, puck.chen
  Cc: Thomas Zimmermann, dri-devel, virtualization

Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
---
 drivers/gpu/drm/hisilicon/hibmc/Kconfig       |   1 +
 .../gpu/drm/hisilicon/hibmc/hibmc_drm_drv.h   |   3 +-
 drivers/gpu/drm/hisilicon/hibmc/hibmc_ttm.c   | 124 ++----------------
 3 files changed, 13 insertions(+), 115 deletions(-)

diff --git a/drivers/gpu/drm/hisilicon/hibmc/Kconfig b/drivers/gpu/drm/hisilicon/hibmc/Kconfig
index 98fc7d546d2a..a0cb0d838105 100644
--- a/drivers/gpu/drm/hisilicon/hibmc/Kconfig
+++ b/drivers/gpu/drm/hisilicon/hibmc/Kconfig
@@ -4,6 +4,7 @@ config DRM_HISI_HIBMC
 	select DRM_KMS_HELPER
 	select DRM_TTM
 	select DRM_GEM_TTM_HELPER
+	select DRM_SIMPLE_TTM_HELPER
 
 	help
 	  Choose this option if you have a Hisilicon Hibmc soc chipset.
diff --git a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.h b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.h
index a46fa0474b59..541edbd9bba7 100644
--- a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.h
+++ b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.h
@@ -24,6 +24,7 @@
 #include <drm/drm_fb_helper.h>
 #include <drm/drm_gem.h>
 #include <drm/drm_gem_ttm_helper.h>
+#include <drm/drm_simple_ttm_helper.h>
 #include <drm/ttm/ttm_bo_driver.h>
 
 struct hibmc_framebuffer {
@@ -50,7 +51,7 @@ struct hibmc_drm_private {
 	bool mode_config_initialized;
 
 	/* ttm */
-	struct ttm_bo_device bdev;
+	struct drm_simple_ttm ttm;
 	bool initialized;
 
 	/* fbdev */
diff --git a/drivers/gpu/drm/hisilicon/hibmc/hibmc_ttm.c b/drivers/gpu/drm/hisilicon/hibmc/hibmc_ttm.c
index cbe42a4f3f08..ca28ef9357a9 100644
--- a/drivers/gpu/drm/hisilicon/hibmc/hibmc_ttm.c
+++ b/drivers/gpu/drm/hisilicon/hibmc/hibmc_ttm.c
@@ -21,125 +21,21 @@
 
 #include "hibmc_drm_drv.h"
 
-static inline struct hibmc_drm_private *
-hibmc_bdev(struct ttm_bo_device *bd)
-{
-	return container_of(bd, struct hibmc_drm_private, bdev);
-}
-
-static int
-hibmc_bo_init_mem_type(struct ttm_bo_device *bdev, u32 type,
-		       struct ttm_mem_type_manager *man)
-{
-	switch (type) {
-	case TTM_PL_SYSTEM:
-		man->flags = TTM_MEMTYPE_FLAG_MAPPABLE;
-		man->available_caching = TTM_PL_MASK_CACHING;
-		man->default_caching = TTM_PL_FLAG_CACHED;
-		break;
-	case TTM_PL_VRAM:
-		man->func = &ttm_bo_manager_func;
-		man->flags = TTM_MEMTYPE_FLAG_FIXED |
-			TTM_MEMTYPE_FLAG_MAPPABLE;
-		man->available_caching = TTM_PL_FLAG_UNCACHED |
-			TTM_PL_FLAG_WC;
-		man->default_caching = TTM_PL_FLAG_WC;
-		break;
-	default:
-		DRM_ERROR("unsupported memory type %u\n", type);
-		return -EINVAL;
-	}
-	return 0;
-}
-
-static int hibmc_ttm_io_mem_reserve(struct ttm_bo_device *bdev,
-				    struct ttm_mem_reg *mem)
-{
-	struct ttm_mem_type_manager *man = &bdev->man[mem->mem_type];
-	struct hibmc_drm_private *hibmc = hibmc_bdev(bdev);
-
-	mem->bus.addr = NULL;
-	mem->bus.offset = 0;
-	mem->bus.size = mem->num_pages << PAGE_SHIFT;
-	mem->bus.base = 0;
-	mem->bus.is_iomem = false;
-	if (!(man->flags & TTM_MEMTYPE_FLAG_MAPPABLE))
-		return -EINVAL;
-	switch (mem->mem_type) {
-	case TTM_PL_SYSTEM:
-		/* system memory */
-		return 0;
-	case TTM_PL_VRAM:
-		mem->bus.offset = mem->start << PAGE_SHIFT;
-		mem->bus.base = pci_resource_start(hibmc->dev->pdev, 0);
-		mem->bus.is_iomem = true;
-		break;
-	default:
-		return -EINVAL;
-	}
-	return 0;
-}
-
-static void hibmc_ttm_backend_destroy(struct ttm_tt *tt)
-{
-	ttm_tt_fini(tt);
-	kfree(tt);
-}
-
-static struct ttm_backend_func hibmc_tt_backend_func = {
-	.destroy = &hibmc_ttm_backend_destroy,
-};
-
-static struct ttm_tt *hibmc_ttm_tt_create(struct ttm_buffer_object *bo,
-					  u32 page_flags)
-{
-	struct ttm_tt *tt;
-	int ret;
-
-	tt = kzalloc(sizeof(*tt), GFP_KERNEL);
-	if (!tt) {
-		DRM_ERROR("failed to allocate ttm_tt\n");
-		return NULL;
-	}
-	tt->func = &hibmc_tt_backend_func;
-	ret = ttm_tt_init(tt, bo, page_flags);
-	if (ret) {
-		DRM_ERROR("failed to initialize ttm_tt: %d\n", ret);
-		kfree(tt);
-		return NULL;
-	}
-	return tt;
-}
-
-struct ttm_bo_driver hibmc_bo_driver = {
-	.ttm_tt_create		= hibmc_ttm_tt_create,
-	.init_mem_type		= hibmc_bo_init_mem_type,
-	.evict_flags		= drm_gem_ttm_bo_driver_evict_flags,
-	.move			= NULL,
-	.verify_access		= drm_gem_ttm_bo_driver_verify_access,
-	.io_mem_reserve		= &hibmc_ttm_io_mem_reserve,
-	.io_mem_free		= NULL,
+static const struct drm_simple_ttm_funcs hibmc_simple_ttm_funcs = {
+	.evict_flags = drm_gem_ttm_bo_driver_evict_flags,
+	.verify_access = drm_gem_ttm_bo_driver_verify_access
 };
 
 int hibmc_mm_init(struct hibmc_drm_private *hibmc)
 {
 	int ret;
 	struct drm_device *dev = hibmc->dev;
-	struct ttm_bo_device *bdev = &hibmc->bdev;
-
-	ret = ttm_bo_device_init(&hibmc->bdev,
-				 &hibmc_bo_driver,
-				 dev->anon_inode->i_mapping,
-				 true);
-	if (ret) {
-		DRM_ERROR("error initializing bo driver: %d\n", ret);
-		return ret;
-	}
 
-	ret = ttm_bo_init_mm(bdev, TTM_PL_VRAM,
-			     hibmc->fb_size >> PAGE_SHIFT);
+	ret = drm_simple_ttm_init(&hibmc->ttm, dev,
+				  pci_resource_start(dev->pdev, 0),
+				  hibmc->fb_size, &hibmc_simple_ttm_funcs);
 	if (ret) {
-		DRM_ERROR("failed ttm VRAM init: %d\n", ret);
+		DRM_ERROR("Error initializing Simple TTM; %d\n", ret);
 		return ret;
 	}
 
@@ -152,7 +48,7 @@ void hibmc_mm_fini(struct hibmc_drm_private *hibmc)
 	if (!hibmc->mm_inited)
 		return;
 
-	ttm_bo_device_release(&hibmc->bdev);
+	drm_simple_ttm_cleanup(&hibmc->ttm);
 	hibmc->mm_inited = false;
 }
 
@@ -161,7 +57,7 @@ int hibmc_mmap(struct file *filp, struct vm_area_struct *vma)
 	struct drm_file *file_priv = filp->private_data;
 	struct hibmc_drm_private *hibmc = file_priv->minor->dev->dev_private;
 
-	return ttm_bo_mmap(filp, vma, &hibmc->bdev);
+	return ttm_bo_mmap(filp, vma, &hibmc->ttm.bdev);
 }
 
 int hibmc_gem_create(struct drm_device *dev, u32 size, bool iskernel,
@@ -177,7 +73,7 @@ int hibmc_gem_create(struct drm_device *dev, u32 size, bool iskernel,
 	if (size == 0)
 		return -EINVAL;
 
-	gbo = drm_gem_ttm_create(dev, &hibmc->bdev, size, 0, false);
+	gbo = drm_gem_ttm_create(dev, &hibmc->ttm.bdev, size, 0, false);
 	if (IS_ERR(gbo)) {
 		ret = PTR_ERR(gbo);
 		if (ret != -ERESTARTSYS)
-- 
2.21.0

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

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

* Re: [PATCH 00/15] Share TTM code among framebuffer drivers
  2019-04-08  9:21 [PATCH 00/15] Share TTM code among framebuffer drivers Thomas Zimmermann
                   ` (14 preceding siblings ...)
  2019-04-08  9:21 ` [PATCH 15/15] drm/hisilicon: Convert hibmc-drm driver to Simple TTM Thomas Zimmermann
@ 2019-04-08 11:10 ` Koenig, Christian
  2019-04-08 11:10 ` Koenig, Christian
  16 siblings, 0 replies; 43+ messages in thread
From: Koenig, Christian @ 2019-04-08 11:10 UTC (permalink / raw)
  To: Thomas Zimmermann, daniel, airlied, kraxel, Huang, Ray, Zhang,
	Jerry, hdegoede, z.liuxinliang, zourongrong, kong.kongxinwei,
	puck.chen
  Cc: dri-devel, virtualization

Well first problem is I'm not sure if that is a good idea. Essentially 
we want to get rid of TTM in the long run.

On the other hand this work might aid with that goal, so it might be 
worth a try.

Second is that this might actually not work of hand. The problem is here:
> +	/* TODO: This test used to be performed by drivers, but can
> +	 * this actually happen? If so, should we put the check into
> +	 * drm_gem_ttm_of_gem()? */
> +	if (!drm_is_gem_ttm(bo))
> +		return;

Yeah, this test is mandatory because TTM on itself can present buffer 
object which doesn't belong to the driver called.

E.g. we sometimes have BOs which don't belong to the current drivers on 
a driver specific LRU. A totally brain dead  design if you ask me, but 
that's how it is.

Not 100% sure, but by converting all drivers to use a common GEM_TTM 
backend you might actually break that test.

I'm not sure if that is actually a problem in the real world, it most 
likely isn't. But I still won't bet on it without being able to test this.

Regards,
Christian.

Am 08.04.19 um 11:21 schrieb Thomas Zimmermann:
> Several simple framebuffer drivers copy most of the TTM code from each
> other. The implementation is always the same; except for the name of
> some data structures.
>
> As recently discussed, this patch set provides generic TTM memory-
> management code for framebuffers with dedicated video memory. It further
> converts the respective drivers to the generic code. The shared code
> is basically the same implementation as the one copied among individual
> drivers.
>
> The patch set contains two major changes: first, it introduces
> |struct drm_gem_ttm_object| and helpers. It's a GEM object that is
> backed by TTM-managed memory. The type's purpose is somewhat similar
> to |struct drm_gem_{cma, shmem}_object|. Second, the patch set
> introduces |struct drm_simple_ttm| (for the lack of a better name) and
> helpers. It's an implementation of a basic TTM-based memory manager.
>
> Both, GEM TTM and Simple TTM, support VRAM and SYSTEM placements. Support
> for TT could probably be added if necessary. Both can be used independedly
> from each other if desired by the DRM driver.
>
> Currently ast, bochs, mgag200, vboxvideo and hisilicon/hibmc can use
> these helpers. Cirrus would also be a candidate, but as it's being
> rewrtten from scratch, I didn't bother doing the conversion.
>
> Future directions: with these changes, the respective drivers can also
> share some of their mode-setting or fbdev code. GEM TTM could implement
> PRIME helpers, which would allow for using the generic fbcon.
>
> The patch set is against a recent drm-tip.
>
> Thomas Zimmermann (15):
>    drm: Add |struct drm_gem_ttm_object| and helpers
>    drm: Add |struct drm_gem_ttm_object| callbacks for |struct
>      ttm_bo_driver|
>    drm: Add |struct drm_gem_ttm_object| callbacks for |struct drm_driver|
>    drm: Add drm_gem_ttm_fill_create_dumb() to create dumb buffers
>    drm: Add Simple TTM, a memory manager for dedicated VRAM
>    drm/ast: Convert AST driver to |struct drm_gem_ttm_object|
>    drm/ast: Convert AST driver to Simple TTM
>    drm/bochs: Convert Bochs driver to |struct drm_gem_ttm_object|
>    drm/bochs: Convert Bochs driver to Simple TTM
>    drm/mgag200: Convert mgag200 driver to |struct drm_gem_ttm_object|
>    drm/mgag200: Convert mgag200 driver to Simple TTM
>    drm/vboxvideo: Convert vboxvideo driver to |struct drm_gem_ttm_object|
>    drm/vboxvideo: Convert vboxvideo driver to Simple TTM
>    drm/hisilicon: Convert hibmc-drm driver to |struct drm_gem_ttm_object|
>    drm/hisilicon: Convert hibmc-drm driver to Simple TTM
>
>   Documentation/gpu/drm-mm.rst                  |  23 +
>   drivers/gpu/drm/Kconfig                       |  20 +
>   drivers/gpu/drm/Makefile                      |   5 +
>   drivers/gpu/drm/ast/Kconfig                   |   3 +-
>   drivers/gpu/drm/ast/ast_drv.c                 |   4 +-
>   drivers/gpu/drm/ast/ast_drv.h                 |  58 +-
>   drivers/gpu/drm/ast/ast_fb.c                  |  18 +-
>   drivers/gpu/drm/ast/ast_main.c                |  74 +--
>   drivers/gpu/drm/ast/ast_mode.c                |  78 +--
>   drivers/gpu/drm/ast/ast_ttm.c                 | 290 +---------
>   drivers/gpu/drm/bochs/Kconfig                 |   2 +
>   drivers/gpu/drm/bochs/bochs.h                 |  42 +-
>   drivers/gpu/drm/bochs/bochs_drv.c             |   4 +-
>   drivers/gpu/drm/bochs/bochs_kms.c             |  18 +-
>   drivers/gpu/drm/bochs/bochs_mm.c              | 392 +-------------
>   drivers/gpu/drm/drm_gem_ttm_helper.c          | 507 ++++++++++++++++++
>   drivers/gpu/drm/drm_simple_ttm_helper.c       | 191 +++++++
>   drivers/gpu/drm/drm_ttm_helper_common.c       |   6 +
>   drivers/gpu/drm/hisilicon/hibmc/Kconfig       |   2 +
>   .../gpu/drm/hisilicon/hibmc/hibmc_drm_de.c    |  19 +-
>   .../gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c   |   4 +-
>   .../gpu/drm/hisilicon/hibmc/hibmc_drm_drv.h   |  28 +-
>   .../gpu/drm/hisilicon/hibmc/hibmc_drm_fbdev.c |  30 +-
>   drivers/gpu/drm/hisilicon/hibmc/hibmc_ttm.c   | 328 +----------
>   drivers/gpu/drm/mgag200/Kconfig               |   2 +
>   drivers/gpu/drm/mgag200/mgag200_cursor.c      |  61 ++-
>   drivers/gpu/drm/mgag200/mgag200_drv.c         |   4 +-
>   drivers/gpu/drm/mgag200/mgag200_drv.h         |  68 +--
>   drivers/gpu/drm/mgag200/mgag200_fb.c          |  18 +-
>   drivers/gpu/drm/mgag200/mgag200_main.c        |  84 +--
>   drivers/gpu/drm/mgag200/mgag200_mode.c        |  45 +-
>   drivers/gpu/drm/mgag200/mgag200_ttm.c         | 290 +---------
>   drivers/gpu/drm/vboxvideo/Kconfig             |   2 +
>   drivers/gpu/drm/vboxvideo/vbox_drv.c          |   5 +-
>   drivers/gpu/drm/vboxvideo/vbox_drv.h          |  64 +--
>   drivers/gpu/drm/vboxvideo/vbox_fb.c           |  22 +-
>   drivers/gpu/drm/vboxvideo/vbox_main.c         |  70 +--
>   drivers/gpu/drm/vboxvideo/vbox_mode.c         |  36 +-
>   drivers/gpu/drm/vboxvideo/vbox_ttm.c          | 344 +-----------
>   include/drm/drm_gem_ttm_helper.h              | 119 ++++
>   include/drm/drm_simple_ttm_helper.h           |  74 +++
>   41 files changed, 1292 insertions(+), 2162 deletions(-)
>   create mode 100644 drivers/gpu/drm/drm_gem_ttm_helper.c
>   create mode 100644 drivers/gpu/drm/drm_simple_ttm_helper.c
>   create mode 100644 drivers/gpu/drm/drm_ttm_helper_common.c
>   create mode 100644 include/drm/drm_gem_ttm_helper.h
>   create mode 100644 include/drm/drm_simple_ttm_helper.h
>
> --
> 2.21.0
>

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

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

* Re: [PATCH 00/15] Share TTM code among framebuffer drivers
  2019-04-08  9:21 [PATCH 00/15] Share TTM code among framebuffer drivers Thomas Zimmermann
                   ` (15 preceding siblings ...)
  2019-04-08 11:10 ` [PATCH 00/15] Share TTM code among framebuffer drivers Koenig, Christian
@ 2019-04-08 11:10 ` Koenig, Christian
  2019-04-08 11:59   ` Thomas Zimmermann
  16 siblings, 1 reply; 43+ messages in thread
From: Koenig, Christian @ 2019-04-08 11:10 UTC (permalink / raw)
  To: Thomas Zimmermann, daniel, airlied, kraxel, Huang, Ray, Zhang,
	Jerry, hdegoede, z.liuxinliang, zourongrong, kong.kongxinwei,
	puck.chen
  Cc: dri-devel, virtualization

Well first problem is I'm not sure if that is a good idea. Essentially 
we want to get rid of TTM in the long run.

On the other hand this work might aid with that goal, so it might be 
worth a try.

Second is that this might actually not work of hand. The problem is here:
> +	/* TODO: This test used to be performed by drivers, but can
> +	 * this actually happen? If so, should we put the check into
> +	 * drm_gem_ttm_of_gem()? */
> +	if (!drm_is_gem_ttm(bo))
> +		return;

Yeah, this test is mandatory because TTM on itself can present buffer 
object which doesn't belong to the driver called.

E.g. we sometimes have BOs which don't belong to the current drivers on 
a driver specific LRU. A totally brain dead  design if you ask me, but 
that's how it is.

Not 100% sure, but by converting all drivers to use a common GEM_TTM 
backend you might actually break that test.

I'm not sure if that is actually a problem in the real world, it most 
likely isn't. But I still won't bet on it without being able to test this.

Regards,
Christian.

Am 08.04.19 um 11:21 schrieb Thomas Zimmermann:
> Several simple framebuffer drivers copy most of the TTM code from each
> other. The implementation is always the same; except for the name of
> some data structures.
>
> As recently discussed, this patch set provides generic TTM memory-
> management code for framebuffers with dedicated video memory. It further
> converts the respective drivers to the generic code. The shared code
> is basically the same implementation as the one copied among individual
> drivers.
>
> The patch set contains two major changes: first, it introduces
> |struct drm_gem_ttm_object| and helpers. It's a GEM object that is
> backed by TTM-managed memory. The type's purpose is somewhat similar
> to |struct drm_gem_{cma, shmem}_object|. Second, the patch set
> introduces |struct drm_simple_ttm| (for the lack of a better name) and
> helpers. It's an implementation of a basic TTM-based memory manager.
>
> Both, GEM TTM and Simple TTM, support VRAM and SYSTEM placements. Support
> for TT could probably be added if necessary. Both can be used independedly
> from each other if desired by the DRM driver.
>
> Currently ast, bochs, mgag200, vboxvideo and hisilicon/hibmc can use
> these helpers. Cirrus would also be a candidate, but as it's being
> rewrtten from scratch, I didn't bother doing the conversion.
>
> Future directions: with these changes, the respective drivers can also
> share some of their mode-setting or fbdev code. GEM TTM could implement
> PRIME helpers, which would allow for using the generic fbcon.
>
> The patch set is against a recent drm-tip.
>
> Thomas Zimmermann (15):
>    drm: Add |struct drm_gem_ttm_object| and helpers
>    drm: Add |struct drm_gem_ttm_object| callbacks for |struct
>      ttm_bo_driver|
>    drm: Add |struct drm_gem_ttm_object| callbacks for |struct drm_driver|
>    drm: Add drm_gem_ttm_fill_create_dumb() to create dumb buffers
>    drm: Add Simple TTM, a memory manager for dedicated VRAM
>    drm/ast: Convert AST driver to |struct drm_gem_ttm_object|
>    drm/ast: Convert AST driver to Simple TTM
>    drm/bochs: Convert Bochs driver to |struct drm_gem_ttm_object|
>    drm/bochs: Convert Bochs driver to Simple TTM
>    drm/mgag200: Convert mgag200 driver to |struct drm_gem_ttm_object|
>    drm/mgag200: Convert mgag200 driver to Simple TTM
>    drm/vboxvideo: Convert vboxvideo driver to |struct drm_gem_ttm_object|
>    drm/vboxvideo: Convert vboxvideo driver to Simple TTM
>    drm/hisilicon: Convert hibmc-drm driver to |struct drm_gem_ttm_object|
>    drm/hisilicon: Convert hibmc-drm driver to Simple TTM
>
>   Documentation/gpu/drm-mm.rst                  |  23 +
>   drivers/gpu/drm/Kconfig                       |  20 +
>   drivers/gpu/drm/Makefile                      |   5 +
>   drivers/gpu/drm/ast/Kconfig                   |   3 +-
>   drivers/gpu/drm/ast/ast_drv.c                 |   4 +-
>   drivers/gpu/drm/ast/ast_drv.h                 |  58 +-
>   drivers/gpu/drm/ast/ast_fb.c                  |  18 +-
>   drivers/gpu/drm/ast/ast_main.c                |  74 +--
>   drivers/gpu/drm/ast/ast_mode.c                |  78 +--
>   drivers/gpu/drm/ast/ast_ttm.c                 | 290 +---------
>   drivers/gpu/drm/bochs/Kconfig                 |   2 +
>   drivers/gpu/drm/bochs/bochs.h                 |  42 +-
>   drivers/gpu/drm/bochs/bochs_drv.c             |   4 +-
>   drivers/gpu/drm/bochs/bochs_kms.c             |  18 +-
>   drivers/gpu/drm/bochs/bochs_mm.c              | 392 +-------------
>   drivers/gpu/drm/drm_gem_ttm_helper.c          | 507 ++++++++++++++++++
>   drivers/gpu/drm/drm_simple_ttm_helper.c       | 191 +++++++
>   drivers/gpu/drm/drm_ttm_helper_common.c       |   6 +
>   drivers/gpu/drm/hisilicon/hibmc/Kconfig       |   2 +
>   .../gpu/drm/hisilicon/hibmc/hibmc_drm_de.c    |  19 +-
>   .../gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c   |   4 +-
>   .../gpu/drm/hisilicon/hibmc/hibmc_drm_drv.h   |  28 +-
>   .../gpu/drm/hisilicon/hibmc/hibmc_drm_fbdev.c |  30 +-
>   drivers/gpu/drm/hisilicon/hibmc/hibmc_ttm.c   | 328 +----------
>   drivers/gpu/drm/mgag200/Kconfig               |   2 +
>   drivers/gpu/drm/mgag200/mgag200_cursor.c      |  61 ++-
>   drivers/gpu/drm/mgag200/mgag200_drv.c         |   4 +-
>   drivers/gpu/drm/mgag200/mgag200_drv.h         |  68 +--
>   drivers/gpu/drm/mgag200/mgag200_fb.c          |  18 +-
>   drivers/gpu/drm/mgag200/mgag200_main.c        |  84 +--
>   drivers/gpu/drm/mgag200/mgag200_mode.c        |  45 +-
>   drivers/gpu/drm/mgag200/mgag200_ttm.c         | 290 +---------
>   drivers/gpu/drm/vboxvideo/Kconfig             |   2 +
>   drivers/gpu/drm/vboxvideo/vbox_drv.c          |   5 +-
>   drivers/gpu/drm/vboxvideo/vbox_drv.h          |  64 +--
>   drivers/gpu/drm/vboxvideo/vbox_fb.c           |  22 +-
>   drivers/gpu/drm/vboxvideo/vbox_main.c         |  70 +--
>   drivers/gpu/drm/vboxvideo/vbox_mode.c         |  36 +-
>   drivers/gpu/drm/vboxvideo/vbox_ttm.c          | 344 +-----------
>   include/drm/drm_gem_ttm_helper.h              | 119 ++++
>   include/drm/drm_simple_ttm_helper.h           |  74 +++
>   41 files changed, 1292 insertions(+), 2162 deletions(-)
>   create mode 100644 drivers/gpu/drm/drm_gem_ttm_helper.c
>   create mode 100644 drivers/gpu/drm/drm_simple_ttm_helper.c
>   create mode 100644 drivers/gpu/drm/drm_ttm_helper_common.c
>   create mode 100644 include/drm/drm_gem_ttm_helper.h
>   create mode 100644 include/drm/drm_simple_ttm_helper.h
>
> --
> 2.21.0
>

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

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

* Re: [PATCH 00/15] Share TTM code among framebuffer drivers
  2019-04-08 11:10 ` Koenig, Christian
@ 2019-04-08 11:59   ` Thomas Zimmermann
  2019-04-09  7:12     ` kraxel
                       ` (2 more replies)
  0 siblings, 3 replies; 43+ messages in thread
From: Thomas Zimmermann @ 2019-04-08 11:59 UTC (permalink / raw)
  To: Koenig, Christian, daniel, airlied, kraxel, Huang, Ray, Zhang,
	Jerry, hdegoede, z.liuxinliang, zourongrong, kong.kongxinwei,
	puck.chen
  Cc: dri-devel, virtualization


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

Hi

Am 08.04.19 um 13:10 schrieb Koenig, Christian:
> Well first problem is I'm not sure if that is a good idea. Essentially 
> we want to get rid of TTM in the long run.
> 
> On the other hand this work might aid with that goal, so it might be 
> worth a try.

I see. I'm actually interested in porting some of the fbdev driver code
over to DRM. So far, that patch set uses TTM. As there's so much
duplicated code among drivers, I was asked to merge some of the code
into helpers first.

If not for TTM, what would be the alternative? One VMA manager per
memory region per device?

With the patch set applied there are very few TTM calls left in the
drivers and some can even be replaced by helpers. Besides the stronger
cleanup, maybe we can merge these helpers under a different API name?
Something that does not imply a TTM-based implementation? Doing so would
ease a later rewrite with non-TTM code. Suggestions?

> Second is that this might actually not work of hand. The problem is here:
>> +	/* TODO: This test used to be performed by drivers, but can
>> +	 * this actually happen? If so, should we put the check into
>> +	 * drm_gem_ttm_of_gem()? */
>> +	if (!drm_is_gem_ttm(bo))
>> +		return;
> 
> Yeah, this test is mandatory because TTM on itself can present buffer 
> object which doesn't belong to the driver called.
> 
> E.g. we sometimes have BOs which don't belong to the current drivers on 
> a driver specific LRU. A totally brain dead  design if you ask me, but 
> that's how it is.
> 
> Not 100% sure, but by converting all drivers to use a common GEM_TTM 
> backend you might actually break that test.
> 
> I'm not sure if that is actually a problem in the real world, it most 
> likely isn't. But I still won't bet on it without being able to test this.

That's for explaining. So this test should best live in driver-specific
code.

Best regards
Thomas

> Regards,
> Christian.
> 
> Am 08.04.19 um 11:21 schrieb Thomas Zimmermann:
>> Several simple framebuffer drivers copy most of the TTM code from each
>> other. The implementation is always the same; except for the name of
>> some data structures.
>>
>> As recently discussed, this patch set provides generic TTM memory-
>> management code for framebuffers with dedicated video memory. It further
>> converts the respective drivers to the generic code. The shared code
>> is basically the same implementation as the one copied among individual
>> drivers.
>>
>> The patch set contains two major changes: first, it introduces
>> |struct drm_gem_ttm_object| and helpers. It's a GEM object that is
>> backed by TTM-managed memory. The type's purpose is somewhat similar
>> to |struct drm_gem_{cma, shmem}_object|. Second, the patch set
>> introduces |struct drm_simple_ttm| (for the lack of a better name) and
>> helpers. It's an implementation of a basic TTM-based memory manager.
>>
>> Both, GEM TTM and Simple TTM, support VRAM and SYSTEM placements. Support
>> for TT could probably be added if necessary. Both can be used independedly
>> from each other if desired by the DRM driver.
>>
>> Currently ast, bochs, mgag200, vboxvideo and hisilicon/hibmc can use
>> these helpers. Cirrus would also be a candidate, but as it's being
>> rewrtten from scratch, I didn't bother doing the conversion.
>>
>> Future directions: with these changes, the respective drivers can also
>> share some of their mode-setting or fbdev code. GEM TTM could implement
>> PRIME helpers, which would allow for using the generic fbcon.
>>
>> The patch set is against a recent drm-tip.
>>
>> Thomas Zimmermann (15):
>>    drm: Add |struct drm_gem_ttm_object| and helpers
>>    drm: Add |struct drm_gem_ttm_object| callbacks for |struct
>>      ttm_bo_driver|
>>    drm: Add |struct drm_gem_ttm_object| callbacks for |struct drm_driver|
>>    drm: Add drm_gem_ttm_fill_create_dumb() to create dumb buffers
>>    drm: Add Simple TTM, a memory manager for dedicated VRAM
>>    drm/ast: Convert AST driver to |struct drm_gem_ttm_object|
>>    drm/ast: Convert AST driver to Simple TTM
>>    drm/bochs: Convert Bochs driver to |struct drm_gem_ttm_object|
>>    drm/bochs: Convert Bochs driver to Simple TTM
>>    drm/mgag200: Convert mgag200 driver to |struct drm_gem_ttm_object|
>>    drm/mgag200: Convert mgag200 driver to Simple TTM
>>    drm/vboxvideo: Convert vboxvideo driver to |struct drm_gem_ttm_object|
>>    drm/vboxvideo: Convert vboxvideo driver to Simple TTM
>>    drm/hisilicon: Convert hibmc-drm driver to |struct drm_gem_ttm_object|
>>    drm/hisilicon: Convert hibmc-drm driver to Simple TTM
>>
>>   Documentation/gpu/drm-mm.rst                  |  23 +
>>   drivers/gpu/drm/Kconfig                       |  20 +
>>   drivers/gpu/drm/Makefile                      |   5 +
>>   drivers/gpu/drm/ast/Kconfig                   |   3 +-
>>   drivers/gpu/drm/ast/ast_drv.c                 |   4 +-
>>   drivers/gpu/drm/ast/ast_drv.h                 |  58 +-
>>   drivers/gpu/drm/ast/ast_fb.c                  |  18 +-
>>   drivers/gpu/drm/ast/ast_main.c                |  74 +--
>>   drivers/gpu/drm/ast/ast_mode.c                |  78 +--
>>   drivers/gpu/drm/ast/ast_ttm.c                 | 290 +---------
>>   drivers/gpu/drm/bochs/Kconfig                 |   2 +
>>   drivers/gpu/drm/bochs/bochs.h                 |  42 +-
>>   drivers/gpu/drm/bochs/bochs_drv.c             |   4 +-
>>   drivers/gpu/drm/bochs/bochs_kms.c             |  18 +-
>>   drivers/gpu/drm/bochs/bochs_mm.c              | 392 +-------------
>>   drivers/gpu/drm/drm_gem_ttm_helper.c          | 507 ++++++++++++++++++
>>   drivers/gpu/drm/drm_simple_ttm_helper.c       | 191 +++++++
>>   drivers/gpu/drm/drm_ttm_helper_common.c       |   6 +
>>   drivers/gpu/drm/hisilicon/hibmc/Kconfig       |   2 +
>>   .../gpu/drm/hisilicon/hibmc/hibmc_drm_de.c    |  19 +-
>>   .../gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c   |   4 +-
>>   .../gpu/drm/hisilicon/hibmc/hibmc_drm_drv.h   |  28 +-
>>   .../gpu/drm/hisilicon/hibmc/hibmc_drm_fbdev.c |  30 +-
>>   drivers/gpu/drm/hisilicon/hibmc/hibmc_ttm.c   | 328 +----------
>>   drivers/gpu/drm/mgag200/Kconfig               |   2 +
>>   drivers/gpu/drm/mgag200/mgag200_cursor.c      |  61 ++-
>>   drivers/gpu/drm/mgag200/mgag200_drv.c         |   4 +-
>>   drivers/gpu/drm/mgag200/mgag200_drv.h         |  68 +--
>>   drivers/gpu/drm/mgag200/mgag200_fb.c          |  18 +-
>>   drivers/gpu/drm/mgag200/mgag200_main.c        |  84 +--
>>   drivers/gpu/drm/mgag200/mgag200_mode.c        |  45 +-
>>   drivers/gpu/drm/mgag200/mgag200_ttm.c         | 290 +---------
>>   drivers/gpu/drm/vboxvideo/Kconfig             |   2 +
>>   drivers/gpu/drm/vboxvideo/vbox_drv.c          |   5 +-
>>   drivers/gpu/drm/vboxvideo/vbox_drv.h          |  64 +--
>>   drivers/gpu/drm/vboxvideo/vbox_fb.c           |  22 +-
>>   drivers/gpu/drm/vboxvideo/vbox_main.c         |  70 +--
>>   drivers/gpu/drm/vboxvideo/vbox_mode.c         |  36 +-
>>   drivers/gpu/drm/vboxvideo/vbox_ttm.c          | 344 +-----------
>>   include/drm/drm_gem_ttm_helper.h              | 119 ++++
>>   include/drm/drm_simple_ttm_helper.h           |  74 +++
>>   41 files changed, 1292 insertions(+), 2162 deletions(-)
>>   create mode 100644 drivers/gpu/drm/drm_gem_ttm_helper.c
>>   create mode 100644 drivers/gpu/drm/drm_simple_ttm_helper.c
>>   create mode 100644 drivers/gpu/drm/drm_ttm_helper_common.c
>>   create mode 100644 include/drm/drm_gem_ttm_helper.h
>>   create mode 100644 include/drm/drm_simple_ttm_helper.h
>>
>> --
>> 2.21.0
>>
> 

-- 
Thomas Zimmermann
Graphics Driver Developer
SUSE Linux GmbH, Maxfeldstrasse 5, 90409 Nuernberg, Germany
GF: Felix Imendörffer, Mary Higgins, Sri Rasiah
HRB 21284 (AG Nürnberg)


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

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

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

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

* Re: [PATCH 12/15] drm/vboxvideo: Convert vboxvideo driver to |struct drm_gem_ttm_object|
  2019-04-08  9:21 ` [PATCH 12/15] drm/vboxvideo: Convert vboxvideo driver to |struct drm_gem_ttm_object| Thomas Zimmermann
  2019-04-09  7:09   ` Hans de Goede
@ 2019-04-09  7:09   ` Hans de Goede
  1 sibling, 0 replies; 43+ messages in thread
From: Hans de Goede @ 2019-04-09  7:09 UTC (permalink / raw)
  To: Thomas Zimmermann, daniel, airlied, kraxel, christian.koenig,
	ray.huang, Jerry.Zhang, z.liuxinliang, zourongrong,
	kong.kongxinwei, puck.chen
  Cc: dri-devel, virtualization

Hi,

On 08-04-19 11:21, Thomas Zimmermann wrote:
> This patch replaces |struct vbox_bo| and its helpers with the generic
> implementation of |struct drm_gem_ttm_object|. The only change in
> semantics is that &ttm_bo_driver.verify_access() now does the actual
> verification.
> 
> Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>

Nice cleanup, thank you, patch looks good to me:

Reviewed-by: Hans de Goede <hdegoede@redhat.com>

Regards,

Hans

> ---
>   drivers/gpu/drm/vboxvideo/Kconfig     |   1 +
>   drivers/gpu/drm/vboxvideo/vbox_drv.c  |   5 +-
>   drivers/gpu/drm/vboxvideo/vbox_drv.h  |  58 +------
>   drivers/gpu/drm/vboxvideo/vbox_fb.c   |  22 +--
>   drivers/gpu/drm/vboxvideo/vbox_main.c |  70 +-------
>   drivers/gpu/drm/vboxvideo/vbox_mode.c |  36 +++--
>   drivers/gpu/drm/vboxvideo/vbox_ttm.c  | 223 +-------------------------
>   7 files changed, 45 insertions(+), 370 deletions(-)
> 
> diff --git a/drivers/gpu/drm/vboxvideo/Kconfig b/drivers/gpu/drm/vboxvideo/Kconfig
> index 1f4182e2e980..c1ca87df81df 100644
> --- a/drivers/gpu/drm/vboxvideo/Kconfig
> +++ b/drivers/gpu/drm/vboxvideo/Kconfig
> @@ -3,6 +3,7 @@ config DRM_VBOXVIDEO
>   	depends on DRM && X86 && PCI
>   	select DRM_KMS_HELPER
>   	select DRM_TTM
> +	select DRM_GEM_TTM_HELPER
>   	select GENERIC_ALLOCATOR
>   	help
>   	  This is a KMS driver for the virtual Graphics Card used in
> diff --git a/drivers/gpu/drm/vboxvideo/vbox_drv.c b/drivers/gpu/drm/vboxvideo/vbox_drv.c
> index fb6a0f0b8167..75b165386935 100644
> --- a/drivers/gpu/drm/vboxvideo/vbox_drv.c
> +++ b/drivers/gpu/drm/vboxvideo/vbox_drv.c
> @@ -215,9 +215,10 @@ static struct drm_driver driver = {
>   	.minor = DRIVER_MINOR,
>   	.patchlevel = DRIVER_PATCHLEVEL,
>   
> -	.gem_free_object_unlocked = vbox_gem_free_object,
> +	.gem_free_object_unlocked =
> +		drm_gem_ttm_driver_gem_free_object_unlocked,
>   	.dumb_create = vbox_dumb_create,
> -	.dumb_map_offset = vbox_dumb_mmap_offset,
> +	.dumb_map_offset = drm_gem_ttm_driver_dumb_mmap_offset,
>   	.prime_handle_to_fd = drm_gem_prime_handle_to_fd,
>   	.prime_fd_to_handle = drm_gem_prime_fd_to_handle,
>   	.gem_prime_export = drm_gem_prime_export,
> diff --git a/drivers/gpu/drm/vboxvideo/vbox_drv.h b/drivers/gpu/drm/vboxvideo/vbox_drv.h
> index ece31f395540..7db4e961805d 100644
> --- a/drivers/gpu/drm/vboxvideo/vbox_drv.h
> +++ b/drivers/gpu/drm/vboxvideo/vbox_drv.h
> @@ -18,6 +18,7 @@
>   #include <drm/drm_encoder.h>
>   #include <drm/drm_fb_helper.h>
>   #include <drm/drm_gem.h>
> +#include <drm/drm_gem_ttm_helper.h>
>   
>   #include <drm/ttm/ttm_bo_api.h>
>   #include <drm/ttm/ttm_bo_driver.h>
> @@ -170,73 +171,16 @@ int vboxfb_create(struct drm_fb_helper *helper,
>   		  struct drm_fb_helper_surface_size *sizes);
>   void vbox_fbdev_fini(struct vbox_private *vbox);
>   
> -struct vbox_bo {
> -	struct ttm_buffer_object bo;
> -	struct ttm_placement placement;
> -	struct ttm_bo_kmap_obj kmap;
> -	struct drm_gem_object gem;
> -	struct ttm_place placements[3];
> -	int pin_count;
> -};
> -
> -#define gem_to_vbox_bo(gobj) container_of((gobj), struct vbox_bo, gem)
> -
> -static inline struct vbox_bo *vbox_bo(struct ttm_buffer_object *bo)
> -{
> -	return container_of(bo, struct vbox_bo, bo);
> -}
> -
> -#define to_vbox_obj(x) container_of(x, struct vbox_gem_object, base)
> -
> -static inline u64 vbox_bo_gpu_offset(struct vbox_bo *bo)
> -{
> -	return bo->bo.offset;
> -}
> -
>   int vbox_dumb_create(struct drm_file *file,
>   		     struct drm_device *dev,
>   		     struct drm_mode_create_dumb *args);
>   
> -void vbox_gem_free_object(struct drm_gem_object *obj);
> -int vbox_dumb_mmap_offset(struct drm_file *file,
> -			  struct drm_device *dev,
> -			  u32 handle, u64 *offset);
> -
>   int vbox_mm_init(struct vbox_private *vbox);
>   void vbox_mm_fini(struct vbox_private *vbox);
>   
> -int vbox_bo_create(struct vbox_private *vbox, int size, int align,
> -		   u32 flags, struct vbox_bo **pvboxbo);
> -
>   int vbox_gem_create(struct vbox_private *vbox,
>   		    u32 size, bool iskernel, struct drm_gem_object **obj);
> -
> -int vbox_bo_pin(struct vbox_bo *bo, u32 pl_flag);
> -int vbox_bo_unpin(struct vbox_bo *bo);
> -
> -static inline int vbox_bo_reserve(struct vbox_bo *bo, bool no_wait)
> -{
> -	int ret;
> -
> -	ret = ttm_bo_reserve(&bo->bo, true, no_wait, NULL);
> -	if (ret) {
> -		if (ret != -ERESTARTSYS && ret != -EBUSY)
> -			DRM_ERROR("reserve failed %p\n", bo);
> -		return ret;
> -	}
> -	return 0;
> -}
> -
> -static inline void vbox_bo_unreserve(struct vbox_bo *bo)
> -{
> -	ttm_bo_unreserve(&bo->bo);
> -}
> -
> -void vbox_ttm_placement(struct vbox_bo *bo, int domain);
> -int vbox_bo_push_sysram(struct vbox_bo *bo);
>   int vbox_mmap(struct file *filp, struct vm_area_struct *vma);
> -void *vbox_bo_kmap(struct vbox_bo *bo);
> -void vbox_bo_kunmap(struct vbox_bo *bo);
>   
>   /* vbox_prime.c */
>   int vbox_gem_prime_pin(struct drm_gem_object *obj);
> diff --git a/drivers/gpu/drm/vboxvideo/vbox_fb.c b/drivers/gpu/drm/vboxvideo/vbox_fb.c
> index b724fe7c0c30..1cf0c6bd58b9 100644
> --- a/drivers/gpu/drm/vboxvideo/vbox_fb.c
> +++ b/drivers/gpu/drm/vboxvideo/vbox_fb.c
> @@ -51,9 +51,9 @@ int vboxfb_create(struct drm_fb_helper *helper,
>   	struct drm_framebuffer *fb;
>   	struct fb_info *info;
>   	struct drm_gem_object *gobj;
> -	struct vbox_bo *bo;
> +	struct drm_gem_ttm_object *gbo;
>   	int size, ret;
> -	u64 gpu_addr;
> +	s64 gpu_addr;
>   	u32 pitch;
>   
>   	mode_cmd.width = sizes->surface_width;
> @@ -75,9 +75,9 @@ int vboxfb_create(struct drm_fb_helper *helper,
>   	if (ret)
>   		return ret;
>   
> -	bo = gem_to_vbox_bo(gobj);
> +	gbo = drm_gem_ttm_of_gem(gobj);
>   
> -	ret = vbox_bo_pin(bo, TTM_PL_FLAG_VRAM);
> +	ret = drm_gem_ttm_pin(gbo, TTM_PL_FLAG_VRAM);
>   	if (ret)
>   		return ret;
>   
> @@ -86,7 +86,7 @@ int vboxfb_create(struct drm_fb_helper *helper,
>   		return PTR_ERR(info);
>   
>   	info->screen_size = size;
> -	info->screen_base = (char __iomem *)vbox_bo_kmap(bo);
> +	info->screen_base = (char __iomem *)drm_gem_ttm_kmap(gbo, true);
>   	if (IS_ERR(info->screen_base))
>   		return PTR_ERR(info->screen_base);
>   
> @@ -104,7 +104,9 @@ int vboxfb_create(struct drm_fb_helper *helper,
>   
>   	drm_fb_helper_fill_info(info, helper, sizes);
>   
> -	gpu_addr = vbox_bo_gpu_offset(bo);
> +	gpu_addr = drm_gem_ttm_vram_offset(gbo);
> +	if (gpu_addr < 0)
> +		return (int)gpu_addr;
>   	info->fix.smem_start = info->apertures->ranges[0].base + gpu_addr;
>   	info->fix.smem_len = vbox->available_vram_size - gpu_addr;
>   
> @@ -132,12 +134,10 @@ void vbox_fbdev_fini(struct vbox_private *vbox)
>   	drm_fb_helper_unregister_fbi(&vbox->fb_helper);
>   
>   	if (afb->obj) {
> -		struct vbox_bo *bo = gem_to_vbox_bo(afb->obj);
> +		struct drm_gem_ttm_object *gbo = drm_gem_ttm_of_gem(afb->obj);
>   
> -		vbox_bo_kunmap(bo);
> -
> -		if (bo->pin_count)
> -			vbox_bo_unpin(bo);
> +		drm_gem_ttm_kunmap(gbo);
> +		drm_gem_ttm_unpin(gbo);
>   
>   		drm_gem_object_put_unlocked(afb->obj);
>   		afb->obj = NULL;
> diff --git a/drivers/gpu/drm/vboxvideo/vbox_main.c b/drivers/gpu/drm/vboxvideo/vbox_main.c
> index f4d02de5518a..0c3ede058f2b 100644
> --- a/drivers/gpu/drm/vboxvideo/vbox_main.c
> +++ b/drivers/gpu/drm/vboxvideo/vbox_main.c
> @@ -274,7 +274,7 @@ void vbox_hw_fini(struct vbox_private *vbox)
>   int vbox_gem_create(struct vbox_private *vbox,
>   		    u32 size, bool iskernel, struct drm_gem_object **obj)
>   {
> -	struct vbox_bo *vboxbo;
> +	struct drm_gem_ttm_object *gbo;
>   	int ret;
>   
>   	*obj = NULL;
> @@ -283,14 +283,15 @@ int vbox_gem_create(struct vbox_private *vbox,
>   	if (size == 0)
>   		return -EINVAL;
>   
> -	ret = vbox_bo_create(vbox, size, 0, 0, &vboxbo);
> -	if (ret) {
> +	gbo = drm_gem_ttm_create(&vbox->ddev, &vbox->ttm.bdev, size, 0, false);
> +	if (IS_ERR(gbo)) {
> +		ret = PTR_ERR(gbo);
>   		if (ret != -ERESTARTSYS)
>   			DRM_ERROR("failed to allocate GEM object\n");
>   		return ret;
>   	}
>   
> -	*obj = &vboxbo->gem;
> +	*obj = &gbo->gem;
>   
>   	return 0;
>   }
> @@ -298,64 +299,9 @@ int vbox_gem_create(struct vbox_private *vbox,
>   int vbox_dumb_create(struct drm_file *file,
>   		     struct drm_device *dev, struct drm_mode_create_dumb *args)
>   {
> -	struct vbox_private *vbox =
> -		container_of(dev, struct vbox_private, ddev);
> -	struct drm_gem_object *gobj;
> -	u32 handle;
> -	int ret;
> -
> -	args->pitch = args->width * ((args->bpp + 7) / 8);
> -	args->size = args->pitch * args->height;
> -
> -	ret = vbox_gem_create(vbox, args->size, false, &gobj);
> -	if (ret)
> -		return ret;
> -
> -	ret = drm_gem_handle_create(file, gobj, &handle);
> -	drm_gem_object_put_unlocked(gobj);
> -	if (ret)
> -		return ret;
> +	struct vbox_private *vbox = dev->dev_private;
>   
> -	args->handle = handle;
> -
> -	return 0;
> -}
> -
> -void vbox_gem_free_object(struct drm_gem_object *obj)
> -{
> -	struct vbox_bo *vbox_bo = gem_to_vbox_bo(obj);
> +	return drm_gem_ttm_fill_create_dumb(file, dev, &vbox->ttm.bdev, 0,
> +					    false, args);
>   
> -	ttm_bo_put(&vbox_bo->bo);
> -}
> -
> -static inline u64 vbox_bo_mmap_offset(struct vbox_bo *bo)
> -{
> -	return drm_vma_node_offset_addr(&bo->bo.vma_node);
> -}
> -
> -int
> -vbox_dumb_mmap_offset(struct drm_file *file,
> -		      struct drm_device *dev,
> -		      u32 handle, u64 *offset)
> -{
> -	struct drm_gem_object *obj;
> -	int ret;
> -	struct vbox_bo *bo;
> -
> -	mutex_lock(&dev->struct_mutex);
> -	obj = drm_gem_object_lookup(file, handle);
> -	if (!obj) {
> -		ret = -ENOENT;
> -		goto out_unlock;
> -	}
> -
> -	bo = gem_to_vbox_bo(obj);
> -	*offset = vbox_bo_mmap_offset(bo);
> -
> -	drm_gem_object_put(obj);
> -	ret = 0;
> -
> -out_unlock:
> -	mutex_unlock(&dev->struct_mutex);
> -	return ret;
>   }
> diff --git a/drivers/gpu/drm/vboxvideo/vbox_mode.c b/drivers/gpu/drm/vboxvideo/vbox_mode.c
> index 620a6e38f71f..faabf2801739 100644
> --- a/drivers/gpu/drm/vboxvideo/vbox_mode.c
> +++ b/drivers/gpu/drm/vboxvideo/vbox_mode.c
> @@ -173,7 +173,8 @@ static void vbox_crtc_set_base_and_mode(struct drm_crtc *crtc,
>   					struct drm_framebuffer *fb,
>   					int x, int y)
>   {
> -	struct vbox_bo *bo = gem_to_vbox_bo(to_vbox_framebuffer(fb)->obj);
> +	struct drm_gem_ttm_object *gbo =
> +		drm_gem_ttm_of_gem(to_vbox_framebuffer(fb)->obj);
>   	struct vbox_private *vbox = crtc->dev->dev_private;
>   	struct vbox_crtc *vbox_crtc = to_vbox_crtc(crtc);
>   	bool needs_modeset = drm_atomic_crtc_needs_modeset(crtc->state);
> @@ -187,7 +188,7 @@ static void vbox_crtc_set_base_and_mode(struct drm_crtc *crtc,
>   
>   	vbox_crtc->x = x;
>   	vbox_crtc->y = y;
> -	vbox_crtc->fb_offset = vbox_bo_gpu_offset(bo);
> +	vbox_crtc->fb_offset = drm_gem_ttm_vram_offset(gbo);
>   
>   	/* vbox_do_modeset() checks vbox->single_framebuffer so update it now */
>   	if (needs_modeset && vbox_set_up_input_mapping(vbox)) {
> @@ -303,14 +304,14 @@ static void vbox_primary_atomic_disable(struct drm_plane *plane,
>   static int vbox_primary_prepare_fb(struct drm_plane *plane,
>   				   struct drm_plane_state *new_state)
>   {
> -	struct vbox_bo *bo;
> +	struct drm_gem_ttm_object *gbo;
>   	int ret;
>   
>   	if (!new_state->fb)
>   		return 0;
>   
> -	bo = gem_to_vbox_bo(to_vbox_framebuffer(new_state->fb)->obj);
> -	ret = vbox_bo_pin(bo, TTM_PL_FLAG_VRAM);
> +	gbo = drm_gem_ttm_of_gem(to_vbox_framebuffer(new_state->fb)->obj);
> +	ret = drm_gem_ttm_pin(gbo, TTM_PL_FLAG_VRAM);
>   	if (ret)
>   		DRM_WARN("Error %d pinning new fb, out of video mem?\n", ret);
>   
> @@ -320,13 +321,13 @@ static int vbox_primary_prepare_fb(struct drm_plane *plane,
>   static void vbox_primary_cleanup_fb(struct drm_plane *plane,
>   				    struct drm_plane_state *old_state)
>   {
> -	struct vbox_bo *bo;
> +	struct drm_gem_ttm_object *gbo;
>   
>   	if (!old_state->fb)
>   		return;
>   
> -	bo = gem_to_vbox_bo(to_vbox_framebuffer(old_state->fb)->obj);
> -	vbox_bo_unpin(bo);
> +	gbo = drm_gem_ttm_of_gem(to_vbox_framebuffer(old_state->fb)->obj);
> +	drm_gem_ttm_unpin(gbo);
>   }
>   
>   static int vbox_cursor_atomic_check(struct drm_plane *plane,
> @@ -386,7 +387,8 @@ static void vbox_cursor_atomic_update(struct drm_plane *plane,
>   		container_of(plane->dev, struct vbox_private, ddev);
>   	struct vbox_crtc *vbox_crtc = to_vbox_crtc(plane->state->crtc);
>   	struct drm_framebuffer *fb = plane->state->fb;
> -	struct vbox_bo *bo = gem_to_vbox_bo(to_vbox_framebuffer(fb)->obj);
> +	struct drm_gem_ttm_object *gbo =
> +		drm_gem_ttm_of_gem(to_vbox_framebuffer(fb)->obj);
>   	u32 width = plane->state->crtc_w;
>   	u32 height = plane->state->crtc_h;
>   	size_t data_size, mask_size;
> @@ -405,7 +407,7 @@ static void vbox_cursor_atomic_update(struct drm_plane *plane,
>   	vbox_crtc->cursor_enabled = true;
>   
>   	/* pinning is done in prepare/cleanup framebuffer */
> -	src = vbox_bo_kmap(bo);
> +	src = drm_gem_ttm_kmap(gbo, true);
>   	if (IS_ERR(src)) {
>   		mutex_unlock(&vbox->hw_mutex);
>   		DRM_WARN("Could not kmap cursor bo, skipping update\n");
> @@ -421,7 +423,7 @@ static void vbox_cursor_atomic_update(struct drm_plane *plane,
>   	data_size = width * height * 4 + mask_size;
>   
>   	copy_cursor_image(src, vbox->cursor_data, width, height, mask_size);
> -	vbox_bo_kunmap(bo);
> +	drm_gem_ttm_kunmap(gbo);
>   
>   	flags = VBOX_MOUSE_POINTER_VISIBLE | VBOX_MOUSE_POINTER_SHAPE |
>   		VBOX_MOUSE_POINTER_ALPHA;
> @@ -461,25 +463,25 @@ static void vbox_cursor_atomic_disable(struct drm_plane *plane,
>   static int vbox_cursor_prepare_fb(struct drm_plane *plane,
>   				  struct drm_plane_state *new_state)
>   {
> -	struct vbox_bo *bo;
> +	struct drm_gem_ttm_object *gbo;
>   
>   	if (!new_state->fb)
>   		return 0;
>   
> -	bo = gem_to_vbox_bo(to_vbox_framebuffer(new_state->fb)->obj);
> -	return vbox_bo_pin(bo, TTM_PL_FLAG_SYSTEM);
> +	gbo = drm_gem_ttm_of_gem(to_vbox_framebuffer(new_state->fb)->obj);
> +	return drm_gem_ttm_pin(gbo, TTM_PL_FLAG_SYSTEM);
>   }
>   
>   static void vbox_cursor_cleanup_fb(struct drm_plane *plane,
>   				   struct drm_plane_state *old_state)
>   {
> -	struct vbox_bo *bo;
> +	struct drm_gem_ttm_object *gbo;
>   
>   	if (!plane->state->fb)
>   		return;
>   
> -	bo = gem_to_vbox_bo(to_vbox_framebuffer(plane->state->fb)->obj);
> -	vbox_bo_unpin(bo);
> +	gbo = drm_gem_ttm_of_gem(to_vbox_framebuffer(plane->state->fb)->obj);
> +	drm_gem_ttm_unpin(gbo);
>   }
>   
>   static const u32 vbox_cursor_plane_formats[] = {
> diff --git a/drivers/gpu/drm/vboxvideo/vbox_ttm.c b/drivers/gpu/drm/vboxvideo/vbox_ttm.c
> index 9d78438c2877..a1d64e1ea90c 100644
> --- a/drivers/gpu/drm/vboxvideo/vbox_ttm.c
> +++ b/drivers/gpu/drm/vboxvideo/vbox_ttm.c
> @@ -16,24 +16,6 @@ static inline struct vbox_private *vbox_bdev(struct ttm_bo_device *bd)
>   	return container_of(bd, struct vbox_private, ttm.bdev);
>   }
>   
> -static void vbox_bo_ttm_destroy(struct ttm_buffer_object *tbo)
> -{
> -	struct vbox_bo *bo;
> -
> -	bo = container_of(tbo, struct vbox_bo, bo);
> -
> -	drm_gem_object_release(&bo->gem);
> -	kfree(bo);
> -}
> -
> -static bool vbox_ttm_bo_is_vbox_bo(struct ttm_buffer_object *bo)
> -{
> -	if (bo->destroy == &vbox_bo_ttm_destroy)
> -		return true;
> -
> -	return false;
> -}
> -
>   static int
>   vbox_bo_init_mem_type(struct ttm_bo_device *bdev, u32 type,
>   		      struct ttm_mem_type_manager *man)
> @@ -58,24 +40,6 @@ vbox_bo_init_mem_type(struct ttm_bo_device *bdev, u32 type,
>   	return 0;
>   }
>   
> -static void
> -vbox_bo_evict_flags(struct ttm_buffer_object *bo, struct ttm_placement *pl)
> -{
> -	struct vbox_bo *vboxbo = vbox_bo(bo);
> -
> -	if (!vbox_ttm_bo_is_vbox_bo(bo))
> -		return;
> -
> -	vbox_ttm_placement(vboxbo, TTM_PL_FLAG_SYSTEM);
> -	*pl = vboxbo->placement;
> -}
> -
> -static int vbox_bo_verify_access(struct ttm_buffer_object *bo,
> -				 struct file *filp)
> -{
> -	return 0;
> -}
> -
>   static int vbox_ttm_io_mem_reserve(struct ttm_bo_device *bdev,
>   				   struct ttm_mem_reg *mem)
>   {
> @@ -141,8 +105,8 @@ static struct ttm_bo_driver vbox_bo_driver = {
>   	.ttm_tt_create = vbox_ttm_tt_create,
>   	.init_mem_type = vbox_bo_init_mem_type,
>   	.eviction_valuable = ttm_bo_eviction_valuable,
> -	.evict_flags = vbox_bo_evict_flags,
> -	.verify_access = vbox_bo_verify_access,
> +	.evict_flags = drm_gem_ttm_bo_driver_evict_flags,
> +	.verify_access = drm_gem_ttm_bo_driver_verify_access,
>   	.io_mem_reserve = &vbox_ttm_io_mem_reserve,
>   	.io_mem_free = &vbox_ttm_io_mem_free,
>   };
> @@ -196,165 +160,6 @@ void vbox_mm_fini(struct vbox_private *vbox)
>   	ttm_bo_device_release(&vbox->ttm.bdev);
>   }
>   
> -void vbox_ttm_placement(struct vbox_bo *bo, int domain)
> -{
> -	unsigned int i;
> -	u32 c = 0;
> -
> -	bo->placement.placement = bo->placements;
> -	bo->placement.busy_placement = bo->placements;
> -
> -	if (domain & TTM_PL_FLAG_VRAM)
> -		bo->placements[c++].flags =
> -		    TTM_PL_FLAG_WC | TTM_PL_FLAG_UNCACHED | TTM_PL_FLAG_VRAM;
> -	if (domain & TTM_PL_FLAG_SYSTEM)
> -		bo->placements[c++].flags =
> -		    TTM_PL_MASK_CACHING | TTM_PL_FLAG_SYSTEM;
> -	if (!c)
> -		bo->placements[c++].flags =
> -		    TTM_PL_MASK_CACHING | TTM_PL_FLAG_SYSTEM;
> -
> -	bo->placement.num_placement = c;
> -	bo->placement.num_busy_placement = c;
> -
> -	for (i = 0; i < c; ++i) {
> -		bo->placements[i].fpfn = 0;
> -		bo->placements[i].lpfn = 0;
> -	}
> -}
> -
> -int vbox_bo_create(struct vbox_private *vbox, int size, int align,
> -		   u32 flags, struct vbox_bo **pvboxbo)
> -{
> -	struct vbox_bo *vboxbo;
> -	size_t acc_size;
> -	int ret;
> -
> -	vboxbo = kzalloc(sizeof(*vboxbo), GFP_KERNEL);
> -	if (!vboxbo)
> -		return -ENOMEM;
> -
> -	ret = drm_gem_object_init(&vbox->ddev, &vboxbo->gem, size);
> -	if (ret)
> -		goto err_free_vboxbo;
> -
> -	vboxbo->bo.bdev = &vbox->ttm.bdev;
> -
> -	vbox_ttm_placement(vboxbo, TTM_PL_FLAG_VRAM | TTM_PL_FLAG_SYSTEM);
> -
> -	acc_size = ttm_bo_dma_acc_size(&vbox->ttm.bdev, size,
> -				       sizeof(struct vbox_bo));
> -
> -	ret = ttm_bo_init(&vbox->ttm.bdev, &vboxbo->bo, size,
> -			  ttm_bo_type_device, &vboxbo->placement,
> -			  align >> PAGE_SHIFT, false, acc_size,
> -			  NULL, NULL, vbox_bo_ttm_destroy);
> -	if (ret)
> -		goto err_free_vboxbo;
> -
> -	*pvboxbo = vboxbo;
> -
> -	return 0;
> -
> -err_free_vboxbo:
> -	kfree(vboxbo);
> -	return ret;
> -}
> -
> -int vbox_bo_pin(struct vbox_bo *bo, u32 pl_flag)
> -{
> -	struct ttm_operation_ctx ctx = { false, false };
> -	int i, ret;
> -
> -	if (bo->pin_count) {
> -		bo->pin_count++;
> -		return 0;
> -	}
> -
> -	ret = vbox_bo_reserve(bo, false);
> -	if (ret)
> -		return ret;
> -
> -	vbox_ttm_placement(bo, pl_flag);
> -
> -	for (i = 0; i < bo->placement.num_placement; i++)
> -		bo->placements[i].flags |= TTM_PL_FLAG_NO_EVICT;
> -
> -	ret = ttm_bo_validate(&bo->bo, &bo->placement, &ctx);
> -	if (ret == 0)
> -		bo->pin_count = 1;
> -
> -	vbox_bo_unreserve(bo);
> -
> -	return ret;
> -}
> -
> -int vbox_bo_unpin(struct vbox_bo *bo)
> -{
> -	struct ttm_operation_ctx ctx = { false, false };
> -	int i, ret;
> -
> -	if (!bo->pin_count) {
> -		DRM_ERROR("unpin bad %p\n", bo);
> -		return 0;
> -	}
> -	bo->pin_count--;
> -	if (bo->pin_count)
> -		return 0;
> -
> -	ret = vbox_bo_reserve(bo, false);
> -	if (ret) {
> -		DRM_ERROR("Error %d reserving bo, leaving it pinned\n", ret);
> -		return ret;
> -	}
> -
> -	for (i = 0; i < bo->placement.num_placement; i++)
> -		bo->placements[i].flags &= ~TTM_PL_FLAG_NO_EVICT;
> -
> -	ret = ttm_bo_validate(&bo->bo, &bo->placement, &ctx);
> -
> -	vbox_bo_unreserve(bo);
> -
> -	return ret;
> -}
> -
> -/*
> - * Move a vbox-owned buffer object to system memory if no one else has it
> - * pinned.  The caller must have pinned it previously, and this call will
> - * release the caller's pin.
> - */
> -int vbox_bo_push_sysram(struct vbox_bo *bo)
> -{
> -	struct ttm_operation_ctx ctx = { false, false };
> -	int i, ret;
> -
> -	if (!bo->pin_count) {
> -		DRM_ERROR("unpin bad %p\n", bo);
> -		return 0;
> -	}
> -	bo->pin_count--;
> -	if (bo->pin_count)
> -		return 0;
> -
> -	if (bo->kmap.virtual) {
> -		ttm_bo_kunmap(&bo->kmap);
> -		bo->kmap.virtual = NULL;
> -	}
> -
> -	vbox_ttm_placement(bo, TTM_PL_FLAG_SYSTEM);
> -
> -	for (i = 0; i < bo->placement.num_placement; i++)
> -		bo->placements[i].flags |= TTM_PL_FLAG_NO_EVICT;
> -
> -	ret = ttm_bo_validate(&bo->bo, &bo->placement, &ctx);
> -	if (ret) {
> -		DRM_ERROR("pushing to VRAM failed\n");
> -		return ret;
> -	}
> -
> -	return 0;
> -}
> -
>   int vbox_mmap(struct file *filp, struct vm_area_struct *vma)
>   {
>   	struct drm_file *file_priv = filp->private_data;
> @@ -362,27 +167,3 @@ int vbox_mmap(struct file *filp, struct vm_area_struct *vma)
>   
>   	return ttm_bo_mmap(filp, vma, &vbox->ttm.bdev);
>   }
> -
> -void *vbox_bo_kmap(struct vbox_bo *bo)
> -{
> -	int ret;
> -
> -	if (bo->kmap.virtual)
> -		return bo->kmap.virtual;
> -
> -	ret = ttm_bo_kmap(&bo->bo, 0, bo->bo.num_pages, &bo->kmap);
> -	if (ret) {
> -		DRM_ERROR("Error kmapping bo: %d\n", ret);
> -		return NULL;
> -	}
> -
> -	return bo->kmap.virtual;
> -}
> -
> -void vbox_bo_kunmap(struct vbox_bo *bo)
> -{
> -	if (bo->kmap.virtual) {
> -		ttm_bo_kunmap(&bo->kmap);
> -		bo->kmap.virtual = NULL;
> -	}
> -}
> 

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

* Re: [PATCH 12/15] drm/vboxvideo: Convert vboxvideo driver to |struct drm_gem_ttm_object|
  2019-04-08  9:21 ` [PATCH 12/15] drm/vboxvideo: Convert vboxvideo driver to |struct drm_gem_ttm_object| Thomas Zimmermann
@ 2019-04-09  7:09   ` Hans de Goede
  2019-04-09  7:09   ` Hans de Goede
  1 sibling, 0 replies; 43+ messages in thread
From: Hans de Goede @ 2019-04-09  7:09 UTC (permalink / raw)
  To: Thomas Zimmermann, daniel, airlied, kraxel, christian.koenig,
	ray.huang, Jerry.Zhang, z.liuxinliang, zourongrong,
	kong.kongxinwei, puck.chen
  Cc: dri-devel, virtualization

Hi,

On 08-04-19 11:21, Thomas Zimmermann wrote:
> This patch replaces |struct vbox_bo| and its helpers with the generic
> implementation of |struct drm_gem_ttm_object|. The only change in
> semantics is that &ttm_bo_driver.verify_access() now does the actual
> verification.
> 
> Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>

Nice cleanup, thank you, patch looks good to me:

Reviewed-by: Hans de Goede <hdegoede@redhat.com>

Regards,

Hans

> ---
>   drivers/gpu/drm/vboxvideo/Kconfig     |   1 +
>   drivers/gpu/drm/vboxvideo/vbox_drv.c  |   5 +-
>   drivers/gpu/drm/vboxvideo/vbox_drv.h  |  58 +------
>   drivers/gpu/drm/vboxvideo/vbox_fb.c   |  22 +--
>   drivers/gpu/drm/vboxvideo/vbox_main.c |  70 +-------
>   drivers/gpu/drm/vboxvideo/vbox_mode.c |  36 +++--
>   drivers/gpu/drm/vboxvideo/vbox_ttm.c  | 223 +-------------------------
>   7 files changed, 45 insertions(+), 370 deletions(-)
> 
> diff --git a/drivers/gpu/drm/vboxvideo/Kconfig b/drivers/gpu/drm/vboxvideo/Kconfig
> index 1f4182e2e980..c1ca87df81df 100644
> --- a/drivers/gpu/drm/vboxvideo/Kconfig
> +++ b/drivers/gpu/drm/vboxvideo/Kconfig
> @@ -3,6 +3,7 @@ config DRM_VBOXVIDEO
>   	depends on DRM && X86 && PCI
>   	select DRM_KMS_HELPER
>   	select DRM_TTM
> +	select DRM_GEM_TTM_HELPER
>   	select GENERIC_ALLOCATOR
>   	help
>   	  This is a KMS driver for the virtual Graphics Card used in
> diff --git a/drivers/gpu/drm/vboxvideo/vbox_drv.c b/drivers/gpu/drm/vboxvideo/vbox_drv.c
> index fb6a0f0b8167..75b165386935 100644
> --- a/drivers/gpu/drm/vboxvideo/vbox_drv.c
> +++ b/drivers/gpu/drm/vboxvideo/vbox_drv.c
> @@ -215,9 +215,10 @@ static struct drm_driver driver = {
>   	.minor = DRIVER_MINOR,
>   	.patchlevel = DRIVER_PATCHLEVEL,
>   
> -	.gem_free_object_unlocked = vbox_gem_free_object,
> +	.gem_free_object_unlocked =
> +		drm_gem_ttm_driver_gem_free_object_unlocked,
>   	.dumb_create = vbox_dumb_create,
> -	.dumb_map_offset = vbox_dumb_mmap_offset,
> +	.dumb_map_offset = drm_gem_ttm_driver_dumb_mmap_offset,
>   	.prime_handle_to_fd = drm_gem_prime_handle_to_fd,
>   	.prime_fd_to_handle = drm_gem_prime_fd_to_handle,
>   	.gem_prime_export = drm_gem_prime_export,
> diff --git a/drivers/gpu/drm/vboxvideo/vbox_drv.h b/drivers/gpu/drm/vboxvideo/vbox_drv.h
> index ece31f395540..7db4e961805d 100644
> --- a/drivers/gpu/drm/vboxvideo/vbox_drv.h
> +++ b/drivers/gpu/drm/vboxvideo/vbox_drv.h
> @@ -18,6 +18,7 @@
>   #include <drm/drm_encoder.h>
>   #include <drm/drm_fb_helper.h>
>   #include <drm/drm_gem.h>
> +#include <drm/drm_gem_ttm_helper.h>
>   
>   #include <drm/ttm/ttm_bo_api.h>
>   #include <drm/ttm/ttm_bo_driver.h>
> @@ -170,73 +171,16 @@ int vboxfb_create(struct drm_fb_helper *helper,
>   		  struct drm_fb_helper_surface_size *sizes);
>   void vbox_fbdev_fini(struct vbox_private *vbox);
>   
> -struct vbox_bo {
> -	struct ttm_buffer_object bo;
> -	struct ttm_placement placement;
> -	struct ttm_bo_kmap_obj kmap;
> -	struct drm_gem_object gem;
> -	struct ttm_place placements[3];
> -	int pin_count;
> -};
> -
> -#define gem_to_vbox_bo(gobj) container_of((gobj), struct vbox_bo, gem)
> -
> -static inline struct vbox_bo *vbox_bo(struct ttm_buffer_object *bo)
> -{
> -	return container_of(bo, struct vbox_bo, bo);
> -}
> -
> -#define to_vbox_obj(x) container_of(x, struct vbox_gem_object, base)
> -
> -static inline u64 vbox_bo_gpu_offset(struct vbox_bo *bo)
> -{
> -	return bo->bo.offset;
> -}
> -
>   int vbox_dumb_create(struct drm_file *file,
>   		     struct drm_device *dev,
>   		     struct drm_mode_create_dumb *args);
>   
> -void vbox_gem_free_object(struct drm_gem_object *obj);
> -int vbox_dumb_mmap_offset(struct drm_file *file,
> -			  struct drm_device *dev,
> -			  u32 handle, u64 *offset);
> -
>   int vbox_mm_init(struct vbox_private *vbox);
>   void vbox_mm_fini(struct vbox_private *vbox);
>   
> -int vbox_bo_create(struct vbox_private *vbox, int size, int align,
> -		   u32 flags, struct vbox_bo **pvboxbo);
> -
>   int vbox_gem_create(struct vbox_private *vbox,
>   		    u32 size, bool iskernel, struct drm_gem_object **obj);
> -
> -int vbox_bo_pin(struct vbox_bo *bo, u32 pl_flag);
> -int vbox_bo_unpin(struct vbox_bo *bo);
> -
> -static inline int vbox_bo_reserve(struct vbox_bo *bo, bool no_wait)
> -{
> -	int ret;
> -
> -	ret = ttm_bo_reserve(&bo->bo, true, no_wait, NULL);
> -	if (ret) {
> -		if (ret != -ERESTARTSYS && ret != -EBUSY)
> -			DRM_ERROR("reserve failed %p\n", bo);
> -		return ret;
> -	}
> -	return 0;
> -}
> -
> -static inline void vbox_bo_unreserve(struct vbox_bo *bo)
> -{
> -	ttm_bo_unreserve(&bo->bo);
> -}
> -
> -void vbox_ttm_placement(struct vbox_bo *bo, int domain);
> -int vbox_bo_push_sysram(struct vbox_bo *bo);
>   int vbox_mmap(struct file *filp, struct vm_area_struct *vma);
> -void *vbox_bo_kmap(struct vbox_bo *bo);
> -void vbox_bo_kunmap(struct vbox_bo *bo);
>   
>   /* vbox_prime.c */
>   int vbox_gem_prime_pin(struct drm_gem_object *obj);
> diff --git a/drivers/gpu/drm/vboxvideo/vbox_fb.c b/drivers/gpu/drm/vboxvideo/vbox_fb.c
> index b724fe7c0c30..1cf0c6bd58b9 100644
> --- a/drivers/gpu/drm/vboxvideo/vbox_fb.c
> +++ b/drivers/gpu/drm/vboxvideo/vbox_fb.c
> @@ -51,9 +51,9 @@ int vboxfb_create(struct drm_fb_helper *helper,
>   	struct drm_framebuffer *fb;
>   	struct fb_info *info;
>   	struct drm_gem_object *gobj;
> -	struct vbox_bo *bo;
> +	struct drm_gem_ttm_object *gbo;
>   	int size, ret;
> -	u64 gpu_addr;
> +	s64 gpu_addr;
>   	u32 pitch;
>   
>   	mode_cmd.width = sizes->surface_width;
> @@ -75,9 +75,9 @@ int vboxfb_create(struct drm_fb_helper *helper,
>   	if (ret)
>   		return ret;
>   
> -	bo = gem_to_vbox_bo(gobj);
> +	gbo = drm_gem_ttm_of_gem(gobj);
>   
> -	ret = vbox_bo_pin(bo, TTM_PL_FLAG_VRAM);
> +	ret = drm_gem_ttm_pin(gbo, TTM_PL_FLAG_VRAM);
>   	if (ret)
>   		return ret;
>   
> @@ -86,7 +86,7 @@ int vboxfb_create(struct drm_fb_helper *helper,
>   		return PTR_ERR(info);
>   
>   	info->screen_size = size;
> -	info->screen_base = (char __iomem *)vbox_bo_kmap(bo);
> +	info->screen_base = (char __iomem *)drm_gem_ttm_kmap(gbo, true);
>   	if (IS_ERR(info->screen_base))
>   		return PTR_ERR(info->screen_base);
>   
> @@ -104,7 +104,9 @@ int vboxfb_create(struct drm_fb_helper *helper,
>   
>   	drm_fb_helper_fill_info(info, helper, sizes);
>   
> -	gpu_addr = vbox_bo_gpu_offset(bo);
> +	gpu_addr = drm_gem_ttm_vram_offset(gbo);
> +	if (gpu_addr < 0)
> +		return (int)gpu_addr;
>   	info->fix.smem_start = info->apertures->ranges[0].base + gpu_addr;
>   	info->fix.smem_len = vbox->available_vram_size - gpu_addr;
>   
> @@ -132,12 +134,10 @@ void vbox_fbdev_fini(struct vbox_private *vbox)
>   	drm_fb_helper_unregister_fbi(&vbox->fb_helper);
>   
>   	if (afb->obj) {
> -		struct vbox_bo *bo = gem_to_vbox_bo(afb->obj);
> +		struct drm_gem_ttm_object *gbo = drm_gem_ttm_of_gem(afb->obj);
>   
> -		vbox_bo_kunmap(bo);
> -
> -		if (bo->pin_count)
> -			vbox_bo_unpin(bo);
> +		drm_gem_ttm_kunmap(gbo);
> +		drm_gem_ttm_unpin(gbo);
>   
>   		drm_gem_object_put_unlocked(afb->obj);
>   		afb->obj = NULL;
> diff --git a/drivers/gpu/drm/vboxvideo/vbox_main.c b/drivers/gpu/drm/vboxvideo/vbox_main.c
> index f4d02de5518a..0c3ede058f2b 100644
> --- a/drivers/gpu/drm/vboxvideo/vbox_main.c
> +++ b/drivers/gpu/drm/vboxvideo/vbox_main.c
> @@ -274,7 +274,7 @@ void vbox_hw_fini(struct vbox_private *vbox)
>   int vbox_gem_create(struct vbox_private *vbox,
>   		    u32 size, bool iskernel, struct drm_gem_object **obj)
>   {
> -	struct vbox_bo *vboxbo;
> +	struct drm_gem_ttm_object *gbo;
>   	int ret;
>   
>   	*obj = NULL;
> @@ -283,14 +283,15 @@ int vbox_gem_create(struct vbox_private *vbox,
>   	if (size == 0)
>   		return -EINVAL;
>   
> -	ret = vbox_bo_create(vbox, size, 0, 0, &vboxbo);
> -	if (ret) {
> +	gbo = drm_gem_ttm_create(&vbox->ddev, &vbox->ttm.bdev, size, 0, false);
> +	if (IS_ERR(gbo)) {
> +		ret = PTR_ERR(gbo);
>   		if (ret != -ERESTARTSYS)
>   			DRM_ERROR("failed to allocate GEM object\n");
>   		return ret;
>   	}
>   
> -	*obj = &vboxbo->gem;
> +	*obj = &gbo->gem;
>   
>   	return 0;
>   }
> @@ -298,64 +299,9 @@ int vbox_gem_create(struct vbox_private *vbox,
>   int vbox_dumb_create(struct drm_file *file,
>   		     struct drm_device *dev, struct drm_mode_create_dumb *args)
>   {
> -	struct vbox_private *vbox =
> -		container_of(dev, struct vbox_private, ddev);
> -	struct drm_gem_object *gobj;
> -	u32 handle;
> -	int ret;
> -
> -	args->pitch = args->width * ((args->bpp + 7) / 8);
> -	args->size = args->pitch * args->height;
> -
> -	ret = vbox_gem_create(vbox, args->size, false, &gobj);
> -	if (ret)
> -		return ret;
> -
> -	ret = drm_gem_handle_create(file, gobj, &handle);
> -	drm_gem_object_put_unlocked(gobj);
> -	if (ret)
> -		return ret;
> +	struct vbox_private *vbox = dev->dev_private;
>   
> -	args->handle = handle;
> -
> -	return 0;
> -}
> -
> -void vbox_gem_free_object(struct drm_gem_object *obj)
> -{
> -	struct vbox_bo *vbox_bo = gem_to_vbox_bo(obj);
> +	return drm_gem_ttm_fill_create_dumb(file, dev, &vbox->ttm.bdev, 0,
> +					    false, args);
>   
> -	ttm_bo_put(&vbox_bo->bo);
> -}
> -
> -static inline u64 vbox_bo_mmap_offset(struct vbox_bo *bo)
> -{
> -	return drm_vma_node_offset_addr(&bo->bo.vma_node);
> -}
> -
> -int
> -vbox_dumb_mmap_offset(struct drm_file *file,
> -		      struct drm_device *dev,
> -		      u32 handle, u64 *offset)
> -{
> -	struct drm_gem_object *obj;
> -	int ret;
> -	struct vbox_bo *bo;
> -
> -	mutex_lock(&dev->struct_mutex);
> -	obj = drm_gem_object_lookup(file, handle);
> -	if (!obj) {
> -		ret = -ENOENT;
> -		goto out_unlock;
> -	}
> -
> -	bo = gem_to_vbox_bo(obj);
> -	*offset = vbox_bo_mmap_offset(bo);
> -
> -	drm_gem_object_put(obj);
> -	ret = 0;
> -
> -out_unlock:
> -	mutex_unlock(&dev->struct_mutex);
> -	return ret;
>   }
> diff --git a/drivers/gpu/drm/vboxvideo/vbox_mode.c b/drivers/gpu/drm/vboxvideo/vbox_mode.c
> index 620a6e38f71f..faabf2801739 100644
> --- a/drivers/gpu/drm/vboxvideo/vbox_mode.c
> +++ b/drivers/gpu/drm/vboxvideo/vbox_mode.c
> @@ -173,7 +173,8 @@ static void vbox_crtc_set_base_and_mode(struct drm_crtc *crtc,
>   					struct drm_framebuffer *fb,
>   					int x, int y)
>   {
> -	struct vbox_bo *bo = gem_to_vbox_bo(to_vbox_framebuffer(fb)->obj);
> +	struct drm_gem_ttm_object *gbo =
> +		drm_gem_ttm_of_gem(to_vbox_framebuffer(fb)->obj);
>   	struct vbox_private *vbox = crtc->dev->dev_private;
>   	struct vbox_crtc *vbox_crtc = to_vbox_crtc(crtc);
>   	bool needs_modeset = drm_atomic_crtc_needs_modeset(crtc->state);
> @@ -187,7 +188,7 @@ static void vbox_crtc_set_base_and_mode(struct drm_crtc *crtc,
>   
>   	vbox_crtc->x = x;
>   	vbox_crtc->y = y;
> -	vbox_crtc->fb_offset = vbox_bo_gpu_offset(bo);
> +	vbox_crtc->fb_offset = drm_gem_ttm_vram_offset(gbo);
>   
>   	/* vbox_do_modeset() checks vbox->single_framebuffer so update it now */
>   	if (needs_modeset && vbox_set_up_input_mapping(vbox)) {
> @@ -303,14 +304,14 @@ static void vbox_primary_atomic_disable(struct drm_plane *plane,
>   static int vbox_primary_prepare_fb(struct drm_plane *plane,
>   				   struct drm_plane_state *new_state)
>   {
> -	struct vbox_bo *bo;
> +	struct drm_gem_ttm_object *gbo;
>   	int ret;
>   
>   	if (!new_state->fb)
>   		return 0;
>   
> -	bo = gem_to_vbox_bo(to_vbox_framebuffer(new_state->fb)->obj);
> -	ret = vbox_bo_pin(bo, TTM_PL_FLAG_VRAM);
> +	gbo = drm_gem_ttm_of_gem(to_vbox_framebuffer(new_state->fb)->obj);
> +	ret = drm_gem_ttm_pin(gbo, TTM_PL_FLAG_VRAM);
>   	if (ret)
>   		DRM_WARN("Error %d pinning new fb, out of video mem?\n", ret);
>   
> @@ -320,13 +321,13 @@ static int vbox_primary_prepare_fb(struct drm_plane *plane,
>   static void vbox_primary_cleanup_fb(struct drm_plane *plane,
>   				    struct drm_plane_state *old_state)
>   {
> -	struct vbox_bo *bo;
> +	struct drm_gem_ttm_object *gbo;
>   
>   	if (!old_state->fb)
>   		return;
>   
> -	bo = gem_to_vbox_bo(to_vbox_framebuffer(old_state->fb)->obj);
> -	vbox_bo_unpin(bo);
> +	gbo = drm_gem_ttm_of_gem(to_vbox_framebuffer(old_state->fb)->obj);
> +	drm_gem_ttm_unpin(gbo);
>   }
>   
>   static int vbox_cursor_atomic_check(struct drm_plane *plane,
> @@ -386,7 +387,8 @@ static void vbox_cursor_atomic_update(struct drm_plane *plane,
>   		container_of(plane->dev, struct vbox_private, ddev);
>   	struct vbox_crtc *vbox_crtc = to_vbox_crtc(plane->state->crtc);
>   	struct drm_framebuffer *fb = plane->state->fb;
> -	struct vbox_bo *bo = gem_to_vbox_bo(to_vbox_framebuffer(fb)->obj);
> +	struct drm_gem_ttm_object *gbo =
> +		drm_gem_ttm_of_gem(to_vbox_framebuffer(fb)->obj);
>   	u32 width = plane->state->crtc_w;
>   	u32 height = plane->state->crtc_h;
>   	size_t data_size, mask_size;
> @@ -405,7 +407,7 @@ static void vbox_cursor_atomic_update(struct drm_plane *plane,
>   	vbox_crtc->cursor_enabled = true;
>   
>   	/* pinning is done in prepare/cleanup framebuffer */
> -	src = vbox_bo_kmap(bo);
> +	src = drm_gem_ttm_kmap(gbo, true);
>   	if (IS_ERR(src)) {
>   		mutex_unlock(&vbox->hw_mutex);
>   		DRM_WARN("Could not kmap cursor bo, skipping update\n");
> @@ -421,7 +423,7 @@ static void vbox_cursor_atomic_update(struct drm_plane *plane,
>   	data_size = width * height * 4 + mask_size;
>   
>   	copy_cursor_image(src, vbox->cursor_data, width, height, mask_size);
> -	vbox_bo_kunmap(bo);
> +	drm_gem_ttm_kunmap(gbo);
>   
>   	flags = VBOX_MOUSE_POINTER_VISIBLE | VBOX_MOUSE_POINTER_SHAPE |
>   		VBOX_MOUSE_POINTER_ALPHA;
> @@ -461,25 +463,25 @@ static void vbox_cursor_atomic_disable(struct drm_plane *plane,
>   static int vbox_cursor_prepare_fb(struct drm_plane *plane,
>   				  struct drm_plane_state *new_state)
>   {
> -	struct vbox_bo *bo;
> +	struct drm_gem_ttm_object *gbo;
>   
>   	if (!new_state->fb)
>   		return 0;
>   
> -	bo = gem_to_vbox_bo(to_vbox_framebuffer(new_state->fb)->obj);
> -	return vbox_bo_pin(bo, TTM_PL_FLAG_SYSTEM);
> +	gbo = drm_gem_ttm_of_gem(to_vbox_framebuffer(new_state->fb)->obj);
> +	return drm_gem_ttm_pin(gbo, TTM_PL_FLAG_SYSTEM);
>   }
>   
>   static void vbox_cursor_cleanup_fb(struct drm_plane *plane,
>   				   struct drm_plane_state *old_state)
>   {
> -	struct vbox_bo *bo;
> +	struct drm_gem_ttm_object *gbo;
>   
>   	if (!plane->state->fb)
>   		return;
>   
> -	bo = gem_to_vbox_bo(to_vbox_framebuffer(plane->state->fb)->obj);
> -	vbox_bo_unpin(bo);
> +	gbo = drm_gem_ttm_of_gem(to_vbox_framebuffer(plane->state->fb)->obj);
> +	drm_gem_ttm_unpin(gbo);
>   }
>   
>   static const u32 vbox_cursor_plane_formats[] = {
> diff --git a/drivers/gpu/drm/vboxvideo/vbox_ttm.c b/drivers/gpu/drm/vboxvideo/vbox_ttm.c
> index 9d78438c2877..a1d64e1ea90c 100644
> --- a/drivers/gpu/drm/vboxvideo/vbox_ttm.c
> +++ b/drivers/gpu/drm/vboxvideo/vbox_ttm.c
> @@ -16,24 +16,6 @@ static inline struct vbox_private *vbox_bdev(struct ttm_bo_device *bd)
>   	return container_of(bd, struct vbox_private, ttm.bdev);
>   }
>   
> -static void vbox_bo_ttm_destroy(struct ttm_buffer_object *tbo)
> -{
> -	struct vbox_bo *bo;
> -
> -	bo = container_of(tbo, struct vbox_bo, bo);
> -
> -	drm_gem_object_release(&bo->gem);
> -	kfree(bo);
> -}
> -
> -static bool vbox_ttm_bo_is_vbox_bo(struct ttm_buffer_object *bo)
> -{
> -	if (bo->destroy == &vbox_bo_ttm_destroy)
> -		return true;
> -
> -	return false;
> -}
> -
>   static int
>   vbox_bo_init_mem_type(struct ttm_bo_device *bdev, u32 type,
>   		      struct ttm_mem_type_manager *man)
> @@ -58,24 +40,6 @@ vbox_bo_init_mem_type(struct ttm_bo_device *bdev, u32 type,
>   	return 0;
>   }
>   
> -static void
> -vbox_bo_evict_flags(struct ttm_buffer_object *bo, struct ttm_placement *pl)
> -{
> -	struct vbox_bo *vboxbo = vbox_bo(bo);
> -
> -	if (!vbox_ttm_bo_is_vbox_bo(bo))
> -		return;
> -
> -	vbox_ttm_placement(vboxbo, TTM_PL_FLAG_SYSTEM);
> -	*pl = vboxbo->placement;
> -}
> -
> -static int vbox_bo_verify_access(struct ttm_buffer_object *bo,
> -				 struct file *filp)
> -{
> -	return 0;
> -}
> -
>   static int vbox_ttm_io_mem_reserve(struct ttm_bo_device *bdev,
>   				   struct ttm_mem_reg *mem)
>   {
> @@ -141,8 +105,8 @@ static struct ttm_bo_driver vbox_bo_driver = {
>   	.ttm_tt_create = vbox_ttm_tt_create,
>   	.init_mem_type = vbox_bo_init_mem_type,
>   	.eviction_valuable = ttm_bo_eviction_valuable,
> -	.evict_flags = vbox_bo_evict_flags,
> -	.verify_access = vbox_bo_verify_access,
> +	.evict_flags = drm_gem_ttm_bo_driver_evict_flags,
> +	.verify_access = drm_gem_ttm_bo_driver_verify_access,
>   	.io_mem_reserve = &vbox_ttm_io_mem_reserve,
>   	.io_mem_free = &vbox_ttm_io_mem_free,
>   };
> @@ -196,165 +160,6 @@ void vbox_mm_fini(struct vbox_private *vbox)
>   	ttm_bo_device_release(&vbox->ttm.bdev);
>   }
>   
> -void vbox_ttm_placement(struct vbox_bo *bo, int domain)
> -{
> -	unsigned int i;
> -	u32 c = 0;
> -
> -	bo->placement.placement = bo->placements;
> -	bo->placement.busy_placement = bo->placements;
> -
> -	if (domain & TTM_PL_FLAG_VRAM)
> -		bo->placements[c++].flags =
> -		    TTM_PL_FLAG_WC | TTM_PL_FLAG_UNCACHED | TTM_PL_FLAG_VRAM;
> -	if (domain & TTM_PL_FLAG_SYSTEM)
> -		bo->placements[c++].flags =
> -		    TTM_PL_MASK_CACHING | TTM_PL_FLAG_SYSTEM;
> -	if (!c)
> -		bo->placements[c++].flags =
> -		    TTM_PL_MASK_CACHING | TTM_PL_FLAG_SYSTEM;
> -
> -	bo->placement.num_placement = c;
> -	bo->placement.num_busy_placement = c;
> -
> -	for (i = 0; i < c; ++i) {
> -		bo->placements[i].fpfn = 0;
> -		bo->placements[i].lpfn = 0;
> -	}
> -}
> -
> -int vbox_bo_create(struct vbox_private *vbox, int size, int align,
> -		   u32 flags, struct vbox_bo **pvboxbo)
> -{
> -	struct vbox_bo *vboxbo;
> -	size_t acc_size;
> -	int ret;
> -
> -	vboxbo = kzalloc(sizeof(*vboxbo), GFP_KERNEL);
> -	if (!vboxbo)
> -		return -ENOMEM;
> -
> -	ret = drm_gem_object_init(&vbox->ddev, &vboxbo->gem, size);
> -	if (ret)
> -		goto err_free_vboxbo;
> -
> -	vboxbo->bo.bdev = &vbox->ttm.bdev;
> -
> -	vbox_ttm_placement(vboxbo, TTM_PL_FLAG_VRAM | TTM_PL_FLAG_SYSTEM);
> -
> -	acc_size = ttm_bo_dma_acc_size(&vbox->ttm.bdev, size,
> -				       sizeof(struct vbox_bo));
> -
> -	ret = ttm_bo_init(&vbox->ttm.bdev, &vboxbo->bo, size,
> -			  ttm_bo_type_device, &vboxbo->placement,
> -			  align >> PAGE_SHIFT, false, acc_size,
> -			  NULL, NULL, vbox_bo_ttm_destroy);
> -	if (ret)
> -		goto err_free_vboxbo;
> -
> -	*pvboxbo = vboxbo;
> -
> -	return 0;
> -
> -err_free_vboxbo:
> -	kfree(vboxbo);
> -	return ret;
> -}
> -
> -int vbox_bo_pin(struct vbox_bo *bo, u32 pl_flag)
> -{
> -	struct ttm_operation_ctx ctx = { false, false };
> -	int i, ret;
> -
> -	if (bo->pin_count) {
> -		bo->pin_count++;
> -		return 0;
> -	}
> -
> -	ret = vbox_bo_reserve(bo, false);
> -	if (ret)
> -		return ret;
> -
> -	vbox_ttm_placement(bo, pl_flag);
> -
> -	for (i = 0; i < bo->placement.num_placement; i++)
> -		bo->placements[i].flags |= TTM_PL_FLAG_NO_EVICT;
> -
> -	ret = ttm_bo_validate(&bo->bo, &bo->placement, &ctx);
> -	if (ret == 0)
> -		bo->pin_count = 1;
> -
> -	vbox_bo_unreserve(bo);
> -
> -	return ret;
> -}
> -
> -int vbox_bo_unpin(struct vbox_bo *bo)
> -{
> -	struct ttm_operation_ctx ctx = { false, false };
> -	int i, ret;
> -
> -	if (!bo->pin_count) {
> -		DRM_ERROR("unpin bad %p\n", bo);
> -		return 0;
> -	}
> -	bo->pin_count--;
> -	if (bo->pin_count)
> -		return 0;
> -
> -	ret = vbox_bo_reserve(bo, false);
> -	if (ret) {
> -		DRM_ERROR("Error %d reserving bo, leaving it pinned\n", ret);
> -		return ret;
> -	}
> -
> -	for (i = 0; i < bo->placement.num_placement; i++)
> -		bo->placements[i].flags &= ~TTM_PL_FLAG_NO_EVICT;
> -
> -	ret = ttm_bo_validate(&bo->bo, &bo->placement, &ctx);
> -
> -	vbox_bo_unreserve(bo);
> -
> -	return ret;
> -}
> -
> -/*
> - * Move a vbox-owned buffer object to system memory if no one else has it
> - * pinned.  The caller must have pinned it previously, and this call will
> - * release the caller's pin.
> - */
> -int vbox_bo_push_sysram(struct vbox_bo *bo)
> -{
> -	struct ttm_operation_ctx ctx = { false, false };
> -	int i, ret;
> -
> -	if (!bo->pin_count) {
> -		DRM_ERROR("unpin bad %p\n", bo);
> -		return 0;
> -	}
> -	bo->pin_count--;
> -	if (bo->pin_count)
> -		return 0;
> -
> -	if (bo->kmap.virtual) {
> -		ttm_bo_kunmap(&bo->kmap);
> -		bo->kmap.virtual = NULL;
> -	}
> -
> -	vbox_ttm_placement(bo, TTM_PL_FLAG_SYSTEM);
> -
> -	for (i = 0; i < bo->placement.num_placement; i++)
> -		bo->placements[i].flags |= TTM_PL_FLAG_NO_EVICT;
> -
> -	ret = ttm_bo_validate(&bo->bo, &bo->placement, &ctx);
> -	if (ret) {
> -		DRM_ERROR("pushing to VRAM failed\n");
> -		return ret;
> -	}
> -
> -	return 0;
> -}
> -
>   int vbox_mmap(struct file *filp, struct vm_area_struct *vma)
>   {
>   	struct drm_file *file_priv = filp->private_data;
> @@ -362,27 +167,3 @@ int vbox_mmap(struct file *filp, struct vm_area_struct *vma)
>   
>   	return ttm_bo_mmap(filp, vma, &vbox->ttm.bdev);
>   }
> -
> -void *vbox_bo_kmap(struct vbox_bo *bo)
> -{
> -	int ret;
> -
> -	if (bo->kmap.virtual)
> -		return bo->kmap.virtual;
> -
> -	ret = ttm_bo_kmap(&bo->bo, 0, bo->bo.num_pages, &bo->kmap);
> -	if (ret) {
> -		DRM_ERROR("Error kmapping bo: %d\n", ret);
> -		return NULL;
> -	}
> -
> -	return bo->kmap.virtual;
> -}
> -
> -void vbox_bo_kunmap(struct vbox_bo *bo)
> -{
> -	if (bo->kmap.virtual) {
> -		ttm_bo_kunmap(&bo->kmap);
> -		bo->kmap.virtual = NULL;
> -	}
> -}
> 
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

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

* Re: [PATCH 13/15] drm/vboxvideo: Convert vboxvideo driver to Simple TTM
  2019-04-08  9:21 ` [PATCH 13/15] drm/vboxvideo: Convert vboxvideo driver to Simple TTM Thomas Zimmermann
  2019-04-09  7:09   ` Hans de Goede
@ 2019-04-09  7:09   ` Hans de Goede
  1 sibling, 0 replies; 43+ messages in thread
From: Hans de Goede @ 2019-04-09  7:09 UTC (permalink / raw)
  To: Thomas Zimmermann, daniel, airlied, kraxel, christian.koenig,
	ray.huang, Jerry.Zhang, z.liuxinliang, zourongrong,
	kong.kongxinwei, puck.chen
  Cc: dri-devel, virtualization

Hi,

On 08-04-19 11:21, Thomas Zimmermann wrote:
> Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>

Patch looks good to me (although perhaps it needs a commit msg):

Reviewed-by: Hans de Goede <hdegoede@redhat.com>

Regards,

Hans



> ---
>   drivers/gpu/drm/vboxvideo/Kconfig    |   1 +
>   drivers/gpu/drm/vboxvideo/vbox_drv.h |   6 +-
>   drivers/gpu/drm/vboxvideo/vbox_ttm.c | 123 ++-------------------------
>   3 files changed, 12 insertions(+), 118 deletions(-)
> 
> diff --git a/drivers/gpu/drm/vboxvideo/Kconfig b/drivers/gpu/drm/vboxvideo/Kconfig
> index c1ca87df81df..e29df360978d 100644
> --- a/drivers/gpu/drm/vboxvideo/Kconfig
> +++ b/drivers/gpu/drm/vboxvideo/Kconfig
> @@ -4,6 +4,7 @@ config DRM_VBOXVIDEO
>   	select DRM_KMS_HELPER
>   	select DRM_TTM
>   	select DRM_GEM_TTM_HELPER
> +	select DRM_SIMPLE_TTM_HELPER
>   	select GENERIC_ALLOCATOR
>   	help
>   	  This is a KMS driver for the virtual Graphics Card used in
> diff --git a/drivers/gpu/drm/vboxvideo/vbox_drv.h b/drivers/gpu/drm/vboxvideo/vbox_drv.h
> index 7db4e961805d..d4cfcc6339ef 100644
> --- a/drivers/gpu/drm/vboxvideo/vbox_drv.h
> +++ b/drivers/gpu/drm/vboxvideo/vbox_drv.h
> @@ -20,6 +20,8 @@
>   #include <drm/drm_gem.h>
>   #include <drm/drm_gem_ttm_helper.h>
>   
> +#include <drm/drm_simple_ttm_helper.h>
> +
>   #include <drm/ttm/ttm_bo_api.h>
>   #include <drm/ttm/ttm_bo_driver.h>
>   #include <drm/ttm/ttm_placement.h>
> @@ -78,9 +80,7 @@ struct vbox_private {
>   
>   	int fb_mtrr;
>   
> -	struct {
> -		struct ttm_bo_device bdev;
> -	} ttm;
> +	struct drm_simple_ttm ttm;
>   
>   	struct mutex hw_mutex; /* protects modeset and accel/vbva accesses */
>   	struct work_struct hotplug_work;
> diff --git a/drivers/gpu/drm/vboxvideo/vbox_ttm.c b/drivers/gpu/drm/vboxvideo/vbox_ttm.c
> index a1d64e1ea90c..115ec44636ab 100644
> --- a/drivers/gpu/drm/vboxvideo/vbox_ttm.c
> +++ b/drivers/gpu/drm/vboxvideo/vbox_ttm.c
> @@ -11,128 +11,25 @@
>   #include <drm/ttm/ttm_page_alloc.h>
>   #include "vbox_drv.h"
>   
> -static inline struct vbox_private *vbox_bdev(struct ttm_bo_device *bd)
> -{
> -	return container_of(bd, struct vbox_private, ttm.bdev);
> -}
> -
> -static int
> -vbox_bo_init_mem_type(struct ttm_bo_device *bdev, u32 type,
> -		      struct ttm_mem_type_manager *man)
> -{
> -	switch (type) {
> -	case TTM_PL_SYSTEM:
> -		man->flags = TTM_MEMTYPE_FLAG_MAPPABLE;
> -		man->available_caching = TTM_PL_MASK_CACHING;
> -		man->default_caching = TTM_PL_FLAG_CACHED;
> -		break;
> -	case TTM_PL_VRAM:
> -		man->func = &ttm_bo_manager_func;
> -		man->flags = TTM_MEMTYPE_FLAG_FIXED | TTM_MEMTYPE_FLAG_MAPPABLE;
> -		man->available_caching = TTM_PL_FLAG_UNCACHED | TTM_PL_FLAG_WC;
> -		man->default_caching = TTM_PL_FLAG_WC;
> -		break;
> -	default:
> -		DRM_ERROR("Unsupported memory type %u\n", (unsigned int)type);
> -		return -EINVAL;
> -	}
> -
> -	return 0;
> -}
> -
> -static int vbox_ttm_io_mem_reserve(struct ttm_bo_device *bdev,
> -				   struct ttm_mem_reg *mem)
> -{
> -	struct ttm_mem_type_manager *man = &bdev->man[mem->mem_type];
> -	struct vbox_private *vbox = vbox_bdev(bdev);
> -
> -	mem->bus.addr = NULL;
> -	mem->bus.offset = 0;
> -	mem->bus.size = mem->num_pages << PAGE_SHIFT;
> -	mem->bus.base = 0;
> -	mem->bus.is_iomem = false;
> -	if (!(man->flags & TTM_MEMTYPE_FLAG_MAPPABLE))
> -		return -EINVAL;
> -	switch (mem->mem_type) {
> -	case TTM_PL_SYSTEM:
> -		/* system memory */
> -		return 0;
> -	case TTM_PL_VRAM:
> -		mem->bus.offset = mem->start << PAGE_SHIFT;
> -		mem->bus.base = pci_resource_start(vbox->ddev.pdev, 0);
> -		mem->bus.is_iomem = true;
> -		break;
> -	default:
> -		return -EINVAL;
> -	}
> -	return 0;
> -}
> -
> -static void vbox_ttm_io_mem_free(struct ttm_bo_device *bdev,
> -				 struct ttm_mem_reg *mem)
> -{
> -}
> -
> -static void vbox_ttm_backend_destroy(struct ttm_tt *tt)
> -{
> -	ttm_tt_fini(tt);
> -	kfree(tt);
> -}
> -
> -static struct ttm_backend_func vbox_tt_backend_func = {
> -	.destroy = &vbox_ttm_backend_destroy,
> -};
> -
> -static struct ttm_tt *vbox_ttm_tt_create(struct ttm_buffer_object *bo,
> -					 u32 page_flags)
> -{
> -	struct ttm_tt *tt;
> -
> -	tt = kzalloc(sizeof(*tt), GFP_KERNEL);
> -	if (!tt)
> -		return NULL;
> -
> -	tt->func = &vbox_tt_backend_func;
> -	if (ttm_tt_init(tt, bo, page_flags)) {
> -		kfree(tt);
> -		return NULL;
> -	}
> -
> -	return tt;
> -}
> -
> -static struct ttm_bo_driver vbox_bo_driver = {
> -	.ttm_tt_create = vbox_ttm_tt_create,
> -	.init_mem_type = vbox_bo_init_mem_type,
> -	.eviction_valuable = ttm_bo_eviction_valuable,
> +static const struct drm_simple_ttm_funcs vbox_simple_ttm_funcs = {
>   	.evict_flags = drm_gem_ttm_bo_driver_evict_flags,
> -	.verify_access = drm_gem_ttm_bo_driver_verify_access,
> -	.io_mem_reserve = &vbox_ttm_io_mem_reserve,
> -	.io_mem_free = &vbox_ttm_io_mem_free,
> +	.verify_access = drm_gem_ttm_bo_driver_verify_access
>   };
>   
>   int vbox_mm_init(struct vbox_private *vbox)
>   {
>   	int ret;
>   	struct drm_device *dev = &vbox->ddev;
> -	struct ttm_bo_device *bdev = &vbox->ttm.bdev;
>   
> -	ret = ttm_bo_device_init(&vbox->ttm.bdev,
> -				 &vbox_bo_driver,
> -				 dev->anon_inode->i_mapping,
> -				 true);
> +	ret = drm_simple_ttm_init(&vbox->ttm, dev,
> +				  pci_resource_start(dev->pdev, 0),
> +				  vbox->available_vram_size,
> +				  &vbox_simple_ttm_funcs);
>   	if (ret) {
> -		DRM_ERROR("Error initialising bo driver; %d\n", ret);
> +		DRM_ERROR("Error initializing Simple TTM; %d\n", ret);
>   		return ret;
>   	}
>   
> -	ret = ttm_bo_init_mm(bdev, TTM_PL_VRAM,
> -			     vbox->available_vram_size >> PAGE_SHIFT);
> -	if (ret) {
> -		DRM_ERROR("Failed ttm VRAM init: %d\n", ret);
> -		goto err_device_release;
> -	}
> -
>   #ifdef DRM_MTRR_WC
>   	vbox->fb_mtrr = drm_mtrr_add(pci_resource_start(dev->pdev, 0),
>   				     pci_resource_len(dev->pdev, 0),
> @@ -142,10 +39,6 @@ int vbox_mm_init(struct vbox_private *vbox)
>   					 pci_resource_len(dev->pdev, 0));
>   #endif
>   	return 0;
> -
> -err_device_release:
> -	ttm_bo_device_release(&vbox->ttm.bdev);
> -	return ret;
>   }
>   
>   void vbox_mm_fini(struct vbox_private *vbox)
> @@ -157,7 +50,7 @@ void vbox_mm_fini(struct vbox_private *vbox)
>   #else
>   	arch_phys_wc_del(vbox->fb_mtrr);
>   #endif
> -	ttm_bo_device_release(&vbox->ttm.bdev);
> +	drm_simple_ttm_cleanup(&vbox->ttm);
>   }
>   
>   int vbox_mmap(struct file *filp, struct vm_area_struct *vma)
> 

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

* Re: [PATCH 13/15] drm/vboxvideo: Convert vboxvideo driver to Simple TTM
  2019-04-08  9:21 ` [PATCH 13/15] drm/vboxvideo: Convert vboxvideo driver to Simple TTM Thomas Zimmermann
@ 2019-04-09  7:09   ` Hans de Goede
  2019-04-09  7:37     ` Thomas Zimmermann
  2019-04-09  7:09   ` Hans de Goede
  1 sibling, 1 reply; 43+ messages in thread
From: Hans de Goede @ 2019-04-09  7:09 UTC (permalink / raw)
  To: Thomas Zimmermann, daniel, airlied, kraxel, christian.koenig,
	ray.huang, Jerry.Zhang, z.liuxinliang, zourongrong,
	kong.kongxinwei, puck.chen
  Cc: dri-devel, virtualization

Hi,

On 08-04-19 11:21, Thomas Zimmermann wrote:
> Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>

Patch looks good to me (although perhaps it needs a commit msg):

Reviewed-by: Hans de Goede <hdegoede@redhat.com>

Regards,

Hans



> ---
>   drivers/gpu/drm/vboxvideo/Kconfig    |   1 +
>   drivers/gpu/drm/vboxvideo/vbox_drv.h |   6 +-
>   drivers/gpu/drm/vboxvideo/vbox_ttm.c | 123 ++-------------------------
>   3 files changed, 12 insertions(+), 118 deletions(-)
> 
> diff --git a/drivers/gpu/drm/vboxvideo/Kconfig b/drivers/gpu/drm/vboxvideo/Kconfig
> index c1ca87df81df..e29df360978d 100644
> --- a/drivers/gpu/drm/vboxvideo/Kconfig
> +++ b/drivers/gpu/drm/vboxvideo/Kconfig
> @@ -4,6 +4,7 @@ config DRM_VBOXVIDEO
>   	select DRM_KMS_HELPER
>   	select DRM_TTM
>   	select DRM_GEM_TTM_HELPER
> +	select DRM_SIMPLE_TTM_HELPER
>   	select GENERIC_ALLOCATOR
>   	help
>   	  This is a KMS driver for the virtual Graphics Card used in
> diff --git a/drivers/gpu/drm/vboxvideo/vbox_drv.h b/drivers/gpu/drm/vboxvideo/vbox_drv.h
> index 7db4e961805d..d4cfcc6339ef 100644
> --- a/drivers/gpu/drm/vboxvideo/vbox_drv.h
> +++ b/drivers/gpu/drm/vboxvideo/vbox_drv.h
> @@ -20,6 +20,8 @@
>   #include <drm/drm_gem.h>
>   #include <drm/drm_gem_ttm_helper.h>
>   
> +#include <drm/drm_simple_ttm_helper.h>
> +
>   #include <drm/ttm/ttm_bo_api.h>
>   #include <drm/ttm/ttm_bo_driver.h>
>   #include <drm/ttm/ttm_placement.h>
> @@ -78,9 +80,7 @@ struct vbox_private {
>   
>   	int fb_mtrr;
>   
> -	struct {
> -		struct ttm_bo_device bdev;
> -	} ttm;
> +	struct drm_simple_ttm ttm;
>   
>   	struct mutex hw_mutex; /* protects modeset and accel/vbva accesses */
>   	struct work_struct hotplug_work;
> diff --git a/drivers/gpu/drm/vboxvideo/vbox_ttm.c b/drivers/gpu/drm/vboxvideo/vbox_ttm.c
> index a1d64e1ea90c..115ec44636ab 100644
> --- a/drivers/gpu/drm/vboxvideo/vbox_ttm.c
> +++ b/drivers/gpu/drm/vboxvideo/vbox_ttm.c
> @@ -11,128 +11,25 @@
>   #include <drm/ttm/ttm_page_alloc.h>
>   #include "vbox_drv.h"
>   
> -static inline struct vbox_private *vbox_bdev(struct ttm_bo_device *bd)
> -{
> -	return container_of(bd, struct vbox_private, ttm.bdev);
> -}
> -
> -static int
> -vbox_bo_init_mem_type(struct ttm_bo_device *bdev, u32 type,
> -		      struct ttm_mem_type_manager *man)
> -{
> -	switch (type) {
> -	case TTM_PL_SYSTEM:
> -		man->flags = TTM_MEMTYPE_FLAG_MAPPABLE;
> -		man->available_caching = TTM_PL_MASK_CACHING;
> -		man->default_caching = TTM_PL_FLAG_CACHED;
> -		break;
> -	case TTM_PL_VRAM:
> -		man->func = &ttm_bo_manager_func;
> -		man->flags = TTM_MEMTYPE_FLAG_FIXED | TTM_MEMTYPE_FLAG_MAPPABLE;
> -		man->available_caching = TTM_PL_FLAG_UNCACHED | TTM_PL_FLAG_WC;
> -		man->default_caching = TTM_PL_FLAG_WC;
> -		break;
> -	default:
> -		DRM_ERROR("Unsupported memory type %u\n", (unsigned int)type);
> -		return -EINVAL;
> -	}
> -
> -	return 0;
> -}
> -
> -static int vbox_ttm_io_mem_reserve(struct ttm_bo_device *bdev,
> -				   struct ttm_mem_reg *mem)
> -{
> -	struct ttm_mem_type_manager *man = &bdev->man[mem->mem_type];
> -	struct vbox_private *vbox = vbox_bdev(bdev);
> -
> -	mem->bus.addr = NULL;
> -	mem->bus.offset = 0;
> -	mem->bus.size = mem->num_pages << PAGE_SHIFT;
> -	mem->bus.base = 0;
> -	mem->bus.is_iomem = false;
> -	if (!(man->flags & TTM_MEMTYPE_FLAG_MAPPABLE))
> -		return -EINVAL;
> -	switch (mem->mem_type) {
> -	case TTM_PL_SYSTEM:
> -		/* system memory */
> -		return 0;
> -	case TTM_PL_VRAM:
> -		mem->bus.offset = mem->start << PAGE_SHIFT;
> -		mem->bus.base = pci_resource_start(vbox->ddev.pdev, 0);
> -		mem->bus.is_iomem = true;
> -		break;
> -	default:
> -		return -EINVAL;
> -	}
> -	return 0;
> -}
> -
> -static void vbox_ttm_io_mem_free(struct ttm_bo_device *bdev,
> -				 struct ttm_mem_reg *mem)
> -{
> -}
> -
> -static void vbox_ttm_backend_destroy(struct ttm_tt *tt)
> -{
> -	ttm_tt_fini(tt);
> -	kfree(tt);
> -}
> -
> -static struct ttm_backend_func vbox_tt_backend_func = {
> -	.destroy = &vbox_ttm_backend_destroy,
> -};
> -
> -static struct ttm_tt *vbox_ttm_tt_create(struct ttm_buffer_object *bo,
> -					 u32 page_flags)
> -{
> -	struct ttm_tt *tt;
> -
> -	tt = kzalloc(sizeof(*tt), GFP_KERNEL);
> -	if (!tt)
> -		return NULL;
> -
> -	tt->func = &vbox_tt_backend_func;
> -	if (ttm_tt_init(tt, bo, page_flags)) {
> -		kfree(tt);
> -		return NULL;
> -	}
> -
> -	return tt;
> -}
> -
> -static struct ttm_bo_driver vbox_bo_driver = {
> -	.ttm_tt_create = vbox_ttm_tt_create,
> -	.init_mem_type = vbox_bo_init_mem_type,
> -	.eviction_valuable = ttm_bo_eviction_valuable,
> +static const struct drm_simple_ttm_funcs vbox_simple_ttm_funcs = {
>   	.evict_flags = drm_gem_ttm_bo_driver_evict_flags,
> -	.verify_access = drm_gem_ttm_bo_driver_verify_access,
> -	.io_mem_reserve = &vbox_ttm_io_mem_reserve,
> -	.io_mem_free = &vbox_ttm_io_mem_free,
> +	.verify_access = drm_gem_ttm_bo_driver_verify_access
>   };
>   
>   int vbox_mm_init(struct vbox_private *vbox)
>   {
>   	int ret;
>   	struct drm_device *dev = &vbox->ddev;
> -	struct ttm_bo_device *bdev = &vbox->ttm.bdev;
>   
> -	ret = ttm_bo_device_init(&vbox->ttm.bdev,
> -				 &vbox_bo_driver,
> -				 dev->anon_inode->i_mapping,
> -				 true);
> +	ret = drm_simple_ttm_init(&vbox->ttm, dev,
> +				  pci_resource_start(dev->pdev, 0),
> +				  vbox->available_vram_size,
> +				  &vbox_simple_ttm_funcs);
>   	if (ret) {
> -		DRM_ERROR("Error initialising bo driver; %d\n", ret);
> +		DRM_ERROR("Error initializing Simple TTM; %d\n", ret);
>   		return ret;
>   	}
>   
> -	ret = ttm_bo_init_mm(bdev, TTM_PL_VRAM,
> -			     vbox->available_vram_size >> PAGE_SHIFT);
> -	if (ret) {
> -		DRM_ERROR("Failed ttm VRAM init: %d\n", ret);
> -		goto err_device_release;
> -	}
> -
>   #ifdef DRM_MTRR_WC
>   	vbox->fb_mtrr = drm_mtrr_add(pci_resource_start(dev->pdev, 0),
>   				     pci_resource_len(dev->pdev, 0),
> @@ -142,10 +39,6 @@ int vbox_mm_init(struct vbox_private *vbox)
>   					 pci_resource_len(dev->pdev, 0));
>   #endif
>   	return 0;
> -
> -err_device_release:
> -	ttm_bo_device_release(&vbox->ttm.bdev);
> -	return ret;
>   }
>   
>   void vbox_mm_fini(struct vbox_private *vbox)
> @@ -157,7 +50,7 @@ void vbox_mm_fini(struct vbox_private *vbox)
>   #else
>   	arch_phys_wc_del(vbox->fb_mtrr);
>   #endif
> -	ttm_bo_device_release(&vbox->ttm.bdev);
> +	drm_simple_ttm_cleanup(&vbox->ttm);
>   }
>   
>   int vbox_mmap(struct file *filp, struct vm_area_struct *vma)
> 
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

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

* Re: [PATCH 00/15] Share TTM code among framebuffer drivers
  2019-04-08 11:59   ` Thomas Zimmermann
  2019-04-09  7:12     ` kraxel
@ 2019-04-09  7:12     ` kraxel
  2019-04-09 13:39     ` Koenig, Christian
  2 siblings, 0 replies; 43+ messages in thread
From: kraxel @ 2019-04-09  7:12 UTC (permalink / raw)
  To: Thomas Zimmermann
  Cc: airlied, puck.chen, dri-devel, virtualization, z.liuxinliang,
	hdegoede, kong.kongxinwei, Huang, Ray, zourongrong, daniel,
	Zhang, Jerry, Koenig, Christian

  Hi,

> If not for TTM, what would be the alternative? One VMA manager per
> memory region per device?

Depends pretty much on the device.

The cirrus is a display device with only 4 MB of vram.  You can't fit
much in there.  A single 1024x768 @ 24bpp framebuffer needs more 50%
of the video memory already.  Which is why the cirrus driver (before the
rewrite) had to migrate buffers from/to vram on every page flip[1].  Which
is one[2] of the reasons why cirrus (after rewrite) doesn't ttm-manage the
vram any more.  gem objects are managed with the shmem helpers instead
and the active framebuffer is blitted to vram.

The qemu stdvga (bochs driver) has 16 MB vram by default and can be
configured to have up to 256 MB.  Plenty of room even for multiple 4k
framebuffers if needed.  So for the bochs driver all the ttm bo
migration logic is not needed, it could just store everything in vram.

A set of drm_gem_vram_* helpers would do the job for bochs.

I'd expect the same applies to the vbox driver.

Dunno about the other drm drivers and the fbdev drivers you plan to
migrate over.

cheers,
  Gerd

[1] Note: The page-flip migration logic is present in some of the other
    drivers too, not sure whenever they actually need that due to being low
    on vram too or whenever they just copied the old cirrus code ...

[2] The other reason is that this allow to convert formats at blit time,
    which helps to deal with some cirrus hardware limitations.

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

* Re: [PATCH 00/15] Share TTM code among framebuffer drivers
  2019-04-08 11:59   ` Thomas Zimmermann
@ 2019-04-09  7:12     ` kraxel
  2019-04-09  7:42       ` Dave Airlie
  2019-04-09  7:50       ` Thomas Zimmermann
  2019-04-09  7:12     ` kraxel
  2019-04-09 13:39     ` Koenig, Christian
  2 siblings, 2 replies; 43+ messages in thread
From: kraxel @ 2019-04-09  7:12 UTC (permalink / raw)
  To: Thomas Zimmermann
  Cc: airlied, puck.chen, dri-devel, virtualization, z.liuxinliang,
	hdegoede, kong.kongxinwei, Huang, Ray, zourongrong, Zhang, Jerry,
	Koenig, Christian

  Hi,

> If not for TTM, what would be the alternative? One VMA manager per
> memory region per device?

Depends pretty much on the device.

The cirrus is a display device with only 4 MB of vram.  You can't fit
much in there.  A single 1024x768 @ 24bpp framebuffer needs more 50%
of the video memory already.  Which is why the cirrus driver (before the
rewrite) had to migrate buffers from/to vram on every page flip[1].  Which
is one[2] of the reasons why cirrus (after rewrite) doesn't ttm-manage the
vram any more.  gem objects are managed with the shmem helpers instead
and the active framebuffer is blitted to vram.

The qemu stdvga (bochs driver) has 16 MB vram by default and can be
configured to have up to 256 MB.  Plenty of room even for multiple 4k
framebuffers if needed.  So for the bochs driver all the ttm bo
migration logic is not needed, it could just store everything in vram.

A set of drm_gem_vram_* helpers would do the job for bochs.

I'd expect the same applies to the vbox driver.

Dunno about the other drm drivers and the fbdev drivers you plan to
migrate over.

cheers,
  Gerd

[1] Note: The page-flip migration logic is present in some of the other
    drivers too, not sure whenever they actually need that due to being low
    on vram too or whenever they just copied the old cirrus code ...

[2] The other reason is that this allow to convert formats at blit time,
    which helps to deal with some cirrus hardware limitations.

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

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

* Re: [PATCH 13/15] drm/vboxvideo: Convert vboxvideo driver to Simple TTM
  2019-04-09  7:09   ` Hans de Goede
@ 2019-04-09  7:37     ` Thomas Zimmermann
  0 siblings, 0 replies; 43+ messages in thread
From: Thomas Zimmermann @ 2019-04-09  7:37 UTC (permalink / raw)
  To: Hans de Goede, daniel, airlied, kraxel, christian.koenig,
	ray.huang, Jerry.Zhang, z.liuxinliang, zourongrong,
	kong.kongxinwei, puck.chen
  Cc: dri-devel, virtualization


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

Hi

Am 09.04.19 um 09:09 schrieb Hans de Goede:
> Hi,
> 
> On 08-04-19 11:21, Thomas Zimmermann wrote:
>> Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
> 
> Patch looks good to me (although perhaps it needs a commit msg):

OK, thanks. I'll add that message here and to the other patches.

Best regards
Thomas

> 
> Reviewed-by: Hans de Goede <hdegoede@redhat.com>
> 
> Regards,
> 
> Hans
> 
> 
> 
>> ---
>>   drivers/gpu/drm/vboxvideo/Kconfig    |   1 +
>>   drivers/gpu/drm/vboxvideo/vbox_drv.h |   6 +-
>>   drivers/gpu/drm/vboxvideo/vbox_ttm.c | 123 ++-------------------------
>>   3 files changed, 12 insertions(+), 118 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/vboxvideo/Kconfig
>> b/drivers/gpu/drm/vboxvideo/Kconfig
>> index c1ca87df81df..e29df360978d 100644
>> --- a/drivers/gpu/drm/vboxvideo/Kconfig
>> +++ b/drivers/gpu/drm/vboxvideo/Kconfig
>> @@ -4,6 +4,7 @@ config DRM_VBOXVIDEO
>>       select DRM_KMS_HELPER
>>       select DRM_TTM
>>       select DRM_GEM_TTM_HELPER
>> +    select DRM_SIMPLE_TTM_HELPER
>>       select GENERIC_ALLOCATOR
>>       help
>>         This is a KMS driver for the virtual Graphics Card used in
>> diff --git a/drivers/gpu/drm/vboxvideo/vbox_drv.h
>> b/drivers/gpu/drm/vboxvideo/vbox_drv.h
>> index 7db4e961805d..d4cfcc6339ef 100644
>> --- a/drivers/gpu/drm/vboxvideo/vbox_drv.h
>> +++ b/drivers/gpu/drm/vboxvideo/vbox_drv.h
>> @@ -20,6 +20,8 @@
>>   #include <drm/drm_gem.h>
>>   #include <drm/drm_gem_ttm_helper.h>
>>   +#include <drm/drm_simple_ttm_helper.h>
>> +
>>   #include <drm/ttm/ttm_bo_api.h>
>>   #include <drm/ttm/ttm_bo_driver.h>
>>   #include <drm/ttm/ttm_placement.h>
>> @@ -78,9 +80,7 @@ struct vbox_private {
>>         int fb_mtrr;
>>   -    struct {
>> -        struct ttm_bo_device bdev;
>> -    } ttm;
>> +    struct drm_simple_ttm ttm;
>>         struct mutex hw_mutex; /* protects modeset and accel/vbva
>> accesses */
>>       struct work_struct hotplug_work;
>> diff --git a/drivers/gpu/drm/vboxvideo/vbox_ttm.c
>> b/drivers/gpu/drm/vboxvideo/vbox_ttm.c
>> index a1d64e1ea90c..115ec44636ab 100644
>> --- a/drivers/gpu/drm/vboxvideo/vbox_ttm.c
>> +++ b/drivers/gpu/drm/vboxvideo/vbox_ttm.c
>> @@ -11,128 +11,25 @@
>>   #include <drm/ttm/ttm_page_alloc.h>
>>   #include "vbox_drv.h"
>>   -static inline struct vbox_private *vbox_bdev(struct ttm_bo_device *bd)
>> -{
>> -    return container_of(bd, struct vbox_private, ttm.bdev);
>> -}
>> -
>> -static int
>> -vbox_bo_init_mem_type(struct ttm_bo_device *bdev, u32 type,
>> -              struct ttm_mem_type_manager *man)
>> -{
>> -    switch (type) {
>> -    case TTM_PL_SYSTEM:
>> -        man->flags = TTM_MEMTYPE_FLAG_MAPPABLE;
>> -        man->available_caching = TTM_PL_MASK_CACHING;
>> -        man->default_caching = TTM_PL_FLAG_CACHED;
>> -        break;
>> -    case TTM_PL_VRAM:
>> -        man->func = &ttm_bo_manager_func;
>> -        man->flags = TTM_MEMTYPE_FLAG_FIXED | TTM_MEMTYPE_FLAG_MAPPABLE;
>> -        man->available_caching = TTM_PL_FLAG_UNCACHED | TTM_PL_FLAG_WC;
>> -        man->default_caching = TTM_PL_FLAG_WC;
>> -        break;
>> -    default:
>> -        DRM_ERROR("Unsupported memory type %u\n", (unsigned int)type);
>> -        return -EINVAL;
>> -    }
>> -
>> -    return 0;
>> -}
>> -
>> -static int vbox_ttm_io_mem_reserve(struct ttm_bo_device *bdev,
>> -                   struct ttm_mem_reg *mem)
>> -{
>> -    struct ttm_mem_type_manager *man = &bdev->man[mem->mem_type];
>> -    struct vbox_private *vbox = vbox_bdev(bdev);
>> -
>> -    mem->bus.addr = NULL;
>> -    mem->bus.offset = 0;
>> -    mem->bus.size = mem->num_pages << PAGE_SHIFT;
>> -    mem->bus.base = 0;
>> -    mem->bus.is_iomem = false;
>> -    if (!(man->flags & TTM_MEMTYPE_FLAG_MAPPABLE))
>> -        return -EINVAL;
>> -    switch (mem->mem_type) {
>> -    case TTM_PL_SYSTEM:
>> -        /* system memory */
>> -        return 0;
>> -    case TTM_PL_VRAM:
>> -        mem->bus.offset = mem->start << PAGE_SHIFT;
>> -        mem->bus.base = pci_resource_start(vbox->ddev.pdev, 0);
>> -        mem->bus.is_iomem = true;
>> -        break;
>> -    default:
>> -        return -EINVAL;
>> -    }
>> -    return 0;
>> -}
>> -
>> -static void vbox_ttm_io_mem_free(struct ttm_bo_device *bdev,
>> -                 struct ttm_mem_reg *mem)
>> -{
>> -}
>> -
>> -static void vbox_ttm_backend_destroy(struct ttm_tt *tt)
>> -{
>> -    ttm_tt_fini(tt);
>> -    kfree(tt);
>> -}
>> -
>> -static struct ttm_backend_func vbox_tt_backend_func = {
>> -    .destroy = &vbox_ttm_backend_destroy,
>> -};
>> -
>> -static struct ttm_tt *vbox_ttm_tt_create(struct ttm_buffer_object *bo,
>> -                     u32 page_flags)
>> -{
>> -    struct ttm_tt *tt;
>> -
>> -    tt = kzalloc(sizeof(*tt), GFP_KERNEL);
>> -    if (!tt)
>> -        return NULL;
>> -
>> -    tt->func = &vbox_tt_backend_func;
>> -    if (ttm_tt_init(tt, bo, page_flags)) {
>> -        kfree(tt);
>> -        return NULL;
>> -    }
>> -
>> -    return tt;
>> -}
>> -
>> -static struct ttm_bo_driver vbox_bo_driver = {
>> -    .ttm_tt_create = vbox_ttm_tt_create,
>> -    .init_mem_type = vbox_bo_init_mem_type,
>> -    .eviction_valuable = ttm_bo_eviction_valuable,
>> +static const struct drm_simple_ttm_funcs vbox_simple_ttm_funcs = {
>>       .evict_flags = drm_gem_ttm_bo_driver_evict_flags,
>> -    .verify_access = drm_gem_ttm_bo_driver_verify_access,
>> -    .io_mem_reserve = &vbox_ttm_io_mem_reserve,
>> -    .io_mem_free = &vbox_ttm_io_mem_free,
>> +    .verify_access = drm_gem_ttm_bo_driver_verify_access
>>   };
>>     int vbox_mm_init(struct vbox_private *vbox)
>>   {
>>       int ret;
>>       struct drm_device *dev = &vbox->ddev;
>> -    struct ttm_bo_device *bdev = &vbox->ttm.bdev;
>>   -    ret = ttm_bo_device_init(&vbox->ttm.bdev,
>> -                 &vbox_bo_driver,
>> -                 dev->anon_inode->i_mapping,
>> -                 true);
>> +    ret = drm_simple_ttm_init(&vbox->ttm, dev,
>> +                  pci_resource_start(dev->pdev, 0),
>> +                  vbox->available_vram_size,
>> +                  &vbox_simple_ttm_funcs);
>>       if (ret) {
>> -        DRM_ERROR("Error initialising bo driver; %d\n", ret);
>> +        DRM_ERROR("Error initializing Simple TTM; %d\n", ret);
>>           return ret;
>>       }
>>   -    ret = ttm_bo_init_mm(bdev, TTM_PL_VRAM,
>> -                 vbox->available_vram_size >> PAGE_SHIFT);
>> -    if (ret) {
>> -        DRM_ERROR("Failed ttm VRAM init: %d\n", ret);
>> -        goto err_device_release;
>> -    }
>> -
>>   #ifdef DRM_MTRR_WC
>>       vbox->fb_mtrr = drm_mtrr_add(pci_resource_start(dev->pdev, 0),
>>                        pci_resource_len(dev->pdev, 0),
>> @@ -142,10 +39,6 @@ int vbox_mm_init(struct vbox_private *vbox)
>>                        pci_resource_len(dev->pdev, 0));
>>   #endif
>>       return 0;
>> -
>> -err_device_release:
>> -    ttm_bo_device_release(&vbox->ttm.bdev);
>> -    return ret;
>>   }
>>     void vbox_mm_fini(struct vbox_private *vbox)
>> @@ -157,7 +50,7 @@ void vbox_mm_fini(struct vbox_private *vbox)
>>   #else
>>       arch_phys_wc_del(vbox->fb_mtrr);
>>   #endif
>> -    ttm_bo_device_release(&vbox->ttm.bdev);
>> +    drm_simple_ttm_cleanup(&vbox->ttm);
>>   }
>>     int vbox_mmap(struct file *filp, struct vm_area_struct *vma)
>>
> _______________________________________________
> dri-devel mailing list
> dri-devel@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/dri-devel

-- 
Thomas Zimmermann
Graphics Driver Developer
SUSE Linux GmbH, Maxfeldstrasse 5, 90409 Nuernberg, Germany
GF: Felix Imendörffer, Mary Higgins, Sri Rasiah
HRB 21284 (AG Nürnberg)


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

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

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

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

* Re: [PATCH 00/15] Share TTM code among framebuffer drivers
  2019-04-09  7:12     ` kraxel
@ 2019-04-09  7:42       ` Dave Airlie
  2019-04-09  8:29         ` kraxel
  2019-04-09  8:29         ` kraxel
  2019-04-09  7:50       ` Thomas Zimmermann
  1 sibling, 2 replies; 43+ messages in thread
From: Dave Airlie @ 2019-04-09  7:42 UTC (permalink / raw)
  To: kraxel
  Cc: airlied, puck.chen, Zhang, Jerry, dri-devel, virtualization,
	z.liuxinliang, hdegoede, kong.kongxinwei, Huang, Ray,
	Thomas Zimmermann, zourongrong, Koenig, Christian

On Tue, 9 Apr 2019 at 17:12, kraxel@redhat.com <kraxel@redhat.com> wrote:
>
>   Hi,
>
> > If not for TTM, what would be the alternative? One VMA manager per
> > memory region per device?
>
> Depends pretty much on the device.
>
> The cirrus is a display device with only 4 MB of vram.  You can't fit
> much in there.  A single 1024x768 @ 24bpp framebuffer needs more 50%
> of the video memory already.  Which is why the cirrus driver (before the
> rewrite) had to migrate buffers from/to vram on every page flip[1].  Which
> is one[2] of the reasons why cirrus (after rewrite) doesn't ttm-manage the
> vram any more.  gem objects are managed with the shmem helpers instead
> and the active framebuffer is blitted to vram.
>
> The qemu stdvga (bochs driver) has 16 MB vram by default and can be
> configured to have up to 256 MB.  Plenty of room even for multiple 4k
> framebuffers if needed.  So for the bochs driver all the ttm bo
> migration logic is not needed, it could just store everything in vram.

To clarify I assume you mean it doesn't need the migrate each bo
logic, but it still needs the when VRAM fills up migrate stuff logic.

Dave.

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

* Re: [PATCH 00/15] Share TTM code among framebuffer drivers
  2019-04-09  7:12     ` kraxel
  2019-04-09  7:42       ` Dave Airlie
@ 2019-04-09  7:50       ` Thomas Zimmermann
  2019-04-15 15:54         ` Daniel Vetter
  1 sibling, 1 reply; 43+ messages in thread
From: Thomas Zimmermann @ 2019-04-09  7:50 UTC (permalink / raw)
  To: kraxel
  Cc: airlied, puck.chen, dri-devel, virtualization, z.liuxinliang,
	hdegoede, kong.kongxinwei, Huang, Ray, zourongrong, Zhang, Jerry,
	Koenig, Christian


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

Hi

Am 09.04.19 um 09:12 schrieb kraxel@redhat.com:
>   Hi,
> 
>> If not for TTM, what would be the alternative? One VMA manager per
>> memory region per device?
> 
> Depends pretty much on the device.
> 
> The cirrus is a display device with only 4 MB of vram.  You can't fit
> much in there.  A single 1024x768 @ 24bpp framebuffer needs more 50%
> of the video memory already.  Which is why the cirrus driver (before the
> rewrite) had to migrate buffers from/to vram on every page flip[1].  Which
> is one[2] of the reasons why cirrus (after rewrite) doesn't ttm-manage the
> vram any more.  gem objects are managed with the shmem helpers instead
> and the active framebuffer is blitted to vram.
> 
> The qemu stdvga (bochs driver) has 16 MB vram by default and can be
> configured to have up to 256 MB.  Plenty of room even for multiple 4k
> framebuffers if needed.  So for the bochs driver all the ttm bo
> migration logic is not needed, it could just store everything in vram.
> 
> A set of drm_gem_vram_* helpers would do the job for bochs.

Thanks for clarifying. drm_gem_vram_* (and drm_vram_mm for Simple TTM)
is probably a better name for the data structures.

> I'd expect the same applies to the vbox driver.
> 
> Dunno about the other drm drivers and the fbdev drivers you plan to
> migrate over.

The AST HW can support up to 512 MiB, but 32-64 MiB seems more realistic
for a server. It's similar with mgag200 HW. The old fbdev-supported
device are all somewhere in the range between cirrus and bochs. Some
drivers would probably benefit from the cirrus approach, some could use
VRAM directly.

Best regards
Thomas

> 
> cheers,
>   Gerd
> 
> [1] Note: The page-flip migration logic is present in some of the other
>     drivers too, not sure whenever they actually need that due to being low
>     on vram too or whenever they just copied the old cirrus code ...
> 
> [2] The other reason is that this allow to convert formats at blit time,
>     which helps to deal with some cirrus hardware limitations.
> 

-- 
Thomas Zimmermann
Graphics Driver Developer
SUSE Linux GmbH, Maxfeldstrasse 5, 90409 Nuernberg, Germany
GF: Felix Imendörffer, Mary Higgins, Sri Rasiah
HRB 21284 (AG Nürnberg)


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

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

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

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

* Re: [PATCH 00/15] Share TTM code among framebuffer drivers
  2019-04-09  7:42       ` Dave Airlie
  2019-04-09  8:29         ` kraxel
@ 2019-04-09  8:29         ` kraxel
  1 sibling, 0 replies; 43+ messages in thread
From: kraxel @ 2019-04-09  8:29 UTC (permalink / raw)
  To: Dave Airlie
  Cc: airlied, puck.chen, Zhang, Jerry, dri-devel, virtualization,
	z.liuxinliang, hdegoede, kong.kongxinwei, Huang, Ray,
	Thomas Zimmermann, zourongrong, Koenig, Christian

  Hi,

> > The qemu stdvga (bochs driver) has 16 MB vram by default and can be
> > configured to have up to 256 MB.  Plenty of room even for multiple 4k
> > framebuffers if needed.  So for the bochs driver all the ttm bo
> > migration logic is not needed, it could just store everything in vram.
> 
> To clarify I assume you mean it doesn't need the migrate each bo
> logic, but it still needs the when VRAM fills up migrate stuff logic.

I think even the "when vram fills up" logic isn't that important.  The
driver has no acceleration so there is nothing to store beside dumb
framebuffers, and the vram size can easily be increased if needed.

cheers,
  Gerd

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

* Re: [PATCH 00/15] Share TTM code among framebuffer drivers
  2019-04-09  7:42       ` Dave Airlie
@ 2019-04-09  8:29         ` kraxel
  2019-04-09 11:55           ` Christian König
  2019-04-09  8:29         ` kraxel
  1 sibling, 1 reply; 43+ messages in thread
From: kraxel @ 2019-04-09  8:29 UTC (permalink / raw)
  To: Dave Airlie
  Cc: airlied, puck.chen, Zhang, Jerry, dri-devel, virtualization,
	z.liuxinliang, hdegoede, kong.kongxinwei, Huang, Ray,
	Thomas Zimmermann, zourongrong, Koenig, Christian

  Hi,

> > The qemu stdvga (bochs driver) has 16 MB vram by default and can be
> > configured to have up to 256 MB.  Plenty of room even for multiple 4k
> > framebuffers if needed.  So for the bochs driver all the ttm bo
> > migration logic is not needed, it could just store everything in vram.
> 
> To clarify I assume you mean it doesn't need the migrate each bo
> logic, but it still needs the when VRAM fills up migrate stuff logic.

I think even the "when vram fills up" logic isn't that important.  The
driver has no acceleration so there is nothing to store beside dumb
framebuffers, and the vram size can easily be increased if needed.

cheers,
  Gerd

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

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

* Re: [PATCH 00/15] Share TTM code among framebuffer drivers
  2019-04-09  8:29         ` kraxel
@ 2019-04-09 11:55           ` Christian König
  0 siblings, 0 replies; 43+ messages in thread
From: Christian König @ 2019-04-09 11:55 UTC (permalink / raw)
  To: kraxel, Dave Airlie
  Cc: airlied, puck.chen, dri-devel, virtualization, z.liuxinliang,
	hdegoede, kong.kongxinwei, Huang, Ray, zourongrong,
	Thomas Zimmermann, Zhang, Jerry, Koenig, Christian

Am 09.04.19 um 10:29 schrieb kraxel@redhat.com:
>    Hi,
>
>>> The qemu stdvga (bochs driver) has 16 MB vram by default and can be
>>> configured to have up to 256 MB.  Plenty of room even for multiple 4k
>>> framebuffers if needed.  So for the bochs driver all the ttm bo
>>> migration logic is not needed, it could just store everything in vram.
>> To clarify I assume you mean it doesn't need the migrate each bo
>> logic, but it still needs the when VRAM fills up migrate stuff logic.
> I think even the "when vram fills up" logic isn't that important.  The
> driver has no acceleration so there is nothing to store beside dumb
> framebuffers, and the vram size can easily be increased if needed.

Yeah, cause in this particular case it is not even real VRAM.

In this case VRAM is backed by system memory which in turn is stolen 
from the host system isn't it?

So just have enough for a framebuffer and don't place anything else in 
there.

Regards,
Christian.

>
> cheers,
>    Gerd
>
> _______________________________________________
> 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] 43+ messages in thread

* Re: [PATCH 00/15] Share TTM code among framebuffer drivers
  2019-04-08 11:59   ` Thomas Zimmermann
  2019-04-09  7:12     ` kraxel
  2019-04-09  7:12     ` kraxel
@ 2019-04-09 13:39     ` Koenig, Christian
  2 siblings, 0 replies; 43+ messages in thread
From: Koenig, Christian @ 2019-04-09 13:39 UTC (permalink / raw)
  To: Thomas Zimmermann, daniel, airlied, kraxel, Huang, Ray, Zhang,
	Jerry, hdegoede, z.liuxinliang, zourongrong, kong.kongxinwei,
	puck.chen
  Cc: dri-devel, virtualization

Am 08.04.19 um 13:59 schrieb Thomas Zimmermann:
[SNIP]
> If not for TTM, what would be the alternative? One VMA manager per
> memory region per device?

Since everybody vital seems to be on this mail thread anyway, let's use 
it a bit for brain storming what a possible replacement for TTM should 
look like.

Well for simple drivers like qemu/bochs and cirrus the answer is to not 
use it at all. E.g. VRAM is only used for scanout and unprivileged 
userspace should not mess with it at all. In this case we don't need 
dynamic eviction and so also don't need TTM.

That leaves us with the more complex drivers, like radeon, amdgpu, 
nouveu and maybe some of the ARM based stuff, with vmwgfx being a bit 
special here.

Now I can summarize the requirements for at least the amdgpu in the 
following way:
1. We need to be able to allocate memory objects in different locations.
2. We need to be able to move around memory objects between different 
locations.
3. We need some LRU component which tells us what to evict when memory 
in a location becomes to tight.

Now for lessons learned we should at least avoid the following design 
pitfalls:
A) DON'T make it a layered design! Layers are for making cake, not software.

B) DON'T make it a "Eierlegende Wollmilchsau" (German saying). E.g. 
don't try to solve every single corner cases in one piece of software.
     Let's make components which solve one specific problem.

C) Pipeline everything! E.g. the hardware we deal with is asynchronous 
by design. Blocking for the hardware to finish in the common components 
itself is an absolutely no-go.
     If a driver wants to do something synchronous it should wait itself.

Those comments where not really intended for you Thomas, but I had to 
write them down somewhere :)

Regards,
Christian.

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

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

* Re: [PATCH 00/15] Share TTM code among framebuffer drivers
  2019-04-09  7:50       ` Thomas Zimmermann
@ 2019-04-15 15:54         ` Daniel Vetter
  2019-04-15 15:57           ` Daniel Vetter
                             ` (2 more replies)
  0 siblings, 3 replies; 43+ messages in thread
From: Daniel Vetter @ 2019-04-15 15:54 UTC (permalink / raw)
  To: Thomas Zimmermann
  Cc: airlied, puck.chen, dri-devel, virtualization, z.liuxinliang,
	hdegoede, kong.kongxinwei, Huang, Ray, daniel, zourongrong,
	Zhang, Jerry, Koenig, Christian

On Tue, Apr 09, 2019 at 09:50:40AM +0200, Thomas Zimmermann wrote:
> Hi
> 
> Am 09.04.19 um 09:12 schrieb kraxel@redhat.com:
> >   Hi,
> > 
> >> If not for TTM, what would be the alternative? One VMA manager per
> >> memory region per device?
> > 
> > Depends pretty much on the device.
> > 
> > The cirrus is a display device with only 4 MB of vram.  You can't fit
> > much in there.  A single 1024x768 @ 24bpp framebuffer needs more 50%
> > of the video memory already.  Which is why the cirrus driver (before the
> > rewrite) had to migrate buffers from/to vram on every page flip[1].  Which
> > is one[2] of the reasons why cirrus (after rewrite) doesn't ttm-manage the
> > vram any more.  gem objects are managed with the shmem helpers instead
> > and the active framebuffer is blitted to vram.
> > 
> > The qemu stdvga (bochs driver) has 16 MB vram by default and can be
> > configured to have up to 256 MB.  Plenty of room even for multiple 4k
> > framebuffers if needed.  So for the bochs driver all the ttm bo
> > migration logic is not needed, it could just store everything in vram.
> > 
> > A set of drm_gem_vram_* helpers would do the job for bochs.
> 
> Thanks for clarifying. drm_gem_vram_* (and drm_vram_mm for Simple TTM)
> is probably a better name for the data structures.

+1 on drm_gem_vram_* naming convention - we want to describe what it's
for, not how it's implemented.

> > I'd expect the same applies to the vbox driver.
> > 
> > Dunno about the other drm drivers and the fbdev drivers you plan to
> > migrate over.
> 
> The AST HW can support up to 512 MiB, but 32-64 MiB seems more realistic
> for a server. It's similar with mgag200 HW. The old fbdev-supported
> device are all somewhere in the range between cirrus and bochs. Some
> drivers would probably benefit from the cirrus approach, some could use
> VRAM directly.

I think for dumb scanout with vram all we need is:
- pin framebuffers, which potentially moves the underlying bo into vram
- unpin framebuffers (which is just accounting, we don't want to move the
  bo on every flip!)
- if a pin doesn't find enough space, move one of the unpinned bo still
  resident in vram out
- no pipelining, no support for dma engines (it's all cpu copies anway)
- a simple drm_mm should be good enough to manage the vram, no need for
  the ttm style abstraction over how memory is manged
- also just bake in the lru eviction list and algorithm
- probably good to have built-in support for redirecting the mmap between
  shmem and iomem.
- anything that needs pipelining or copy engines would be out of scope for
  these helpers

I think for starting points we can go with a copypasted version of the
various ttm implementations we already have, and then simplify from there
as needed. Or just start fresh if that's too complicated, due to the issue
Christian highlighted.
-Daniel

> Best regards
> Thomas
> 
> > 
> > cheers,
> >   Gerd
> > 
> > [1] Note: The page-flip migration logic is present in some of the other
> >     drivers too, not sure whenever they actually need that due to being low
> >     on vram too or whenever they just copied the old cirrus code ...
> > 
> > [2] The other reason is that this allow to convert formats at blit time,
> >     which helps to deal with some cirrus hardware limitations.
> > 
> 
> -- 
> Thomas Zimmermann
> Graphics Driver Developer
> SUSE Linux GmbH, Maxfeldstrasse 5, 90409 Nuernberg, Germany
> GF: Felix Imendörffer, Mary Higgins, Sri Rasiah
> HRB 21284 (AG Nürnberg)
> 




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

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

* Re: [PATCH 00/15] Share TTM code among framebuffer drivers
  2019-04-15 15:54         ` Daniel Vetter
  2019-04-15 15:57           ` Daniel Vetter
@ 2019-04-15 15:57           ` Daniel Vetter
  2019-04-15 16:21           ` Thomas Zimmermann
  2 siblings, 0 replies; 43+ messages in thread
From: Daniel Vetter @ 2019-04-15 15:57 UTC (permalink / raw)
  To: Thomas Zimmermann
  Cc: airlied, puck.chen, dri-devel, virtualization, z.liuxinliang,
	hdegoede, kong.kongxinwei, Huang, Ray, daniel, zourongrong,
	Zhang, Jerry, Koenig, Christian

On Mon, Apr 15, 2019 at 05:54:30PM +0200, Daniel Vetter wrote:
> On Tue, Apr 09, 2019 at 09:50:40AM +0200, Thomas Zimmermann wrote:
> > Hi
> > 
> > Am 09.04.19 um 09:12 schrieb kraxel@redhat.com:
> > >   Hi,
> > > 
> > >> If not for TTM, what would be the alternative? One VMA manager per
> > >> memory region per device?
> > > 
> > > Depends pretty much on the device.
> > > 
> > > The cirrus is a display device with only 4 MB of vram.  You can't fit
> > > much in there.  A single 1024x768 @ 24bpp framebuffer needs more 50%
> > > of the video memory already.  Which is why the cirrus driver (before the
> > > rewrite) had to migrate buffers from/to vram on every page flip[1].  Which
> > > is one[2] of the reasons why cirrus (after rewrite) doesn't ttm-manage the
> > > vram any more.  gem objects are managed with the shmem helpers instead
> > > and the active framebuffer is blitted to vram.
> > > 
> > > The qemu stdvga (bochs driver) has 16 MB vram by default and can be
> > > configured to have up to 256 MB.  Plenty of room even for multiple 4k
> > > framebuffers if needed.  So for the bochs driver all the ttm bo
> > > migration logic is not needed, it could just store everything in vram.
> > > 
> > > A set of drm_gem_vram_* helpers would do the job for bochs.
> > 
> > Thanks for clarifying. drm_gem_vram_* (and drm_vram_mm for Simple TTM)
> > is probably a better name for the data structures.
> 
> +1 on drm_gem_vram_* naming convention - we want to describe what it's
> for, not how it's implemented.
> 
> > > I'd expect the same applies to the vbox driver.
> > > 
> > > Dunno about the other drm drivers and the fbdev drivers you plan to
> > > migrate over.
> > 
> > The AST HW can support up to 512 MiB, but 32-64 MiB seems more realistic
> > for a server. It's similar with mgag200 HW. The old fbdev-supported
> > device are all somewhere in the range between cirrus and bochs. Some
> > drivers would probably benefit from the cirrus approach, some could use
> > VRAM directly.
> 
> I think for dumb scanout with vram all we need is:
> - pin framebuffers, which potentially moves the underlying bo into vram
> - unpin framebuffers (which is just accounting, we don't want to move the
>   bo on every flip!)
> - if a pin doesn't find enough space, move one of the unpinned bo still
>   resident in vram out
> - no pipelining, no support for dma engines (it's all cpu copies anway)
> - a simple drm_mm should be good enough to manage the vram, no need for
>   the ttm style abstraction over how memory is manged
> - also just bake in the lru eviction list and algorithm
> - probably good to have built-in support for redirecting the mmap between
>   shmem and iomem.
> - anything that needs pipelining or copy engines would be out of scope for
>   these helpers

One more:

- Only bother supporting hw that needs contiguous scanout buffers in VRAM.
  I think hw that has pagetables for scanout (and everything else really)
  is sufficiently different that cramming them into the same helpers
  doesn't make much sense: You want to manage your VRAM with a buddy
  allocator at a page level, plus you need to manage your pagetables, and
  all is likely very hw specific anyway. Plus I haven't seen such hw that
  doesn't come with a real gpu attached :-)

-Daniel

> 
> I think for starting points we can go with a copypasted version of the
> various ttm implementations we already have, and then simplify from there
> as needed. Or just start fresh if that's too complicated, due to the issue
> Christian highlighted.
> -Daniel
> 
> > Best regards
> > Thomas
> > 
> > > 
> > > cheers,
> > >   Gerd
> > > 
> > > [1] Note: The page-flip migration logic is present in some of the other
> > >     drivers too, not sure whenever they actually need that due to being low
> > >     on vram too or whenever they just copied the old cirrus code ...
> > > 
> > > [2] The other reason is that this allow to convert formats at blit time,
> > >     which helps to deal with some cirrus hardware limitations.
> > > 
> > 
> > -- 
> > Thomas Zimmermann
> > Graphics Driver Developer
> > SUSE Linux GmbH, Maxfeldstrasse 5, 90409 Nuernberg, Germany
> > GF: Felix Imendörffer, Mary Higgins, Sri Rasiah
> > HRB 21284 (AG Nürnberg)
> > 
> 
> 
> 
> 
> -- 
> Daniel Vetter
> Software Engineer, Intel Corporation
> http://blog.ffwll.ch

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

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

* Re: [PATCH 00/15] Share TTM code among framebuffer drivers
  2019-04-15 15:54         ` Daniel Vetter
@ 2019-04-15 15:57           ` Daniel Vetter
  2019-04-15 15:57           ` Daniel Vetter
  2019-04-15 16:21           ` Thomas Zimmermann
  2 siblings, 0 replies; 43+ messages in thread
From: Daniel Vetter @ 2019-04-15 15:57 UTC (permalink / raw)
  To: Thomas Zimmermann
  Cc: airlied, puck.chen, dri-devel, virtualization, z.liuxinliang,
	hdegoede, kong.kongxinwei, Huang, Ray, kraxel, zourongrong,
	Zhang, Jerry, Koenig, Christian

On Mon, Apr 15, 2019 at 05:54:30PM +0200, Daniel Vetter wrote:
> On Tue, Apr 09, 2019 at 09:50:40AM +0200, Thomas Zimmermann wrote:
> > Hi
> > 
> > Am 09.04.19 um 09:12 schrieb kraxel@redhat.com:
> > >   Hi,
> > > 
> > >> If not for TTM, what would be the alternative? One VMA manager per
> > >> memory region per device?
> > > 
> > > Depends pretty much on the device.
> > > 
> > > The cirrus is a display device with only 4 MB of vram.  You can't fit
> > > much in there.  A single 1024x768 @ 24bpp framebuffer needs more 50%
> > > of the video memory already.  Which is why the cirrus driver (before the
> > > rewrite) had to migrate buffers from/to vram on every page flip[1].  Which
> > > is one[2] of the reasons why cirrus (after rewrite) doesn't ttm-manage the
> > > vram any more.  gem objects are managed with the shmem helpers instead
> > > and the active framebuffer is blitted to vram.
> > > 
> > > The qemu stdvga (bochs driver) has 16 MB vram by default and can be
> > > configured to have up to 256 MB.  Plenty of room even for multiple 4k
> > > framebuffers if needed.  So for the bochs driver all the ttm bo
> > > migration logic is not needed, it could just store everything in vram.
> > > 
> > > A set of drm_gem_vram_* helpers would do the job for bochs.
> > 
> > Thanks for clarifying. drm_gem_vram_* (and drm_vram_mm for Simple TTM)
> > is probably a better name for the data structures.
> 
> +1 on drm_gem_vram_* naming convention - we want to describe what it's
> for, not how it's implemented.
> 
> > > I'd expect the same applies to the vbox driver.
> > > 
> > > Dunno about the other drm drivers and the fbdev drivers you plan to
> > > migrate over.
> > 
> > The AST HW can support up to 512 MiB, but 32-64 MiB seems more realistic
> > for a server. It's similar with mgag200 HW. The old fbdev-supported
> > device are all somewhere in the range between cirrus and bochs. Some
> > drivers would probably benefit from the cirrus approach, some could use
> > VRAM directly.
> 
> I think for dumb scanout with vram all we need is:
> - pin framebuffers, which potentially moves the underlying bo into vram
> - unpin framebuffers (which is just accounting, we don't want to move the
>   bo on every flip!)
> - if a pin doesn't find enough space, move one of the unpinned bo still
>   resident in vram out
> - no pipelining, no support for dma engines (it's all cpu copies anway)
> - a simple drm_mm should be good enough to manage the vram, no need for
>   the ttm style abstraction over how memory is manged
> - also just bake in the lru eviction list and algorithm
> - probably good to have built-in support for redirecting the mmap between
>   shmem and iomem.
> - anything that needs pipelining or copy engines would be out of scope for
>   these helpers

One more:

- Only bother supporting hw that needs contiguous scanout buffers in VRAM.
  I think hw that has pagetables for scanout (and everything else really)
  is sufficiently different that cramming them into the same helpers
  doesn't make much sense: You want to manage your VRAM with a buddy
  allocator at a page level, plus you need to manage your pagetables, and
  all is likely very hw specific anyway. Plus I haven't seen such hw that
  doesn't come with a real gpu attached :-)

-Daniel

> 
> I think for starting points we can go with a copypasted version of the
> various ttm implementations we already have, and then simplify from there
> as needed. Or just start fresh if that's too complicated, due to the issue
> Christian highlighted.
> -Daniel
> 
> > Best regards
> > Thomas
> > 
> > > 
> > > cheers,
> > >   Gerd
> > > 
> > > [1] Note: The page-flip migration logic is present in some of the other
> > >     drivers too, not sure whenever they actually need that due to being low
> > >     on vram too or whenever they just copied the old cirrus code ...
> > > 
> > > [2] The other reason is that this allow to convert formats at blit time,
> > >     which helps to deal with some cirrus hardware limitations.
> > > 
> > 
> > -- 
> > Thomas Zimmermann
> > Graphics Driver Developer
> > SUSE Linux GmbH, Maxfeldstrasse 5, 90409 Nuernberg, Germany
> > GF: Felix Imendörffer, Mary Higgins, Sri Rasiah
> > HRB 21284 (AG Nürnberg)
> > 
> 
> 
> 
> 
> -- 
> Daniel Vetter
> Software Engineer, Intel Corporation
> 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] 43+ messages in thread

* Re: [PATCH 00/15] Share TTM code among framebuffer drivers
  2019-04-15 15:54         ` Daniel Vetter
  2019-04-15 15:57           ` Daniel Vetter
  2019-04-15 15:57           ` Daniel Vetter
@ 2019-04-15 16:21           ` Thomas Zimmermann
  2019-04-15 19:17             ` Daniel Vetter
  2019-04-15 19:17             ` Daniel Vetter
  2 siblings, 2 replies; 43+ messages in thread
From: Thomas Zimmermann @ 2019-04-15 16:21 UTC (permalink / raw)
  To: Daniel Vetter
  Cc: airlied, puck.chen, Zhang, Jerry, dri-devel, virtualization,
	z.liuxinliang, hdegoede, kong.kongxinwei, Huang, Ray, kraxel,
	zourongrong, Koenig, Christian


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

Hi

Am 15.04.19 um 17:54 schrieb Daniel Vetter:
> On Tue, Apr 09, 2019 at 09:50:40AM +0200, Thomas Zimmermann wrote:
>> Hi
>>
>> Am 09.04.19 um 09:12 schrieb kraxel@redhat.com:
>>>   Hi,
>>>
>>>> If not for TTM, what would be the alternative? One VMA manager per
>>>> memory region per device?
>>>
>>> Depends pretty much on the device.
>>>
>>> The cirrus is a display device with only 4 MB of vram.  You can't fit
>>> much in there.  A single 1024x768 @ 24bpp framebuffer needs more 50%
>>> of the video memory already.  Which is why the cirrus driver (before the
>>> rewrite) had to migrate buffers from/to vram on every page flip[1].  Which
>>> is one[2] of the reasons why cirrus (after rewrite) doesn't ttm-manage the
>>> vram any more.  gem objects are managed with the shmem helpers instead
>>> and the active framebuffer is blitted to vram.
>>>
>>> The qemu stdvga (bochs driver) has 16 MB vram by default and can be
>>> configured to have up to 256 MB.  Plenty of room even for multiple 4k
>>> framebuffers if needed.  So for the bochs driver all the ttm bo
>>> migration logic is not needed, it could just store everything in vram.
>>>
>>> A set of drm_gem_vram_* helpers would do the job for bochs.
>>
>> Thanks for clarifying. drm_gem_vram_* (and drm_vram_mm for Simple TTM)
>> is probably a better name for the data structures.
> 
> +1 on drm_gem_vram_* naming convention - we want to describe what it's
> for, not how it's implemented.

OK, great.

>>> I'd expect the same applies to the vbox driver.
>>>
>>> Dunno about the other drm drivers and the fbdev drivers you plan to
>>> migrate over.
>>
>> The AST HW can support up to 512 MiB, but 32-64 MiB seems more realistic
>> for a server. It's similar with mgag200 HW. The old fbdev-supported
>> device are all somewhere in the range between cirrus and bochs. Some
>> drivers would probably benefit from the cirrus approach, some could use
>> VRAM directly.
> 
> I think for dumb scanout with vram all we need is:
> - pin framebuffers, which potentially moves the underlying bo into vram
> - unpin framebuffers (which is just accounting, we don't want to move the
>   bo on every flip!)
> - if a pin doesn't find enough space, move one of the unpinned bo still
>   resident in vram out

For dumb buffers, I'd expect userspace to have a working set of only a
front and back buffer (plus maybe a third one). This working set has to
reside in VRAM for performance reasons; non-WS BOs from other userspace
programs don't have to be.

So we could simplify even more: if there's not enough free space in
vram, remove all unpinned BO's. This would avoid the need to implement
an LRU algorithm or another eviction strategy. Userspace with a WS
larger than the absolute VRAM would see degraded performance but
otherwise still work.

Best regards
Thomas

> - no pipelining, no support for dma engines (it's all cpu copies anway)
> - a simple drm_mm should be good enough to manage the vram, no need for
>   the ttm style abstraction over how memory is manged
> - also just bake in the lru eviction list and algorithm
> - probably good to have built-in support for redirecting the mmap between
>   shmem and iomem.
> - anything that needs pipelining or copy engines would be out of scope for
>   these helpers
> 
> I think for starting points we can go with a copypasted version of the
> various ttm implementations we already have, and then simplify from there
> as needed. Or just start fresh if that's too complicated, due to the issue
> Christian highlighted.
> -Daniel
> 
>> Best regards
>> Thomas
>>
>>>
>>> cheers,
>>>   Gerd
>>>
>>> [1] Note: The page-flip migration logic is present in some of the other
>>>     drivers too, not sure whenever they actually need that due to being low
>>>     on vram too or whenever they just copied the old cirrus code ...
>>>
>>> [2] The other reason is that this allow to convert formats at blit time,
>>>     which helps to deal with some cirrus hardware limitations.
>>>
>>
>> -- 
>> Thomas Zimmermann
>> Graphics Driver Developer
>> SUSE Linux GmbH, Maxfeldstrasse 5, 90409 Nuernberg, Germany
>> GF: Felix Imendörffer, Mary Higgins, Sri Rasiah
>> HRB 21284 (AG Nürnberg)
>>
> 
> 
> 
> 

-- 
Thomas Zimmermann
Graphics Driver Developer
SUSE Linux GmbH, Maxfeldstrasse 5, 90409 Nuernberg, Germany
GF: Felix Imendörffer, Mary Higgins, Sri Rasiah
HRB 21284 (AG Nürnberg)


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

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

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

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

* Re: [PATCH 00/15] Share TTM code among framebuffer drivers
  2019-04-15 16:21           ` Thomas Zimmermann
  2019-04-15 19:17             ` Daniel Vetter
@ 2019-04-15 19:17             ` Daniel Vetter
  1 sibling, 0 replies; 43+ messages in thread
From: Daniel Vetter @ 2019-04-15 19:17 UTC (permalink / raw)
  To: Thomas Zimmermann
  Cc: airlied, puck.chen, Zhang, Jerry, dri-devel, virtualization,
	z.liuxinliang, hdegoede, kong.kongxinwei, Huang, Ray,
	zourongrong, Koenig, Christian

On Mon, Apr 15, 2019 at 6:21 PM Thomas Zimmermann <tzimmermann@suse.de> wrote:
>
> Hi
>
> Am 15.04.19 um 17:54 schrieb Daniel Vetter:
> > On Tue, Apr 09, 2019 at 09:50:40AM +0200, Thomas Zimmermann wrote:
> >> Hi
> >>
> >> Am 09.04.19 um 09:12 schrieb kraxel@redhat.com:
> >>>   Hi,
> >>>
> >>>> If not for TTM, what would be the alternative? One VMA manager per
> >>>> memory region per device?
> >>>
> >>> Depends pretty much on the device.
> >>>
> >>> The cirrus is a display device with only 4 MB of vram.  You can't fit
> >>> much in there.  A single 1024x768 @ 24bpp framebuffer needs more 50%
> >>> of the video memory already.  Which is why the cirrus driver (before the
> >>> rewrite) had to migrate buffers from/to vram on every page flip[1].  Which
> >>> is one[2] of the reasons why cirrus (after rewrite) doesn't ttm-manage the
> >>> vram any more.  gem objects are managed with the shmem helpers instead
> >>> and the active framebuffer is blitted to vram.
> >>>
> >>> The qemu stdvga (bochs driver) has 16 MB vram by default and can be
> >>> configured to have up to 256 MB.  Plenty of room even for multiple 4k
> >>> framebuffers if needed.  So for the bochs driver all the ttm bo
> >>> migration logic is not needed, it could just store everything in vram.
> >>>
> >>> A set of drm_gem_vram_* helpers would do the job for bochs.
> >>
> >> Thanks for clarifying. drm_gem_vram_* (and drm_vram_mm for Simple TTM)
> >> is probably a better name for the data structures.
> >
> > +1 on drm_gem_vram_* naming convention - we want to describe what it's
> > for, not how it's implemented.
>
> OK, great.
>
> >>> I'd expect the same applies to the vbox driver.
> >>>
> >>> Dunno about the other drm drivers and the fbdev drivers you plan to
> >>> migrate over.
> >>
> >> The AST HW can support up to 512 MiB, but 32-64 MiB seems more realistic
> >> for a server. It's similar with mgag200 HW. The old fbdev-supported
> >> device are all somewhere in the range between cirrus and bochs. Some
> >> drivers would probably benefit from the cirrus approach, some could use
> >> VRAM directly.
> >
> > I think for dumb scanout with vram all we need is:
> > - pin framebuffers, which potentially moves the underlying bo into vram
> > - unpin framebuffers (which is just accounting, we don't want to move the
> >   bo on every flip!)
> > - if a pin doesn't find enough space, move one of the unpinned bo still
> >   resident in vram out
>
> For dumb buffers, I'd expect userspace to have a working set of only a
> front and back buffer (plus maybe a third one). This working set has to
> reside in VRAM for performance reasons; non-WS BOs from other userspace
> programs don't have to be.
>
> So we could simplify even more: if there's not enough free space in
> vram, remove all unpinned BO's. This would avoid the need to implement
> an LRU algorithm or another eviction strategy. Userspace with a WS
> larger than the absolute VRAM would see degraded performance but
> otherwise still work.

You still need a list of unpinned bo, and the lru scan algorithm is
just a few lines of code more than unpinning everything. Plus it'd be
a neat example of the drm_mm scan logic. Given that some folks might
think that not having lru evict si a problem and get them to type
their own, I'd just add it. But up to you. Plus with ttm you get it no
matter what.
-Daniel


> Best regards
> Thomas
>
> > - no pipelining, no support for dma engines (it's all cpu copies anway)
> > - a simple drm_mm should be good enough to manage the vram, no need for
> >   the ttm style abstraction over how memory is manged
> > - also just bake in the lru eviction list and algorithm
> > - probably good to have built-in support for redirecting the mmap between
> >   shmem and iomem.
> > - anything that needs pipelining or copy engines would be out of scope for
> >   these helpers
> >
> > I think for starting points we can go with a copypasted version of the
> > various ttm implementations we already have, and then simplify from there
> > as needed. Or just start fresh if that's too complicated, due to the issue
> > Christian highlighted.
> > -Daniel
> >
> >> Best regards
> >> Thomas
> >>
> >>>
> >>> cheers,
> >>>   Gerd
> >>>
> >>> [1] Note: The page-flip migration logic is present in some of the other
> >>>     drivers too, not sure whenever they actually need that due to being low
> >>>     on vram too or whenever they just copied the old cirrus code ...
> >>>
> >>> [2] The other reason is that this allow to convert formats at blit time,
> >>>     which helps to deal with some cirrus hardware limitations.
> >>>
> >>
> >> --
> >> Thomas Zimmermann
> >> Graphics Driver Developer
> >> SUSE Linux GmbH, Maxfeldstrasse 5, 90409 Nuernberg, Germany
> >> GF: Felix Imendörffer, Mary Higgins, Sri Rasiah
> >> HRB 21284 (AG Nürnberg)
> >>
> >
> >
> >
> >
>
> --
> Thomas Zimmermann
> Graphics Driver Developer
> SUSE Linux GmbH, Maxfeldstrasse 5, 90409 Nuernberg, Germany
> GF: Felix Imendörffer, Mary Higgins, Sri Rasiah
> HRB 21284 (AG Nürnberg)
>


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

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

* Re: [PATCH 00/15] Share TTM code among framebuffer drivers
  2019-04-15 16:21           ` Thomas Zimmermann
@ 2019-04-15 19:17             ` Daniel Vetter
  2019-04-16 10:05               ` Koenig, Christian
  2019-04-16 10:05               ` Koenig, Christian
  2019-04-15 19:17             ` Daniel Vetter
  1 sibling, 2 replies; 43+ messages in thread
From: Daniel Vetter @ 2019-04-15 19:17 UTC (permalink / raw)
  To: Thomas Zimmermann
  Cc: airlied, puck.chen, Zhang, Jerry, dri-devel, virtualization,
	z.liuxinliang, hdegoede, kong.kongxinwei, Huang, Ray, kraxel,
	zourongrong, Koenig, Christian

On Mon, Apr 15, 2019 at 6:21 PM Thomas Zimmermann <tzimmermann@suse.de> wrote:
>
> Hi
>
> Am 15.04.19 um 17:54 schrieb Daniel Vetter:
> > On Tue, Apr 09, 2019 at 09:50:40AM +0200, Thomas Zimmermann wrote:
> >> Hi
> >>
> >> Am 09.04.19 um 09:12 schrieb kraxel@redhat.com:
> >>>   Hi,
> >>>
> >>>> If not for TTM, what would be the alternative? One VMA manager per
> >>>> memory region per device?
> >>>
> >>> Depends pretty much on the device.
> >>>
> >>> The cirrus is a display device with only 4 MB of vram.  You can't fit
> >>> much in there.  A single 1024x768 @ 24bpp framebuffer needs more 50%
> >>> of the video memory already.  Which is why the cirrus driver (before the
> >>> rewrite) had to migrate buffers from/to vram on every page flip[1].  Which
> >>> is one[2] of the reasons why cirrus (after rewrite) doesn't ttm-manage the
> >>> vram any more.  gem objects are managed with the shmem helpers instead
> >>> and the active framebuffer is blitted to vram.
> >>>
> >>> The qemu stdvga (bochs driver) has 16 MB vram by default and can be
> >>> configured to have up to 256 MB.  Plenty of room even for multiple 4k
> >>> framebuffers if needed.  So for the bochs driver all the ttm bo
> >>> migration logic is not needed, it could just store everything in vram.
> >>>
> >>> A set of drm_gem_vram_* helpers would do the job for bochs.
> >>
> >> Thanks for clarifying. drm_gem_vram_* (and drm_vram_mm for Simple TTM)
> >> is probably a better name for the data structures.
> >
> > +1 on drm_gem_vram_* naming convention - we want to describe what it's
> > for, not how it's implemented.
>
> OK, great.
>
> >>> I'd expect the same applies to the vbox driver.
> >>>
> >>> Dunno about the other drm drivers and the fbdev drivers you plan to
> >>> migrate over.
> >>
> >> The AST HW can support up to 512 MiB, but 32-64 MiB seems more realistic
> >> for a server. It's similar with mgag200 HW. The old fbdev-supported
> >> device are all somewhere in the range between cirrus and bochs. Some
> >> drivers would probably benefit from the cirrus approach, some could use
> >> VRAM directly.
> >
> > I think for dumb scanout with vram all we need is:
> > - pin framebuffers, which potentially moves the underlying bo into vram
> > - unpin framebuffers (which is just accounting, we don't want to move the
> >   bo on every flip!)
> > - if a pin doesn't find enough space, move one of the unpinned bo still
> >   resident in vram out
>
> For dumb buffers, I'd expect userspace to have a working set of only a
> front and back buffer (plus maybe a third one). This working set has to
> reside in VRAM for performance reasons; non-WS BOs from other userspace
> programs don't have to be.
>
> So we could simplify even more: if there's not enough free space in
> vram, remove all unpinned BO's. This would avoid the need to implement
> an LRU algorithm or another eviction strategy. Userspace with a WS
> larger than the absolute VRAM would see degraded performance but
> otherwise still work.

You still need a list of unpinned bo, and the lru scan algorithm is
just a few lines of code more than unpinning everything. Plus it'd be
a neat example of the drm_mm scan logic. Given that some folks might
think that not having lru evict si a problem and get them to type
their own, I'd just add it. But up to you. Plus with ttm you get it no
matter what.
-Daniel


> Best regards
> Thomas
>
> > - no pipelining, no support for dma engines (it's all cpu copies anway)
> > - a simple drm_mm should be good enough to manage the vram, no need for
> >   the ttm style abstraction over how memory is manged
> > - also just bake in the lru eviction list and algorithm
> > - probably good to have built-in support for redirecting the mmap between
> >   shmem and iomem.
> > - anything that needs pipelining or copy engines would be out of scope for
> >   these helpers
> >
> > I think for starting points we can go with a copypasted version of the
> > various ttm implementations we already have, and then simplify from there
> > as needed. Or just start fresh if that's too complicated, due to the issue
> > Christian highlighted.
> > -Daniel
> >
> >> Best regards
> >> Thomas
> >>
> >>>
> >>> cheers,
> >>>   Gerd
> >>>
> >>> [1] Note: The page-flip migration logic is present in some of the other
> >>>     drivers too, not sure whenever they actually need that due to being low
> >>>     on vram too or whenever they just copied the old cirrus code ...
> >>>
> >>> [2] The other reason is that this allow to convert formats at blit time,
> >>>     which helps to deal with some cirrus hardware limitations.
> >>>
> >>
> >> --
> >> Thomas Zimmermann
> >> Graphics Driver Developer
> >> SUSE Linux GmbH, Maxfeldstrasse 5, 90409 Nuernberg, Germany
> >> GF: Felix Imendörffer, Mary Higgins, Sri Rasiah
> >> HRB 21284 (AG Nürnberg)
> >>
> >
> >
> >
> >
>
> --
> Thomas Zimmermann
> Graphics Driver Developer
> SUSE Linux GmbH, Maxfeldstrasse 5, 90409 Nuernberg, Germany
> GF: Felix Imendörffer, Mary Higgins, Sri Rasiah
> HRB 21284 (AG Nürnberg)
>


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

* Re: [PATCH 00/15] Share TTM code among framebuffer drivers
  2019-04-15 19:17             ` Daniel Vetter
  2019-04-16 10:05               ` Koenig, Christian
@ 2019-04-16 10:05               ` Koenig, Christian
  1 sibling, 0 replies; 43+ messages in thread
From: Koenig, Christian @ 2019-04-16 10:05 UTC (permalink / raw)
  To: Daniel Vetter, Thomas Zimmermann
  Cc: airlied, puck.chen, Zhang, Jerry, dri-devel, virtualization,
	z.liuxinliang, hdegoede, kong.kongxinwei, Huang, Ray,
	zourongrong

Am 15.04.19 um 21:17 schrieb Daniel Vetter:
> On Mon, Apr 15, 2019 at 6:21 PM Thomas Zimmermann <tzimmermann@suse.de> wrote:
>> Hi
>>
>> Am 15.04.19 um 17:54 schrieb Daniel Vetter:
>>> On Tue, Apr 09, 2019 at 09:50:40AM +0200, Thomas Zimmermann wrote:
>>>> Hi
>>>>
>>>> Am 09.04.19 um 09:12 schrieb kraxel@redhat.com:
>>>> [SNIP]
>>>>> I'd expect the same applies to the vbox driver.
>>>>>
>>>>> Dunno about the other drm drivers and the fbdev drivers you plan to
>>>>> migrate over.
>>>> The AST HW can support up to 512 MiB, but 32-64 MiB seems more realistic
>>>> for a server. It's similar with mgag200 HW. The old fbdev-supported
>>>> device are all somewhere in the range between cirrus and bochs. Some
>>>> drivers would probably benefit from the cirrus approach, some could use
>>>> VRAM directly.
>>> I think for dumb scanout with vram all we need is:
>>> - pin framebuffers, which potentially moves the underlying bo into vram
>>> - unpin framebuffers (which is just accounting, we don't want to move the
>>>    bo on every flip!)
>>> - if a pin doesn't find enough space, move one of the unpinned bo still
>>>    resident in vram out
>> For dumb buffers, I'd expect userspace to have a working set of only a
>> front and back buffer (plus maybe a third one). This working set has to
>> reside in VRAM for performance reasons; non-WS BOs from other userspace
>> programs don't have to be.
>>
>> So we could simplify even more: if there's not enough free space in
>> vram, remove all unpinned BO's. This would avoid the need to implement
>> an LRU algorithm or another eviction strategy. Userspace with a WS
>> larger than the absolute VRAM would see degraded performance but
>> otherwise still work.
> You still need a list of unpinned bo, and the lru scan algorithm is
> just a few lines of code more than unpinning everything. Plus it'd be
> a neat example of the drm_mm scan logic. Given that some folks might
> think that not having lru evict si a problem and get them to type
> their own, I'd just add it. But up to you. Plus with ttm you get it no
> matter what.

Well how about making an drm_lru component which just does the following 
(and nothing else, please :):

1. Keep a list of objects and a spinlock protecting the list.

2. Offer helpers for adding/deleting/moving stuff from the list.

3. Offer a functionality to do the necessary dance of picking the first 
entry where we can trylock it's reservation object.

4. Offer bulk move functionality similar to what TTM does at the moment 
(can be implemented later on).

Regards,
Christian.

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

* Re: [PATCH 00/15] Share TTM code among framebuffer drivers
  2019-04-15 19:17             ` Daniel Vetter
@ 2019-04-16 10:05               ` Koenig, Christian
  2019-04-16 11:03                 ` Daniel Vetter
  2019-04-16 11:03                 ` Daniel Vetter
  2019-04-16 10:05               ` Koenig, Christian
  1 sibling, 2 replies; 43+ messages in thread
From: Koenig, Christian @ 2019-04-16 10:05 UTC (permalink / raw)
  To: Daniel Vetter, Thomas Zimmermann
  Cc: airlied, puck.chen, Zhang, Jerry, dri-devel, virtualization,
	z.liuxinliang, hdegoede, kong.kongxinwei, Huang, Ray, kraxel,
	zourongrong

Am 15.04.19 um 21:17 schrieb Daniel Vetter:
> On Mon, Apr 15, 2019 at 6:21 PM Thomas Zimmermann <tzimmermann@suse.de> wrote:
>> Hi
>>
>> Am 15.04.19 um 17:54 schrieb Daniel Vetter:
>>> On Tue, Apr 09, 2019 at 09:50:40AM +0200, Thomas Zimmermann wrote:
>>>> Hi
>>>>
>>>> Am 09.04.19 um 09:12 schrieb kraxel@redhat.com:
>>>> [SNIP]
>>>>> I'd expect the same applies to the vbox driver.
>>>>>
>>>>> Dunno about the other drm drivers and the fbdev drivers you plan to
>>>>> migrate over.
>>>> The AST HW can support up to 512 MiB, but 32-64 MiB seems more realistic
>>>> for a server. It's similar with mgag200 HW. The old fbdev-supported
>>>> device are all somewhere in the range between cirrus and bochs. Some
>>>> drivers would probably benefit from the cirrus approach, some could use
>>>> VRAM directly.
>>> I think for dumb scanout with vram all we need is:
>>> - pin framebuffers, which potentially moves the underlying bo into vram
>>> - unpin framebuffers (which is just accounting, we don't want to move the
>>>    bo on every flip!)
>>> - if a pin doesn't find enough space, move one of the unpinned bo still
>>>    resident in vram out
>> For dumb buffers, I'd expect userspace to have a working set of only a
>> front and back buffer (plus maybe a third one). This working set has to
>> reside in VRAM for performance reasons; non-WS BOs from other userspace
>> programs don't have to be.
>>
>> So we could simplify even more: if there's not enough free space in
>> vram, remove all unpinned BO's. This would avoid the need to implement
>> an LRU algorithm or another eviction strategy. Userspace with a WS
>> larger than the absolute VRAM would see degraded performance but
>> otherwise still work.
> You still need a list of unpinned bo, and the lru scan algorithm is
> just a few lines of code more than unpinning everything. Plus it'd be
> a neat example of the drm_mm scan logic. Given that some folks might
> think that not having lru evict si a problem and get them to type
> their own, I'd just add it. But up to you. Plus with ttm you get it no
> matter what.

Well how about making an drm_lru component which just does the following 
(and nothing else, please :):

1. Keep a list of objects and a spinlock protecting the list.

2. Offer helpers for adding/deleting/moving stuff from the list.

3. Offer a functionality to do the necessary dance of picking the first 
entry where we can trylock it's reservation object.

4. Offer bulk move functionality similar to what TTM does at the moment 
(can be implemented later on).

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

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

* Re: [PATCH 00/15] Share TTM code among framebuffer drivers
  2019-04-16 10:05               ` Koenig, Christian
  2019-04-16 11:03                 ` Daniel Vetter
@ 2019-04-16 11:03                 ` Daniel Vetter
  1 sibling, 0 replies; 43+ messages in thread
From: Daniel Vetter @ 2019-04-16 11:03 UTC (permalink / raw)
  To: Koenig, Christian
  Cc: airlied, puck.chen, Zhang, Jerry, dri-devel, virtualization,
	z.liuxinliang, hdegoede, kong.kongxinwei, Huang, Ray,
	Thomas Zimmermann, zourongrong

On Tue, Apr 16, 2019 at 12:05 PM Koenig, Christian
<Christian.Koenig@amd.com> wrote:
>
> Am 15.04.19 um 21:17 schrieb Daniel Vetter:
> > On Mon, Apr 15, 2019 at 6:21 PM Thomas Zimmermann <tzimmermann@suse.de> wrote:
> >> Hi
> >>
> >> Am 15.04.19 um 17:54 schrieb Daniel Vetter:
> >>> On Tue, Apr 09, 2019 at 09:50:40AM +0200, Thomas Zimmermann wrote:
> >>>> Hi
> >>>>
> >>>> Am 09.04.19 um 09:12 schrieb kraxel@redhat.com:
> >>>> [SNIP]
> >>>>> I'd expect the same applies to the vbox driver.
> >>>>>
> >>>>> Dunno about the other drm drivers and the fbdev drivers you plan to
> >>>>> migrate over.
> >>>> The AST HW can support up to 512 MiB, but 32-64 MiB seems more realistic
> >>>> for a server. It's similar with mgag200 HW. The old fbdev-supported
> >>>> device are all somewhere in the range between cirrus and bochs. Some
> >>>> drivers would probably benefit from the cirrus approach, some could use
> >>>> VRAM directly.
> >>> I think for dumb scanout with vram all we need is:
> >>> - pin framebuffers, which potentially moves the underlying bo into vram
> >>> - unpin framebuffers (which is just accounting, we don't want to move the
> >>>    bo on every flip!)
> >>> - if a pin doesn't find enough space, move one of the unpinned bo still
> >>>    resident in vram out
> >> For dumb buffers, I'd expect userspace to have a working set of only a
> >> front and back buffer (plus maybe a third one). This working set has to
> >> reside in VRAM for performance reasons; non-WS BOs from other userspace
> >> programs don't have to be.
> >>
> >> So we could simplify even more: if there's not enough free space in
> >> vram, remove all unpinned BO's. This would avoid the need to implement
> >> an LRU algorithm or another eviction strategy. Userspace with a WS
> >> larger than the absolute VRAM would see degraded performance but
> >> otherwise still work.
> > You still need a list of unpinned bo, and the lru scan algorithm is
> > just a few lines of code more than unpinning everything. Plus it'd be
> > a neat example of the drm_mm scan logic. Given that some folks might
> > think that not having lru evict si a problem and get them to type
> > their own, I'd just add it. But up to you. Plus with ttm you get it no
> > matter what.
>
> Well how about making an drm_lru component which just does the following
> (and nothing else, please :):
>
> 1. Keep a list of objects and a spinlock protecting the list.
>
> 2. Offer helpers for adding/deleting/moving stuff from the list.
>
> 3. Offer a functionality to do the necessary dance of picking the first
> entry where we can trylock it's reservation object.
>
> 4. Offer bulk move functionality similar to what TTM does at the moment
> (can be implemented later on).

At a basic level, this is list_head of drm_gem_object. Not sure that's
all that useful (outside of the fairly simplistic vram helpers we're
discussing here). Reasons for that is that there's a lot of trickery
in selecting which is the best object to pick in any given case (e.g.
do you want to use drm_mm scanning, or is there a slab of objects you
prefer to throw out because that avoids. Given that I'm not sure
implementing the entire scanning/drm_lru logic is beneficial.

The magic trylock+kref_get_unless_zero otoh could be worth
implementing as a helper, together with a note about how to build your
own custom lru algorithm. Same for some bulk/nonblocking movement
helpers maybe. Both not really needed for the dumb scanout vram
helpers we're discussing here.
-Daniel

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

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

* Re: [PATCH 00/15] Share TTM code among framebuffer drivers
  2019-04-16 10:05               ` Koenig, Christian
@ 2019-04-16 11:03                 ` Daniel Vetter
  2019-04-16 11:10                   ` Koenig, Christian
  2019-04-16 11:03                 ` Daniel Vetter
  1 sibling, 1 reply; 43+ messages in thread
From: Daniel Vetter @ 2019-04-16 11:03 UTC (permalink / raw)
  To: Koenig, Christian
  Cc: airlied, puck.chen, Zhang, Jerry, dri-devel, virtualization,
	z.liuxinliang, hdegoede, kong.kongxinwei, Huang, Ray, kraxel,
	Thomas Zimmermann, zourongrong

On Tue, Apr 16, 2019 at 12:05 PM Koenig, Christian
<Christian.Koenig@amd.com> wrote:
>
> Am 15.04.19 um 21:17 schrieb Daniel Vetter:
> > On Mon, Apr 15, 2019 at 6:21 PM Thomas Zimmermann <tzimmermann@suse.de> wrote:
> >> Hi
> >>
> >> Am 15.04.19 um 17:54 schrieb Daniel Vetter:
> >>> On Tue, Apr 09, 2019 at 09:50:40AM +0200, Thomas Zimmermann wrote:
> >>>> Hi
> >>>>
> >>>> Am 09.04.19 um 09:12 schrieb kraxel@redhat.com:
> >>>> [SNIP]
> >>>>> I'd expect the same applies to the vbox driver.
> >>>>>
> >>>>> Dunno about the other drm drivers and the fbdev drivers you plan to
> >>>>> migrate over.
> >>>> The AST HW can support up to 512 MiB, but 32-64 MiB seems more realistic
> >>>> for a server. It's similar with mgag200 HW. The old fbdev-supported
> >>>> device are all somewhere in the range between cirrus and bochs. Some
> >>>> drivers would probably benefit from the cirrus approach, some could use
> >>>> VRAM directly.
> >>> I think for dumb scanout with vram all we need is:
> >>> - pin framebuffers, which potentially moves the underlying bo into vram
> >>> - unpin framebuffers (which is just accounting, we don't want to move the
> >>>    bo on every flip!)
> >>> - if a pin doesn't find enough space, move one of the unpinned bo still
> >>>    resident in vram out
> >> For dumb buffers, I'd expect userspace to have a working set of only a
> >> front and back buffer (plus maybe a third one). This working set has to
> >> reside in VRAM for performance reasons; non-WS BOs from other userspace
> >> programs don't have to be.
> >>
> >> So we could simplify even more: if there's not enough free space in
> >> vram, remove all unpinned BO's. This would avoid the need to implement
> >> an LRU algorithm or another eviction strategy. Userspace with a WS
> >> larger than the absolute VRAM would see degraded performance but
> >> otherwise still work.
> > You still need a list of unpinned bo, and the lru scan algorithm is
> > just a few lines of code more than unpinning everything. Plus it'd be
> > a neat example of the drm_mm scan logic. Given that some folks might
> > think that not having lru evict si a problem and get them to type
> > their own, I'd just add it. But up to you. Plus with ttm you get it no
> > matter what.
>
> Well how about making an drm_lru component which just does the following
> (and nothing else, please :):
>
> 1. Keep a list of objects and a spinlock protecting the list.
>
> 2. Offer helpers for adding/deleting/moving stuff from the list.
>
> 3. Offer a functionality to do the necessary dance of picking the first
> entry where we can trylock it's reservation object.
>
> 4. Offer bulk move functionality similar to what TTM does at the moment
> (can be implemented later on).

At a basic level, this is list_head of drm_gem_object. Not sure that's
all that useful (outside of the fairly simplistic vram helpers we're
discussing here). Reasons for that is that there's a lot of trickery
in selecting which is the best object to pick in any given case (e.g.
do you want to use drm_mm scanning, or is there a slab of objects you
prefer to throw out because that avoids. Given that I'm not sure
implementing the entire scanning/drm_lru logic is beneficial.

The magic trylock+kref_get_unless_zero otoh could be worth
implementing as a helper, together with a note about how to build your
own custom lru algorithm. Same for some bulk/nonblocking movement
helpers maybe. Both not really needed for the dumb scanout vram
helpers we're discussing here.
-Daniel

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

* Re: [PATCH 00/15] Share TTM code among framebuffer drivers
  2019-04-16 11:03                 ` Daniel Vetter
@ 2019-04-16 11:10                   ` Koenig, Christian
  0 siblings, 0 replies; 43+ messages in thread
From: Koenig, Christian @ 2019-04-16 11:10 UTC (permalink / raw)
  To: Daniel Vetter
  Cc: airlied, puck.chen, Zhang, Jerry, dri-devel, virtualization,
	z.liuxinliang, hdegoede, kong.kongxinwei, Huang, Ray,
	Thomas Zimmermann, zourongrong

Am 16.04.19 um 13:03 schrieb Daniel Vetter:
> On Tue, Apr 16, 2019 at 12:05 PM Koenig, Christian
> <Christian.Koenig@amd.com> wrote:
>> Am 15.04.19 um 21:17 schrieb Daniel Vetter:
>>> On Mon, Apr 15, 2019 at 6:21 PM Thomas Zimmermann <tzimmermann@suse.de> wrote:
>>>> Hi
>>>>
>>>> Am 15.04.19 um 17:54 schrieb Daniel Vetter:
>>>>> On Tue, Apr 09, 2019 at 09:50:40AM +0200, Thomas Zimmermann wrote:
>>>>>> Hi
>>>>>>
>>>>>> Am 09.04.19 um 09:12 schrieb kraxel@redhat.com:
>>>>>> [SNIP]
>>>>>>> I'd expect the same applies to the vbox driver.
>>>>>>>
>>>>>>> Dunno about the other drm drivers and the fbdev drivers you plan to
>>>>>>> migrate over.
>>>>>> The AST HW can support up to 512 MiB, but 32-64 MiB seems more realistic
>>>>>> for a server. It's similar with mgag200 HW. The old fbdev-supported
>>>>>> device are all somewhere in the range between cirrus and bochs. Some
>>>>>> drivers would probably benefit from the cirrus approach, some could use
>>>>>> VRAM directly.
>>>>> I think for dumb scanout with vram all we need is:
>>>>> - pin framebuffers, which potentially moves the underlying bo into vram
>>>>> - unpin framebuffers (which is just accounting, we don't want to move the
>>>>>     bo on every flip!)
>>>>> - if a pin doesn't find enough space, move one of the unpinned bo still
>>>>>     resident in vram out
>>>> For dumb buffers, I'd expect userspace to have a working set of only a
>>>> front and back buffer (plus maybe a third one). This working set has to
>>>> reside in VRAM for performance reasons; non-WS BOs from other userspace
>>>> programs don't have to be.
>>>>
>>>> So we could simplify even more: if there's not enough free space in
>>>> vram, remove all unpinned BO's. This would avoid the need to implement
>>>> an LRU algorithm or another eviction strategy. Userspace with a WS
>>>> larger than the absolute VRAM would see degraded performance but
>>>> otherwise still work.
>>> You still need a list of unpinned bo, and the lru scan algorithm is
>>> just a few lines of code more than unpinning everything. Plus it'd be
>>> a neat example of the drm_mm scan logic. Given that some folks might
>>> think that not having lru evict si a problem and get them to type
>>> their own, I'd just add it. But up to you. Plus with ttm you get it no
>>> matter what.
>> Well how about making an drm_lru component which just does the following
>> (and nothing else, please :):
>>
>> 1. Keep a list of objects and a spinlock protecting the list.
>>
>> 2. Offer helpers for adding/deleting/moving stuff from the list.
>>
>> 3. Offer a functionality to do the necessary dance of picking the first
>> entry where we can trylock it's reservation object.
>>
>> 4. Offer bulk move functionality similar to what TTM does at the moment
>> (can be implemented later on).
> At a basic level, this is list_head of drm_gem_object. Not sure that's
> all that useful (outside of the fairly simplistic vram helpers we're
> discussing here). Reasons for that is that there's a lot of trickery
> in selecting which is the best object to pick in any given case (e.g.
> do you want to use drm_mm scanning, or is there a slab of objects you
> prefer to throw out because that avoids. Given that I'm not sure
> implementing the entire scanning/drm_lru logic is beneficial.
>
> The magic trylock+kref_get_unless_zero otoh could be worth
> implementing as a helper, together with a note about how to build your
> own custom lru algorithm. Same for some bulk/nonblocking movement
> helpers maybe. Both not really needed for the dumb scanout vram
> helpers we're discussing here.

Yeah, exactly that's what I wanted to get towards as well.

This magic trylock+kref_get is what needs to be handled correctly by all 
drivers which implement an LRU.

LRU bulk move is something which is tricky to get right as well, but so 
far only amdgpu uses it so it only make sense to share when somebody 
else wants the same approach.

Christian.

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

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

end of thread, other threads:[~2019-04-16 11:10 UTC | newest]

Thread overview: 43+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-04-08  9:21 [PATCH 00/15] Share TTM code among framebuffer drivers Thomas Zimmermann
2019-04-08  9:21 ` [PATCH 01/15] drm: Add |struct drm_gem_ttm_object| and helpers Thomas Zimmermann
2019-04-08  9:21 ` [PATCH 02/15] drm: Add |struct drm_gem_ttm_object| callbacks for |struct ttm_bo_driver| Thomas Zimmermann
2019-04-08  9:21 ` [PATCH 03/15] drm: Add |struct drm_gem_ttm_object| callbacks for |struct drm_driver| Thomas Zimmermann
2019-04-08  9:21 ` [PATCH 04/15] drm: Add drm_gem_ttm_fill_create_dumb() to create dumb buffers Thomas Zimmermann
2019-04-08  9:21 ` [PATCH 05/15] drm: Add Simple TTM, a memory manager for dedicated VRAM Thomas Zimmermann
2019-04-08  9:21 ` [PATCH 06/15] drm/ast: Convert AST driver to |struct drm_gem_ttm_object| Thomas Zimmermann
2019-04-08  9:21 ` [PATCH 07/15] drm/ast: Convert AST driver to Simple TTM Thomas Zimmermann
2019-04-08  9:21 ` [PATCH 08/15] drm/bochs: Convert Bochs driver to |struct drm_gem_ttm_object| Thomas Zimmermann
2019-04-08  9:21 ` [PATCH 09/15] drm/bochs: Convert Bochs driver to Simple TTM Thomas Zimmermann
2019-04-08  9:21 ` [PATCH 10/15] drm/mgag200: Convert mgag200 driver to |struct drm_gem_ttm_object| Thomas Zimmermann
2019-04-08  9:21 ` [PATCH 11/15] drm/mgag200: Convert mgag200 driver to Simple TTM Thomas Zimmermann
2019-04-08  9:21 ` [PATCH 12/15] drm/vboxvideo: Convert vboxvideo driver to |struct drm_gem_ttm_object| Thomas Zimmermann
2019-04-09  7:09   ` Hans de Goede
2019-04-09  7:09   ` Hans de Goede
2019-04-08  9:21 ` [PATCH 13/15] drm/vboxvideo: Convert vboxvideo driver to Simple TTM Thomas Zimmermann
2019-04-09  7:09   ` Hans de Goede
2019-04-09  7:37     ` Thomas Zimmermann
2019-04-09  7:09   ` Hans de Goede
2019-04-08  9:21 ` [PATCH 14/15] drm/hisilicon: Convert hibmc-drm driver to |struct drm_gem_ttm_object| Thomas Zimmermann
2019-04-08  9:21 ` [PATCH 15/15] drm/hisilicon: Convert hibmc-drm driver to Simple TTM Thomas Zimmermann
2019-04-08 11:10 ` [PATCH 00/15] Share TTM code among framebuffer drivers Koenig, Christian
2019-04-08 11:10 ` Koenig, Christian
2019-04-08 11:59   ` Thomas Zimmermann
2019-04-09  7:12     ` kraxel
2019-04-09  7:42       ` Dave Airlie
2019-04-09  8:29         ` kraxel
2019-04-09 11:55           ` Christian König
2019-04-09  8:29         ` kraxel
2019-04-09  7:50       ` Thomas Zimmermann
2019-04-15 15:54         ` Daniel Vetter
2019-04-15 15:57           ` Daniel Vetter
2019-04-15 15:57           ` Daniel Vetter
2019-04-15 16:21           ` Thomas Zimmermann
2019-04-15 19:17             ` Daniel Vetter
2019-04-16 10:05               ` Koenig, Christian
2019-04-16 11:03                 ` Daniel Vetter
2019-04-16 11:10                   ` Koenig, Christian
2019-04-16 11:03                 ` Daniel Vetter
2019-04-16 10:05               ` Koenig, Christian
2019-04-15 19:17             ` Daniel Vetter
2019-04-09  7:12     ` kraxel
2019-04-09 13:39     ` Koenig, Christian

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.