OSDN Git Service

Make the user_token 44-bit for TTMs, and have them occupy a unique file space
authorThomas Hellstrom <thomas-at-tungstengraphics-dot-com>
Mon, 2 Oct 2006 13:06:35 +0000 (15:06 +0200)
committerThomas Hellstrom <thomas-at-tungstengraphics-dot-com>
Mon, 2 Oct 2006 13:06:35 +0000 (15:06 +0200)
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
libdrm/xf86drm.c
linux-core/drm_ttm.c

index 69b111f..b5d7945 100644 (file)
@@ -30,6 +30,7 @@ AC_PROG_LIBTOOL
 AC_PROG_CC
 
 AC_HEADER_STDC
+AC_SYS_LARGEFILE
 
 pkgconfigdir=${libdir}/pkgconfig
 AC_SUBST(pkgconfigdir)
index ab884eb..bce913d 100644 (file)
@@ -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;
index 5fbe283..311c57f 100644 (file)
@@ -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;