Ok, we clearly need to deal with mapping subsets of the graphics
aperture, both for discrete graphics cards and for 2D on tiled surfaces.
Plus, there are reasons for using WC object mappings which is easily
done through the aperture.

I haven't spend a huge amount of time thinking about this, but I figured
I'd prod people into discussion to try and sort things out.

First off, here's what I think I want.

We expose mmap ioctls on the gem objects, and I'd like to use the same
basic mechanism; when (if?) gem objects become "real" files, we would
want to continue using the same interface. I suggest creating two mmap
windows for main memory objects:

0x00000000-0x7fffffff: map the backing pages directly
0x80000000-0xffffffff: map the object through the aperture

I don't quite know what to do with discrete card memory; suggestions
here are welcome from people who've thought about this more than I.

Using these two per-object windows means there isn't any need to manage
a synthetic linear address space for some global object (like the DRM
fd).

Next, we need to hook the mmap path in the driver so that our code can
get a chance to play. I attached something that might work.

Once we've got an mmap request, here's what I think we want to do:

     1. Detect an aperture mapping request (bit 31)
     2. Map the object to the aperture (speculating that the app will
        actually use it)
     3. Initialize the vma to point at the aperture physical address
        range

If the object remains mapped to the GTT, there's nothing else to do
until the unmap request comes along at which point we tear down the vma.

If the object gets unmapped from the GTT, we need to go find every VMA
mapping it and fix up their PTEs to be unreadable/writable. I'm hoping
this won't kill performance, but I'm fairly sure this will require an
IPI to get the TLBs flushed on every core. Right? At least there won't
be a cache flush as well.

Now, if the application touches any one of those pages, we should map
the whole object back to the GTT and rewrite the PTEs again. We could do
this a page at a time, but I don't see any real benefit as we have to
allocate the aperture space anyways, and it shouldn't be that much more
expensive to fix up a lot of PTEs than to fix up just one.

I think that's the whole story here; am I missing any big pieces?

-- 
[EMAIL PROTECTED]
commit 0eb8c53640406c08b5a304d09bf08079b53eef84
Author: Keith Packard <[EMAIL PROTECTED]>
Date:   Tue Jul 29 20:19:28 2008 -0700

    Start adding gtt mapping ioctls

diff --git a/linux-core/i915_gem.c b/linux-core/i915_gem.c
index 236203a..f187361 100644
--- a/linux-core/i915_gem.c
+++ b/linux-core/i915_gem.c
@@ -85,6 +85,23 @@ i915_gem_init_ioctl(struct drm_device *dev, void *data,
 }
 
 
+static struct file_operations i915_gem_file_operations;
+
+#define I915_GEM_MAP_GTT_BASE	(1 << 31)
+
+static int i915_gem_mmap(struct file *file, struct vm_area_struct *vma)
+{
+	struct drm_device *dev = file->private_data;
+	drm_i915_private_t *dev_priv = dev->dev_private;
+	
+	DRM_INFO("mmap %08lx\n", vma->vm_start);
+	if (vma->vm_start & I915_GEM_MAP_GTT_BASE)
+		return -ENODEV;
+	else
+		return dev_priv->shmem_mmap (file, vma);
+}
+
+
 /**
  * Creates a new mm object and returns a handle to it.
  */
@@ -103,6 +120,16 @@ i915_gem_create_ioctl(struct drm_device *dev, void *data,
 	if (obj == NULL)
 		return -ENOMEM;
 
+	obj->filp->private_data = dev;
+	spin_lock(&dev->object_name_lock);
+	if (i915_gem_file_operations.mmap == NULL) {
+		dev->shmem_mmap = obj->filp->f_path.dentry->d_inode->i_fop->mmap;
+		i915_gem_file_operations = *obj->filp->f_path.dentry->d_inode->i_fop;
+		i915_gem_file_operations.mmap = i915_gem_mmap;
+	}
+	obj->filp->f_path.dentry->d_inode->i_fop = &i915_gem_file_operations;
+	spin_unlock(&dev->object_name_lock);
+
 	ret = drm_gem_handle_create(file_priv, obj, &handle);
 	mutex_lock(&dev->struct_mutex);
 	drm_gem_object_handle_unreference(obj);
diff --git a/shared-core/i915_drv.h b/shared-core/i915_drv.h
index a9a431c..a577292 100644
--- a/shared-core/i915_drv.h
+++ b/shared-core/i915_drv.h
@@ -321,6 +321,9 @@ typedef struct drm_i915_private {
 		uint32_t bit_6_swizzle_x;
 		/** Bit 6 swizzling required for Y tiling */
 		uint32_t bit_6_swizzle_y;
+
+		/** shmem_mmap isn't public, but we discover it by magic */
+		int (*shmem_mmap) (struct file *file, struct vm_area_struct *vma);
 	} mm;
 } drm_i915_private_t;
 

Attachment: signature.asc
Description: This is a digitally signed message part

-------------------------------------------------------------------------
This SF.Net email is sponsored by the Moblin Your Move Developer's challenge
Build the coolest Linux based applications with Moblin SDK & win great prizes
Grand prize is a trip for two to an Open Source event anywhere in the world
http://moblin-contest.org/redirect.php?banner_id=100&url=/
--
_______________________________________________
Dri-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/dri-devel

Reply via email to