Commit b0e40e08 authored by Thomas Zimmermann's avatar Thomas Zimmermann

drm/vram: Have VRAM MM call GEM VRAM functions directly

VRAM MM and GEM VRAM buffer objects are only used with each other;
connected via 3 function pointers. Simplify this code by making the
memory manager call the rsp. functions of the BOs directly; and
remove the functions from the BO's public interface.

v2:
	* typos in commit message
Signed-off-by: default avatarThomas Zimmermann <tzimmermann@suse.de>
Acked-by: default avatarGerd Hoffmann <kraxel@redhat.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20190911110910.30698-3-tzimmermann@suse.de
parent 6b5ce4a1
...@@ -41,7 +41,7 @@ int ast_mm_init(struct ast_private *ast) ...@@ -41,7 +41,7 @@ int ast_mm_init(struct ast_private *ast)
vmm = drm_vram_helper_alloc_mm( vmm = drm_vram_helper_alloc_mm(
dev, pci_resource_start(dev->pdev, 0), dev, pci_resource_start(dev->pdev, 0),
ast->vram_size, &drm_gem_vram_mm_funcs); ast->vram_size);
if (IS_ERR(vmm)) { if (IS_ERR(vmm)) {
ret = PTR_ERR(vmm); ret = PTR_ERR(vmm);
DRM_ERROR("Error initializing VRAM MM; %d\n", ret); DRM_ERROR("Error initializing VRAM MM; %d\n", ret);
......
...@@ -11,8 +11,7 @@ int bochs_mm_init(struct bochs_device *bochs) ...@@ -11,8 +11,7 @@ int bochs_mm_init(struct bochs_device *bochs)
struct drm_vram_mm *vmm; struct drm_vram_mm *vmm;
vmm = drm_vram_helper_alloc_mm(bochs->dev, bochs->fb_base, vmm = drm_vram_helper_alloc_mm(bochs->dev, bochs->fb_base,
bochs->fb_size, bochs->fb_size);
&drm_gem_vram_mm_funcs);
return PTR_ERR_OR_ZERO(vmm); return PTR_ERR_OR_ZERO(vmm);
} }
......
...@@ -7,7 +7,6 @@ ...@@ -7,7 +7,6 @@
#include <drm/drm_gem_vram_helper.h> #include <drm/drm_gem_vram_helper.h>
#include <drm/drm_mode.h> #include <drm/drm_mode.h>
#include <drm/drm_prime.h> #include <drm/drm_prime.h>
#include <drm/drm_vram_mm_helper.h>
#include <drm/ttm/ttm_page_alloc.h> #include <drm/ttm/ttm_page_alloc.h>
static const struct drm_gem_object_funcs drm_gem_vram_object_funcs; static const struct drm_gem_object_funcs drm_gem_vram_object_funcs;
...@@ -464,68 +463,25 @@ static bool drm_is_gem_vram(struct ttm_buffer_object *bo) ...@@ -464,68 +463,25 @@ static bool drm_is_gem_vram(struct ttm_buffer_object *bo)
return (bo->destroy == ttm_buffer_object_destroy); return (bo->destroy == ttm_buffer_object_destroy);
} }
/** static void drm_gem_vram_bo_driver_evict_flags(struct drm_gem_vram_object *gbo,
* drm_gem_vram_bo_driver_evict_flags() - \ struct ttm_placement *pl)
Implements &struct ttm_bo_driver.evict_flags
* @bo: TTM buffer object. Refers to &struct drm_gem_vram_object.bo
* @pl: TTM placement information.
*/
void drm_gem_vram_bo_driver_evict_flags(struct ttm_buffer_object *bo,
struct ttm_placement *pl)
{ {
struct drm_gem_vram_object *gbo;
/* TTM may pass BOs that are not GEM VRAM BOs. */
if (!drm_is_gem_vram(bo))
return;
gbo = drm_gem_vram_of_bo(bo);
drm_gem_vram_placement(gbo, TTM_PL_FLAG_SYSTEM); drm_gem_vram_placement(gbo, TTM_PL_FLAG_SYSTEM);
*pl = gbo->placement; *pl = gbo->placement;
} }
EXPORT_SYMBOL(drm_gem_vram_bo_driver_evict_flags);
/** static int drm_gem_vram_bo_driver_verify_access(struct drm_gem_vram_object *gbo,
* drm_gem_vram_bo_driver_verify_access() - \ struct file *filp)
Implements &struct ttm_bo_driver.verify_access
* @bo: TTM buffer object. Refers to &struct drm_gem_vram_object.bo
* @filp: File pointer.
*
* Returns:
* 0 on success, or
* a negative errno code otherwise.
*/
int drm_gem_vram_bo_driver_verify_access(struct ttm_buffer_object *bo,
struct file *filp)
{ {
struct drm_gem_vram_object *gbo = drm_gem_vram_of_bo(bo);
return drm_vma_node_verify_access(&gbo->bo.base.vma_node, return drm_vma_node_verify_access(&gbo->bo.base.vma_node,
filp->private_data); filp->private_data);
} }
EXPORT_SYMBOL(drm_gem_vram_bo_driver_verify_access);
/** static void drm_gem_vram_bo_driver_move_notify(struct drm_gem_vram_object *gbo,
* drm_gem_vram_bo_driver_move_notify() - bool evict,
* Implements &struct ttm_bo_driver.move_notify struct ttm_mem_reg *new_mem)
* @bo: TTM buffer object. Refers to &struct drm_gem_vram_object.bo
* @evict: True, if the BO is being evicted from graphics memory;
* false otherwise.
* @new_mem: New memory region, or NULL on destruction
*/
void drm_gem_vram_bo_driver_move_notify(struct ttm_buffer_object *bo,
bool evict,
struct ttm_mem_reg *new_mem)
{ {
struct drm_gem_vram_object *gbo; struct ttm_bo_kmap_obj *kmap = &gbo->kmap;
struct ttm_bo_kmap_obj *kmap;
/* TTM may pass BOs that are not GEM VRAM BOs. */
if (!drm_is_gem_vram(bo))
return;
gbo = drm_gem_vram_of_bo(bo);
kmap = &gbo->kmap;
if (WARN_ON_ONCE(gbo->kmap_use_count)) if (WARN_ON_ONCE(gbo->kmap_use_count))
return; return;
...@@ -535,21 +491,6 @@ void drm_gem_vram_bo_driver_move_notify(struct ttm_buffer_object *bo, ...@@ -535,21 +491,6 @@ void drm_gem_vram_bo_driver_move_notify(struct ttm_buffer_object *bo,
ttm_bo_kunmap(kmap); ttm_bo_kunmap(kmap);
kmap->virtual = NULL; kmap->virtual = NULL;
} }
EXPORT_SYMBOL(drm_gem_vram_bo_driver_move_notify);
/*
* drm_gem_vram_mm_funcs - Functions for &struct drm_vram_mm
*
* Most users of @struct drm_gem_vram_object will also use
* @struct drm_vram_mm. This instance of &struct drm_vram_mm_funcs
* can be used to connect both.
*/
const struct drm_vram_mm_funcs drm_gem_vram_mm_funcs = {
.evict_flags = drm_gem_vram_bo_driver_evict_flags,
.verify_access = drm_gem_vram_bo_driver_verify_access,
.move_notify = drm_gem_vram_bo_driver_move_notify,
};
EXPORT_SYMBOL(drm_gem_vram_mm_funcs);
/* /*
* Helpers for struct drm_gem_object_funcs * Helpers for struct drm_gem_object_funcs
...@@ -815,31 +756,44 @@ static int bo_driver_init_mem_type(struct ttm_bo_device *bdev, uint32_t type, ...@@ -815,31 +756,44 @@ static int bo_driver_init_mem_type(struct ttm_bo_device *bdev, uint32_t type,
static void bo_driver_evict_flags(struct ttm_buffer_object *bo, static void bo_driver_evict_flags(struct ttm_buffer_object *bo,
struct ttm_placement *placement) struct ttm_placement *placement)
{ {
struct drm_vram_mm *vmm = drm_vram_mm_of_bdev(bo->bdev); struct drm_gem_vram_object *gbo;
if (vmm->funcs && vmm->funcs->evict_flags) /* TTM may pass BOs that are not GEM VRAM BOs. */
vmm->funcs->evict_flags(bo, placement); if (!drm_is_gem_vram(bo))
return;
gbo = drm_gem_vram_of_bo(bo);
drm_gem_vram_bo_driver_evict_flags(gbo, placement);
} }
static int bo_driver_verify_access(struct ttm_buffer_object *bo, static int bo_driver_verify_access(struct ttm_buffer_object *bo,
struct file *filp) struct file *filp)
{ {
struct drm_vram_mm *vmm = drm_vram_mm_of_bdev(bo->bdev); struct drm_gem_vram_object *gbo;
if (!vmm->funcs || !vmm->funcs->verify_access) /* TTM may pass BOs that are not GEM VRAM BOs. */
return 0; if (!drm_is_gem_vram(bo))
return vmm->funcs->verify_access(bo, filp); return -EINVAL;
gbo = drm_gem_vram_of_bo(bo);
return drm_gem_vram_bo_driver_verify_access(gbo, filp);
} }
static void bo_driver_move_notify(struct ttm_buffer_object *bo, static void bo_driver_move_notify(struct ttm_buffer_object *bo,
bool evict, bool evict,
struct ttm_mem_reg *new_mem) struct ttm_mem_reg *new_mem)
{ {
struct drm_vram_mm *vmm = drm_vram_mm_of_bdev(bo->bdev); struct drm_gem_vram_object *gbo;
if (!vmm->funcs || !vmm->funcs->move_notify) /* TTM may pass BOs that are not GEM VRAM BOs. */
if (!drm_is_gem_vram(bo))
return; return;
vmm->funcs->move_notify(bo, evict, new_mem);
gbo = drm_gem_vram_of_bo(bo);
drm_gem_vram_bo_driver_move_notify(gbo, evict, new_mem);
} }
static int bo_driver_io_mem_reserve(struct ttm_bo_device *bdev, static int bo_driver_io_mem_reserve(struct ttm_bo_device *bdev,
...@@ -941,21 +895,18 @@ EXPORT_SYMBOL(drm_vram_mm_debugfs_init); ...@@ -941,21 +895,18 @@ EXPORT_SYMBOL(drm_vram_mm_debugfs_init);
* @dev: the DRM device * @dev: the DRM device
* @vram_base: the base address of the video memory * @vram_base: the base address of the video memory
* @vram_size: the size of the video memory in bytes * @vram_size: the size of the video memory in bytes
* @funcs: callback functions for buffer objects
* *
* Returns: * Returns:
* 0 on success, or * 0 on success, or
* a negative error code otherwise. * a negative error code otherwise.
*/ */
int drm_vram_mm_init(struct drm_vram_mm *vmm, struct drm_device *dev, int drm_vram_mm_init(struct drm_vram_mm *vmm, struct drm_device *dev,
uint64_t vram_base, size_t vram_size, uint64_t vram_base, size_t vram_size)
const struct drm_vram_mm_funcs *funcs)
{ {
int ret; int ret;
vmm->vram_base = vram_base; vmm->vram_base = vram_base;
vmm->vram_size = vram_size; vmm->vram_size = vram_size;
vmm->funcs = funcs;
ret = ttm_bo_device_init(&vmm->bdev, &bo_driver, ret = ttm_bo_device_init(&vmm->bdev, &bo_driver,
dev->anon_inode->i_mapping, dev->anon_inode->i_mapping,
...@@ -1009,15 +960,13 @@ EXPORT_SYMBOL(drm_vram_mm_mmap); ...@@ -1009,15 +960,13 @@ EXPORT_SYMBOL(drm_vram_mm_mmap);
* @dev: the DRM device * @dev: the DRM device
* @vram_base: the base address of the video memory * @vram_base: the base address of the video memory
* @vram_size: the size of the video memory in bytes * @vram_size: the size of the video memory in bytes
* @funcs: callback functions for buffer objects
* *
* Returns: * Returns:
* The new instance of &struct drm_vram_mm on success, or * The new instance of &struct drm_vram_mm on success, or
* an ERR_PTR()-encoded errno code otherwise. * an ERR_PTR()-encoded errno code otherwise.
*/ */
struct drm_vram_mm *drm_vram_helper_alloc_mm( struct drm_vram_mm *drm_vram_helper_alloc_mm(
struct drm_device *dev, uint64_t vram_base, size_t vram_size, struct drm_device *dev, uint64_t vram_base, size_t vram_size)
const struct drm_vram_mm_funcs *funcs)
{ {
int ret; int ret;
...@@ -1028,7 +977,7 @@ struct drm_vram_mm *drm_vram_helper_alloc_mm( ...@@ -1028,7 +977,7 @@ struct drm_vram_mm *drm_vram_helper_alloc_mm(
if (!dev->vram_mm) if (!dev->vram_mm)
return ERR_PTR(-ENOMEM); return ERR_PTR(-ENOMEM);
ret = drm_vram_mm_init(dev->vram_mm, dev, vram_base, vram_size, funcs); ret = drm_vram_mm_init(dev->vram_mm, dev, vram_base, vram_size);
if (ret) if (ret)
goto err_kfree; goto err_kfree;
......
...@@ -7,9 +7,8 @@ ...@@ -7,9 +7,8 @@
* *
* This library provides &struct drm_gem_vram_object (GEM VRAM), a GEM * This library provides &struct drm_gem_vram_object (GEM VRAM), a GEM
* buffer object that is backed by video RAM. It can be used for * buffer object that is backed by video RAM. It can be used for
* framebuffer devices with dedicated memory. The video RAM can be * framebuffer devices with dedicated memory. The video RAM is managed
* managed with &struct drm_vram_mm (VRAM MM). Both data structures are * by &struct drm_vram_mm (VRAM MM).
* supposed to be used together, but can also be used individually.
* *
* With the GEM interface userspace applications create, manage and destroy * With the GEM interface userspace applications create, manage and destroy
* graphics buffers, such as an on-screen framebuffer. GEM does not provide * graphics buffers, such as an on-screen framebuffer. GEM does not provide
...@@ -50,8 +49,7 @@ ...@@ -50,8 +49,7 @@
* // setup device, vram base and size * // setup device, vram base and size
* // ... * // ...
* *
* ret = drm_vram_helper_alloc_mm(dev, vram_base, vram_size, * ret = drm_vram_helper_alloc_mm(dev, vram_base, vram_size);
* &drm_gem_vram_mm_funcs);
* if (ret) * if (ret)
* return ret; * return ret;
* return 0; * return 0;
......
...@@ -28,7 +28,7 @@ int hibmc_mm_init(struct hibmc_drm_private *hibmc) ...@@ -28,7 +28,7 @@ int hibmc_mm_init(struct hibmc_drm_private *hibmc)
vmm = drm_vram_helper_alloc_mm(dev, vmm = drm_vram_helper_alloc_mm(dev,
pci_resource_start(dev->pdev, 0), pci_resource_start(dev->pdev, 0),
hibmc->fb_size, &drm_gem_vram_mm_funcs); hibmc->fb_size);
if (IS_ERR(vmm)) { if (IS_ERR(vmm)) {
ret = PTR_ERR(vmm); ret = PTR_ERR(vmm);
DRM_ERROR("Error initializing VRAM MM; %d\n", ret); DRM_ERROR("Error initializing VRAM MM; %d\n", ret);
......
...@@ -37,8 +37,7 @@ int mgag200_mm_init(struct mga_device *mdev) ...@@ -37,8 +37,7 @@ int mgag200_mm_init(struct mga_device *mdev)
struct drm_device *dev = mdev->dev; struct drm_device *dev = mdev->dev;
vmm = drm_vram_helper_alloc_mm(dev, pci_resource_start(dev->pdev, 0), vmm = drm_vram_helper_alloc_mm(dev, pci_resource_start(dev->pdev, 0),
mdev->mc.vram_size, mdev->mc.vram_size);
&drm_gem_vram_mm_funcs);
if (IS_ERR(vmm)) { if (IS_ERR(vmm)) {
ret = PTR_ERR(vmm); ret = PTR_ERR(vmm);
DRM_ERROR("Error initializing VRAM MM; %d\n", ret); DRM_ERROR("Error initializing VRAM MM; %d\n", ret);
......
...@@ -17,8 +17,7 @@ int vbox_mm_init(struct vbox_private *vbox) ...@@ -17,8 +17,7 @@ int vbox_mm_init(struct vbox_private *vbox)
struct drm_device *dev = &vbox->ddev; struct drm_device *dev = &vbox->ddev;
vmm = drm_vram_helper_alloc_mm(dev, pci_resource_start(dev->pdev, 0), vmm = drm_vram_helper_alloc_mm(dev, pci_resource_start(dev->pdev, 0),
vbox->available_vram_size, vbox->available_vram_size);
&drm_gem_vram_mm_funcs);
if (IS_ERR(vmm)) { if (IS_ERR(vmm)) {
ret = PTR_ERR(vmm); ret = PTR_ERR(vmm);
DRM_ERROR("Error initializing VRAM MM; %d\n", ret); DRM_ERROR("Error initializing VRAM MM; %d\n", ret);
......
...@@ -109,22 +109,6 @@ int drm_gem_vram_fill_create_dumb(struct drm_file *file, ...@@ -109,22 +109,6 @@ int drm_gem_vram_fill_create_dumb(struct drm_file *file,
bool interruptible, bool interruptible,
struct drm_mode_create_dumb *args); struct drm_mode_create_dumb *args);
/*
* Helpers for struct ttm_bo_driver
*/
void drm_gem_vram_bo_driver_evict_flags(struct ttm_buffer_object *bo,
struct ttm_placement *pl);
void drm_gem_vram_bo_driver_move_notify(struct ttm_buffer_object *bo,
bool evict,
struct ttm_mem_reg *new_mem);
int drm_gem_vram_bo_driver_verify_access(struct ttm_buffer_object *bo,
struct file *filp);
extern const struct drm_vram_mm_funcs drm_gem_vram_mm_funcs;
/* /*
* Helpers for struct drm_driver * Helpers for struct drm_driver
*/ */
...@@ -170,8 +154,6 @@ struct drm_vram_mm { ...@@ -170,8 +154,6 @@ struct drm_vram_mm {
size_t vram_size; size_t vram_size;
struct ttm_bo_device bdev; struct ttm_bo_device bdev;
const struct drm_vram_mm_funcs *funcs;
}; };
/** /**
...@@ -190,8 +172,7 @@ static inline struct drm_vram_mm *drm_vram_mm_of_bdev( ...@@ -190,8 +172,7 @@ static inline struct drm_vram_mm *drm_vram_mm_of_bdev(
int drm_vram_mm_debugfs_init(struct drm_minor *minor); int drm_vram_mm_debugfs_init(struct drm_minor *minor);
int drm_vram_mm_init(struct drm_vram_mm *vmm, struct drm_device *dev, int drm_vram_mm_init(struct drm_vram_mm *vmm, struct drm_device *dev,
uint64_t vram_base, size_t vram_size, uint64_t vram_base, size_t vram_size);
const struct drm_vram_mm_funcs *funcs);
void drm_vram_mm_cleanup(struct drm_vram_mm *vmm); void drm_vram_mm_cleanup(struct drm_vram_mm *vmm);
int drm_vram_mm_mmap(struct file *filp, struct vm_area_struct *vma, int drm_vram_mm_mmap(struct file *filp, struct vm_area_struct *vma,
...@@ -202,8 +183,7 @@ int drm_vram_mm_mmap(struct file *filp, struct vm_area_struct *vma, ...@@ -202,8 +183,7 @@ int drm_vram_mm_mmap(struct file *filp, struct vm_area_struct *vma,
*/ */
struct drm_vram_mm *drm_vram_helper_alloc_mm( struct drm_vram_mm *drm_vram_helper_alloc_mm(
struct drm_device *dev, uint64_t vram_base, size_t vram_size, struct drm_device *dev, uint64_t vram_base, size_t vram_size);
const struct drm_vram_mm_funcs *funcs);
void drm_vram_helper_release_mm(struct drm_device *dev); void drm_vram_helper_release_mm(struct drm_device *dev);
/* /*
......
/* SPDX-License-Identifier: GPL-2.0-or-later */
#ifndef DRM_VRAM_MM_HELPER_H
#define DRM_VRAM_MM_HELPER_H
#include <drm/drm_file.h>
#include <drm/drm_ioctl.h>
#include <drm/ttm/ttm_bo_driver.h>
struct drm_device;
/**
* struct drm_vram_mm_funcs - Callback functions for &struct drm_vram_mm
* @evict_flags: Provides an implementation for struct \
&ttm_bo_driver.evict_flags
* @verify_access: Provides an implementation for \
struct &ttm_bo_driver.verify_access
* @move_notify: Provides an implementation for
* struct &ttm_bo_driver.move_notify
*
* These callback function integrate VRAM MM with TTM buffer objects. New
* functions can be added if necessary.
*/
struct drm_vram_mm_funcs {
void (*evict_flags)(struct ttm_buffer_object *bo,
struct ttm_placement *placement);
int (*verify_access)(struct ttm_buffer_object *bo, struct file *filp);
void (*move_notify)(struct ttm_buffer_object *bo, bool evict,
struct ttm_mem_reg *new_mem);
};
#endif
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment