From a31046b8734f12ed22127ef5f6ca4fc33df72ec1 Mon Sep 17 00:00:00 2001 From: Thomas Hellstrom Date: Mon, 2 Oct 2006 14:03:15 +0200 Subject: [PATCH] Add a buffer object manager for TTM maps. --- linux-core/drmP.h | 43 +++++++++++++++++++++++++------------------ linux-core/drm_drv.c | 1 + linux-core/drm_stub.c | 11 +++++++++-- 3 files changed, 35 insertions(+), 20 deletions(-) diff --git a/linux-core/drmP.h b/linux-core/drmP.h index 8b3364e4..f17a3421 100644 --- a/linux-core/drmP.h +++ b/linux-core/drmP.h @@ -163,6 +163,10 @@ #define DRM_MAX_CTXBITMAP (PAGE_SIZE * 8) #define DRM_MAP_HASH_OFFSET 0x10000000 +#define DRM_MAP_HASH_ORDER 12 +#define DRM_OBJECT_HASH_ORDER 12 +#define DRM_FILE_PAGE_OFFSET_START ((0xFFFFFFFFUL >> PAGE_SHIFT) + 1) +#define DRM_FILE_PAGE_OFFSET_SIZE ((0xFFFFFFFFUL >> PAGE_SHIFT) * 16) /*@}*/ @@ -532,6 +536,25 @@ typedef struct drm_sigdata { drm_hw_lock_t *lock; } drm_sigdata_t; + +/* + * Generic memory manager structs + */ + +typedef struct drm_mm_node { + struct list_head fl_entry; + struct list_head ml_entry; + int free; + unsigned long start; + unsigned long size; + void *private; +} drm_mm_node_t; + +typedef struct drm_mm { + drm_mm_node_t root_node; +} drm_mm_t; + + /** * Mappings list */ @@ -540,6 +563,7 @@ typedef struct drm_map_list { drm_hash_item_t hash; drm_map_t *map; /**< mapping */ drm_u64_t user_token; + drm_mm_node_t *file_offset_node; } drm_map_list_t; typedef drm_map_t drm_local_map_t; @@ -572,24 +596,6 @@ typedef struct ati_pcigart_info { drm_local_map_t mapping; } drm_ati_pcigart_info; -/* - * Generic memory manager structs - */ - -typedef struct drm_mm_node { - struct list_head fl_entry; - struct list_head ml_entry; - int free; - unsigned long start; - unsigned long size; - void *private; -} drm_mm_node_t; - -typedef struct drm_mm { - drm_mm_node_t root_node; -} drm_mm_t; - - /* * User space objects and their references. */ @@ -866,6 +872,7 @@ typedef struct drm_device { drm_map_list_t *maplist; /**< Linked list of regions */ int map_count; /**< Number of mappable regions */ drm_open_hash_t map_hash; /**< User token hash table for maps */ + drm_mm_t offset_manager; /**< User token manager */ drm_open_hash_t object_hash; /**< User token hash table for objects */ /** \name Context handle management */ diff --git a/linux-core/drm_drv.c b/linux-core/drm_drv.c index 37539f34..ae0c37a5 100644 --- a/linux-core/drm_drv.c +++ b/linux-core/drm_drv.c @@ -377,6 +377,7 @@ static void drm_cleanup(drm_device_t * dev) drm_free(dev->maplist, sizeof(*dev->maplist), DRM_MEM_MAPS); dev->maplist = NULL; drm_ht_remove(&dev->map_hash); + drm_mm_takedown(&dev->offset_manager); drm_ht_remove(&dev->object_hash); } diff --git a/linux-core/drm_stub.c b/linux-core/drm_stub.c index 5d28284c..1b406fef 100644 --- a/linux-core/drm_stub.c +++ b/linux-core/drm_stub.c @@ -83,14 +83,21 @@ static int drm_fill_in_dev(drm_device_t * dev, struct pci_dev *pdev, if (dev->maplist == NULL) return -ENOMEM; INIT_LIST_HEAD(&dev->maplist->head); - if (drm_ht_create(&dev->map_hash, 12)) { + if (drm_ht_create(&dev->map_hash, DRM_MAP_HASH_ORDER)) { drm_free(dev->maplist, sizeof(*dev->maplist), DRM_MEM_MAPS); return -ENOMEM; } + if (drm_mm_init(&dev->offset_manager, DRM_FILE_PAGE_OFFSET_START, + DRM_FILE_PAGE_OFFSET_SIZE)) { + drm_free(dev->maplist, sizeof(*dev->maplist), DRM_MEM_MAPS); + drm_ht_remove(&dev->map_hash); + return -ENOMEM; + } - if (drm_ht_create(&dev->object_hash, 12)) { + if (drm_ht_create(&dev->object_hash, DRM_OBJECT_HASH_ORDER)) { drm_free(dev->maplist, sizeof(*dev->maplist), DRM_MEM_MAPS); drm_ht_remove(&dev->map_hash); + drm_mm_takedown(&dev->offset_manager); return -ENOMEM; }