Re: [git pull] drm patches for 2.6.27-rc1

Previous message: [thread] [date] [author]
Next message: [thread] [date] [author]
From: Linus Torvalds
Date: Friday, October 17, 2008 - 3:43 pm

On Fri, 17 Oct 2008, Dave Airlie wrote:

Grr.

This whole merge series has been full of people sending me UNTESTED CRAP.

So what's the excuse _this_ time for adding all these stupid warnings to 
my build log? Did nobody test this?

  drivers/gpu/drm/drm_proc.c: In function ‘drm_gem_one_name_info’:
  drivers/gpu/drm/drm_proc.c:525: warning: format ‘%d’ expects type ‘int’, but argument 3 has type ‘size_t’
  drivers/gpu/drm/drm_proc.c:533: warning: format ‘%9d’ expects type ‘int’, but argument 4 has type ‘size_t’
  drivers/gpu/drm/i915/i915_gem.c: In function ‘i915_gem_gtt_pwrite’:
  drivers/gpu/drm/i915/i915_gem.c:184: warning: unused variable ‘vaddr_atomic’

and I wonder how many other warnings got added that I never even noticed 
because I don't build them?

And yes, it's not just warnings. One of thse is horribly bad code:

	nid->len += sprintf(&nid->buf[nid->len],
                            "%6d%9d%8d%9d\n",
                            obj->name, obj->size,
                            atomic_read(&obj->handlecount.refcount),
                            atomic_read(&obj->refcount.refcount));

where it's just wrong to use the field width as a separator. Because if 
the counts are big enough, the separator suddenly goes away!

So that format string should be

	"%6d %8zd %7d %8d\n"

instead. Which  gives the same output when you don't overflow, and doesn't 
have the overflow bug when you do.

As to that "vaddr_atomic" thing, the warning would have been avoided if 
you had just cleanly split up the optimistic fast case.

IOW, write cleaner code, and the warning just goes away on its own. 
Something like the appended. UNTESTED!

Hmm?

I really wish people were more careful, and took more pride in trying to 
write readable code, with small modular functions instead. And move those 
variables down to the block they are needed in.

Anyway, I pulled the thing, but _please_ test this cleanup and send it 
back to me if it passes your testing. Ok? 

			Linus

---
 drivers/gpu/drm/drm_proc.c      |    4 +-
 drivers/gpu/drm/i915/i915_gem.c |   59 +++++++++++++++++++++++---------------
 2 files changed, 38 insertions(+), 25 deletions(-)

diff --git a/drivers/gpu/drm/drm_proc.c b/drivers/gpu/drm/drm_proc.c
index d490db4..ae73b7f 100644
--- a/drivers/gpu/drm/drm_proc.c
+++ b/drivers/gpu/drm/drm_proc.c
@@ -522,12 +522,12 @@ static int drm_gem_one_name_info(int id, void *ptr, void *data)
 	struct drm_gem_object *obj = ptr;
 	struct drm_gem_name_info_data   *nid = data;
 
-	DRM_INFO("name %d size %d\n", obj->name, obj->size);
+	DRM_INFO("name %d size %zd\n", obj->name, obj->size);
 	if (nid->eof)
 		return 0;
 
 	nid->len += sprintf(&nid->buf[nid->len],
-			    "%6d%9d%8d%9d\n",
+			    "%6d %8zd %7d %8d\n",
 			    obj->name, obj->size,
 			    atomic_read(&obj->handlecount.refcount),
 			    atomic_read(&obj->refcount.refcount));
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index 9ac73dd..b8c8b2e 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 1;
+#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 "
--
Previous message: [thread] [date] [author]
Next message: [thread] [date] [author]

Messages in current thread:
[git pull] drm patches for 2.6.27-rc1, Dave Airlie, (Fri Oct 17, 2:29 pm)
Re: [git pull] drm patches for 2.6.27-rc1, Linus Torvalds, (Fri Oct 17, 3:43 pm)
Re: [git pull] drm patches for 2.6.27-rc1, Nick Piggin, (Fri Oct 17, 6:37 pm)
Re: [git pull] drm patches for 2.6.27-rc1, Eric Anholt, (Fri Oct 17, 7:10 pm)
Re: [git pull] drm patches for 2.6.27-rc1, Linus Torvalds, (Fri Oct 17, 7:47 pm)
Re: [git pull] drm patches for 2.6.27-rc1, Keith Packard, (Fri Oct 17, 8:49 pm)
Re: [git pull] drm patches for 2.6.27-rc1, Corbin Simpson, (Fri Oct 17, 11:44 pm)
Re: [git pull] drm patches for 2.6.27-rc1, Eric Anholt, (Sat Oct 18, 12:49 am)
Re: [git pull] drm patches for 2.6.27-rc1, Dave Airlie, (Sat Oct 18, 2:11 am)
Re: [git pull] drm patches for 2.6.27-rc1, Keith Packard, (Sat Oct 18, 12:11 pm)
Re: [git pull] drm patches for 2.6.27-rc1, Linus Torvalds, (Sat Oct 18, 12:31 pm)
Re: [git pull] drm patches for 2.6.27-rc1, Thomas Hellström, (Sat Oct 18, 1:07 pm)
Re: [git pull] drm patches for 2.6.27-rc1, Keith Packard, (Sat Oct 18, 1:20 pm)
Re: [git pull] drm patches for 2.6.27-rc1, Ingo Molnar, (Sat Oct 18, 1:37 pm)
Re: [git pull] drm patches for 2.6.27-rc1, Keith Packard, (Sat Oct 18, 2:51 pm)
Re: [git pull] drm patches for 2.6.27-rc1, Ingo Molnar, (Sat Oct 18, 3:32 pm)
Re: [git pull] drm patches for 2.6.27-rc1, Jon Smirl, (Sat Oct 18, 3:47 pm)
Re: [git pull] drm patches for 2.6.27-rc1, Linus Torvalds, (Sat Oct 18, 3:53 pm)
Re: [git pull] drm patches for 2.6.27-rc1, Keith Packard, (Sat Oct 18, 5:38 pm)
Re: [git pull] drm patches for 2.6.27-rc1, Arjan van de Ven, (Sat Oct 18, 6:06 pm)
Re: [git pull] drm patches for 2.6.27-rc1, Keith Packard, (Sat Oct 18, 6:15 pm)
Re: [git pull] drm patches for 2.6.27-rc1, Nick Piggin, (Sat Oct 18, 8:14 pm)
Re: [git pull] drm patches for 2.6.27-rc1, Keith Packard, (Sat Oct 18, 9:14 pm)
Re: [git pull] drm patches for 2.6.27-rc1, Yinghai Lu, (Sat Oct 18, 9:28 pm)
Re: [git pull] drm patches for 2.6.27-rc1, Keith Packard, (Sat Oct 18, 11:41 pm)
Re: [git pull] drm patches for 2.6.27-rc1, Peter Zijlstra, (Sun Oct 19, 10:52 am)
Re: io resources and cached mappings (was: [git pull] drm ..., Arjan van de Ven, (Sun Oct 19, 11:00 am)
Re: [git pull] drm patches for 2.6.27-rc1, Steven J Newbury, (Sun Oct 19, 9:17 pm)
Re: [git pull] drm patches for 2.6.27-rc1, Ingo Molnar, (Mon Oct 20, 3:01 am)
Re: [git pull] drm patches for 2.6.27-rc1, Linus Torvalds, (Mon Oct 20, 9:31 am)
Re: [git pull] drm patches for 2.6.27-rc1, Jesse Barnes, (Mon Oct 20, 1:04 pm)
Re: Adding kmap_atomic_prot_pfn (was: [git pull] drm patc ..., Benjamin Herrenschmidt, (Thu Oct 23, 8:21 pm)
Re: Adding kmap_atomic_prot_pfn (was: [git pull] drm patc ..., Benjamin Herrenschmidt, (Thu Oct 23, 8:24 pm)
Re: Adding kmap_atomic_prot_pfn , Thomas Hellström, (Fri Oct 24, 12:33 am)
Re: Adding kmap_atomic_prot_pfn, Ingo Molnar, (Fri Oct 24, 1:38 am)
Re: Adding kmap_atomic_prot_pfn, Thomas Hellström, (Fri Oct 24, 2:19 am)
Re: Adding kmap_atomic_prot_pfn, Ingo Molnar, (Fri Oct 24, 2:32 am)
Re: Adding kmap_atomic_prot_pfn, Thomas Hellström, (Fri Oct 24, 3:18 am)
Re: Adding kmap_atomic_prot_pfn, Thomas Hellström, (Fri Oct 24, 4:04 am)
Re: Adding kmap_atomic_prot_pfn, Keith Packard, (Fri Oct 24, 8:48 am)
[git pull] IO mappings, #2, Ingo Molnar, (Mon Nov 3, 10:29 am)
Re: [git pull] IO mappings, #2, Jonathan Corbet, (Tue Nov 4, 3:36 pm)
Re: [git pull] IO mappings, #2, Ingo Molnar, (Wed Nov 5, 2:01 am)