summaryrefslogtreecommitdiffstats
path: root/drivers/gpu
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2008-10-20 23:16:43 +0200
committerLinus Torvalds <torvalds@linux-foundation.org>2008-10-20 23:16:43 +0200
commit9b7530cc329eb036cfa589930c270e85031f554c (patch)
tree3d8fad63c228e988a65b344be42ba9e0c7ed8e56 /drivers/gpu
parentFix sprintf format warnings in drm_proc.c (diff)
downloadlinux-9b7530cc329eb036cfa589930c270e85031f554c.tar.xz
linux-9b7530cc329eb036cfa589930c270e85031f554c.zip
i915: cleanup coding horrors in i915_gem_gtt_pwrite()
Yes, this will probably be switched over to a cleaner model anyway, but in the meantime I don't want to see the 'unused variable' warnings that come from the disgusting #ifdef code. Make the special case be a nice inlien function of its own, clean up the code, and make the warning go away. I wish people didn't write code that gets (valid) warnings from the compiler, but I'll limit my fixes to code that I actually care about (in this case just because I see the warning and it annoys me). Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'drivers/gpu')
-rw-r--r--drivers/gpu/drm/i915/i915_gem.c59
1 files changed, 36 insertions, 23 deletions
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index 9ac73dd1b422..49c5a1798ac4 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -171,6 +171,36 @@ i915_gem_pread_ioctl(struct drm_device *dev, void *data,
return 0;
}
+/*
+ * Try to write quickly with an atomic kmap. Return true on success.
+ *
+ * If this fails (which includes a partial write), we'll redo the whole
+ * thing with the slow version.
+ *
+ * This is a workaround for the low performance of iounmap (approximate
+ * 10% cpu cost on normal 3D workloads). kmap_atomic on HIGHMEM kernels
+ * happens to let us map card memory without taking IPIs. When the vmap
+ * rework lands we should be able to dump this hack.
+ */
+static inline int fast_user_write(unsigned long pfn, char __user *user_data, int l)
+{
+#ifdef CONFIG_HIGHMEM
+ unsigned long unwritten;
+ char *vaddr_atomic;
+
+ vaddr_atomic = kmap_atomic_pfn(pfn, KM_USER0);
+#if WATCH_PWRITE
+ DRM_INFO("pwrite i %d o %d l %d pfn %ld vaddr %p\n",
+ i, o, l, pfn, vaddr_atomic);
+#endif
+ unwritten = __copy_from_user_inatomic_nocache(vaddr_atomic + o, user_data, l);
+ kunmap_atomic(vaddr_atomic, KM_USER0);
+ return !unwritten;
+#else
+ return 0;
+#endif
+}
+
static int
i915_gem_gtt_pwrite(struct drm_device *dev, struct drm_gem_object *obj,
struct drm_i915_gem_pwrite *args,
@@ -180,12 +210,7 @@ i915_gem_gtt_pwrite(struct drm_device *dev, struct drm_gem_object *obj,
ssize_t remain;
loff_t offset;
char __user *user_data;
- char __iomem *vaddr;
- char *vaddr_atomic;
- int i, o, l;
int ret = 0;
- unsigned long pfn;
- unsigned long unwritten;
user_data = (char __user *) (uintptr_t) args->data_ptr;
remain = args->size;
@@ -209,6 +234,9 @@ i915_gem_gtt_pwrite(struct drm_device *dev, struct drm_gem_object *obj,
obj_priv->dirty = 1;
while (remain > 0) {
+ unsigned long pfn;
+ int i, o, l;
+
/* Operation in this page
*
* i = page number
@@ -223,25 +251,10 @@ i915_gem_gtt_pwrite(struct drm_device *dev, struct drm_gem_object *obj,
pfn = (dev->agp->base >> PAGE_SHIFT) + i;
-#ifdef CONFIG_HIGHMEM
- /* This is a workaround for the low performance of iounmap
- * (approximate 10% cpu cost on normal 3D workloads).
- * kmap_atomic on HIGHMEM kernels happens to let us map card
- * memory without taking IPIs. When the vmap rework lands
- * we should be able to dump this hack.
- */
- vaddr_atomic = kmap_atomic_pfn(pfn, KM_USER0);
-#if WATCH_PWRITE
- DRM_INFO("pwrite i %d o %d l %d pfn %ld vaddr %p\n",
- i, o, l, pfn, vaddr_atomic);
-#endif
- unwritten = __copy_from_user_inatomic_nocache(vaddr_atomic + o,
- user_data, l);
- kunmap_atomic(vaddr_atomic, KM_USER0);
+ if (!fast_user_write(pfn, user_data, l)) {
+ unsigned long unwritten;
+ char __iomem *vaddr;
- if (unwritten)
-#endif /* CONFIG_HIGHMEM */
- {
vaddr = ioremap_wc(pfn << PAGE_SHIFT, PAGE_SIZE);
#if WATCH_PWRITE
DRM_INFO("pwrite slow i %d o %d l %d "