Memory manager init and takedown.

This commit is contained in:
Thomas Hellstrom 2006-08-30 13:04:08 +02:00
parent 033bda07e9
commit e47a4fda2e
8 changed files with 175 additions and 18 deletions

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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 */

View file

@ -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;
}

View file

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

View file

@ -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
/*@}*/