Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 9b7530cc authored by Linus Torvalds's avatar Linus Torvalds
Browse files

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: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent 1ae87786
Loading
Loading
Loading
Loading
+36 −23
Original line number Diff line number Diff line
@@ -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 "