summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Hellstrom <thomas-at-tungstengraphics-dot-com>2006-10-02 15:06:35 +0200
committerThomas Hellstrom <thomas-at-tungstengraphics-dot-com>2006-10-02 15:06:35 +0200
commiteacedf41a65f135722e7bee6f1a66a803619237f (patch)
tree6b24f01790d18972f0b103ed4ec3d6246dd22435
parenta31046b8734f12ed22127ef5f6ca4fc33df72ec1 (diff)
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.
-rw-r--r--configure.ac1
-rw-r--r--libdrm/xf86drm.c13
-rw-r--r--linux-core/drm_ttm.c24
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 <sys/mman.h>
# endif
#else
+# ifdef HAVE_CONFIG_H
+# include <config.h>
+# endif
# include <stdio.h>
# include <stdlib.h>
# include <unistd.h>
@@ -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;