mirror of
https://gitlab.freedesktop.org/mesa/drm.git
synced 2025-12-30 06:10:15 +01:00
Memory manager init and takedown.
This commit is contained in:
parent
033bda07e9
commit
e47a4fda2e
8 changed files with 175 additions and 18 deletions
|
|
@ -26,6 +26,6 @@ AM_CFLAGS = -I$(top_srcdir)/shared-core
|
|||
libdrm_la_SOURCES = xf86drm.c xf86drmHash.c xf86drmRandom.c xf86drmSL.c
|
||||
|
||||
libdrmincludedir = ${includedir}
|
||||
libdrminclude_HEADERS = xf86drm.h
|
||||
libdrminclude_HEADERS = xf86drm.h xf86mm.h
|
||||
|
||||
EXTRA_DIST = ChangeLog TODO
|
||||
|
|
|
|||
|
|
@ -65,7 +65,6 @@
|
|||
# define _DRM_FREE free
|
||||
# include "drm.h"
|
||||
#endif
|
||||
#include "xf86mm.h"
|
||||
|
||||
|
||||
/* Not all systems have MAP_FAILED defined */
|
||||
|
|
@ -2582,6 +2581,7 @@ int drmBOCreate(int fd, drmTTM *ttm, unsigned long start, unsigned long size,
|
|||
buf->ttm = ttm;
|
||||
break;
|
||||
case drm_bo_type_dc:
|
||||
req->buffer_start = start;
|
||||
break;
|
||||
case drm_bo_type_user:
|
||||
req->buffer_start = (unsigned long) user_buffer;
|
||||
|
|
@ -2699,4 +2699,32 @@ int drmBOUnReference(int fd, drmBO *buf)
|
|||
return 0;
|
||||
}
|
||||
|
||||
int drmMMInit(int fd, unsigned long vramPOffset, unsigned long vramPSize,
|
||||
unsigned long ttPOffset, unsigned long ttPSize)
|
||||
{
|
||||
drm_mm_init_arg_t arg;
|
||||
|
||||
arg.req.op = mm_init;
|
||||
arg.req.vr_p_offset = vramPOffset;
|
||||
arg.req.vr_p_size = vramPSize;
|
||||
arg.req.tt_p_offset = vramPOffset;
|
||||
arg.req.tt_p_size = vramPSize;
|
||||
|
||||
if (ioctl(fd, DRM_IOCTL_MM_INIT, &arg))
|
||||
return -errno;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int drmMMTakedown(int fd)
|
||||
{
|
||||
drm_mm_init_arg_t arg;
|
||||
arg.req.op = mm_takedown;
|
||||
|
||||
if (ioctl(fd, DRM_IOCTL_MM_INIT, &arg))
|
||||
return -errno;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -670,4 +670,6 @@ extern int drmSLLookupNeighbors(void *l, unsigned long key,
|
|||
unsigned long *prev_key, void **prev_value,
|
||||
unsigned long *next_key, void **next_value);
|
||||
|
||||
#include "xf86mm.h"
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@
|
|||
#ifndef _XF86MM_H_
|
||||
#define _XF86MM_H_
|
||||
#include <stddef.h>
|
||||
#include "xf86drm.h"
|
||||
#include "drm.h"
|
||||
|
||||
/*
|
||||
* List macros heavily inspired by the Linux kernel
|
||||
|
|
@ -114,5 +114,12 @@ typedef struct _drmBOList {
|
|||
drmMMListHead free;
|
||||
} drmBOList;
|
||||
|
||||
extern int drmBOCreate(int fd, drmTTM *ttm, unsigned long start, unsigned long size,
|
||||
void *user_buffer, drm_bo_type_t type, unsigned mask,
|
||||
unsigned hint, drmBO *buf);
|
||||
extern int drmBODestroy(int fd, drmBO *buf);
|
||||
extern int drmBOReference(int fd, unsigned handle, drmBO *buf);
|
||||
extern int drmBOUnReference(int fd, drmBO *buf);
|
||||
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -775,7 +775,9 @@ typedef struct drm_fence_manager{
|
|||
|
||||
typedef struct drm_buffer_manager{
|
||||
int initialized;
|
||||
struct mutex bm_mutex;
|
||||
int has_vram;
|
||||
int has_tt;
|
||||
struct mutex mutex;
|
||||
drm_mm_t tt_manager;
|
||||
struct list_head tt_lru;
|
||||
drm_mm_t vram_manager;
|
||||
|
|
@ -1363,6 +1365,7 @@ extern int drm_fence_ioctl(DRM_IOCTL_ARGS);
|
|||
*/
|
||||
|
||||
extern int drm_bo_ioctl(DRM_IOCTL_ARGS);
|
||||
extern int drm_mm_init_ioctl(DRM_IOCTL_ARGS);
|
||||
|
||||
|
||||
/* Inline replacements for DRM_IOREMAP macros */
|
||||
|
|
|
|||
|
|
@ -66,7 +66,7 @@ int drm_fence_buffer_objects(drm_file_t * priv)
|
|||
drm_fence_object_t *fence;
|
||||
int ret;
|
||||
|
||||
mutex_lock(&bm->bm_mutex);
|
||||
mutex_lock(&bm->mutex);
|
||||
|
||||
list_for_each_entry(entry, &bm->unfenced, head) {
|
||||
BUG_ON(!entry->unfenced);
|
||||
|
|
@ -75,21 +75,21 @@ int drm_fence_buffer_objects(drm_file_t * priv)
|
|||
}
|
||||
|
||||
if (!count) {
|
||||
mutex_unlock(&bm->bm_mutex);
|
||||
mutex_unlock(&bm->mutex);
|
||||
return 0;
|
||||
}
|
||||
|
||||
fence = drm_calloc(1, sizeof(*fence), DRM_MEM_FENCE);
|
||||
|
||||
if (!fence) {
|
||||
mutex_unlock(&bm->bm_mutex);
|
||||
mutex_unlock(&bm->mutex);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
ret = drm_fence_object_init(dev, fence_flags, 1, fence);
|
||||
if (ret) {
|
||||
drm_free(fence, sizeof(*fence), DRM_MEM_FENCE);
|
||||
mutex_unlock(&bm->bm_mutex);
|
||||
mutex_unlock(&bm->mutex);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
@ -111,7 +111,7 @@ int drm_fence_buffer_objects(drm_file_t * priv)
|
|||
mutex_lock(&dev->struct_mutex);
|
||||
atomic_add(count - 1, &fence->usage);
|
||||
mutex_unlock(&dev->struct_mutex);
|
||||
mutex_unlock(&bm->bm_mutex);
|
||||
mutex_unlock(&bm->mutex);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -179,11 +179,12 @@ static void drm_bo_destroy_locked(drm_device_t * dev, drm_buffer_object_t * bo)
|
|||
drm_mm_put_block(&bm->vram_manager, bo->vram);
|
||||
bo->vram = NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* FIXME: Destroy ttm.
|
||||
*/
|
||||
|
||||
if (bo->ttm_region) {
|
||||
drm_destroy_ttm_region(bo->ttm_region);
|
||||
}
|
||||
if (bo->ttm_object) {
|
||||
drm_ttm_object_deref_locked(dev, bo->ttm_object);
|
||||
}
|
||||
drm_free(bo, sizeof(*bo), DRM_MEM_BUFOBJ);
|
||||
}
|
||||
|
||||
|
|
@ -356,8 +357,11 @@ drm_buffer_object_t *drm_lookup_buffer_object(drm_file_t * priv,
|
|||
|
||||
uo = drm_lookup_user_object(priv, handle);
|
||||
|
||||
if (!uo || (uo->type != drm_buffer_type))
|
||||
if (!uo || (uo->type != drm_buffer_type)) {
|
||||
DRM_ERROR("Could not find buffer object 0x%08x\n",
|
||||
handle);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (check_owner && priv != uo->owner) {
|
||||
if (!drm_lookup_ref_object(priv, uo, _DRM_REF_USE))
|
||||
|
|
@ -541,9 +545,10 @@ static void drm_buffer_user_object_unmap(drm_file_t * priv,
|
|||
}
|
||||
}
|
||||
|
||||
static int drm_buffer_object_validate(drm_device_t * dev,
|
||||
static int drm_buffer_object_validate(drm_device_t * dev, uint32_t new_flags,
|
||||
drm_buffer_object_t * bo)
|
||||
{
|
||||
bo->flags = new_flags;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -574,14 +579,18 @@ static int drm_bo_add_ttm(drm_file_t * priv, drm_buffer_object_t * bo,
|
|||
mutex_lock(&dev->struct_mutex);
|
||||
to = drm_lookup_ttm_object(priv, ttm_handle, 1);
|
||||
mutex_unlock(&dev->struct_mutex);
|
||||
if (!to)
|
||||
if (!to) {
|
||||
DRM_ERROR("Could not find TTM object\n");
|
||||
ret = -EINVAL;
|
||||
}
|
||||
break;
|
||||
case drm_bo_type_user:
|
||||
case drm_bo_type_fake:
|
||||
break;
|
||||
default:
|
||||
DRM_ERROR("Illegal buffer object type\n");
|
||||
ret = -EINVAL;
|
||||
break;
|
||||
}
|
||||
|
||||
if (ret) {
|
||||
|
|
@ -656,7 +665,7 @@ int drm_buffer_object_create(drm_file_t * priv,
|
|||
bo->mask = mask;
|
||||
bo->hint = hint;
|
||||
|
||||
ret = drm_buffer_object_validate(dev, bo);
|
||||
ret = drm_buffer_object_validate(dev, new_flags, bo);
|
||||
if (ret)
|
||||
goto out_err;
|
||||
|
||||
|
|
@ -805,3 +814,89 @@ int drm_bo_ioctl(DRM_IOCTL_ARGS)
|
|||
return 0;
|
||||
|
||||
}
|
||||
|
||||
static void drm_bo_clean_mm(drm_file_t *priv)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
int drm_mm_init_ioctl(DRM_IOCTL_ARGS)
|
||||
{
|
||||
DRM_DEVICE;
|
||||
|
||||
int ret = 0;
|
||||
drm_mm_init_arg_t arg;
|
||||
drm_buffer_manager_t *bm = &dev->bm;
|
||||
drm_bo_driver_t *driver = dev->driver->bo_driver;
|
||||
|
||||
if (!driver) {
|
||||
DRM_ERROR("Buffer objects is not supported by this driver\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
DRM_COPY_FROM_USER_IOCTL(arg, (void __user *)data, sizeof(arg));
|
||||
|
||||
switch(arg.req.op) {
|
||||
case mm_init:
|
||||
if (bm->initialized) {
|
||||
DRM_ERROR("Memory manager already initialized\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
mutex_init(&bm->mutex);
|
||||
mutex_lock(&bm->mutex);
|
||||
bm->has_vram = 0;
|
||||
bm->has_tt = 0;
|
||||
|
||||
if (arg.req.vr_p_size) {
|
||||
ret = drm_mm_init(&bm->vram_manager,
|
||||
arg.req.vr_p_offset,
|
||||
arg.req.vr_p_size);
|
||||
bm->has_vram = 1;
|
||||
if (ret)
|
||||
break;
|
||||
}
|
||||
|
||||
if (arg.req.tt_p_size) {
|
||||
ret = drm_mm_init(&bm->tt_manager,
|
||||
arg.req.tt_p_offset,
|
||||
arg.req.tt_p_size);
|
||||
bm->has_tt = 1;
|
||||
if (ret) {
|
||||
if (bm->has_vram)
|
||||
drm_mm_takedown(&bm->vram_manager);
|
||||
break;
|
||||
}
|
||||
}
|
||||
arg.rep.mm_sarea = 0;
|
||||
|
||||
INIT_LIST_HEAD(&bm->vram_lru);
|
||||
INIT_LIST_HEAD(&bm->tt_lru);
|
||||
INIT_LIST_HEAD(&bm->unfenced);
|
||||
INIT_LIST_HEAD(&bm->ddestroy);
|
||||
|
||||
bm->initialized = 1;
|
||||
break;
|
||||
case mm_takedown:
|
||||
if (!bm->initialized) {
|
||||
DRM_ERROR("Memory manager was not initialized\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
mutex_lock(&bm->mutex);
|
||||
drm_bo_clean_mm(priv);
|
||||
if (bm->has_vram)
|
||||
drm_mm_takedown(&bm->vram_manager);
|
||||
if (bm->has_tt)
|
||||
drm_mm_takedown(&bm->tt_manager);
|
||||
bm->initialized = 0;
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
mutex_unlock(&bm->mutex);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
DRM_COPY_TO_USER_IOCTL((void __user *)data, arg, sizeof(arg));
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -121,6 +121,9 @@ static drm_ioctl_desc_t drm_ioctls[] = {
|
|||
[DRM_IOCTL_NR(DRM_IOCTL_WAIT_VBLANK)] = {drm_wait_vblank, 0},
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_FENCE)] = {drm_fence_ioctl, DRM_AUTH},
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_TTM)] = {drm_ttm_ioctl, DRM_AUTH},
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_BUFOBJ)] = {drm_bo_ioctl, DRM_AUTH},
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_MM_INIT)] = {drm_mm_init_ioctl,
|
||||
DRM_AUTH | DRM_MASTER | DRM_ROOT_ONLY},
|
||||
};
|
||||
|
||||
#define DRIVER_IOCTL_COUNT ARRAY_SIZE( drm_ioctls )
|
||||
|
|
|
|||
|
|
@ -747,8 +747,26 @@ typedef union drm_bo_arg{
|
|||
drm_bo_arg_request_t req;
|
||||
drm_bo_arg_reply_t rep;
|
||||
} drm_bo_arg_t;
|
||||
|
||||
typedef union drm_mm_init_arg{
|
||||
struct {
|
||||
enum {
|
||||
mm_init,
|
||||
mm_takedown,
|
||||
mm_query
|
||||
} op;
|
||||
drm_u64_t vr_p_offset;
|
||||
drm_u64_t vr_p_size;
|
||||
drm_u64_t tt_p_offset;
|
||||
drm_u64_t tt_p_size;
|
||||
} req;
|
||||
struct {
|
||||
drm_handle_t mm_sarea;
|
||||
} rep;
|
||||
} drm_mm_init_arg_t;
|
||||
#endif
|
||||
|
||||
|
||||
/**
|
||||
* \name Ioctls Definitions
|
||||
*/
|
||||
|
|
@ -818,6 +836,7 @@ typedef union drm_bo_arg{
|
|||
#define DRM_IOCTL_FENCE DRM_IOWR(0x3b, drm_fence_arg_t)
|
||||
#define DRM_IOCTL_TTM DRM_IOWR(0x3c, drm_ttm_arg_t)
|
||||
#define DRM_IOCTL_BUFOBJ DRM_IOWR(0x3d, drm_bo_arg_t)
|
||||
#define DRM_IOCTL_MM_INIT DRM_IOWR(0x3e, drm_mm_init_arg_t)
|
||||
#endif
|
||||
|
||||
/*@}*/
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue