1 /*
2 * SPDX-License-Identifier: MIT
3 *
4 * Copyright © 2014-2016 Intel Corporation
5 */
6
7 #include "display/intel_frontbuffer.h"
8 #include "gt/intel_gt.h"
9
10 #include "i915_drv.h"
11 #include "i915_gem_clflush.h"
12 #include "i915_gem_domain.h"
13 #include "i915_gem_gtt.h"
14 #include "i915_gem_ioctls.h"
15 #include "i915_gem_lmem.h"
16 #include "i915_gem_mman.h"
17 #include "i915_gem_object.h"
18 #include "i915_vma.h"
19
gpu_write_needs_clflush(struct drm_i915_gem_object * obj)20 static bool gpu_write_needs_clflush(struct drm_i915_gem_object *obj)
21 {
22 struct drm_i915_private *i915 = to_i915(obj->base.dev);
23
24 if (IS_DGFX(i915))
25 return false;
26
27 return !(obj->cache_level == I915_CACHE_NONE ||
28 obj->cache_level == I915_CACHE_WT);
29 }
30
i915_gem_cpu_write_needs_clflush(struct drm_i915_gem_object * obj)31 bool i915_gem_cpu_write_needs_clflush(struct drm_i915_gem_object *obj)
32 {
33 struct drm_i915_private *i915 = to_i915(obj->base.dev);
34
35 if (obj->cache_dirty)
36 return false;
37
38 if (IS_DGFX(i915))
39 return false;
40
41 if (!(obj->cache_coherent & I915_BO_CACHE_COHERENT_FOR_WRITE))
42 return true;
43
44 /* Currently in use by HW (display engine)? Keep flushed. */
45 return i915_gem_object_is_framebuffer(obj);
46 }
47
48 static void
flush_write_domain(struct drm_i915_gem_object * obj,unsigned int flush_domains)49 flush_write_domain(struct drm_i915_gem_object *obj, unsigned int flush_domains)
50 {
51 struct i915_vma *vma;
52
53 assert_object_held(obj);
54
55 if (!(obj->write_domain & flush_domains))
56 return;
57
58 switch (obj->write_domain) {
59 case I915_GEM_DOMAIN_GTT:
60 spin_lock(&obj->vma.lock);
61 for_each_ggtt_vma(vma, obj) {
62 if (i915_vma_unset_ggtt_write(vma))
63 intel_gt_flush_ggtt_writes(vma->vm->gt);
64 }
65 spin_unlock(&obj->vma.lock);
66
67 i915_gem_object_flush_frontbuffer(obj, ORIGIN_CPU);
68 break;
69
70 case I915_GEM_DOMAIN_WC:
71 wmb();
72 break;
73
74 case I915_GEM_DOMAIN_CPU:
75 i915_gem_clflush_object(obj, I915_CLFLUSH_SYNC);
76 break;
77
78 case I915_GEM_DOMAIN_RENDER:
79 if (gpu_write_needs_clflush(obj))
80 obj->cache_dirty = true;
81 break;
82 }
83
84 obj->write_domain = 0;
85 }
86
__i915_gem_object_flush_for_display(struct drm_i915_gem_object * obj)87 static void __i915_gem_object_flush_for_display(struct drm_i915_gem_object *obj)
88 {
89 /*
90 * We manually flush the CPU domain so that we can override and
91 * force the flush for the display, and perform it asyncrhonously.
92 */
93 flush_write_domain(obj, ~I915_GEM_DOMAIN_CPU);
94 if (obj->cache_dirty)
95 i915_gem_clflush_object(obj, I915_CLFLUSH_FORCE);
96 obj->write_domain = 0;
97 }
98
i915_gem_object_flush_if_display(struct drm_i915_gem_object * obj)99 void i915_gem_object_flush_if_display(struct drm_i915_gem_object *obj)
100 {
101 if (!i915_gem_object_is_framebuffer(obj))
102 return;
103
104 i915_gem_object_lock(obj, NULL);
105 __i915_gem_object_flush_for_display(obj);
106 i915_gem_object_unlock(obj);
107 }
108
i915_gem_object_flush_if_display_locked(struct drm_i915_gem_object * obj)109 void i915_gem_object_flush_if_display_locked(struct drm_i915_gem_object *obj)
110 {
111 if (i915_gem_object_is_framebuffer(obj))
112 __i915_gem_object_flush_for_display(obj);
113 }
114
115 /**
116 * Moves a single object to the WC read, and possibly write domain.
117 * @obj: object to act on
118 * @write: ask for write access or read only
119 *
120 * This function returns when the move is complete, including waiting on
121 * flushes to occur.
122 */
123 int
i915_gem_object_set_to_wc_domain(struct drm_i915_gem_object * obj,bool write)124 i915_gem_object_set_to_wc_domain(struct drm_i915_gem_object *obj, bool write)
125 {
126 int ret;
127
128 assert_object_held(obj);
129
130 ret = i915_gem_object_wait(obj,
131 I915_WAIT_INTERRUPTIBLE |
132 (write ? I915_WAIT_ALL : 0),
133 MAX_SCHEDULE_TIMEOUT);
134 if (ret)
135 return ret;
136
137 if (obj->write_domain == I915_GEM_DOMAIN_WC)
138 return 0;
139
140 /* Flush and acquire obj->pages so that we are coherent through
141 * direct access in memory with previous cached writes through
142 * shmemfs and that our cache domain tracking remains valid.
143 * For example, if the obj->filp was moved to swap without us
144 * being notified and releasing the pages, we would mistakenly
145 * continue to assume that the obj remained out of the CPU cached
146 * domain.
147 */
148 ret = i915_gem_object_pin_pages(obj);
149 if (ret)
150 return ret;
151
152 flush_write_domain(obj, ~I915_GEM_DOMAIN_WC);
153
154 /* Serialise direct access to this object with the barriers for
155 * coherent writes from the GPU, by effectively invalidating the
156 * WC domain upon first access.
157 */
158 if ((obj->read_domains & I915_GEM_DOMAIN_WC) == 0)
159 mb();
160
161 /* It should now be out of any other write domains, and we can update
162 * the domain values for our changes.
163 */
164 GEM_BUG_ON((obj->write_domain & ~I915_GEM_DOMAIN_WC) != 0);
165 obj->read_domains |= I915_GEM_DOMAIN_WC;
166 if (write) {
167 obj->read_domains = I915_GEM_DOMAIN_WC;
168 obj->write_domain = I915_GEM_DOMAIN_WC;
169 obj->mm.dirty = true;
170 }
171
172 i915_gem_object_unpin_pages(obj);
173 return 0;
174 }
175
176 /**
177 * Moves a single object to the GTT read, and possibly write domain.
178 * @obj: object to act on
179 * @write: ask for write access or read only
180 *
181 * This function returns when the move is complete, including waiting on
182 * flushes to occur.
183 */
184 int
i915_gem_object_set_to_gtt_domain(struct drm_i915_gem_object * obj,bool write)185 i915_gem_object_set_to_gtt_domain(struct drm_i915_gem_object *obj, bool write)
186 {
187 int ret;
188
189 assert_object_held(obj);
190
191 ret = i915_gem_object_wait(obj,
192 I915_WAIT_INTERRUPTIBLE |
193 (write ? I915_WAIT_ALL : 0),
194 MAX_SCHEDULE_TIMEOUT);
195 if (ret)
196 return ret;
197
198 if (obj->write_domain == I915_GEM_DOMAIN_GTT)
199 return 0;
200
201 /* Flush and acquire obj->pages so that we are coherent through
202 * direct access in memory with previous cached writes through
203 * shmemfs and that our cache domain tracking remains valid.
204 * For example, if the obj->filp was moved to swap without us
205 * being notified and releasing the pages, we would mistakenly
206 * continue to assume that the obj remained out of the CPU cached
207 * domain.
208 */
209 ret = i915_gem_object_pin_pages(obj);
210 if (ret)
211 return ret;
212
213 flush_write_domain(obj, ~I915_GEM_DOMAIN_GTT);
214
215 /* Serialise direct access to this object with the barriers for
216 * coherent writes from the GPU, by effectively invalidating the
217 * GTT domain upon first access.
218 */
219 if ((obj->read_domains & I915_GEM_DOMAIN_GTT) == 0)
220 mb();
221
222 /* It should now be out of any other write domains, and we can update
223 * the domain values for our changes.
224 */
225 GEM_BUG_ON((obj->write_domain & ~I915_GEM_DOMAIN_GTT) != 0);
226 obj->read_domains |= I915_GEM_DOMAIN_GTT;
227 if (write) {
228 struct i915_vma *vma;
229
230 obj->read_domains = I915_GEM_DOMAIN_GTT;
231 obj->write_domain = I915_GEM_DOMAIN_GTT;
232 obj->mm.dirty = true;
233
234 spin_lock(&obj->vma.lock);
235 for_each_ggtt_vma(vma, obj)
236 if (i915_vma_is_bound(vma, I915_VMA_GLOBAL_BIND))
237 i915_vma_set_ggtt_write(vma);
238 spin_unlock(&obj->vma.lock);
239 }
240
241 i915_gem_object_unpin_pages(obj);
242 return 0;
243 }
244
245 /**
246 * Changes the cache-level of an object across all VMA.
247 * @obj: object to act on
248 * @cache_level: new cache level to set for the object
249 *
250 * After this function returns, the object will be in the new cache-level
251 * across all GTT and the contents of the backing storage will be coherent,
252 * with respect to the new cache-level. In order to keep the backing storage
253 * coherent for all users, we only allow a single cache level to be set
254 * globally on the object and prevent it from being changed whilst the
255 * hardware is reading from the object. That is if the object is currently
256 * on the scanout it will be set to uncached (or equivalent display
257 * cache coherency) and all non-MOCS GPU access will also be uncached so
258 * that all direct access to the scanout remains coherent.
259 */
i915_gem_object_set_cache_level(struct drm_i915_gem_object * obj,enum i915_cache_level cache_level)260 int i915_gem_object_set_cache_level(struct drm_i915_gem_object *obj,
261 enum i915_cache_level cache_level)
262 {
263 int ret;
264
265 if (obj->cache_level == cache_level)
266 return 0;
267
268 ret = i915_gem_object_wait(obj,
269 I915_WAIT_INTERRUPTIBLE |
270 I915_WAIT_ALL,
271 MAX_SCHEDULE_TIMEOUT);
272 if (ret)
273 return ret;
274
275 /* Always invalidate stale cachelines */
276 if (obj->cache_level != cache_level) {
277 i915_gem_object_set_cache_coherency(obj, cache_level);
278 obj->cache_dirty = true;
279 }
280
281 /* The cache-level will be applied when each vma is rebound. */
282 return i915_gem_object_unbind(obj,
283 I915_GEM_OBJECT_UNBIND_ACTIVE |
284 I915_GEM_OBJECT_UNBIND_BARRIER);
285 }
286
i915_gem_get_caching_ioctl(struct drm_device * dev,void * data,struct drm_file * file)287 int i915_gem_get_caching_ioctl(struct drm_device *dev, void *data,
288 struct drm_file *file)
289 {
290 struct drm_i915_gem_caching *args = data;
291 struct drm_i915_gem_object *obj;
292 int err = 0;
293
294 if (IS_DGFX(to_i915(dev)))
295 return -ENODEV;
296
297 rcu_read_lock();
298 obj = i915_gem_object_lookup_rcu(file, args->handle);
299 if (!obj) {
300 err = -ENOENT;
301 goto out;
302 }
303
304 switch (obj->cache_level) {
305 case I915_CACHE_LLC:
306 case I915_CACHE_L3_LLC:
307 args->caching = I915_CACHING_CACHED;
308 break;
309
310 case I915_CACHE_WT:
311 args->caching = I915_CACHING_DISPLAY;
312 break;
313
314 default:
315 args->caching = I915_CACHING_NONE;
316 break;
317 }
318 out:
319 rcu_read_unlock();
320 return err;
321 }
322
i915_gem_set_caching_ioctl(struct drm_device * dev,void * data,struct drm_file * file)323 int i915_gem_set_caching_ioctl(struct drm_device *dev, void *data,
324 struct drm_file *file)
325 {
326 struct drm_i915_private *i915 = to_i915(dev);
327 struct drm_i915_gem_caching *args = data;
328 struct drm_i915_gem_object *obj;
329 enum i915_cache_level level;
330 int ret = 0;
331
332 if (IS_DGFX(i915))
333 return -ENODEV;
334
335 switch (args->caching) {
336 case I915_CACHING_NONE:
337 level = I915_CACHE_NONE;
338 break;
339 case I915_CACHING_CACHED:
340 /*
341 * Due to a HW issue on BXT A stepping, GPU stores via a
342 * snooped mapping may leave stale data in a corresponding CPU
343 * cacheline, whereas normally such cachelines would get
344 * invalidated.
345 */
346 if (!HAS_LLC(i915) && !HAS_SNOOP(i915))
347 return -ENODEV;
348
349 level = I915_CACHE_LLC;
350 break;
351 case I915_CACHING_DISPLAY:
352 level = HAS_WT(i915) ? I915_CACHE_WT : I915_CACHE_NONE;
353 break;
354 default:
355 return -EINVAL;
356 }
357
358 obj = i915_gem_object_lookup(file, args->handle);
359 if (!obj)
360 return -ENOENT;
361
362 /*
363 * The caching mode of proxy object is handled by its generator, and
364 * not allowed to be changed by userspace.
365 */
366 if (i915_gem_object_is_proxy(obj)) {
367 /*
368 * Silently allow cached for userptr; the vulkan driver
369 * sets all objects to cached
370 */
371 if (!i915_gem_object_is_userptr(obj) ||
372 args->caching != I915_CACHING_CACHED)
373 ret = -ENXIO;
374
375 goto out;
376 }
377
378 ret = i915_gem_object_lock_interruptible(obj, NULL);
379 if (ret)
380 goto out;
381
382 ret = i915_gem_object_set_cache_level(obj, level);
383 i915_gem_object_unlock(obj);
384
385 out:
386 i915_gem_object_put(obj);
387 return ret;
388 }
389
390 /*
391 * Prepare buffer for display plane (scanout, cursors, etc). Can be called from
392 * an uninterruptible phase (modesetting) and allows any flushes to be pipelined
393 * (for pageflips). We only flush the caches while preparing the buffer for
394 * display, the callers are responsible for frontbuffer flush.
395 */
396 struct i915_vma *
i915_gem_object_pin_to_display_plane(struct drm_i915_gem_object * obj,struct i915_gem_ww_ctx * ww,u32 alignment,const struct i915_gtt_view * view,unsigned int flags)397 i915_gem_object_pin_to_display_plane(struct drm_i915_gem_object *obj,
398 struct i915_gem_ww_ctx *ww,
399 u32 alignment,
400 const struct i915_gtt_view *view,
401 unsigned int flags)
402 {
403 struct drm_i915_private *i915 = to_i915(obj->base.dev);
404 struct i915_vma *vma;
405 int ret;
406
407 /* Frame buffer must be in LMEM */
408 if (HAS_LMEM(i915) && !i915_gem_object_is_lmem(obj))
409 return ERR_PTR(-EINVAL);
410
411 /*
412 * The display engine is not coherent with the LLC cache on gen6. As
413 * a result, we make sure that the pinning that is about to occur is
414 * done with uncached PTEs. This is lowest common denominator for all
415 * chipsets.
416 *
417 * However for gen6+, we could do better by using the GFDT bit instead
418 * of uncaching, which would allow us to flush all the LLC-cached data
419 * with that bit in the PTE to main memory with just one PIPE_CONTROL.
420 */
421 ret = i915_gem_object_set_cache_level(obj,
422 HAS_WT(i915) ?
423 I915_CACHE_WT : I915_CACHE_NONE);
424 if (ret)
425 return ERR_PTR(ret);
426
427 /*
428 * As the user may map the buffer once pinned in the display plane
429 * (e.g. libkms for the bootup splash), we have to ensure that we
430 * always use map_and_fenceable for all scanout buffers. However,
431 * it may simply be too big to fit into mappable, in which case
432 * put it anyway and hope that userspace can cope (but always first
433 * try to preserve the existing ABI).
434 */
435 vma = ERR_PTR(-ENOSPC);
436 if ((flags & PIN_MAPPABLE) == 0 &&
437 (!view || view->type == I915_GTT_VIEW_NORMAL))
438 vma = i915_gem_object_ggtt_pin_ww(obj, ww, view, 0, alignment,
439 flags | PIN_MAPPABLE |
440 PIN_NONBLOCK);
441 if (IS_ERR(vma) && vma != ERR_PTR(-EDEADLK))
442 vma = i915_gem_object_ggtt_pin_ww(obj, ww, view, 0,
443 alignment, flags);
444 if (IS_ERR(vma))
445 return vma;
446
447 vma->display_alignment = max_t(u64, vma->display_alignment, alignment);
448 i915_vma_mark_scanout(vma);
449
450 i915_gem_object_flush_if_display_locked(obj);
451
452 return vma;
453 }
454
455 /**
456 * Moves a single object to the CPU read, and possibly write domain.
457 * @obj: object to act on
458 * @write: requesting write or read-only access
459 *
460 * This function returns when the move is complete, including waiting on
461 * flushes to occur.
462 */
463 int
i915_gem_object_set_to_cpu_domain(struct drm_i915_gem_object * obj,bool write)464 i915_gem_object_set_to_cpu_domain(struct drm_i915_gem_object *obj, bool write)
465 {
466 int ret;
467
468 assert_object_held(obj);
469
470 ret = i915_gem_object_wait(obj,
471 I915_WAIT_INTERRUPTIBLE |
472 (write ? I915_WAIT_ALL : 0),
473 MAX_SCHEDULE_TIMEOUT);
474 if (ret)
475 return ret;
476
477 flush_write_domain(obj, ~I915_GEM_DOMAIN_CPU);
478
479 /* Flush the CPU cache if it's still invalid. */
480 if ((obj->read_domains & I915_GEM_DOMAIN_CPU) == 0) {
481 i915_gem_clflush_object(obj, I915_CLFLUSH_SYNC);
482 obj->read_domains |= I915_GEM_DOMAIN_CPU;
483 }
484
485 /* It should now be out of any other write domains, and we can update
486 * the domain values for our changes.
487 */
488 GEM_BUG_ON(obj->write_domain & ~I915_GEM_DOMAIN_CPU);
489
490 /* If we're writing through the CPU, then the GPU read domains will
491 * need to be invalidated at next use.
492 */
493 if (write)
494 __start_cpu_write(obj);
495
496 return 0;
497 }
498
499 /**
500 * Called when user space prepares to use an object with the CPU, either
501 * through the mmap ioctl's mapping or a GTT mapping.
502 * @dev: drm device
503 * @data: ioctl data blob
504 * @file: drm file
505 */
506 int
i915_gem_set_domain_ioctl(struct drm_device * dev,void * data,struct drm_file * file)507 i915_gem_set_domain_ioctl(struct drm_device *dev, void *data,
508 struct drm_file *file)
509 {
510 struct drm_i915_gem_set_domain *args = data;
511 struct drm_i915_gem_object *obj;
512 u32 read_domains = args->read_domains;
513 u32 write_domain = args->write_domain;
514 int err;
515
516 if (IS_DGFX(to_i915(dev)))
517 return -ENODEV;
518
519 /* Only handle setting domains to types used by the CPU. */
520 if ((write_domain | read_domains) & I915_GEM_GPU_DOMAINS)
521 return -EINVAL;
522
523 /*
524 * Having something in the write domain implies it's in the read
525 * domain, and only that read domain. Enforce that in the request.
526 */
527 if (write_domain && read_domains != write_domain)
528 return -EINVAL;
529
530 if (!read_domains)
531 return 0;
532
533 obj = i915_gem_object_lookup(file, args->handle);
534 if (!obj)
535 return -ENOENT;
536
537 /*
538 * Try to flush the object off the GPU without holding the lock.
539 * We will repeat the flush holding the lock in the normal manner
540 * to catch cases where we are gazumped.
541 */
542 err = i915_gem_object_wait(obj,
543 I915_WAIT_INTERRUPTIBLE |
544 I915_WAIT_PRIORITY |
545 (write_domain ? I915_WAIT_ALL : 0),
546 MAX_SCHEDULE_TIMEOUT);
547 if (err)
548 goto out;
549
550 if (i915_gem_object_is_userptr(obj)) {
551 /*
552 * Try to grab userptr pages, iris uses set_domain to check
553 * userptr validity
554 */
555 err = i915_gem_object_userptr_validate(obj);
556 if (!err)
557 err = i915_gem_object_wait(obj,
558 I915_WAIT_INTERRUPTIBLE |
559 I915_WAIT_PRIORITY |
560 (write_domain ? I915_WAIT_ALL : 0),
561 MAX_SCHEDULE_TIMEOUT);
562 goto out;
563 }
564
565 /*
566 * Proxy objects do not control access to the backing storage, ergo
567 * they cannot be used as a means to manipulate the cache domain
568 * tracking for that backing storage. The proxy object is always
569 * considered to be outside of any cache domain.
570 */
571 if (i915_gem_object_is_proxy(obj)) {
572 err = -ENXIO;
573 goto out;
574 }
575
576 err = i915_gem_object_lock_interruptible(obj, NULL);
577 if (err)
578 goto out;
579
580 /*
581 * Flush and acquire obj->pages so that we are coherent through
582 * direct access in memory with previous cached writes through
583 * shmemfs and that our cache domain tracking remains valid.
584 * For example, if the obj->filp was moved to swap without us
585 * being notified and releasing the pages, we would mistakenly
586 * continue to assume that the obj remained out of the CPU cached
587 * domain.
588 */
589 err = i915_gem_object_pin_pages(obj);
590 if (err)
591 goto out_unlock;
592
593 /*
594 * Already in the desired write domain? Nothing for us to do!
595 *
596 * We apply a little bit of cunning here to catch a broader set of
597 * no-ops. If obj->write_domain is set, we must be in the same
598 * obj->read_domains, and only that domain. Therefore, if that
599 * obj->write_domain matches the request read_domains, we are
600 * already in the same read/write domain and can skip the operation,
601 * without having to further check the requested write_domain.
602 */
603 if (READ_ONCE(obj->write_domain) == read_domains)
604 goto out_unpin;
605
606 if (read_domains & I915_GEM_DOMAIN_WC)
607 err = i915_gem_object_set_to_wc_domain(obj, write_domain);
608 else if (read_domains & I915_GEM_DOMAIN_GTT)
609 err = i915_gem_object_set_to_gtt_domain(obj, write_domain);
610 else
611 err = i915_gem_object_set_to_cpu_domain(obj, write_domain);
612
613 out_unpin:
614 i915_gem_object_unpin_pages(obj);
615
616 out_unlock:
617 i915_gem_object_unlock(obj);
618
619 if (!err && write_domain)
620 i915_gem_object_invalidate_frontbuffer(obj, ORIGIN_CPU);
621
622 out:
623 i915_gem_object_put(obj);
624 return err;
625 }
626
627 /*
628 * Pins the specified object's pages and synchronizes the object with
629 * GPU accesses. Sets needs_clflush to non-zero if the caller should
630 * flush the object from the CPU cache.
631 */
i915_gem_object_prepare_read(struct drm_i915_gem_object * obj,unsigned int * needs_clflush)632 int i915_gem_object_prepare_read(struct drm_i915_gem_object *obj,
633 unsigned int *needs_clflush)
634 {
635 int ret;
636
637 *needs_clflush = 0;
638 if (!i915_gem_object_has_struct_page(obj))
639 return -ENODEV;
640
641 assert_object_held(obj);
642
643 ret = i915_gem_object_wait(obj,
644 I915_WAIT_INTERRUPTIBLE,
645 MAX_SCHEDULE_TIMEOUT);
646 if (ret)
647 return ret;
648
649 ret = i915_gem_object_pin_pages(obj);
650 if (ret)
651 return ret;
652
653 if (obj->cache_coherent & I915_BO_CACHE_COHERENT_FOR_READ ||
654 !static_cpu_has(X86_FEATURE_CLFLUSH)) {
655 ret = i915_gem_object_set_to_cpu_domain(obj, false);
656 if (ret)
657 goto err_unpin;
658 else
659 goto out;
660 }
661
662 flush_write_domain(obj, ~I915_GEM_DOMAIN_CPU);
663
664 /* If we're not in the cpu read domain, set ourself into the gtt
665 * read domain and manually flush cachelines (if required). This
666 * optimizes for the case when the gpu will dirty the data
667 * anyway again before the next pread happens.
668 */
669 if (!obj->cache_dirty &&
670 !(obj->read_domains & I915_GEM_DOMAIN_CPU))
671 *needs_clflush = CLFLUSH_BEFORE;
672
673 out:
674 /* return with the pages pinned */
675 return 0;
676
677 err_unpin:
678 i915_gem_object_unpin_pages(obj);
679 return ret;
680 }
681
i915_gem_object_prepare_write(struct drm_i915_gem_object * obj,unsigned int * needs_clflush)682 int i915_gem_object_prepare_write(struct drm_i915_gem_object *obj,
683 unsigned int *needs_clflush)
684 {
685 int ret;
686
687 *needs_clflush = 0;
688 if (!i915_gem_object_has_struct_page(obj))
689 return -ENODEV;
690
691 assert_object_held(obj);
692
693 ret = i915_gem_object_wait(obj,
694 I915_WAIT_INTERRUPTIBLE |
695 I915_WAIT_ALL,
696 MAX_SCHEDULE_TIMEOUT);
697 if (ret)
698 return ret;
699
700 ret = i915_gem_object_pin_pages(obj);
701 if (ret)
702 return ret;
703
704 if (obj->cache_coherent & I915_BO_CACHE_COHERENT_FOR_WRITE ||
705 !static_cpu_has(X86_FEATURE_CLFLUSH)) {
706 ret = i915_gem_object_set_to_cpu_domain(obj, true);
707 if (ret)
708 goto err_unpin;
709 else
710 goto out;
711 }
712
713 flush_write_domain(obj, ~I915_GEM_DOMAIN_CPU);
714
715 /* If we're not in the cpu write domain, set ourself into the
716 * gtt write domain and manually flush cachelines (as required).
717 * This optimizes for the case when the gpu will use the data
718 * right away and we therefore have to clflush anyway.
719 */
720 if (!obj->cache_dirty) {
721 *needs_clflush |= CLFLUSH_AFTER;
722
723 /*
724 * Same trick applies to invalidate partially written
725 * cachelines read before writing.
726 */
727 if (!(obj->read_domains & I915_GEM_DOMAIN_CPU))
728 *needs_clflush |= CLFLUSH_BEFORE;
729 }
730
731 out:
732 i915_gem_object_invalidate_frontbuffer(obj, ORIGIN_CPU);
733 obj->mm.dirty = true;
734 /* return with the pages pinned */
735 return 0;
736
737 err_unpin:
738 i915_gem_object_unpin_pages(obj);
739 return ret;
740 }
741