From eacedf41a65f135722e7bee6f1a66a803619237f Mon Sep 17 00:00:00 2001 From: Thomas Hellstrom Date: Mon, 2 Oct 2006 15:06:35 +0200 Subject: Make the user_token 44-bit for TTMs, and have them occupy a unique file space starting at 0x00100000000. This will hopefully allow us to use unmap_mapping_range(). Note that user-space will need 64-bit file offset support. --- configure.ac | 1 + libdrm/xf86drm.c | 13 ++++++++++--- linux-core/drm_ttm.c | 24 +++++++++++++++++++----- 3 files changed, 30 insertions(+), 8 deletions(-) diff --git a/configure.ac b/configure.ac index 69b111fb..b5d79456 100644 --- a/configure.ac +++ b/configure.ac @@ -30,6 +30,7 @@ AC_PROG_LIBTOOL AC_PROG_CC AC_HEADER_STDC +AC_SYS_LARGEFILE pkgconfigdir=${libdir}/pkgconfig AC_SUBST(pkgconfigdir) diff --git a/libdrm/xf86drm.c b/libdrm/xf86drm.c index ab884eb5..bce913d3 100644 --- a/libdrm/xf86drm.c +++ b/libdrm/xf86drm.c @@ -46,6 +46,9 @@ # include # endif #else +# ifdef HAVE_CONFIG_H +# include +# endif # include # include # include @@ -2804,7 +2807,7 @@ int drmBOUnReference(int fd, drmBO *buf) if (buf->mapVirtual && (buf->type != drm_bo_type_fake)) { - (void) drmUnmap(buf->mapVirtual, buf->start + buf->size); + (void) munmap(buf->mapVirtual, buf->start + buf->size); buf->mapVirtual = NULL; buf->virtual = NULL; } @@ -2847,8 +2850,12 @@ int drmBOMap(int fd, drmBO *buf, unsigned mapFlags, unsigned mapHint, if (!buf->virtual && buf->type != drm_bo_type_fake) { drmAddress virtual; - ret = drmMap(fd, buf->mapHandle, buf->size + buf->start, &virtual); - if (ret) + virtual = mmap(0, buf->size + buf->start, + PROT_READ | PROT_WRITE, MAP_SHARED, + fd, buf->mapHandle); + if (virtual == MAP_FAILED) + ret = -errno; + if (ret) return ret; buf->mapVirtual = virtual; buf->virtual = ((char *) virtual) + buf->start; diff --git a/linux-core/drm_ttm.c b/linux-core/drm_ttm.c index 5fbe283e..311c57fa 100644 --- a/linux-core/drm_ttm.c +++ b/linux-core/drm_ttm.c @@ -817,6 +817,11 @@ static void drm_ttm_object_remove(drm_device_t * dev, drm_ttm_object_t * object) if (list->user_token) drm_ht_remove_item(&dev->map_hash, &list->hash); + if (list->file_offset_node) { + drm_mm_put_block(&dev->offset_manager, list->file_offset_node); + list->file_offset_node = NULL; + } + map = list->map; if (map) { @@ -901,15 +906,24 @@ int drm_ttm_object_create(drm_device_t * dev, unsigned long size, map->size = ttm->num_pages * PAGE_SIZE; map->handle = (void *)object; - if (drm_ht_just_insert_please(&dev->map_hash, &list->hash, - (unsigned long)map->handle, - 32 - PAGE_SHIFT - 3, 0, - DRM_MAP_HASH_OFFSET >> PAGE_SHIFT)) { + list->file_offset_node = drm_mm_search_free(&dev->offset_manager, + ttm->num_pages, + 0,0); + if (!list->file_offset_node) { + drm_ttm_object_remove(dev, object); + return -ENOMEM; + } + list->file_offset_node = drm_mm_get_block(list->file_offset_node, + ttm->num_pages,0); + + list->hash.key = list->file_offset_node->start; + + if (drm_ht_insert_item(&dev->map_hash, &list->hash)) { drm_ttm_object_remove(dev, object); return -ENOMEM; } - list->user_token = list->hash.key << PAGE_SHIFT; + list->user_token = ((drm_u64_t) list->hash.key) << PAGE_SHIFT; atomic_set(&object->usage, 1); *ttm_object = object; -- cgit v1.2.3