Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

+36 -23
+36 -23
drivers/gpu/drm/i915/i915_gem.c
··· 171 171 return 0; 172 172 } 173 173 174 + /* 175 + * Try to write quickly with an atomic kmap. Return true on success. 176 + * 177 + * If this fails (which includes a partial write), we'll redo the whole 178 + * thing with the slow version. 179 + * 180 + * This is a workaround for the low performance of iounmap (approximate 181 + * 10% cpu cost on normal 3D workloads). kmap_atomic on HIGHMEM kernels 182 + * happens to let us map card memory without taking IPIs. When the vmap 183 + * rework lands we should be able to dump this hack. 184 + */ 185 + static inline int fast_user_write(unsigned long pfn, char __user *user_data, int l) 186 + { 187 + #ifdef CONFIG_HIGHMEM 188 + unsigned long unwritten; 189 + char *vaddr_atomic; 190 + 191 + vaddr_atomic = kmap_atomic_pfn(pfn, KM_USER0); 192 + #if WATCH_PWRITE 193 + DRM_INFO("pwrite i %d o %d l %d pfn %ld vaddr %p\n", 194 + i, o, l, pfn, vaddr_atomic); 195 + #endif 196 + unwritten = __copy_from_user_inatomic_nocache(vaddr_atomic + o, user_data, l); 197 + kunmap_atomic(vaddr_atomic, KM_USER0); 198 + return !unwritten; 199 + #else 200 + return 0; 201 + #endif 202 + } 203 + 174 204 static int 175 205 i915_gem_gtt_pwrite(struct drm_device *dev, struct drm_gem_object *obj, 176 206 struct drm_i915_gem_pwrite *args, ··· 210 180 ssize_t remain; 211 181 loff_t offset; 212 182 char __user *user_data; 213 - char __iomem *vaddr; 214 - char *vaddr_atomic; 215 - int i, o, l; 216 183 int ret = 0; 217 - unsigned long pfn; 218 - unsigned long unwritten; 219 184 220 185 user_data = (char __user *) (uintptr_t) args->data_ptr; 221 186 remain = args->size; ··· 234 209 obj_priv->dirty = 1; 235 210 236 211 while (remain > 0) { 212 + unsigned long pfn; 213 + int i, o, l; 214 + 237 215 /* Operation in this page 238 216 * 239 217 * i = page number ··· 251 223 252 224 pfn = (dev->agp->base >> PAGE_SHIFT) + i; 253 225 254 - #ifdef CONFIG_HIGHMEM 255 - /* This is a workaround for the low performance of iounmap 256 - * (approximate 10% cpu cost on normal 3D workloads). 257 - * kmap_atomic on HIGHMEM kernels happens to let us map card 258 - * memory without taking IPIs. When the vmap rework lands 259 - * we should be able to dump this hack. 260 - */ 261 - vaddr_atomic = kmap_atomic_pfn(pfn, KM_USER0); 262 - #if WATCH_PWRITE 263 - DRM_INFO("pwrite i %d o %d l %d pfn %ld vaddr %p\n", 264 - i, o, l, pfn, vaddr_atomic); 265 - #endif 266 - unwritten = __copy_from_user_inatomic_nocache(vaddr_atomic + o, 267 - user_data, l); 268 - kunmap_atomic(vaddr_atomic, KM_USER0); 226 + if (!fast_user_write(pfn, user_data, l)) { 227 + unsigned long unwritten; 228 + char __iomem *vaddr; 269 229 270 - if (unwritten) 271 - #endif /* CONFIG_HIGHMEM */ 272 - { 273 230 vaddr = ioremap_wc(pfn << PAGE_SHIFT, PAGE_SIZE); 274 231 #if WATCH_PWRITE 275 232 DRM_INFO("pwrite slow i %d o %d l %d "