i915_gem.c (271705) | i915_gem.c (277487) |
---|---|
1/*- 2 * Copyright �� 2008 Intel Corporation 3 * 4 * Permission is hereby granted, free of charge, to any person obtaining a 5 * copy of this software and associated documentation files (the "Software"), 6 * to deal in the Software without restriction, including without limitation 7 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 * and/or sell copies of the Software, and to permit persons to whom the --- 38 unchanged lines hidden (view full) --- 47 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 48 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 49 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 50 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 51 * SUCH DAMAGE. 52 */ 53 54#include <sys/cdefs.h> | 1/*- 2 * Copyright �� 2008 Intel Corporation 3 * 4 * Permission is hereby granted, free of charge, to any person obtaining a 5 * copy of this software and associated documentation files (the "Software"), 6 * to deal in the Software without restriction, including without limitation 7 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 * and/or sell copies of the Software, and to permit persons to whom the --- 38 unchanged lines hidden (view full) --- 47 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 48 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 49 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 50 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 51 * SUCH DAMAGE. 52 */ 53 54#include <sys/cdefs.h> |
55__FBSDID("$FreeBSD: head/sys/dev/drm2/i915/i915_gem.c 271705 2014-09-17 08:28:50Z dumbbell $"); | 55__FBSDID("$FreeBSD: head/sys/dev/drm2/i915/i915_gem.c 277487 2015-01-21 16:10:37Z kib $"); |
56 57#include <dev/drm2/drmP.h> 58#include <dev/drm2/drm.h> 59#include <dev/drm2/i915/i915_drm.h> 60#include <dev/drm2/i915/i915_drv.h> 61#include <dev/drm2/i915/intel_drv.h> 62#include <dev/drm2/i915/intel_ringbuffer.h> 63#include <sys/resourcevar.h> 64#include <sys/sched.h> 65#include <sys/sf_buf.h> 66 67#include <vm/vm.h> 68#include <vm/vm_pageout.h> 69 | 56 57#include <dev/drm2/drmP.h> 58#include <dev/drm2/drm.h> 59#include <dev/drm2/i915/i915_drm.h> 60#include <dev/drm2/i915/i915_drv.h> 61#include <dev/drm2/i915/intel_drv.h> 62#include <dev/drm2/i915/intel_ringbuffer.h> 63#include <sys/resourcevar.h> 64#include <sys/sched.h> 65#include <sys/sf_buf.h> 66 67#include <vm/vm.h> 68#include <vm/vm_pageout.h> 69 |
70#include <machine/md_var.h> 71 |
|
70static void i915_gem_object_flush_cpu_write_domain( 71 struct drm_i915_gem_object *obj); 72static uint32_t i915_gem_get_gtt_size(struct drm_device *dev, uint32_t size, 73 int tiling_mode); 74static uint32_t i915_gem_get_gtt_alignment(struct drm_device *dev, 75 uint32_t size, int tiling_mode); 76static int i915_gem_object_bind_to_gtt(struct drm_i915_gem_object *obj, 77 unsigned alignment, bool map_and_fenceable); 78static int i915_gem_object_get_pages_gtt(struct drm_i915_gem_object *obj, 79 int flags); 80static void i915_gem_object_put_pages_gtt(struct drm_i915_gem_object *obj); | 72static void i915_gem_object_flush_cpu_write_domain( 73 struct drm_i915_gem_object *obj); 74static uint32_t i915_gem_get_gtt_size(struct drm_device *dev, uint32_t size, 75 int tiling_mode); 76static uint32_t i915_gem_get_gtt_alignment(struct drm_device *dev, 77 uint32_t size, int tiling_mode); 78static int i915_gem_object_bind_to_gtt(struct drm_i915_gem_object *obj, 79 unsigned alignment, bool map_and_fenceable); 80static int i915_gem_object_get_pages_gtt(struct drm_i915_gem_object *obj, 81 int flags); 82static void i915_gem_object_put_pages_gtt(struct drm_i915_gem_object *obj); |
81static int i915_gem_object_set_to_cpu_domain(struct drm_i915_gem_object *obj, 82 bool write); 83static void i915_gem_object_set_to_full_cpu_read_domain( 84 struct drm_i915_gem_object *obj); 85static int i915_gem_object_set_cpu_read_domain_range( 86 struct drm_i915_gem_object *obj, uint64_t offset, uint64_t size); | 83static void i915_gem_object_put_pages_range(struct drm_i915_gem_object *obj, 84 off_t start, off_t end); 85static int i915_gem_object_get_pages_range(struct drm_i915_gem_object *obj, 86 off_t start, off_t end); |
87static void i915_gem_object_finish_gtt(struct drm_i915_gem_object *obj); 88static void i915_gem_object_truncate(struct drm_i915_gem_object *obj); 89static int i915_gem_object_is_purgeable(struct drm_i915_gem_object *obj); 90static bool i915_gem_object_is_inactive(struct drm_i915_gem_object *obj); 91static int i915_gem_object_needs_bit17_swizzle(struct drm_i915_gem_object *obj); | 87static void i915_gem_object_finish_gtt(struct drm_i915_gem_object *obj); 88static void i915_gem_object_truncate(struct drm_i915_gem_object *obj); 89static int i915_gem_object_is_purgeable(struct drm_i915_gem_object *obj); 90static bool i915_gem_object_is_inactive(struct drm_i915_gem_object *obj); 91static int i915_gem_object_needs_bit17_swizzle(struct drm_i915_gem_object *obj); |
92static vm_page_t i915_gem_wire_page(vm_object_t object, vm_pindex_t pindex); | 92static vm_page_t i915_gem_wire_page(vm_object_t object, vm_pindex_t pindex, 93 bool *fresh); |
93static void i915_gem_process_flushing_list(struct intel_ring_buffer *ring, 94 uint32_t flush_domains); | 94static void i915_gem_process_flushing_list(struct intel_ring_buffer *ring, 95 uint32_t flush_domains); |
95static void i915_gem_clear_fence_reg(struct drm_device *dev, 96 struct drm_i915_fence_reg *reg); | |
97static void i915_gem_reset_fences(struct drm_device *dev); 98static void i915_gem_retire_task_handler(void *arg, int pending); | 96static void i915_gem_reset_fences(struct drm_device *dev); 97static void i915_gem_retire_task_handler(void *arg, int pending); |
99static int i915_gem_phys_pwrite(struct drm_device *dev, 100 struct drm_i915_gem_object *obj, uint64_t data_ptr, uint64_t offset, 101 uint64_t size, struct drm_file *file_priv); | |
102static void i915_gem_lowmem(void *arg); | 98static void i915_gem_lowmem(void *arg); |
99static void i915_gem_write_fence(struct drm_device *dev, int reg, 100 struct drm_i915_gem_object *obj); 101static int __wait_seqno(struct intel_ring_buffer *ring, u32 seqno, 102 bool interruptible); 103static int i915_gem_check_olr(struct intel_ring_buffer *ring, u32 seqno); |
|
103 104MALLOC_DEFINE(DRM_I915_GEM, "i915gem", "Allocations from i915 gem"); 105long i915_gem_wired_pages_cnt; 106 | 104 105MALLOC_DEFINE(DRM_I915_GEM, "i915gem", "Allocations from i915 gem"); 106long i915_gem_wired_pages_cnt; 107 |
108static bool cpu_cache_is_coherent(struct drm_device *dev, 109 enum i915_cache_level level) 110{ 111 return HAS_LLC(dev) || level != I915_CACHE_NONE; 112} 113 114static bool cpu_write_needs_clflush(struct drm_i915_gem_object *obj) 115{ 116 if (!cpu_cache_is_coherent(obj->base.dev, obj->cache_level)) 117 return true; 118 119 return obj->pin_display; 120} 121 122static inline void i915_gem_object_fence_lost(struct drm_i915_gem_object *obj) 123{ 124 if (obj->tiling_mode) 125 i915_gem_release_mmap(obj); 126 127 /* As we do not have an associated fence register, we will force 128 * a tiling change if we ever need to acquire one. 129 */ 130 obj->fence_dirty = false; 131 obj->fence_reg = I915_FENCE_REG_NONE; 132} 133 |
|
107static void 108i915_gem_info_add_obj(struct drm_i915_private *dev_priv, size_t size) 109{ 110 111 dev_priv->mm.object_count++; 112 dev_priv->mm.object_memory += size; 113} 114 --- 52 unchanged lines hidden (view full) --- 167 ret = sx_xlock_sig(&dev->dev_struct_lock); 168 if (ret != 0) 169 return (-ret); 170 171 return (0); 172} 173 174 | 134static void 135i915_gem_info_add_obj(struct drm_i915_private *dev_priv, size_t size) 136{ 137 138 dev_priv->mm.object_count++; 139 dev_priv->mm.object_memory += size; 140} 141 --- 52 unchanged lines hidden (view full) --- 194 ret = sx_xlock_sig(&dev->dev_struct_lock); 195 if (ret != 0) 196 return (-ret); 197 198 return (0); 199} 200 201 |
175static void 176i915_gem_free_object_tail(struct drm_i915_gem_object *obj) | 202void 203i915_gem_free_object(struct drm_gem_object *gem_obj) |
177{ | 204{ |
205 struct drm_i915_gem_object *obj = to_intel_bo(gem_obj); |
|
178 struct drm_device *dev; 179 drm_i915_private_t *dev_priv; | 206 struct drm_device *dev; 207 drm_i915_private_t *dev_priv; |
180 int ret; | |
181 182 dev = obj->base.dev; 183 dev_priv = dev->dev_private; 184 | 208 209 dev = obj->base.dev; 210 dev_priv = dev->dev_private; 211 |
185 ret = i915_gem_object_unbind(obj); 186 if (ret == -ERESTART) { 187 list_move(&obj->mm_list, &dev_priv->mm.deferred_free_list); 188 return; | 212 CTR1(KTR_DRM, "object_destroy_tail %p", obj); 213 214 if (obj->phys_obj) 215 i915_gem_detach_phys_object(dev, obj); 216 217 obj->pin_count = 0; 218 if (i915_gem_object_unbind(obj) == -ERESTARTSYS) { 219 bool was_interruptible; 220 221 was_interruptible = dev_priv->mm.interruptible; 222 dev_priv->mm.interruptible = false; 223 224 if (i915_gem_object_unbind(obj)) 225 printf("i915_gem_free_object: unbind\n"); 226 227 dev_priv->mm.interruptible = was_interruptible; |
189 } 190 | 228 } 229 |
191 CTR1(KTR_DRM, "object_destroy_tail %p", obj); | |
192 drm_gem_free_mmap_offset(&obj->base); 193 drm_gem_object_release(&obj->base); 194 i915_gem_info_remove_obj(dev_priv, obj->base.size); 195 | 230 drm_gem_free_mmap_offset(&obj->base); 231 drm_gem_object_release(&obj->base); 232 i915_gem_info_remove_obj(dev_priv, obj->base.size); 233 |
196 free(obj->page_cpu_valid, DRM_I915_GEM); | |
197 free(obj->bit_17, DRM_I915_GEM); 198 free(obj, DRM_I915_GEM); 199} 200 | 234 free(obj->bit_17, DRM_I915_GEM); 235 free(obj, DRM_I915_GEM); 236} 237 |
201void 202i915_gem_free_object(struct drm_gem_object *gem_obj) 203{ 204 struct drm_i915_gem_object *obj; 205 struct drm_device *dev; 206 207 obj = to_intel_bo(gem_obj); 208 dev = obj->base.dev; 209 210 while (obj->pin_count > 0) 211 i915_gem_object_unpin(obj); 212 213 if (obj->phys_obj != NULL) 214 i915_gem_detach_phys_object(dev, obj); 215 216 i915_gem_free_object_tail(obj); 217} 218 | |
219static void 220init_ring_lists(struct intel_ring_buffer *ring) 221{ 222 223 INIT_LIST_HEAD(&ring->active_list); 224 INIT_LIST_HEAD(&ring->request_list); 225 INIT_LIST_HEAD(&ring->gpu_write_list); 226} --- 4 unchanged lines hidden (view full) --- 231 drm_i915_private_t *dev_priv; 232 int i; 233 234 dev_priv = dev->dev_private; 235 236 INIT_LIST_HEAD(&dev_priv->mm.active_list); 237 INIT_LIST_HEAD(&dev_priv->mm.flushing_list); 238 INIT_LIST_HEAD(&dev_priv->mm.inactive_list); | 238static void 239init_ring_lists(struct intel_ring_buffer *ring) 240{ 241 242 INIT_LIST_HEAD(&ring->active_list); 243 INIT_LIST_HEAD(&ring->request_list); 244 INIT_LIST_HEAD(&ring->gpu_write_list); 245} --- 4 unchanged lines hidden (view full) --- 250 drm_i915_private_t *dev_priv; 251 int i; 252 253 dev_priv = dev->dev_private; 254 255 INIT_LIST_HEAD(&dev_priv->mm.active_list); 256 INIT_LIST_HEAD(&dev_priv->mm.flushing_list); 257 INIT_LIST_HEAD(&dev_priv->mm.inactive_list); |
239 INIT_LIST_HEAD(&dev_priv->mm.pinned_list); | |
240 INIT_LIST_HEAD(&dev_priv->mm.fence_list); | 258 INIT_LIST_HEAD(&dev_priv->mm.fence_list); |
241 INIT_LIST_HEAD(&dev_priv->mm.deferred_free_list); | |
242 INIT_LIST_HEAD(&dev_priv->mm.gtt_list); 243 for (i = 0; i < I915_NUM_RINGS; i++) 244 init_ring_lists(&dev_priv->rings[i]); 245 for (i = 0; i < I915_MAX_NUM_FENCES; i++) 246 INIT_LIST_HEAD(&dev_priv->fence_regs[i].lru_list); 247 TIMEOUT_TASK_INIT(dev_priv->tq, &dev_priv->mm.retire_task, 0, 248 i915_gem_retire_task_handler, dev_priv); 249 dev_priv->error_completion = 0; 250 251 /* On GEN3 we really need to make sure the ARB C3 LP bit is set */ 252 if (IS_GEN3(dev)) { | 259 INIT_LIST_HEAD(&dev_priv->mm.gtt_list); 260 for (i = 0; i < I915_NUM_RINGS; i++) 261 init_ring_lists(&dev_priv->rings[i]); 262 for (i = 0; i < I915_MAX_NUM_FENCES; i++) 263 INIT_LIST_HEAD(&dev_priv->fence_regs[i].lru_list); 264 TIMEOUT_TASK_INIT(dev_priv->tq, &dev_priv->mm.retire_task, 0, 265 i915_gem_retire_task_handler, dev_priv); 266 dev_priv->error_completion = 0; 267 268 /* On GEN3 we really need to make sure the ARB C3 LP bit is set */ 269 if (IS_GEN3(dev)) { |
253 u32 tmp = I915_READ(MI_ARB_STATE); 254 if (!(tmp & MI_ARB_C3_LP_WRITE_ENABLE)) { 255 /* 256 * arb state is a masked write, so set bit + 257 * bit in mask. 258 */ 259 tmp = MI_ARB_C3_LP_WRITE_ENABLE | 260 (MI_ARB_C3_LP_WRITE_ENABLE << MI_ARB_MASK_SHIFT); 261 I915_WRITE(MI_ARB_STATE, tmp); 262 } | 270 I915_WRITE(MI_ARB_STATE, 271 _MASKED_BIT_ENABLE(MI_ARB_C3_LP_WRITE_ENABLE)); |
263 } 264 265 dev_priv->relative_constants_mode = I915_EXEC_CONSTANTS_REL_GENERAL; 266 267 /* Old X drivers will take 0-2 for front, back, depth buffers */ 268 if (!drm_core_check_feature(dev, DRIVER_MODESET)) 269 dev_priv->fence_reg_start = 3; 270 271 if (INTEL_INFO(dev)->gen >= 4 || IS_I945G(dev) || IS_I945GM(dev) || 272 IS_G33(dev)) 273 dev_priv->num_fence_regs = 16; 274 else 275 dev_priv->num_fence_regs = 8; 276 277 /* Initialize fence registers to zero */ | 272 } 273 274 dev_priv->relative_constants_mode = I915_EXEC_CONSTANTS_REL_GENERAL; 275 276 /* Old X drivers will take 0-2 for front, back, depth buffers */ 277 if (!drm_core_check_feature(dev, DRIVER_MODESET)) 278 dev_priv->fence_reg_start = 3; 279 280 if (INTEL_INFO(dev)->gen >= 4 || IS_I945G(dev) || IS_I945GM(dev) || 281 IS_G33(dev)) 282 dev_priv->num_fence_regs = 16; 283 else 284 dev_priv->num_fence_regs = 8; 285 286 /* Initialize fence registers to zero */ |
278 for (i = 0; i < dev_priv->num_fence_regs; i++) { 279 i915_gem_clear_fence_reg(dev, &dev_priv->fence_regs[i]); 280 } | 287 i915_gem_reset_fences(dev); 288 |
281 i915_gem_detect_bit_6_swizzle(dev); 282 dev_priv->mm.interruptible = true; 283 284 dev_priv->mm.i915_lowmem = EVENTHANDLER_REGISTER(vm_lowmem, 285 i915_gem_lowmem, dev, EVENTHANDLER_PRI_ANY); 286} 287 288int | 289 i915_gem_detect_bit_6_swizzle(dev); 290 dev_priv->mm.interruptible = true; 291 292 dev_priv->mm.i915_lowmem = EVENTHANDLER_REGISTER(vm_lowmem, 293 i915_gem_lowmem, dev, EVENTHANDLER_PRI_ANY); 294} 295 296int |
289i915_gem_do_init(struct drm_device *dev, unsigned long start, 290 unsigned long mappable_end, unsigned long end) 291{ 292 drm_i915_private_t *dev_priv; 293 unsigned long mappable; 294 int error; 295 296 dev_priv = dev->dev_private; 297 mappable = min(end, mappable_end) - start; 298 299 drm_mm_init(&dev_priv->mm.gtt_space, start, end - start); 300 301 dev_priv->mm.gtt_start = start; 302 dev_priv->mm.gtt_mappable_end = mappable_end; 303 dev_priv->mm.gtt_end = end; 304 dev_priv->mm.gtt_total = end - start; 305 dev_priv->mm.mappable_gtt_total = mappable; 306 307 /* Take over this portion of the GTT */ 308 intel_gtt_clear_range(start / PAGE_SIZE, (end-start) / PAGE_SIZE); 309 device_printf(dev->device, 310 "taking over the fictitious range 0x%lx-0x%lx\n", 311 dev->agp->base + start, dev->agp->base + start + mappable); 312 error = -vm_phys_fictitious_reg_range(dev->agp->base + start, 313 dev->agp->base + start + mappable, VM_MEMATTR_WRITE_COMBINING); 314 return (error); 315} 316 317int | |
318i915_gem_init_ioctl(struct drm_device *dev, void *data, 319 struct drm_file *file) 320{ 321 struct drm_i915_gem_init *args; 322 drm_i915_private_t *dev_priv; 323 | 297i915_gem_init_ioctl(struct drm_device *dev, void *data, 298 struct drm_file *file) 299{ 300 struct drm_i915_gem_init *args; 301 drm_i915_private_t *dev_priv; 302 |
303 if (drm_core_check_feature(dev, DRIVER_MODESET)) 304 return -ENODEV; 305 |
|
324 dev_priv = dev->dev_private; 325 args = data; 326 327 if (args->gtt_start >= args->gtt_end || 328 (args->gtt_end | args->gtt_start) & (PAGE_SIZE - 1)) 329 return (-EINVAL); 330 331 if (mtx_initialized(&dev_priv->mm.gtt_space.unused_lock)) 332 return (-EBUSY); | 306 dev_priv = dev->dev_private; 307 args = data; 308 309 if (args->gtt_start >= args->gtt_end || 310 (args->gtt_end | args->gtt_start) & (PAGE_SIZE - 1)) 311 return (-EINVAL); 312 313 if (mtx_initialized(&dev_priv->mm.gtt_space.unused_lock)) 314 return (-EBUSY); |
315 316 /* GEM with user mode setting was never supported on ilk and later. */ 317 if (INTEL_INFO(dev)->gen >= 5) 318 return -ENODEV; 319 |
|
333 /* 334 * XXXKIB. The second-time initialization should be guarded 335 * against. 336 */ | 320 /* 321 * XXXKIB. The second-time initialization should be guarded 322 * against. 323 */ |
337 return (i915_gem_do_init(dev, args->gtt_start, args->gtt_end, | 324 return (i915_gem_init_global_gtt(dev, args->gtt_start, args->gtt_end, |
338 args->gtt_end)); 339} 340 341int 342i915_gem_idle(struct drm_device *dev) 343{ 344 drm_i915_private_t *dev_priv; 345 int ret; 346 347 dev_priv = dev->dev_private; 348 if (dev_priv->mm.suspended) 349 return (0); 350 | 325 args->gtt_end)); 326} 327 328int 329i915_gem_idle(struct drm_device *dev) 330{ 331 drm_i915_private_t *dev_priv; 332 int ret; 333 334 dev_priv = dev->dev_private; 335 if (dev_priv->mm.suspended) 336 return (0); 337 |
351 ret = i915_gpu_idle(dev, true); | 338 ret = i915_gpu_idle(dev); |
352 if (ret != 0) 353 return (ret); | 339 if (ret != 0) 340 return (ret); |
341 i915_gem_retire_requests(dev); |
|
354 355 /* Under UMS, be paranoid and evict. */ 356 if (!drm_core_check_feature(dev, DRIVER_MODESET)) { | 342 343 /* Under UMS, be paranoid and evict. */ 344 if (!drm_core_check_feature(dev, DRIVER_MODESET)) { |
357 ret = i915_gem_evict_inactive(dev, false); | 345 ret = i915_gem_evict_everything(dev, false); |
358 if (ret != 0) 359 return ret; 360 } 361 362 i915_gem_reset_fences(dev); 363 364 /* Hack! Don't let anybody do execbuf while we don't control the chip. 365 * We need to replace this with a semaphore, or something. --- 22 unchanged lines hidden (view full) --- 388 return; 389 390 I915_WRITE(DISP_ARB_CTL, I915_READ(DISP_ARB_CTL) | 391 DISP_TILE_SURFACE_SWIZZLING); 392 393 if (IS_GEN5(dev)) 394 return; 395 | 346 if (ret != 0) 347 return ret; 348 } 349 350 i915_gem_reset_fences(dev); 351 352 /* Hack! Don't let anybody do execbuf while we don't control the chip. 353 * We need to replace this with a semaphore, or something. --- 22 unchanged lines hidden (view full) --- 376 return; 377 378 I915_WRITE(DISP_ARB_CTL, I915_READ(DISP_ARB_CTL) | 379 DISP_TILE_SURFACE_SWIZZLING); 380 381 if (IS_GEN5(dev)) 382 return; 383 |
384 |
|
396 I915_WRITE(TILECTL, I915_READ(TILECTL) | TILECTL_SWZCTL); 397 if (IS_GEN6(dev)) | 385 I915_WRITE(TILECTL, I915_READ(TILECTL) | TILECTL_SWZCTL); 386 if (IS_GEN6(dev)) |
398 I915_WRITE(ARB_MODE, ARB_MODE_ENABLE(ARB_MODE_SWIZZLE_SNB)); | 387 I915_WRITE(ARB_MODE, _MASKED_BIT_ENABLE(ARB_MODE_SWIZZLE_SNB)); |
399 else | 388 else |
400 I915_WRITE(ARB_MODE, ARB_MODE_ENABLE(ARB_MODE_SWIZZLE_IVB)); | 389 I915_WRITE(ARB_MODE, _MASKED_BIT_ENABLE(ARB_MODE_SWIZZLE_IVB)); |
401} 402 | 390} 391 |
403void 404i915_gem_init_ppgtt(struct drm_device *dev) | 392void i915_gem_init_ppgtt(struct drm_device *dev) |
405{ 406 drm_i915_private_t *dev_priv; 407 struct i915_hw_ppgtt *ppgtt; 408 uint32_t pd_offset, pd_entry; 409 vm_paddr_t pt_addr; 410 struct intel_ring_buffer *ring; 411 u_int first_pd_entry_in_global_pt, i; 412 --- 11 unchanged lines hidden (view full) --- 424 } 425 intel_gtt_read_pte(first_pd_entry_in_global_pt); 426 427 pd_offset = ppgtt->pd_offset; 428 pd_offset /= 64; /* in cachelines, */ 429 pd_offset <<= 16; 430 431 if (INTEL_INFO(dev)->gen == 6) { | 393{ 394 drm_i915_private_t *dev_priv; 395 struct i915_hw_ppgtt *ppgtt; 396 uint32_t pd_offset, pd_entry; 397 vm_paddr_t pt_addr; 398 struct intel_ring_buffer *ring; 399 u_int first_pd_entry_in_global_pt, i; 400 --- 11 unchanged lines hidden (view full) --- 412 } 413 intel_gtt_read_pte(first_pd_entry_in_global_pt); 414 415 pd_offset = ppgtt->pd_offset; 416 pd_offset /= 64; /* in cachelines, */ 417 pd_offset <<= 16; 418 419 if (INTEL_INFO(dev)->gen == 6) { |
432 uint32_t ecochk = I915_READ(GAM_ECOCHK); | 420 uint32_t ecochk, gab_ctl, ecobits; 421 422 ecobits = I915_READ(GAC_ECO_BITS); 423 I915_WRITE(GAC_ECO_BITS, ecobits | ECOBITS_PPGTT_CACHE64B); 424 425 gab_ctl = I915_READ(GAB_CTL); 426 I915_WRITE(GAB_CTL, gab_ctl | GAB_CTL_CONT_AFTER_PAGEFAULT); 427 428 ecochk = I915_READ(GAM_ECOCHK); |
433 I915_WRITE(GAM_ECOCHK, ecochk | ECOCHK_SNB_BIT | 434 ECOCHK_PPGTT_CACHE64B); | 429 I915_WRITE(GAM_ECOCHK, ecochk | ECOCHK_SNB_BIT | 430 ECOCHK_PPGTT_CACHE64B); |
435 I915_WRITE(GFX_MODE, GFX_MODE_ENABLE(GFX_PPGTT_ENABLE)); | 431 I915_WRITE(GFX_MODE, _MASKED_BIT_ENABLE(GFX_PPGTT_ENABLE)); |
436 } else if (INTEL_INFO(dev)->gen >= 7) { 437 I915_WRITE(GAM_ECOCHK, ECOCHK_PPGTT_CACHE64B); 438 /* GFX_MODE is per-ring on gen7+ */ 439 } 440 | 432 } else if (INTEL_INFO(dev)->gen >= 7) { 433 I915_WRITE(GAM_ECOCHK, ECOCHK_PPGTT_CACHE64B); 434 /* GFX_MODE is per-ring on gen7+ */ 435 } 436 |
441 for (i = 0; i < I915_NUM_RINGS; i++) { 442 ring = &dev_priv->rings[i]; 443 | 437 for_each_ring(ring, dev_priv, i) { |
444 if (INTEL_INFO(dev)->gen >= 7) 445 I915_WRITE(RING_MODE_GEN7(ring), | 438 if (INTEL_INFO(dev)->gen >= 7) 439 I915_WRITE(RING_MODE_GEN7(ring), |
446 GFX_MODE_ENABLE(GFX_PPGTT_ENABLE)); | 440 _MASKED_BIT_ENABLE(GFX_PPGTT_ENABLE)); |
447 448 I915_WRITE(RING_PP_DIR_DCLV(ring), PP_DIR_DCLV_2G); 449 I915_WRITE(RING_PP_DIR_BASE(ring), pd_offset); 450 } 451} 452 453int 454i915_gem_init_hw(struct drm_device *dev) --- 28 unchanged lines hidden (view full) --- 483 484cleanup_bsd_ring: 485 intel_cleanup_ring_buffer(&dev_priv->rings[VCS]); 486cleanup_render_ring: 487 intel_cleanup_ring_buffer(&dev_priv->rings[RCS]); 488 return (ret); 489} 490 | 441 442 I915_WRITE(RING_PP_DIR_DCLV(ring), PP_DIR_DCLV_2G); 443 I915_WRITE(RING_PP_DIR_BASE(ring), pd_offset); 444 } 445} 446 447int 448i915_gem_init_hw(struct drm_device *dev) --- 28 unchanged lines hidden (view full) --- 477 478cleanup_bsd_ring: 479 intel_cleanup_ring_buffer(&dev_priv->rings[VCS]); 480cleanup_render_ring: 481 intel_cleanup_ring_buffer(&dev_priv->rings[RCS]); 482 return (ret); 483} 484 |
485static bool 486intel_enable_ppgtt(struct drm_device *dev) 487{ 488 if (i915_enable_ppgtt >= 0) 489 return i915_enable_ppgtt; 490 491 /* Disable ppgtt on SNB if VT-d is on. */ 492 if (INTEL_INFO(dev)->gen == 6 && intel_iommu_enabled) 493 return false; 494 495 return true; 496} 497 498int i915_gem_init(struct drm_device *dev) 499{ 500 struct drm_i915_private *dev_priv = dev->dev_private; 501 unsigned long gtt_size, mappable_size; 502 int ret; 503 504 gtt_size = dev_priv->mm.gtt.gtt_total_entries << PAGE_SHIFT; 505 mappable_size = dev_priv->mm.gtt.gtt_mappable_entries << PAGE_SHIFT; 506 507 DRM_LOCK(dev); 508 if (intel_enable_ppgtt(dev) && HAS_ALIASING_PPGTT(dev)) { 509 /* PPGTT pdes are stolen from global gtt ptes, so shrink the 510 * aperture accordingly when using aliasing ppgtt. */ 511 gtt_size -= I915_PPGTT_PD_ENTRIES*PAGE_SIZE; 512 513 i915_gem_init_global_gtt(dev, 0, mappable_size, gtt_size); 514 515 ret = i915_gem_init_aliasing_ppgtt(dev); 516 if (ret) { 517 DRM_UNLOCK(dev); 518 return ret; 519 } 520 } else { 521 /* Let GEM Manage all of the aperture. 522 * 523 * However, leave one page at the end still bound to the scratch 524 * page. There are a number of places where the hardware 525 * apparently prefetches past the end of the object, and we've 526 * seen multiple hangs with the GPU head pointer stuck in a 527 * batchbuffer bound at the last page of the aperture. One page 528 * should be enough to keep any prefetching inside of the 529 * aperture. 530 */ 531 i915_gem_init_global_gtt(dev, 0, mappable_size, 532 gtt_size); 533 } 534 535 ret = i915_gem_init_hw(dev); 536 DRM_UNLOCK(dev); 537 if (ret != 0) { 538 i915_gem_cleanup_aliasing_ppgtt(dev); 539 return (ret); 540 } 541 542 /* Allow hardware batchbuffers unless told otherwise, but not for KMS. */ 543 if (!drm_core_check_feature(dev, DRIVER_MODESET)) 544 dev_priv->dri1.allow_batchbuffer = 1; 545 return 0; 546} 547 |
|
491int 492i915_gem_get_aperture_ioctl(struct drm_device *dev, void *data, 493 struct drm_file *file) 494{ 495 struct drm_i915_private *dev_priv; 496 struct drm_i915_gem_get_aperture *args; 497 struct drm_i915_gem_object *obj; 498 size_t pinned; 499 500 dev_priv = dev->dev_private; 501 args = data; 502 | 548int 549i915_gem_get_aperture_ioctl(struct drm_device *dev, void *data, 550 struct drm_file *file) 551{ 552 struct drm_i915_private *dev_priv; 553 struct drm_i915_gem_get_aperture *args; 554 struct drm_i915_gem_object *obj; 555 size_t pinned; 556 557 dev_priv = dev->dev_private; 558 args = data; 559 |
503 if (!(dev->driver->driver_features & DRIVER_GEM)) 504 return (-ENODEV); 505 | |
506 pinned = 0; 507 DRM_LOCK(dev); | 560 pinned = 0; 561 DRM_LOCK(dev); |
508 list_for_each_entry(obj, &dev_priv->mm.pinned_list, mm_list) 509 pinned += obj->gtt_space->size; | 562 list_for_each_entry(obj, &dev_priv->mm.gtt_list, gtt_list) 563 if (obj->pin_count) 564 pinned += obj->gtt_space->size; |
510 DRM_UNLOCK(dev); 511 512 args->aper_size = dev_priv->mm.gtt_total; 513 args->aper_available_size = args->aper_size - pinned; 514 515 return (0); 516} 517 518int 519i915_gem_object_pin(struct drm_i915_gem_object *obj, uint32_t alignment, 520 bool map_and_fenceable) 521{ | 565 DRM_UNLOCK(dev); 566 567 args->aper_size = dev_priv->mm.gtt_total; 568 args->aper_available_size = args->aper_size - pinned; 569 570 return (0); 571} 572 573int 574i915_gem_object_pin(struct drm_i915_gem_object *obj, uint32_t alignment, 575 bool map_and_fenceable) 576{ |
522 struct drm_device *dev; 523 struct drm_i915_private *dev_priv; | |
524 int ret; 525 | 577 int ret; 578 |
526 dev = obj->base.dev; 527 dev_priv = dev->dev_private; | 579 if (obj->pin_count == DRM_I915_GEM_OBJECT_MAX_PIN_COUNT) 580 return (-EBUSY); |
528 | 581 |
529 KASSERT(obj->pin_count != DRM_I915_GEM_OBJECT_MAX_PIN_COUNT, 530 ("Max pin count")); 531 | |
532 if (obj->gtt_space != NULL) { 533 if ((alignment && obj->gtt_offset & (alignment - 1)) || 534 (map_and_fenceable && !obj->map_and_fenceable)) { 535 DRM_DEBUG("bo is already pinned with incorrect alignment:" 536 " offset=%x, req.alignment=%x, req.map_and_fenceable=%d," 537 " obj->map_and_fenceable=%d\n", 538 obj->gtt_offset, alignment, 539 map_and_fenceable, --- 6 unchanged lines hidden (view full) --- 546 547 if (obj->gtt_space == NULL) { 548 ret = i915_gem_object_bind_to_gtt(obj, alignment, 549 map_and_fenceable); 550 if (ret) 551 return (ret); 552 } 553 | 582 if (obj->gtt_space != NULL) { 583 if ((alignment && obj->gtt_offset & (alignment - 1)) || 584 (map_and_fenceable && !obj->map_and_fenceable)) { 585 DRM_DEBUG("bo is already pinned with incorrect alignment:" 586 " offset=%x, req.alignment=%x, req.map_and_fenceable=%d," 587 " obj->map_and_fenceable=%d\n", 588 obj->gtt_offset, alignment, 589 map_and_fenceable, --- 6 unchanged lines hidden (view full) --- 596 597 if (obj->gtt_space == NULL) { 598 ret = i915_gem_object_bind_to_gtt(obj, alignment, 599 map_and_fenceable); 600 if (ret) 601 return (ret); 602 } 603 |
554 if (obj->pin_count++ == 0 && !obj->active) 555 list_move_tail(&obj->mm_list, &dev_priv->mm.pinned_list); | 604 if (!obj->has_global_gtt_mapping && map_and_fenceable) 605 i915_gem_gtt_bind_object(obj, obj->cache_level); 606 607 obj->pin_count++; |
556 obj->pin_mappable |= map_and_fenceable; 557 | 608 obj->pin_mappable |= map_and_fenceable; 609 |
558#if 1 559 KIB_NOTYET(); 560#else 561 WARN_ON(i915_verify_lists(dev)); 562#endif 563 return (0); | 610 return 0; |
564} 565 566void 567i915_gem_object_unpin(struct drm_i915_gem_object *obj) 568{ | 611} 612 613void 614i915_gem_object_unpin(struct drm_i915_gem_object *obj) 615{ |
569 struct drm_device *dev; 570 drm_i915_private_t *dev_priv; 571 572 dev = obj->base.dev; 573 dev_priv = dev->dev_private; 574 575#if 1 576 KIB_NOTYET(); 577#else 578 WARN_ON(i915_verify_lists(dev)); 579#endif | |
580 581 KASSERT(obj->pin_count != 0, ("zero pin count")); 582 KASSERT(obj->gtt_space != NULL, ("No gtt mapping")); 583 | 616 617 KASSERT(obj->pin_count != 0, ("zero pin count")); 618 KASSERT(obj->gtt_space != NULL, ("No gtt mapping")); 619 |
584 if (--obj->pin_count == 0) { 585 if (!obj->active) 586 list_move_tail(&obj->mm_list, 587 &dev_priv->mm.inactive_list); | 620 if (--obj->pin_count == 0) |
588 obj->pin_mappable = false; | 621 obj->pin_mappable = false; |
589 } 590#if 1 591 KIB_NOTYET(); 592#else 593 WARN_ON(i915_verify_lists(dev)); 594#endif | |
595} 596 597int 598i915_gem_pin_ioctl(struct drm_device *dev, void *data, 599 struct drm_file *file) 600{ 601 struct drm_i915_gem_pin *args; 602 struct drm_i915_gem_object *obj; --- 85 unchanged lines hidden (view full) --- 688} 689 690int 691i915_gem_busy_ioctl(struct drm_device *dev, void *data, 692 struct drm_file *file) 693{ 694 struct drm_i915_gem_busy *args; 695 struct drm_i915_gem_object *obj; | 622} 623 624int 625i915_gem_pin_ioctl(struct drm_device *dev, void *data, 626 struct drm_file *file) 627{ 628 struct drm_i915_gem_pin *args; 629 struct drm_i915_gem_object *obj; --- 85 unchanged lines hidden (view full) --- 715} 716 717int 718i915_gem_busy_ioctl(struct drm_device *dev, void *data, 719 struct drm_file *file) 720{ 721 struct drm_i915_gem_busy *args; 722 struct drm_i915_gem_object *obj; |
696 struct drm_i915_gem_request *request; | |
697 int ret; 698 699 args = data; 700 701 ret = i915_mutex_lock_interruptible(dev); 702 if (ret != 0) 703 return ret; 704 705 obj = to_intel_bo(drm_gem_object_lookup(dev, file, args->handle)); 706 if (&obj->base == NULL) { 707 ret = -ENOENT; 708 goto unlock; 709 } 710 711 args->busy = obj->active; 712 if (args->busy) { 713 if (obj->base.write_domain & I915_GEM_GPU_DOMAINS) { 714 ret = i915_gem_flush_ring(obj->ring, 715 0, obj->base.write_domain); | 723 int ret; 724 725 args = data; 726 727 ret = i915_mutex_lock_interruptible(dev); 728 if (ret != 0) 729 return ret; 730 731 obj = to_intel_bo(drm_gem_object_lookup(dev, file, args->handle)); 732 if (&obj->base == NULL) { 733 ret = -ENOENT; 734 goto unlock; 735 } 736 737 args->busy = obj->active; 738 if (args->busy) { 739 if (obj->base.write_domain & I915_GEM_GPU_DOMAINS) { 740 ret = i915_gem_flush_ring(obj->ring, 741 0, obj->base.write_domain); |
716 } else if (obj->ring->outstanding_lazy_request == 717 obj->last_rendering_seqno) { 718 request = malloc(sizeof(*request), DRM_I915_GEM, 719 M_WAITOK | M_ZERO); 720 ret = i915_add_request(obj->ring, NULL, request); 721 if (ret != 0) 722 free(request, DRM_I915_GEM); | 742 } else { 743 ret = i915_gem_check_olr(obj->ring, 744 obj->last_rendering_seqno); |
723 } 724 725 i915_gem_retire_requests_ring(obj->ring); 726 args->busy = obj->active; 727 } 728 729 drm_gem_object_unreference(&obj->base); 730unlock: --- 27 unchanged lines hidden (view full) --- 758 break; 759 ring = request->ring; 760 seqno = request->seqno; 761 } 762 mtx_unlock(&file_priv->mm.lck); 763 if (seqno == 0) 764 return (0); 765 | 745 } 746 747 i915_gem_retire_requests_ring(obj->ring); 748 args->busy = obj->active; 749 } 750 751 drm_gem_object_unreference(&obj->base); 752unlock: --- 27 unchanged lines hidden (view full) --- 780 break; 781 ring = request->ring; 782 seqno = request->seqno; 783 } 784 mtx_unlock(&file_priv->mm.lck); 785 if (seqno == 0) 786 return (0); 787 |
766 ret = 0; 767 mtx_lock(&ring->irq_lock); 768 if (!i915_seqno_passed(ring->get_seqno(ring), seqno)) { 769 if (ring->irq_get(ring)) { 770 while (ret == 0 && 771 !(i915_seqno_passed(ring->get_seqno(ring), seqno) || 772 atomic_load_acq_int(&dev_priv->mm.wedged))) 773 ret = -msleep(ring, &ring->irq_lock, PCATCH, 774 "915thr", 0); 775 ring->irq_put(ring); 776 if (ret == 0 && atomic_load_acq_int(&dev_priv->mm.wedged)) 777 ret = -EIO; 778 } else if (_intel_wait_for(dev, 779 i915_seqno_passed(ring->get_seqno(ring), seqno) || 780 atomic_load_acq_int(&dev_priv->mm.wedged), 3000, 0, "915rtr")) { 781 ret = -EBUSY; 782 } 783 } 784 mtx_unlock(&ring->irq_lock); 785 | 788 ret = __wait_seqno(ring, seqno, true); |
786 if (ret == 0) 787 taskqueue_enqueue_timeout(dev_priv->tq, 788 &dev_priv->mm.retire_task, 0); 789 790 return (ret); 791} 792 793int --- 48 unchanged lines hidden (view full) --- 842 DRM_UNLOCK(dev); 843 return (ret); 844} 845 846void 847i915_gem_cleanup_ringbuffer(struct drm_device *dev) 848{ 849 drm_i915_private_t *dev_priv; | 789 if (ret == 0) 790 taskqueue_enqueue_timeout(dev_priv->tq, 791 &dev_priv->mm.retire_task, 0); 792 793 return (ret); 794} 795 796int --- 48 unchanged lines hidden (view full) --- 845 DRM_UNLOCK(dev); 846 return (ret); 847} 848 849void 850i915_gem_cleanup_ringbuffer(struct drm_device *dev) 851{ 852 drm_i915_private_t *dev_priv; |
853 struct intel_ring_buffer *ring; |
|
850 int i; 851 852 dev_priv = dev->dev_private; | 854 int i; 855 856 dev_priv = dev->dev_private; |
853 for (i = 0; i < I915_NUM_RINGS; i++) 854 intel_cleanup_ring_buffer(&dev_priv->rings[i]); | 857 for_each_ring(ring, dev_priv, i) 858 intel_cleanup_ring_buffer(ring); |
855} 856 857int 858i915_gem_entervt_ioctl(struct drm_device *dev, void *data, 859 struct drm_file *file_priv) 860{ 861 drm_i915_private_t *dev_priv; | 859} 860 861int 862i915_gem_entervt_ioctl(struct drm_device *dev, void *data, 863 struct drm_file *file_priv) 864{ 865 drm_i915_private_t *dev_priv; |
862 int ret, i; | 866 int ret; |
863 864 if (drm_core_check_feature(dev, DRIVER_MODESET)) 865 return (0); 866 dev_priv = dev->dev_private; 867 if (atomic_load_acq_int(&dev_priv->mm.wedged) != 0) { 868 DRM_ERROR("Reenabling wedged hardware, good luck\n"); 869 atomic_store_rel_int(&dev_priv->mm.wedged, 0); 870 } 871 872 dev_priv->mm.suspended = 0; 873 874 ret = i915_gem_init_hw(dev); 875 if (ret != 0) { 876 return (ret); 877 } 878 879 KASSERT(list_empty(&dev_priv->mm.active_list), ("active list")); 880 KASSERT(list_empty(&dev_priv->mm.flushing_list), ("flushing list")); 881 KASSERT(list_empty(&dev_priv->mm.inactive_list), ("inactive list")); | 867 868 if (drm_core_check_feature(dev, DRIVER_MODESET)) 869 return (0); 870 dev_priv = dev->dev_private; 871 if (atomic_load_acq_int(&dev_priv->mm.wedged) != 0) { 872 DRM_ERROR("Reenabling wedged hardware, good luck\n"); 873 atomic_store_rel_int(&dev_priv->mm.wedged, 0); 874 } 875 876 dev_priv->mm.suspended = 0; 877 878 ret = i915_gem_init_hw(dev); 879 if (ret != 0) { 880 return (ret); 881 } 882 883 KASSERT(list_empty(&dev_priv->mm.active_list), ("active list")); 884 KASSERT(list_empty(&dev_priv->mm.flushing_list), ("flushing list")); 885 KASSERT(list_empty(&dev_priv->mm.inactive_list), ("inactive list")); |
882 for (i = 0; i < I915_NUM_RINGS; i++) { 883 KASSERT(list_empty(&dev_priv->rings[i].active_list), 884 ("ring %d active list", i)); 885 KASSERT(list_empty(&dev_priv->rings[i].request_list), 886 ("ring %d request list", i)); 887 } 888 | |
889 DRM_UNLOCK(dev); 890 ret = drm_irq_install(dev); 891 DRM_LOCK(dev); 892 if (ret) 893 goto cleanup_ringbuffer; 894 895 return (0); 896 --- 71 unchanged lines hidden (view full) --- 968i915_gem_create_ioctl(struct drm_device *dev, void *data, 969 struct drm_file *file) 970{ 971 struct drm_i915_gem_create *args = data; 972 973 return (i915_gem_create(file, dev, args->size, &args->handle)); 974} 975 | 886 DRM_UNLOCK(dev); 887 ret = drm_irq_install(dev); 888 DRM_LOCK(dev); 889 if (ret) 890 goto cleanup_ringbuffer; 891 892 return (0); 893 --- 71 unchanged lines hidden (view full) --- 965i915_gem_create_ioctl(struct drm_device *dev, void *data, 966 struct drm_file *file) 967{ 968 struct drm_i915_gem_create *args = data; 969 970 return (i915_gem_create(file, dev, args->size, &args->handle)); 971} 972 |
973#define __user 974#define __force 975#define __iomem 976#define to_user_ptr(x) ((void *)(uintptr_t)(x)) 977#define offset_in_page(x) ((x) & PAGE_MASK) 978#define page_to_phys(x) VM_PAGE_TO_PHYS(x) 979static inline long 980__copy_to_user(void __user *to, const void *from, unsigned long n) 981{ 982 return (copyout(from, to, n) != 0 ? n : 0); 983} 984static inline int 985__copy_to_user_inatomic(void __user *to, const void *from, unsigned n) 986{ 987 return (copyout_nofault(from, to, n) != 0 ? n : 0); 988} 989static inline unsigned long 990__copy_from_user(void *to, const void __user *from, unsigned long n) 991{ 992 return ((copyin(__DECONST(void *, from), to, n) != 0 ? n : 0)); 993} 994#define copy_from_user(to, from, n) __copy_from_user((to), (from), (n)) 995static inline unsigned long 996__copy_from_user_inatomic_nocache(void *to, const void __user *from, 997 unsigned long n) 998{ 999 1000 /* 1001 * XXXKIB. Equivalent Linux function is implemented using 1002 * MOVNTI for aligned moves. For unaligned head and tail, 1003 * normal move is performed. As such, it is not incorrect, if 1004 * only somewhat slower, to use normal copyin. All uses 1005 * except shmem_pwrite_fast() have the destination mapped WC. 1006 */ 1007 return ((copyin_nofault(__DECONST(void *, from), to, n) != 0 ? n : 0)); 1008} 1009static inline int 1010fault_in_multipages_readable(const char __user *uaddr, int size) 1011{ 1012 char c; 1013 int ret = 0; 1014 const char __user *end = uaddr + size - 1; 1015 1016 if (unlikely(size == 0)) 1017 return ret; 1018 1019 while (uaddr <= end) { 1020 ret = copyin(uaddr, &c, 1); 1021 if (ret != 0) 1022 return -EFAULT; 1023 uaddr += PAGE_SIZE; 1024 } 1025 1026 /* Check whether the range spilled into the next page. */ 1027 if (((unsigned long)uaddr & ~PAGE_MASK) == 1028 ((unsigned long)end & ~PAGE_MASK)) { 1029 ret = copyin(end, &c, 1); 1030 } 1031 1032 return -ret; 1033} 1034 1035static inline int 1036fault_in_multipages_writeable(char __user *uaddr, int size) 1037{ 1038 int ret = 0; 1039 char __user *end = uaddr + size - 1; 1040 1041 if (unlikely(size == 0)) 1042 return ret; 1043 1044 /* 1045 * Writing zeroes into userspace here is OK, because we know that if 1046 * the zero gets there, we'll be overwriting it. 1047 */ 1048 while (uaddr <= end) { 1049 ret = subyte(uaddr, 0); 1050 if (ret != 0) 1051 return -EFAULT; 1052 uaddr += PAGE_SIZE; 1053 } 1054 1055 /* Check whether the range spilled into the next page. */ 1056 if (((unsigned long)uaddr & ~PAGE_MASK) == 1057 ((unsigned long)end & ~PAGE_MASK)) 1058 ret = subyte(end, 0); 1059 1060 return ret; 1061} 1062 1063static inline int 1064__copy_to_user_swizzled(char __user *cpu_vaddr, 1065 const char *gpu_vaddr, int gpu_offset, 1066 int length) 1067{ 1068 int ret, cpu_offset = 0; 1069 1070 while (length > 0) { 1071 int cacheline_end = roundup2(gpu_offset + 1, 64); 1072 int this_length = min(cacheline_end - gpu_offset, length); 1073 int swizzled_gpu_offset = gpu_offset ^ 64; 1074 1075 ret = __copy_to_user(cpu_vaddr + cpu_offset, 1076 gpu_vaddr + swizzled_gpu_offset, 1077 this_length); 1078 if (ret) 1079 return ret + length; 1080 1081 cpu_offset += this_length; 1082 gpu_offset += this_length; 1083 length -= this_length; 1084 } 1085 1086 return 0; 1087} 1088 1089static inline int 1090__copy_from_user_swizzled(char *gpu_vaddr, int gpu_offset, 1091 const char __user *cpu_vaddr, 1092 int length) 1093{ 1094 int ret, cpu_offset = 0; 1095 1096 while (length > 0) { 1097 int cacheline_end = roundup2(gpu_offset + 1, 64); 1098 int this_length = min(cacheline_end - gpu_offset, length); 1099 int swizzled_gpu_offset = gpu_offset ^ 64; 1100 1101 ret = __copy_from_user(gpu_vaddr + swizzled_gpu_offset, 1102 cpu_vaddr + cpu_offset, 1103 this_length); 1104 if (ret) 1105 return ret + length; 1106 1107 cpu_offset += this_length; 1108 gpu_offset += this_length; 1109 length -= this_length; 1110 } 1111 1112 return 0; 1113} 1114 |
|
976static int | 1115static int |
977i915_gem_swap_io(struct drm_device *dev, struct drm_i915_gem_object *obj, 978 uint64_t data_ptr, uint64_t size, uint64_t offset, enum uio_rw rw, 979 struct drm_file *file) | 1116i915_gem_phys_pwrite(struct drm_device *dev, 1117 struct drm_i915_gem_object *obj, 1118 struct drm_i915_gem_pwrite *args, 1119 struct drm_file *file_priv) |
980{ | 1120{ |
981 vm_object_t vm_obj; 982 vm_page_t m; 983 struct sf_buf *sf; 984 vm_offset_t mkva; 985 vm_pindex_t obj_pi; 986 int cnt, do_bit17_swizzling, length, obj_po, ret, swizzled_po; | 1121 void *vaddr = (char *)obj->phys_obj->handle->vaddr + args->offset; 1122 char __user *user_data = to_user_ptr(args->data_ptr); |
987 | 1123 |
988 if (obj->gtt_offset != 0 && rw == UIO_READ) 989 do_bit17_swizzling = i915_gem_object_needs_bit17_swizzle(obj); 990 else 991 do_bit17_swizzling = 0; | 1124 if (__copy_from_user_inatomic_nocache(vaddr, user_data, args->size)) { 1125 unsigned long unwritten; |
992 | 1126 |
993 obj->dirty = 1; 994 vm_obj = obj->base.vm_obj; 995 ret = 0; | 1127 /* The physical object once assigned is fixed for the lifetime 1128 * of the obj, so we can safely drop the lock and continue 1129 * to access vaddr. 1130 */ 1131 DRM_UNLOCK(dev); 1132 unwritten = copy_from_user(vaddr, user_data, args->size); 1133 DRM_LOCK(dev); 1134 if (unwritten) 1135 return -EFAULT; 1136 } |
996 | 1137 |
997 VM_OBJECT_WLOCK(vm_obj); 998 vm_object_pip_add(vm_obj, 1); 999 while (size > 0) { 1000 obj_pi = OFF_TO_IDX(offset); 1001 obj_po = offset & PAGE_MASK; | 1138 i915_gem_chipset_flush(dev); 1139 return 0; 1140} |
1002 | 1141 |
1003 m = i915_gem_wire_page(vm_obj, obj_pi); 1004 VM_OBJECT_WUNLOCK(vm_obj); | 1142/* Per-page copy function for the shmem pread fastpath. 1143 * Flushes invalid cachelines before reading the target if 1144 * needs_clflush is set. */ 1145static int 1146shmem_pread_fast(vm_page_t page, int shmem_page_offset, int page_length, 1147 char __user *user_data, 1148 bool page_do_bit17_swizzling, bool needs_clflush) 1149{ 1150 char *vaddr; 1151 struct sf_buf *sf; 1152 int ret; |
1005 | 1153 |
1006 sched_pin(); 1007 sf = sf_buf_alloc(m, SFB_CPUPRIVATE); 1008 mkva = sf_buf_kva(sf); 1009 length = min(size, PAGE_SIZE - obj_po); 1010 while (length > 0) { 1011 if (do_bit17_swizzling && 1012 (VM_PAGE_TO_PHYS(m) & (1 << 17)) != 0) { 1013 cnt = roundup2(obj_po + 1, 64); 1014 cnt = min(cnt - obj_po, length); 1015 swizzled_po = obj_po ^ 64; 1016 } else { 1017 cnt = length; 1018 swizzled_po = obj_po; 1019 } 1020 if (rw == UIO_READ) 1021 ret = -copyout_nofault( 1022 (char *)mkva + swizzled_po, 1023 (void *)(uintptr_t)data_ptr, cnt); 1024 else 1025 ret = -copyin_nofault( 1026 (void *)(uintptr_t)data_ptr, 1027 (char *)mkva + swizzled_po, cnt); 1028 if (ret != 0) 1029 break; 1030 data_ptr += cnt; 1031 size -= cnt; 1032 length -= cnt; 1033 offset += cnt; 1034 obj_po += cnt; 1035 } 1036 sf_buf_free(sf); | 1154 if (unlikely(page_do_bit17_swizzling)) 1155 return -EINVAL; 1156 1157 sched_pin(); 1158 sf = sf_buf_alloc(page, SFB_NOWAIT | SFB_CPUPRIVATE); 1159 if (sf == NULL) { |
1037 sched_unpin(); | 1160 sched_unpin(); |
1038 VM_OBJECT_WLOCK(vm_obj); 1039 if (rw == UIO_WRITE) 1040 vm_page_dirty(m); 1041 vm_page_reference(m); 1042 vm_page_lock(m); 1043 vm_page_unwire(m, PQ_ACTIVE); 1044 vm_page_unlock(m); 1045 atomic_add_long(&i915_gem_wired_pages_cnt, -1); | 1161 return (-EFAULT); 1162 } 1163 vaddr = (char *)sf_buf_kva(sf); 1164 if (needs_clflush) 1165 drm_clflush_virt_range(vaddr + shmem_page_offset, 1166 page_length); 1167 ret = __copy_to_user_inatomic(user_data, 1168 vaddr + shmem_page_offset, 1169 page_length); 1170 sf_buf_free(sf); 1171 sched_unpin(); |
1046 | 1172 |
1047 if (ret != 0) 1048 break; | 1173 return ret ? -EFAULT : 0; 1174} 1175 1176static void 1177shmem_clflush_swizzled_range(char *addr, unsigned long length, 1178 bool swizzled) 1179{ 1180 if (unlikely(swizzled)) { 1181 unsigned long start = (unsigned long) addr; 1182 unsigned long end = (unsigned long) addr + length; 1183 1184 /* For swizzling simply ensure that we always flush both 1185 * channels. Lame, but simple and it works. Swizzled 1186 * pwrite/pread is far from a hotpath - current userspace 1187 * doesn't use it at all. */ 1188 start = rounddown2(start, 128); 1189 end = roundup2(end, 128); 1190 1191 drm_clflush_virt_range((void *)start, end - start); 1192 } else { 1193 drm_clflush_virt_range(addr, length); |
1049 } | 1194 } |
1050 vm_object_pip_wakeup(vm_obj); 1051 VM_OBJECT_WUNLOCK(vm_obj); | |
1052 | 1195 |
1053 return (ret); | |
1054} 1055 | 1196} 1197 |
1198/* Only difference to the fast-path function is that this can handle bit17 1199 * and uses non-atomic copy and kmap functions. */ |
|
1056static int | 1200static int |
1057i915_gem_gtt_write(struct drm_device *dev, struct drm_i915_gem_object *obj, 1058 uint64_t data_ptr, uint64_t size, uint64_t offset, struct drm_file *file) | 1201shmem_pread_slow(vm_page_t page, int shmem_page_offset, int page_length, 1202 char __user *user_data, 1203 bool page_do_bit17_swizzling, bool needs_clflush) |
1059{ | 1204{ |
1060 vm_offset_t mkva; 1061 vm_pindex_t obj_pi; 1062 int obj_po, ret; | 1205 char *vaddr; 1206 struct sf_buf *sf; 1207 int ret; |
1063 | 1208 |
1064 obj_pi = OFF_TO_IDX(offset); 1065 obj_po = offset & PAGE_MASK; | 1209 sf = sf_buf_alloc(page, 0); 1210 vaddr = (char *)sf_buf_kva(sf); 1211 if (needs_clflush) 1212 shmem_clflush_swizzled_range(vaddr + shmem_page_offset, 1213 page_length, 1214 page_do_bit17_swizzling); |
1066 | 1215 |
1067 mkva = (vm_offset_t)pmap_mapdev_attr(dev->agp->base + obj->gtt_offset + 1068 IDX_TO_OFF(obj_pi), size, PAT_WRITE_COMBINING); 1069 ret = -copyin_nofault((void *)(uintptr_t)data_ptr, (char *)mkva + 1070 obj_po, size); 1071 pmap_unmapdev(mkva, size); 1072 return (ret); | 1216 if (page_do_bit17_swizzling) 1217 ret = __copy_to_user_swizzled(user_data, 1218 vaddr, shmem_page_offset, 1219 page_length); 1220 else 1221 ret = __copy_to_user(user_data, 1222 vaddr + shmem_page_offset, 1223 page_length); 1224 sf_buf_free(sf); 1225 1226 return ret ? - EFAULT : 0; |
1073} 1074 1075static int | 1227} 1228 1229static int |
1076i915_gem_obj_io(struct drm_device *dev, uint32_t handle, uint64_t data_ptr, 1077 uint64_t size, uint64_t offset, enum uio_rw rw, struct drm_file *file) | 1230i915_gem_shmem_pread(struct drm_device *dev, 1231 struct drm_i915_gem_object *obj, 1232 struct drm_i915_gem_pread *args, 1233 struct drm_file *file) |
1078{ | 1234{ |
1079 struct drm_i915_gem_object *obj; 1080 vm_page_t *ma; 1081 vm_offset_t start, end; 1082 int npages, ret; | 1235 char __user *user_data; 1236 ssize_t remain, sremain; 1237 off_t offset, soffset; 1238 int shmem_page_offset, page_length, ret = 0; 1239 int obj_do_bit17_swizzling, page_do_bit17_swizzling; 1240 int prefaulted = 0; 1241 int needs_clflush = 0; |
1083 | 1242 |
1084 if (size == 0) 1085 return (0); 1086 start = trunc_page(data_ptr); 1087 end = round_page(data_ptr + size); 1088 npages = howmany(end - start, PAGE_SIZE); 1089 ma = malloc(npages * sizeof(vm_page_t), DRM_I915_GEM, M_WAITOK | 1090 M_ZERO); 1091 npages = vm_fault_quick_hold_pages(&curproc->p_vmspace->vm_map, 1092 (vm_offset_t)data_ptr, size, 1093 (rw == UIO_READ ? VM_PROT_WRITE : 0 ) | VM_PROT_READ, ma, npages); 1094 if (npages == -1) { 1095 ret = -EFAULT; 1096 goto free_ma; | 1243 user_data = to_user_ptr(args->data_ptr); 1244 sremain = remain = args->size; 1245 1246 obj_do_bit17_swizzling = i915_gem_object_needs_bit17_swizzle(obj); 1247 1248 if (!(obj->base.read_domains & I915_GEM_DOMAIN_CPU)) { 1249 /* If we're not in the cpu read domain, set ourself into the gtt 1250 * read domain and manually flush cachelines (if required). This 1251 * optimizes for the case when the gpu will dirty the data 1252 * anyway again before the next pread happens. */ 1253 needs_clflush = !cpu_cache_is_coherent(dev, obj->cache_level); 1254 ret = i915_gem_object_set_to_gtt_domain(obj, false); 1255 if (ret) 1256 return ret; |
1097 } 1098 | 1257 } 1258 |
1259 soffset = offset = args->offset; 1260 ret = i915_gem_object_get_pages_range(obj, soffset, soffset + sremain); 1261 if (ret) 1262 return ret; 1263 1264 i915_gem_object_pin_pages(obj); 1265 1266 VM_OBJECT_WLOCK(obj->base.vm_obj); 1267 for (vm_page_t page = vm_page_find_least(obj->base.vm_obj, 1268 OFF_TO_IDX(offset));; page = vm_page_next(page)) { 1269 VM_OBJECT_WUNLOCK(obj->base.vm_obj); 1270 1271 if (remain <= 0) 1272 break; 1273 1274 /* Operation in this page 1275 * 1276 * shmem_page_offset = offset within page in shmem file 1277 * page_length = bytes to copy for this page 1278 */ 1279 shmem_page_offset = offset_in_page(offset); 1280 page_length = remain; 1281 if ((shmem_page_offset + page_length) > PAGE_SIZE) 1282 page_length = PAGE_SIZE - shmem_page_offset; 1283 1284 page_do_bit17_swizzling = obj_do_bit17_swizzling && 1285 (page_to_phys(page) & (1 << 17)) != 0; 1286 1287 ret = shmem_pread_fast(page, shmem_page_offset, page_length, 1288 user_data, page_do_bit17_swizzling, 1289 needs_clflush); 1290 if (ret == 0) 1291 goto next_page; 1292 1293 DRM_UNLOCK(dev); 1294 1295 if (likely(!i915_prefault_disable) && !prefaulted) { 1296 ret = fault_in_multipages_writeable(user_data, remain); 1297 /* Userspace is tricking us, but we've already clobbered 1298 * its pages with the prefault and promised to write the 1299 * data up to the first fault. Hence ignore any errors 1300 * and just continue. */ 1301 (void)ret; 1302 prefaulted = 1; 1303 } 1304 1305 ret = shmem_pread_slow(page, shmem_page_offset, page_length, 1306 user_data, page_do_bit17_swizzling, 1307 needs_clflush); 1308 1309 DRM_LOCK(dev); 1310 1311next_page: 1312 vm_page_reference(page); 1313 1314 if (ret) 1315 goto out; 1316 1317 remain -= page_length; 1318 user_data += page_length; 1319 offset += page_length; 1320 VM_OBJECT_WLOCK(obj->base.vm_obj); 1321 } 1322 1323out: 1324 i915_gem_object_unpin_pages(obj); 1325 i915_gem_object_put_pages_range(obj, soffset, soffset + sremain); 1326 1327 return ret; 1328} 1329 1330/** 1331 * Reads data from the object referenced by handle. 1332 * 1333 * On error, the contents of *data are undefined. 1334 */ 1335int 1336i915_gem_pread_ioctl(struct drm_device *dev, void *data, 1337 struct drm_file *file) 1338{ 1339 struct drm_i915_gem_pread *args = data; 1340 struct drm_i915_gem_object *obj; 1341 int ret = 0; 1342 1343 if (args->size == 0) 1344 return 0; 1345 1346 if (!useracc(to_user_ptr(args->data_ptr), args->size, VM_PROT_WRITE)) 1347 return -EFAULT; 1348 |
|
1099 ret = i915_mutex_lock_interruptible(dev); | 1349 ret = i915_mutex_lock_interruptible(dev); |
1100 if (ret != 0) 1101 goto unlocked; | 1350 if (ret) 1351 return ret; |
1102 | 1352 |
1103 obj = to_intel_bo(drm_gem_object_lookup(dev, file, handle)); | 1353 obj = to_intel_bo(drm_gem_object_lookup(dev, file, args->handle)); |
1104 if (&obj->base == NULL) { 1105 ret = -ENOENT; 1106 goto unlock; 1107 } | 1354 if (&obj->base == NULL) { 1355 ret = -ENOENT; 1356 goto unlock; 1357 } |
1108 if (offset > obj->base.size || size > obj->base.size - offset) { | 1358 1359 /* Bounds check source. */ 1360 if (args->offset > obj->base.size || 1361 args->size > obj->base.size - args->offset) { |
1109 ret = -EINVAL; 1110 goto out; 1111 } 1112 | 1362 ret = -EINVAL; 1363 goto out; 1364 } 1365 |
1113 if (rw == UIO_READ) { 1114 CTR3(KTR_DRM, "object_pread %p %jx %jx", obj, offset, size); 1115 ret = i915_gem_object_set_cpu_read_domain_range(obj, 1116 offset, size); 1117 if (ret != 0) 1118 goto out; 1119 ret = i915_gem_swap_io(dev, obj, data_ptr, size, offset, 1120 UIO_READ, file); 1121 } else { 1122 if (obj->phys_obj) { 1123 CTR3(KTR_DRM, "object_phys_write %p %jx %jx", obj, 1124 offset, size); 1125 ret = i915_gem_phys_pwrite(dev, obj, data_ptr, offset, 1126 size, file); 1127 } else if (obj->gtt_space && 1128 obj->base.write_domain != I915_GEM_DOMAIN_CPU) { 1129 CTR3(KTR_DRM, "object_gtt_write %p %jx %jx", obj, 1130 offset, size); 1131 ret = i915_gem_object_pin(obj, 0, true); 1132 if (ret != 0) 1133 goto out; 1134 ret = i915_gem_object_set_to_gtt_domain(obj, true); 1135 if (ret != 0) 1136 goto out_unpin; 1137 ret = i915_gem_object_put_fence(obj); 1138 if (ret != 0) 1139 goto out_unpin; 1140 ret = i915_gem_gtt_write(dev, obj, data_ptr, size, 1141 offset, file); 1142out_unpin: 1143 i915_gem_object_unpin(obj); 1144 } else { 1145 CTR3(KTR_DRM, "object_pwrite %p %jx %jx", obj, 1146 offset, size); 1147 ret = i915_gem_object_set_to_cpu_domain(obj, true); 1148 if (ret != 0) 1149 goto out; 1150 ret = i915_gem_swap_io(dev, obj, data_ptr, size, offset, 1151 UIO_WRITE, file); 1152 } | 1366#if 1 1367 KIB_NOTYET(); 1368#else 1369 /* prime objects have no backing filp to GEM pread/pwrite 1370 * pages from. 1371 */ 1372 if (!obj->base.filp) { 1373 ret = -EINVAL; 1374 goto out; |
1153 } | 1375 } |
1376#endif 1377 1378 CTR3(KTR_DRM, "pread %p %jx %jx", obj, args->offset, args->size); 1379 1380 ret = i915_gem_shmem_pread(dev, obj, args, file); 1381 |
|
1154out: 1155 drm_gem_object_unreference(&obj->base); 1156unlock: 1157 DRM_UNLOCK(dev); | 1382out: 1383 drm_gem_object_unreference(&obj->base); 1384unlock: 1385 DRM_UNLOCK(dev); |
1158unlocked: 1159 vm_page_unhold_pages(ma, npages); 1160free_ma: 1161 free(ma, DRM_I915_GEM); 1162 return (ret); | 1386 return ret; |
1163} 1164 | 1387} 1388 |
1165int 1166i915_gem_pread_ioctl(struct drm_device *dev, void *data, struct drm_file *file) | 1389/* This is the fast write path which cannot handle 1390 * page faults in the source data 1391 */ 1392 1393static inline int 1394fast_user_write(struct drm_device *dev, 1395 off_t page_base, int page_offset, 1396 char __user *user_data, 1397 int length) |
1167{ | 1398{ |
1168 struct drm_i915_gem_pread *args; | 1399 void __iomem *vaddr_atomic; 1400 void *vaddr; 1401 unsigned long unwritten; |
1169 | 1402 |
1170 args = data; 1171 return (i915_gem_obj_io(dev, args->handle, args->data_ptr, args->size, 1172 args->offset, UIO_READ, file)); | 1403 vaddr_atomic = pmap_mapdev_attr(dev->agp->base + page_base, 1404 length, PAT_WRITE_COMBINING); 1405 /* We can use the cpu mem copy function because this is X86. */ 1406 vaddr = (char *)vaddr_atomic + page_offset; 1407 unwritten = __copy_from_user_inatomic_nocache(vaddr, 1408 user_data, length); 1409 pmap_unmapdev((vm_offset_t)vaddr_atomic, length); 1410 return unwritten; |
1173} 1174 | 1411} 1412 |
1413/** 1414 * This is the fast pwrite path, where we copy the data directly from the 1415 * user into the GTT, uncached. 1416 */ 1417static int 1418i915_gem_gtt_pwrite_fast(struct drm_device *dev, 1419 struct drm_i915_gem_object *obj, 1420 struct drm_i915_gem_pwrite *args, 1421 struct drm_file *file) 1422{ 1423 ssize_t remain; 1424 off_t offset, page_base; 1425 char __user *user_data; 1426 int page_offset, page_length, ret; 1427 1428 ret = i915_gem_object_pin(obj, 0, true); 1429 /* XXXKIB ret = i915_gem_obj_ggtt_pin(obj, 0, true, true); */ 1430 if (ret != 0) 1431 goto out; 1432 1433 ret = i915_gem_object_set_to_gtt_domain(obj, true); 1434 if (ret) 1435 goto out_unpin; 1436 1437 ret = i915_gem_object_put_fence(obj); 1438 if (ret) 1439 goto out_unpin; 1440 1441 user_data = to_user_ptr(args->data_ptr); 1442 remain = args->size; 1443 1444 offset = obj->gtt_offset + args->offset; 1445 1446 while (remain > 0) { 1447 /* Operation in this page 1448 * 1449 * page_base = page offset within aperture 1450 * page_offset = offset within page 1451 * page_length = bytes to copy for this page 1452 */ 1453 page_base = offset & ~PAGE_MASK; 1454 page_offset = offset_in_page(offset); 1455 page_length = remain; 1456 if ((page_offset + remain) > PAGE_SIZE) 1457 page_length = PAGE_SIZE - page_offset; 1458 1459 /* If we get a fault while copying data, then (presumably) our 1460 * source page isn't available. Return the error and we'll 1461 * retry in the slow path. 1462 */ 1463 if (fast_user_write(dev, page_base, 1464 page_offset, user_data, page_length)) { 1465 ret = -EFAULT; 1466 goto out_unpin; 1467 } 1468 1469 remain -= page_length; 1470 user_data += page_length; 1471 offset += page_length; 1472 } 1473 1474out_unpin: 1475 i915_gem_object_unpin(obj); 1476out: 1477 return ret; 1478} 1479 1480/* Per-page copy function for the shmem pwrite fastpath. 1481 * Flushes invalid cachelines before writing to the target if 1482 * needs_clflush_before is set and flushes out any written cachelines after 1483 * writing if needs_clflush is set. */ 1484static int 1485shmem_pwrite_fast(vm_page_t page, int shmem_page_offset, int page_length, 1486 char __user *user_data, 1487 bool page_do_bit17_swizzling, 1488 bool needs_clflush_before, 1489 bool needs_clflush_after) 1490{ 1491 char *vaddr; 1492 struct sf_buf *sf; 1493 int ret; 1494 1495 if (unlikely(page_do_bit17_swizzling)) 1496 return -EINVAL; 1497 1498 sched_pin(); 1499 sf = sf_buf_alloc(page, SFB_NOWAIT | SFB_CPUPRIVATE); 1500 if (sf == NULL) { 1501 sched_unpin(); 1502 return (-EFAULT); 1503 } 1504 vaddr = (char *)sf_buf_kva(sf); 1505 if (needs_clflush_before) 1506 drm_clflush_virt_range(vaddr + shmem_page_offset, 1507 page_length); 1508 ret = __copy_from_user_inatomic_nocache(vaddr + shmem_page_offset, 1509 user_data, 1510 page_length); 1511 if (needs_clflush_after) 1512 drm_clflush_virt_range(vaddr + shmem_page_offset, 1513 page_length); 1514 sf_buf_free(sf); 1515 sched_unpin(); 1516 1517 return ret ? -EFAULT : 0; 1518} 1519 1520/* Only difference to the fast-path function is that this can handle bit17 1521 * and uses non-atomic copy and kmap functions. */ 1522static int 1523shmem_pwrite_slow(vm_page_t page, int shmem_page_offset, int page_length, 1524 char __user *user_data, 1525 bool page_do_bit17_swizzling, 1526 bool needs_clflush_before, 1527 bool needs_clflush_after) 1528{ 1529 char *vaddr; 1530 struct sf_buf *sf; 1531 int ret; 1532 1533 sf = sf_buf_alloc(page, 0); 1534 vaddr = (char *)sf_buf_kva(sf); 1535 if (unlikely(needs_clflush_before || page_do_bit17_swizzling)) 1536 shmem_clflush_swizzled_range(vaddr + shmem_page_offset, 1537 page_length, 1538 page_do_bit17_swizzling); 1539 if (page_do_bit17_swizzling) 1540 ret = __copy_from_user_swizzled(vaddr, shmem_page_offset, 1541 user_data, 1542 page_length); 1543 else 1544 ret = __copy_from_user(vaddr + shmem_page_offset, 1545 user_data, 1546 page_length); 1547 if (needs_clflush_after) 1548 shmem_clflush_swizzled_range(vaddr + shmem_page_offset, 1549 page_length, 1550 page_do_bit17_swizzling); 1551 sf_buf_free(sf); 1552 1553 return ret ? -EFAULT : 0; 1554} 1555 1556static int 1557i915_gem_shmem_pwrite(struct drm_device *dev, 1558 struct drm_i915_gem_object *obj, 1559 struct drm_i915_gem_pwrite *args, 1560 struct drm_file *file) 1561{ 1562 ssize_t remain, sremain; 1563 off_t offset, soffset; 1564 char __user *user_data; 1565 int shmem_page_offset, page_length, ret = 0; 1566 int obj_do_bit17_swizzling, page_do_bit17_swizzling; 1567 int hit_slowpath = 0; 1568 int needs_clflush_after = 0; 1569 int needs_clflush_before = 0; 1570 1571 user_data = to_user_ptr(args->data_ptr); 1572 sremain = remain = args->size; 1573 1574 obj_do_bit17_swizzling = i915_gem_object_needs_bit17_swizzle(obj); 1575 1576 if (obj->base.write_domain != I915_GEM_DOMAIN_CPU) { 1577 /* If we're not in the cpu write domain, set ourself into the gtt 1578 * write domain and manually flush cachelines (if required). This 1579 * optimizes for the case when the gpu will use the data 1580 * right away and we therefore have to clflush anyway. */ 1581 needs_clflush_after = cpu_write_needs_clflush(obj); 1582 ret = i915_gem_object_set_to_gtt_domain(obj, true); 1583 if (ret) 1584 return ret; 1585 } 1586 /* Same trick applies to invalidate partially written cachelines read 1587 * before writing. */ 1588 if ((obj->base.read_domains & I915_GEM_DOMAIN_CPU) == 0) 1589 needs_clflush_before = 1590 !cpu_cache_is_coherent(dev, obj->cache_level); 1591 1592 soffset = offset = args->offset; 1593 ret = i915_gem_object_get_pages_range(obj, soffset, soffset + sremain); 1594 if (ret) 1595 return ret; 1596 1597 i915_gem_object_pin_pages(obj); 1598 1599 obj->dirty = 1; 1600 1601 VM_OBJECT_WLOCK(obj->base.vm_obj); 1602 for (vm_page_t page = vm_page_find_least(obj->base.vm_obj, 1603 OFF_TO_IDX(offset));; page = vm_page_next(page)) { 1604 VM_OBJECT_WUNLOCK(obj->base.vm_obj); 1605 int partial_cacheline_write; 1606 1607 if (remain <= 0) 1608 break; 1609 1610 /* Operation in this page 1611 * 1612 * shmem_page_offset = offset within page in shmem file 1613 * page_length = bytes to copy for this page 1614 */ 1615 shmem_page_offset = offset_in_page(offset); 1616 1617 page_length = remain; 1618 if ((shmem_page_offset + page_length) > PAGE_SIZE) 1619 page_length = PAGE_SIZE - shmem_page_offset; 1620 1621 /* If we don't overwrite a cacheline completely we need to be 1622 * careful to have up-to-date data by first clflushing. Don't 1623 * overcomplicate things and flush the entire patch. */ 1624 partial_cacheline_write = needs_clflush_before && 1625 ((shmem_page_offset | page_length) 1626 & (cpu_clflush_line_size - 1)); 1627 1628 page_do_bit17_swizzling = obj_do_bit17_swizzling && 1629 (page_to_phys(page) & (1 << 17)) != 0; 1630 1631 ret = shmem_pwrite_fast(page, shmem_page_offset, page_length, 1632 user_data, page_do_bit17_swizzling, 1633 partial_cacheline_write, 1634 needs_clflush_after); 1635 if (ret == 0) 1636 goto next_page; 1637 1638 hit_slowpath = 1; 1639 DRM_UNLOCK(dev); 1640 ret = shmem_pwrite_slow(page, shmem_page_offset, page_length, 1641 user_data, page_do_bit17_swizzling, 1642 partial_cacheline_write, 1643 needs_clflush_after); 1644 1645 DRM_LOCK(dev); 1646 1647next_page: 1648 vm_page_dirty(page); 1649 vm_page_reference(page); 1650 1651 if (ret) 1652 goto out; 1653 1654 remain -= page_length; 1655 user_data += page_length; 1656 offset += page_length; 1657 VM_OBJECT_WLOCK(obj->base.vm_obj); 1658 } 1659 1660out: 1661 i915_gem_object_unpin_pages(obj); 1662 i915_gem_object_put_pages_range(obj, soffset, soffset + sremain); 1663 1664 if (hit_slowpath) { 1665 /* 1666 * Fixup: Flush cpu caches in case we didn't flush the dirty 1667 * cachelines in-line while writing and the object moved 1668 * out of the cpu write domain while we've dropped the lock. 1669 */ 1670 if (!needs_clflush_after && 1671 obj->base.write_domain != I915_GEM_DOMAIN_CPU) { 1672 i915_gem_clflush_object(obj); 1673 i915_gem_chipset_flush(dev); 1674 } 1675 } 1676 1677 if (needs_clflush_after) 1678 i915_gem_chipset_flush(dev); 1679 1680 return ret; 1681} 1682 1683/** 1684 * Writes data to the object referenced by handle. 1685 * 1686 * On error, the contents of the buffer that were to be modified are undefined. 1687 */ |
|
1175int | 1688int |
1176i915_gem_pwrite_ioctl(struct drm_device *dev, void *data, struct drm_file *file) | 1689i915_gem_pwrite_ioctl(struct drm_device *dev, void *data, 1690 struct drm_file *file) |
1177{ | 1691{ |
1178 struct drm_i915_gem_pwrite *args; | 1692 struct drm_i915_gem_pwrite *args = data; 1693 struct drm_i915_gem_object *obj; 1694 int ret; |
1179 | 1695 |
1180 args = data; 1181 return (i915_gem_obj_io(dev, args->handle, args->data_ptr, args->size, 1182 args->offset, UIO_WRITE, file)); | 1696 if (args->size == 0) 1697 return 0; 1698 1699 if (!useracc(to_user_ptr(args->data_ptr), args->size, VM_PROT_READ)) 1700 return -EFAULT; 1701 1702 if (likely(!i915_prefault_disable)) { 1703 ret = fault_in_multipages_readable(to_user_ptr(args->data_ptr), 1704 args->size); 1705 if (ret) 1706 return -EFAULT; 1707 } 1708 1709 ret = i915_mutex_lock_interruptible(dev); 1710 if (ret) 1711 return ret; 1712 1713 obj = to_intel_bo(drm_gem_object_lookup(dev, file, args->handle)); 1714 if (&obj->base == NULL) { 1715 ret = -ENOENT; 1716 goto unlock; 1717 } 1718 1719 /* Bounds check destination. */ 1720 if (args->offset > obj->base.size || 1721 args->size > obj->base.size - args->offset) { 1722 ret = -EINVAL; 1723 goto out; 1724 } 1725 1726#if 1 1727 KIB_NOTYET(); 1728#else 1729 /* prime objects have no backing filp to GEM pread/pwrite 1730 * pages from. 1731 */ 1732 if (!obj->base.filp) { 1733 ret = -EINVAL; 1734 goto out; 1735 } 1736#endif 1737 1738 CTR3(KTR_DRM, "pwrite %p %jx %jx", obj, args->offset, args->size); 1739 1740 ret = -EFAULT; 1741 /* We can only do the GTT pwrite on untiled buffers, as otherwise 1742 * it would end up going through the fenced access, and we'll get 1743 * different detiling behavior between reading and writing. 1744 * pread/pwrite currently are reading and writing from the CPU 1745 * perspective, requiring manual detiling by the client. 1746 */ 1747 if (obj->phys_obj) { 1748 ret = i915_gem_phys_pwrite(dev, obj, args, file); 1749 goto out; 1750 } 1751 1752 if (obj->tiling_mode == I915_TILING_NONE && 1753 obj->base.write_domain != I915_GEM_DOMAIN_CPU && 1754 cpu_write_needs_clflush(obj)) { 1755 ret = i915_gem_gtt_pwrite_fast(dev, obj, args, file); 1756 /* Note that the gtt paths might fail with non-page-backed user 1757 * pointers (e.g. gtt mappings when moving data between 1758 * textures). Fallback to the shmem path in that case. */ 1759 } 1760 1761 if (ret == -EFAULT || ret == -ENOSPC) 1762 ret = i915_gem_shmem_pwrite(dev, obj, args, file); 1763 1764out: 1765 drm_gem_object_unreference(&obj->base); 1766unlock: 1767 DRM_UNLOCK(dev); 1768 return ret; |
1183} | 1769} |
1770#undef __user 1771#undef __force 1772#undef __iomem 1773#undef to_user_ptr 1774#undef offset_in_page 1775#undef page_to_phys |
|
1184 1185int 1186i915_gem_set_domain_ioctl(struct drm_device *dev, void *data, 1187 struct drm_file *file) 1188{ 1189 struct drm_i915_gem_set_domain *args; 1190 struct drm_i915_gem_object *obj; 1191 uint32_t read_domains; 1192 uint32_t write_domain; 1193 int ret; 1194 | 1776 1777int 1778i915_gem_set_domain_ioctl(struct drm_device *dev, void *data, 1779 struct drm_file *file) 1780{ 1781 struct drm_i915_gem_set_domain *args; 1782 struct drm_i915_gem_object *obj; 1783 uint32_t read_domains; 1784 uint32_t write_domain; 1785 int ret; 1786 |
1195 if ((dev->driver->driver_features & DRIVER_GEM) == 0) 1196 return (-ENODEV); 1197 | |
1198 args = data; 1199 read_domains = args->read_domains; 1200 write_domain = args->write_domain; 1201 1202 if ((write_domain & I915_GEM_GPU_DOMAINS) != 0 || 1203 (read_domains & I915_GEM_GPU_DOMAINS) != 0 || 1204 (write_domain != 0 && read_domains != write_domain)) 1205 return (-EINVAL); --- 25 unchanged lines hidden (view full) --- 1231i915_gem_sw_finish_ioctl(struct drm_device *dev, void *data, 1232 struct drm_file *file) 1233{ 1234 struct drm_i915_gem_sw_finish *args; 1235 struct drm_i915_gem_object *obj; 1236 int ret; 1237 1238 args = data; | 1787 args = data; 1788 read_domains = args->read_domains; 1789 write_domain = args->write_domain; 1790 1791 if ((write_domain & I915_GEM_GPU_DOMAINS) != 0 || 1792 (read_domains & I915_GEM_GPU_DOMAINS) != 0 || 1793 (write_domain != 0 && read_domains != write_domain)) 1794 return (-EINVAL); --- 25 unchanged lines hidden (view full) --- 1820i915_gem_sw_finish_ioctl(struct drm_device *dev, void *data, 1821 struct drm_file *file) 1822{ 1823 struct drm_i915_gem_sw_finish *args; 1824 struct drm_i915_gem_object *obj; 1825 int ret; 1826 1827 args = data; |
1239 ret = 0; 1240 if ((dev->driver->driver_features & DRIVER_GEM) == 0) 1241 return (ENODEV); | 1828 |
1242 ret = i915_mutex_lock_interruptible(dev); 1243 if (ret != 0) 1244 return (ret); 1245 obj = to_intel_bo(drm_gem_object_lookup(dev, file, args->handle)); 1246 if (&obj->base == NULL) { 1247 ret = -ENOENT; 1248 goto unlock; 1249 } --- 14 unchanged lines hidden (view full) --- 1264 struct proc *p; 1265 vm_map_t map; 1266 vm_offset_t addr; 1267 vm_size_t size; 1268 int error, rv; 1269 1270 args = data; 1271 | 1829 ret = i915_mutex_lock_interruptible(dev); 1830 if (ret != 0) 1831 return (ret); 1832 obj = to_intel_bo(drm_gem_object_lookup(dev, file, args->handle)); 1833 if (&obj->base == NULL) { 1834 ret = -ENOENT; 1835 goto unlock; 1836 } --- 14 unchanged lines hidden (view full) --- 1851 struct proc *p; 1852 vm_map_t map; 1853 vm_offset_t addr; 1854 vm_size_t size; 1855 int error, rv; 1856 1857 args = data; 1858 |
1272 if ((dev->driver->driver_features & DRIVER_GEM) == 0) 1273 return (-ENODEV); 1274 | |
1275 obj = drm_gem_object_lookup(dev, file, args->handle); 1276 if (obj == NULL) 1277 return (-ENOENT); 1278 error = 0; 1279 if (args->size == 0) 1280 goto out; 1281 p = curproc; 1282 map = &p->p_vmspace->vm_map; --- 127 unchanged lines hidden (view full) --- 1410 1411 ret = i915_gem_object_set_to_gtt_domain(obj, write); 1412 if (ret != 0) { 1413 cause = 40; 1414 goto unlock; 1415 } 1416 } 1417 | 1859 obj = drm_gem_object_lookup(dev, file, args->handle); 1860 if (obj == NULL) 1861 return (-ENOENT); 1862 error = 0; 1863 if (args->size == 0) 1864 goto out; 1865 p = curproc; 1866 map = &p->p_vmspace->vm_map; --- 127 unchanged lines hidden (view full) --- 1994 1995 ret = i915_gem_object_set_to_gtt_domain(obj, write); 1996 if (ret != 0) { 1997 cause = 40; 1998 goto unlock; 1999 } 2000 } 2001 |
1418 if (obj->tiling_mode == I915_TILING_NONE) 1419 ret = i915_gem_object_put_fence(obj); 1420 else 1421 ret = i915_gem_object_get_fence(obj, NULL); | 2002 if (!obj->has_global_gtt_mapping) 2003 i915_gem_gtt_bind_object(obj, obj->cache_level); 2004 2005 ret = i915_gem_object_get_fence(obj); |
1422 if (ret != 0) { 1423 cause = 50; 1424 goto unlock; 1425 } 1426 1427 if (i915_gem_object_is_inactive(obj)) 1428 list_move_tail(&obj->mm_list, &dev_priv->mm.inactive_list); 1429 --- 82 unchanged lines hidden (view full) --- 1512int 1513i915_gem_mmap_gtt(struct drm_file *file, struct drm_device *dev, 1514 uint32_t handle, uint64_t *offset) 1515{ 1516 struct drm_i915_private *dev_priv; 1517 struct drm_i915_gem_object *obj; 1518 int ret; 1519 | 2006 if (ret != 0) { 2007 cause = 50; 2008 goto unlock; 2009 } 2010 2011 if (i915_gem_object_is_inactive(obj)) 2012 list_move_tail(&obj->mm_list, &dev_priv->mm.inactive_list); 2013 --- 82 unchanged lines hidden (view full) --- 2096int 2097i915_gem_mmap_gtt(struct drm_file *file, struct drm_device *dev, 2098 uint32_t handle, uint64_t *offset) 2099{ 2100 struct drm_i915_private *dev_priv; 2101 struct drm_i915_gem_object *obj; 2102 int ret; 2103 |
1520 if (!(dev->driver->driver_features & DRIVER_GEM)) 1521 return (-ENODEV); 1522 | |
1523 dev_priv = dev->dev_private; 1524 1525 ret = i915_mutex_lock_interruptible(dev); 1526 if (ret != 0) 1527 return (ret); 1528 1529 obj = to_intel_bo(drm_gem_object_lookup(dev, file, handle)); 1530 if (&obj->base == NULL) { --- 143 unchanged lines hidden (view full) --- 1674 1675 CTR3(KTR_DRM, "object_change_domain flush gtt_write %p %x %x", obj, 1676 obj->base.read_domains, old_write_domain); 1677} 1678 1679int 1680i915_gem_object_set_to_gtt_domain(struct drm_i915_gem_object *obj, bool write) 1681{ | 2104 dev_priv = dev->dev_private; 2105 2106 ret = i915_mutex_lock_interruptible(dev); 2107 if (ret != 0) 2108 return (ret); 2109 2110 obj = to_intel_bo(drm_gem_object_lookup(dev, file, handle)); 2111 if (&obj->base == NULL) { --- 143 unchanged lines hidden (view full) --- 2255 2256 CTR3(KTR_DRM, "object_change_domain flush gtt_write %p %x %x", obj, 2257 obj->base.read_domains, old_write_domain); 2258} 2259 2260int 2261i915_gem_object_set_to_gtt_domain(struct drm_i915_gem_object *obj, bool write) 2262{ |
2263 drm_i915_private_t *dev_priv = obj->base.dev->dev_private; |
|
1682 uint32_t old_write_domain, old_read_domains; 1683 int ret; 1684 1685 if (obj->gtt_space == NULL) 1686 return (-EINVAL); 1687 1688 if (obj->base.write_domain == I915_GEM_DOMAIN_GTT) 1689 return 0; --- 17 unchanged lines hidden (view full) --- 1707 ("In GTT write domain")); 1708 obj->base.read_domains |= I915_GEM_DOMAIN_GTT; 1709 if (write) { 1710 obj->base.read_domains = I915_GEM_DOMAIN_GTT; 1711 obj->base.write_domain = I915_GEM_DOMAIN_GTT; 1712 obj->dirty = 1; 1713 } 1714 | 2264 uint32_t old_write_domain, old_read_domains; 2265 int ret; 2266 2267 if (obj->gtt_space == NULL) 2268 return (-EINVAL); 2269 2270 if (obj->base.write_domain == I915_GEM_DOMAIN_GTT) 2271 return 0; --- 17 unchanged lines hidden (view full) --- 2289 ("In GTT write domain")); 2290 obj->base.read_domains |= I915_GEM_DOMAIN_GTT; 2291 if (write) { 2292 obj->base.read_domains = I915_GEM_DOMAIN_GTT; 2293 obj->base.write_domain = I915_GEM_DOMAIN_GTT; 2294 obj->dirty = 1; 2295 } 2296 |
2297 /* And bump the LRU for this access */ 2298 if (i915_gem_object_is_inactive(obj)) 2299 list_move_tail(&obj->mm_list, &dev_priv->mm.inactive_list); 2300 |
|
1715 CTR3(KTR_DRM, "object_change_domain set_to_gtt %p %x %x", obj, 1716 old_read_domains, old_write_domain); 1717 return (0); 1718} 1719 1720int 1721i915_gem_object_set_cache_level(struct drm_i915_gem_object *obj, 1722 enum i915_cache_level cache_level) --- 24 unchanged lines hidden (view full) --- 1747 * currently pointing to our region in the aperture. 1748 */ 1749 if (INTEL_INFO(obj->base.dev)->gen < 6) { 1750 ret = i915_gem_object_put_fence(obj); 1751 if (ret != 0) 1752 return (ret); 1753 } 1754 | 2301 CTR3(KTR_DRM, "object_change_domain set_to_gtt %p %x %x", obj, 2302 old_read_domains, old_write_domain); 2303 return (0); 2304} 2305 2306int 2307i915_gem_object_set_cache_level(struct drm_i915_gem_object *obj, 2308 enum i915_cache_level cache_level) --- 24 unchanged lines hidden (view full) --- 2333 * currently pointing to our region in the aperture. 2334 */ 2335 if (INTEL_INFO(obj->base.dev)->gen < 6) { 2336 ret = i915_gem_object_put_fence(obj); 2337 if (ret != 0) 2338 return (ret); 2339 } 2340 |
1755 i915_gem_gtt_rebind_object(obj, cache_level); | 2341 if (obj->has_global_gtt_mapping) 2342 i915_gem_gtt_bind_object(obj, cache_level); |
1756 if (obj->has_aliasing_ppgtt_mapping) 1757 i915_ppgtt_bind_object(dev_priv->mm.aliasing_ppgtt, 1758 obj, cache_level); 1759 } 1760 1761 if (cache_level == I915_CACHE_NONE) { 1762 u32 old_read_domains, old_write_domain; 1763 --- 17 unchanged lines hidden (view full) --- 1781 CTR3(KTR_DRM, "object_change_domain set_cache_level %p %x %x", 1782 obj, old_read_domains, old_write_domain); 1783 } 1784 1785 obj->cache_level = cache_level; 1786 return (0); 1787} 1788 | 2343 if (obj->has_aliasing_ppgtt_mapping) 2344 i915_ppgtt_bind_object(dev_priv->mm.aliasing_ppgtt, 2345 obj, cache_level); 2346 } 2347 2348 if (cache_level == I915_CACHE_NONE) { 2349 u32 old_read_domains, old_write_domain; 2350 --- 17 unchanged lines hidden (view full) --- 2368 CTR3(KTR_DRM, "object_change_domain set_cache_level %p %x %x", 2369 obj, old_read_domains, old_write_domain); 2370 } 2371 2372 obj->cache_level = cache_level; 2373 return (0); 2374} 2375 |
2376static bool is_pin_display(struct drm_i915_gem_object *obj) 2377{ 2378 /* There are 3 sources that pin objects: 2379 * 1. The display engine (scanouts, sprites, cursors); 2380 * 2. Reservations for execbuffer; 2381 * 3. The user. 2382 * 2383 * We can ignore reservations as we hold the struct_mutex and 2384 * are only called outside of the reservation path. The user 2385 * can only increment pin_count once, and so if after 2386 * subtracting the potential reference by the user, any pin_count 2387 * remains, it must be due to another use by the display engine. 2388 */ 2389 return obj->pin_count - !!obj->user_pin_count; 2390} 2391 |
|
1789int 1790i915_gem_object_pin_to_display_plane(struct drm_i915_gem_object *obj, 1791 u32 alignment, struct intel_ring_buffer *pipelined) 1792{ 1793 u32 old_read_domains, old_write_domain; 1794 int ret; 1795 1796 ret = i915_gem_object_flush_gpu_write_domain(obj); 1797 if (ret != 0) 1798 return (ret); 1799 1800 if (pipelined != obj->ring) { | 2392int 2393i915_gem_object_pin_to_display_plane(struct drm_i915_gem_object *obj, 2394 u32 alignment, struct intel_ring_buffer *pipelined) 2395{ 2396 u32 old_read_domains, old_write_domain; 2397 int ret; 2398 2399 ret = i915_gem_object_flush_gpu_write_domain(obj); 2400 if (ret != 0) 2401 return (ret); 2402 2403 if (pipelined != obj->ring) { |
1801 ret = i915_gem_object_wait_rendering(obj); 1802 if (ret == -ERESTART || ret == -EINTR) | 2404 ret = i915_gem_object_sync(obj, pipelined); 2405 if (ret) |
1803 return (ret); 1804 } 1805 | 2406 return (ret); 2407 } 2408 |
2409 obj->pin_display = true; |
|
1806 ret = i915_gem_object_set_cache_level(obj, I915_CACHE_NONE); 1807 if (ret != 0) | 2410 ret = i915_gem_object_set_cache_level(obj, I915_CACHE_NONE); 2411 if (ret != 0) |
1808 return (ret); | 2412 goto err_unpin_display; |
1809 1810 ret = i915_gem_object_pin(obj, alignment, true); 1811 if (ret != 0) | 2413 2414 ret = i915_gem_object_pin(obj, alignment, true); 2415 if (ret != 0) |
1812 return (ret); | 2416 goto err_unpin_display; |
1813 1814 i915_gem_object_flush_cpu_write_domain(obj); 1815 1816 old_write_domain = obj->base.write_domain; 1817 old_read_domains = obj->base.read_domains; 1818 1819 KASSERT((obj->base.write_domain & ~I915_GEM_DOMAIN_GTT) == 0, 1820 ("obj %p in GTT write domain", obj)); 1821 obj->base.read_domains |= I915_GEM_DOMAIN_GTT; 1822 1823 CTR3(KTR_DRM, "object_change_domain pin_to_display_plan %p %x %x", 1824 obj, old_read_domains, obj->base.write_domain); 1825 return (0); | 2417 2418 i915_gem_object_flush_cpu_write_domain(obj); 2419 2420 old_write_domain = obj->base.write_domain; 2421 old_read_domains = obj->base.read_domains; 2422 2423 KASSERT((obj->base.write_domain & ~I915_GEM_DOMAIN_GTT) == 0, 2424 ("obj %p in GTT write domain", obj)); 2425 obj->base.read_domains |= I915_GEM_DOMAIN_GTT; 2426 2427 CTR3(KTR_DRM, "object_change_domain pin_to_display_plan %p %x %x", 2428 obj, old_read_domains, obj->base.write_domain); 2429 return (0); |
2430 2431err_unpin_display: 2432 obj->pin_display = is_pin_display(obj); 2433 return ret; |
|
1826} 1827 | 2434} 2435 |
2436void 2437i915_gem_object_unpin_from_display_plane(struct drm_i915_gem_object *obj) 2438{ 2439 i915_gem_object_unpin(obj); 2440 obj->pin_display = is_pin_display(obj); 2441} 2442 |
|
1828int 1829i915_gem_object_finish_gpu(struct drm_i915_gem_object *obj) 1830{ 1831 int ret; 1832 1833 if ((obj->base.read_domains & I915_GEM_GPU_DOMAINS) == 0) 1834 return (0); 1835 --- 7 unchanged lines hidden (view full) --- 1843 if (ret != 0) 1844 return (ret); 1845 1846 obj->base.read_domains &= ~I915_GEM_GPU_DOMAINS; 1847 1848 return (0); 1849} 1850 | 2443int 2444i915_gem_object_finish_gpu(struct drm_i915_gem_object *obj) 2445{ 2446 int ret; 2447 2448 if ((obj->base.read_domains & I915_GEM_GPU_DOMAINS) == 0) 2449 return (0); 2450 --- 7 unchanged lines hidden (view full) --- 2458 if (ret != 0) 2459 return (ret); 2460 2461 obj->base.read_domains &= ~I915_GEM_GPU_DOMAINS; 2462 2463 return (0); 2464} 2465 |
1851static int | 2466int |
1852i915_gem_object_set_to_cpu_domain(struct drm_i915_gem_object *obj, bool write) 1853{ 1854 uint32_t old_write_domain, old_read_domains; 1855 int ret; 1856 1857 if (obj->base.write_domain == I915_GEM_DOMAIN_CPU) 1858 return 0; 1859 1860 ret = i915_gem_object_flush_gpu_write_domain(obj); 1861 if (ret != 0) 1862 return (ret); 1863 | 2467i915_gem_object_set_to_cpu_domain(struct drm_i915_gem_object *obj, bool write) 2468{ 2469 uint32_t old_write_domain, old_read_domains; 2470 int ret; 2471 2472 if (obj->base.write_domain == I915_GEM_DOMAIN_CPU) 2473 return 0; 2474 2475 ret = i915_gem_object_flush_gpu_write_domain(obj); 2476 if (ret != 0) 2477 return (ret); 2478 |
1864 ret = i915_gem_object_wait_rendering(obj); 1865 if (ret != 0) 1866 return (ret); | 2479 if (write || obj->pending_gpu_write) { 2480 ret = i915_gem_object_wait_rendering(obj); 2481 if (ret != 0) 2482 return (ret); 2483 } |
1867 1868 i915_gem_object_flush_gtt_write_domain(obj); | 2484 2485 i915_gem_object_flush_gtt_write_domain(obj); |
1869 i915_gem_object_set_to_full_cpu_read_domain(obj); | |
1870 1871 old_write_domain = obj->base.write_domain; 1872 old_read_domains = obj->base.read_domains; 1873 1874 if ((obj->base.read_domains & I915_GEM_DOMAIN_CPU) == 0) { 1875 i915_gem_clflush_object(obj); 1876 obj->base.read_domains |= I915_GEM_DOMAIN_CPU; 1877 } --- 6 unchanged lines hidden (view full) --- 1884 obj->base.write_domain = I915_GEM_DOMAIN_CPU; 1885 } 1886 1887 CTR3(KTR_DRM, "object_change_domain set_to_cpu %p %x %x", obj, 1888 old_read_domains, old_write_domain); 1889 return (0); 1890} 1891 | 2486 2487 old_write_domain = obj->base.write_domain; 2488 old_read_domains = obj->base.read_domains; 2489 2490 if ((obj->base.read_domains & I915_GEM_DOMAIN_CPU) == 0) { 2491 i915_gem_clflush_object(obj); 2492 obj->base.read_domains |= I915_GEM_DOMAIN_CPU; 2493 } --- 6 unchanged lines hidden (view full) --- 2500 obj->base.write_domain = I915_GEM_DOMAIN_CPU; 2501 } 2502 2503 CTR3(KTR_DRM, "object_change_domain set_to_cpu %p %x %x", obj, 2504 old_read_domains, old_write_domain); 2505 return (0); 2506} 2507 |
1892static void 1893i915_gem_object_set_to_full_cpu_read_domain(struct drm_i915_gem_object *obj) 1894{ 1895 int i; 1896 1897 if (obj->page_cpu_valid == NULL) 1898 return; 1899 1900 if ((obj->base.read_domains & I915_GEM_DOMAIN_CPU) != 0) { 1901 for (i = 0; i <= (obj->base.size - 1) / PAGE_SIZE; i++) { 1902 if (obj->page_cpu_valid[i] != 0) 1903 continue; 1904 drm_clflush_pages(obj->pages + i, 1); 1905 } 1906 } 1907 1908 free(obj->page_cpu_valid, DRM_I915_GEM); 1909 obj->page_cpu_valid = NULL; 1910} 1911 1912static int 1913i915_gem_object_set_cpu_read_domain_range(struct drm_i915_gem_object *obj, 1914 uint64_t offset, uint64_t size) 1915{ 1916 uint32_t old_read_domains; 1917 int i, ret; 1918 1919 if (offset == 0 && size == obj->base.size) 1920 return (i915_gem_object_set_to_cpu_domain(obj, 0)); 1921 1922 ret = i915_gem_object_flush_gpu_write_domain(obj); 1923 if (ret != 0) 1924 return (ret); 1925 ret = i915_gem_object_wait_rendering(obj); 1926 if (ret != 0) 1927 return (ret); 1928 1929 i915_gem_object_flush_gtt_write_domain(obj); 1930 1931 if (obj->page_cpu_valid == NULL && 1932 (obj->base.read_domains & I915_GEM_DOMAIN_CPU) != 0) 1933 return (0); 1934 1935 if (obj->page_cpu_valid == NULL) { 1936 obj->page_cpu_valid = malloc(obj->base.size / PAGE_SIZE, 1937 DRM_I915_GEM, M_WAITOK | M_ZERO); 1938 } else if ((obj->base.read_domains & I915_GEM_DOMAIN_CPU) == 0) 1939 memset(obj->page_cpu_valid, 0, obj->base.size / PAGE_SIZE); 1940 1941 for (i = offset / PAGE_SIZE; i <= (offset + size - 1) / PAGE_SIZE; 1942 i++) { 1943 if (obj->page_cpu_valid[i]) 1944 continue; 1945 drm_clflush_pages(obj->pages + i, 1); 1946 obj->page_cpu_valid[i] = 1; 1947 } 1948 1949 KASSERT((obj->base.write_domain & ~I915_GEM_DOMAIN_CPU) == 0, 1950 ("In gpu write domain")); 1951 1952 old_read_domains = obj->base.read_domains; 1953 obj->base.read_domains |= I915_GEM_DOMAIN_CPU; 1954 1955 CTR3(KTR_DRM, "object_change_domain set_cpu_read %p %x %x", obj, 1956 old_read_domains, obj->base.write_domain); 1957 return (0); 1958} 1959 | |
1960static uint32_t 1961i915_gem_get_gtt_size(struct drm_device *dev, uint32_t size, int tiling_mode) 1962{ 1963 uint32_t gtt_size; 1964 1965 if (INTEL_INFO(dev)->gen >= 4 || 1966 tiling_mode == I915_TILING_NONE) 1967 return (size); --- 134 unchanged lines hidden (view full) --- 2102 obj->gtt_space = NULL; 2103 /* 2104 * i915_gem_object_get_pages_gtt() cannot return 2105 * ENOMEM, since we use vm_page_grab(). 2106 */ 2107 return (ret); 2108 } 2109 | 2508static uint32_t 2509i915_gem_get_gtt_size(struct drm_device *dev, uint32_t size, int tiling_mode) 2510{ 2511 uint32_t gtt_size; 2512 2513 if (INTEL_INFO(dev)->gen >= 4 || 2514 tiling_mode == I915_TILING_NONE) 2515 return (size); --- 134 unchanged lines hidden (view full) --- 2650 obj->gtt_space = NULL; 2651 /* 2652 * i915_gem_object_get_pages_gtt() cannot return 2653 * ENOMEM, since we use vm_page_grab(). 2654 */ 2655 return (ret); 2656 } 2657 |
2110 ret = i915_gem_gtt_bind_object(obj); | 2658 ret = i915_gem_gtt_prepare_object(obj); |
2111 if (ret != 0) { 2112 i915_gem_object_put_pages_gtt(obj); 2113 drm_mm_put_block(obj->gtt_space); 2114 obj->gtt_space = NULL; 2115 if (i915_gem_evict_everything(dev, false)) 2116 return (ret); 2117 goto search_free; 2118 } 2119 | 2659 if (ret != 0) { 2660 i915_gem_object_put_pages_gtt(obj); 2661 drm_mm_put_block(obj->gtt_space); 2662 obj->gtt_space = NULL; 2663 if (i915_gem_evict_everything(dev, false)) 2664 return (ret); 2665 goto search_free; 2666 } 2667 |
2668 if (!dev_priv->mm.aliasing_ppgtt) 2669 i915_gem_gtt_bind_object(obj, obj->cache_level); 2670 |
|
2120 list_add_tail(&obj->gtt_list, &dev_priv->mm.gtt_list); 2121 list_add_tail(&obj->mm_list, &dev_priv->mm.inactive_list); 2122 2123 KASSERT((obj->base.read_domains & I915_GEM_GPU_DOMAINS) == 0, 2124 ("Object in gpu read domain")); 2125 KASSERT((obj->base.write_domain & I915_GEM_GPU_DOMAINS) == 0, 2126 ("Object in gpu write domain")); 2127 --- 7 unchanged lines hidden (view full) --- 2135 obj->gtt_offset + obj->base.size <= dev_priv->mm.gtt_mappable_end; 2136 obj->map_and_fenceable = mappable && fenceable; 2137 2138 CTR4(KTR_DRM, "object_bind %p %x %x %d", obj, obj->gtt_offset, 2139 obj->base.size, map_and_fenceable); 2140 return (0); 2141} 2142 | 2671 list_add_tail(&obj->gtt_list, &dev_priv->mm.gtt_list); 2672 list_add_tail(&obj->mm_list, &dev_priv->mm.inactive_list); 2673 2674 KASSERT((obj->base.read_domains & I915_GEM_GPU_DOMAINS) == 0, 2675 ("Object in gpu read domain")); 2676 KASSERT((obj->base.write_domain & I915_GEM_GPU_DOMAINS) == 0, 2677 ("Object in gpu write domain")); 2678 --- 7 unchanged lines hidden (view full) --- 2686 obj->gtt_offset + obj->base.size <= dev_priv->mm.gtt_mappable_end; 2687 obj->map_and_fenceable = mappable && fenceable; 2688 2689 CTR4(KTR_DRM, "object_bind %p %x %x %d", obj, obj->gtt_offset, 2690 obj->base.size, map_and_fenceable); 2691 return (0); 2692} 2693 |
2143static void 2144i915_gem_object_finish_gtt(struct drm_i915_gem_object *obj) | 2694int 2695i915_gem_object_sync(struct drm_i915_gem_object *obj, 2696 struct intel_ring_buffer *to) |
2145{ | 2697{ |
2698 struct intel_ring_buffer *from = obj->ring; 2699 u32 seqno; 2700 int ret, idx; 2701 2702 if (from == NULL || to == from) 2703 return 0; 2704 2705 if (to == NULL || !i915_semaphore_is_enabled(obj->base.dev)) 2706 return i915_gem_object_wait_rendering(obj); 2707 2708 idx = intel_ring_sync_index(from, to); 2709 2710 seqno = obj->last_rendering_seqno; 2711 if (seqno <= from->sync_seqno[idx]) 2712 return 0; 2713 2714 if (seqno == from->outstanding_lazy_request) { 2715 struct drm_i915_gem_request *request; 2716 2717 request = malloc(sizeof(*request), DRM_I915_GEM, 2718 M_WAITOK | M_ZERO); 2719 ret = i915_add_request(from, NULL, request); 2720 if (ret) { 2721 free(request, DRM_I915_GEM); 2722 return ret; 2723 } 2724 seqno = request->seqno; 2725 } 2726 2727 2728 ret = to->sync_to(to, from, seqno); 2729 if (!ret) 2730 from->sync_seqno[idx] = seqno; 2731 2732 return ret; 2733} 2734 2735static void i915_gem_object_finish_gtt(struct drm_i915_gem_object *obj) 2736{ |
|
2146 u32 old_write_domain, old_read_domains; 2147 2148 /* Act a barrier for all accesses through the GTT */ 2149 mb(); 2150 2151 /* Force a pagefault for domain tracking on next user access */ 2152 i915_gem_release_mmap(obj); 2153 --- 37 unchanged lines hidden (view full) --- 2191 return (ret); 2192 if (ret != 0) { 2193 i915_gem_clflush_object(obj); 2194 obj->base.read_domains = obj->base.write_domain = 2195 I915_GEM_DOMAIN_CPU; 2196 } 2197 2198 ret = i915_gem_object_put_fence(obj); | 2737 u32 old_write_domain, old_read_domains; 2738 2739 /* Act a barrier for all accesses through the GTT */ 2740 mb(); 2741 2742 /* Force a pagefault for domain tracking on next user access */ 2743 i915_gem_release_mmap(obj); 2744 --- 37 unchanged lines hidden (view full) --- 2782 return (ret); 2783 if (ret != 0) { 2784 i915_gem_clflush_object(obj); 2785 obj->base.read_domains = obj->base.write_domain = 2786 I915_GEM_DOMAIN_CPU; 2787 } 2788 2789 ret = i915_gem_object_put_fence(obj); |
2199 if (ret == -ERESTART) | 2790 if (ret) |
2200 return (ret); 2201 | 2791 return (ret); 2792 |
2202 i915_gem_gtt_unbind_object(obj); | 2793 if (obj->has_global_gtt_mapping) 2794 i915_gem_gtt_unbind_object(obj); |
2203 if (obj->has_aliasing_ppgtt_mapping) { 2204 i915_ppgtt_unbind_object(dev_priv->mm.aliasing_ppgtt, obj); 2205 obj->has_aliasing_ppgtt_mapping = 0; 2206 } | 2795 if (obj->has_aliasing_ppgtt_mapping) { 2796 i915_ppgtt_unbind_object(dev_priv->mm.aliasing_ppgtt, obj); 2797 obj->has_aliasing_ppgtt_mapping = 0; 2798 } |
2799 i915_gem_gtt_finish_object(obj); 2800 |
|
2207 i915_gem_object_put_pages_gtt(obj); 2208 2209 list_del_init(&obj->gtt_list); 2210 list_del_init(&obj->mm_list); 2211 obj->map_and_fenceable = true; 2212 2213 drm_mm_put_block(obj->gtt_space); 2214 obj->gtt_space = NULL; 2215 obj->gtt_offset = 0; 2216 2217 if (i915_gem_object_is_purgeable(obj)) 2218 i915_gem_object_truncate(obj); 2219 CTR1(KTR_DRM, "object_unbind %p", obj); 2220 2221 return (ret); 2222} 2223 | 2801 i915_gem_object_put_pages_gtt(obj); 2802 2803 list_del_init(&obj->gtt_list); 2804 list_del_init(&obj->mm_list); 2805 obj->map_and_fenceable = true; 2806 2807 drm_mm_put_block(obj->gtt_space); 2808 obj->gtt_space = NULL; 2809 obj->gtt_offset = 0; 2810 2811 if (i915_gem_object_is_purgeable(obj)) 2812 i915_gem_object_truncate(obj); 2813 CTR1(KTR_DRM, "object_unbind %p", obj); 2814 2815 return (ret); 2816} 2817 |
2818static void 2819i915_gem_object_put_pages_range_locked(struct drm_i915_gem_object *obj, 2820 vm_pindex_t si, vm_pindex_t ei) 2821{ 2822 vm_object_t vm_obj; 2823 vm_page_t m; 2824 vm_pindex_t i; 2825 2826 vm_obj = obj->base.vm_obj; 2827 VM_OBJECT_ASSERT_LOCKED(vm_obj); 2828 for (i = si, m = vm_page_lookup(vm_obj, i); i < ei; 2829 m = vm_page_next(m), i++) { 2830 KASSERT(m->pindex == i, ("pindex %jx %jx", 2831 (uintmax_t)m->pindex, (uintmax_t)i)); 2832 vm_page_lock(m); 2833 vm_page_unwire(m, PQ_INACTIVE); 2834 if (m->wire_count == 0) 2835 atomic_add_long(&i915_gem_wired_pages_cnt, -1); 2836 vm_page_unlock(m); 2837 } 2838} 2839 2840static void 2841i915_gem_object_put_pages_range(struct drm_i915_gem_object *obj, 2842 off_t start, off_t end) 2843{ 2844 vm_object_t vm_obj; 2845 2846 vm_obj = obj->base.vm_obj; 2847 VM_OBJECT_WLOCK(vm_obj); 2848 i915_gem_object_put_pages_range_locked(obj, 2849 OFF_TO_IDX(trunc_page(start)), OFF_TO_IDX(round_page(end))); 2850 VM_OBJECT_WUNLOCK(vm_obj); 2851} 2852 |
|
2224static int | 2853static int |
2854i915_gem_object_get_pages_range(struct drm_i915_gem_object *obj, 2855 off_t start, off_t end) 2856{ 2857 vm_object_t vm_obj; 2858 vm_page_t m; 2859 vm_pindex_t si, ei, i; 2860 bool need_swizzle, fresh; 2861 2862 need_swizzle = i915_gem_object_needs_bit17_swizzle(obj) != 0; 2863 vm_obj = obj->base.vm_obj; 2864 si = OFF_TO_IDX(trunc_page(start)); 2865 ei = OFF_TO_IDX(round_page(end)); 2866 VM_OBJECT_WLOCK(vm_obj); 2867 for (i = si; i < ei; i++) { 2868 m = i915_gem_wire_page(vm_obj, i, &fresh); 2869 if (m == NULL) 2870 goto failed; 2871 if (need_swizzle && fresh) 2872 i915_gem_object_do_bit_17_swizzle_page(obj, m); 2873 } 2874 VM_OBJECT_WUNLOCK(vm_obj); 2875 return (0); 2876failed: 2877 i915_gem_object_put_pages_range_locked(obj, si, i); 2878 VM_OBJECT_WUNLOCK(vm_obj); 2879 return (-EIO); 2880} 2881 2882static int |
|
2225i915_gem_object_get_pages_gtt(struct drm_i915_gem_object *obj, 2226 int flags) 2227{ 2228 struct drm_device *dev; 2229 vm_object_t vm_obj; 2230 vm_page_t m; | 2883i915_gem_object_get_pages_gtt(struct drm_i915_gem_object *obj, 2884 int flags) 2885{ 2886 struct drm_device *dev; 2887 vm_object_t vm_obj; 2888 vm_page_t m; |
2231 int page_count, i, j; | 2889 vm_pindex_t i, page_count; 2890 int res; |
2232 2233 dev = obj->base.dev; 2234 KASSERT(obj->pages == NULL, ("Obj already has pages")); | 2891 2892 dev = obj->base.dev; 2893 KASSERT(obj->pages == NULL, ("Obj already has pages")); |
2235 page_count = obj->base.size / PAGE_SIZE; | 2894 page_count = OFF_TO_IDX(obj->base.size); |
2236 obj->pages = malloc(page_count * sizeof(vm_page_t), DRM_I915_GEM, 2237 M_WAITOK); | 2895 obj->pages = malloc(page_count * sizeof(vm_page_t), DRM_I915_GEM, 2896 M_WAITOK); |
2897 res = i915_gem_object_get_pages_range(obj, 0, obj->base.size); 2898 if (res != 0) { 2899 free(obj->pages, DRM_I915_GEM); 2900 obj->pages = NULL; 2901 return (res); 2902 } |
|
2238 vm_obj = obj->base.vm_obj; 2239 VM_OBJECT_WLOCK(vm_obj); | 2903 vm_obj = obj->base.vm_obj; 2904 VM_OBJECT_WLOCK(vm_obj); |
2240 for (i = 0; i < page_count; i++) { 2241 if ((obj->pages[i] = i915_gem_wire_page(vm_obj, i)) == NULL) 2242 goto failed; | 2905 for (i = 0, m = vm_page_lookup(vm_obj, 0); i < page_count; 2906 i++, m = vm_page_next(m)) { 2907 KASSERT(m->pindex == i, ("pindex %jx %jx", 2908 (uintmax_t)m->pindex, (uintmax_t)i)); 2909 obj->pages[i] = m; |
2243 } 2244 VM_OBJECT_WUNLOCK(vm_obj); | 2910 } 2911 VM_OBJECT_WUNLOCK(vm_obj); |
2245 if (i915_gem_object_needs_bit17_swizzle(obj)) 2246 i915_gem_object_do_bit_17_swizzle(obj); | |
2247 return (0); | 2912 return (0); |
2248 2249failed: 2250 for (j = 0; j < i; j++) { 2251 m = obj->pages[j]; 2252 vm_page_lock(m); 2253 vm_page_unwire(m, PQ_INACTIVE); 2254 vm_page_unlock(m); 2255 atomic_add_long(&i915_gem_wired_pages_cnt, -1); 2256 } 2257 VM_OBJECT_WUNLOCK(vm_obj); 2258 free(obj->pages, DRM_I915_GEM); 2259 obj->pages = NULL; 2260 return (-EIO); | |
2261} 2262 2263#define GEM_PARANOID_CHECK_GTT 0 2264#if GEM_PARANOID_CHECK_GTT 2265static void 2266i915_gem_assert_pages_not_mapped(struct drm_device *dev, vm_page_t *ma, 2267 int page_count) 2268{ --- 92 unchanged lines hidden (view full) --- 2361 2362 KASSERT((obj->base.write_domain & I915_GEM_GPU_DOMAINS) == 0, 2363 ("In GPU write domain")); 2364 2365 CTR5(KTR_DRM, "object_wait_rendering %p %s %x %d %d", obj, 2366 obj->ring != NULL ? obj->ring->name : "none", obj->gtt_offset, 2367 obj->active, obj->last_rendering_seqno); 2368 if (obj->active) { | 2913} 2914 2915#define GEM_PARANOID_CHECK_GTT 0 2916#if GEM_PARANOID_CHECK_GTT 2917static void 2918i915_gem_assert_pages_not_mapped(struct drm_device *dev, vm_page_t *ma, 2919 int page_count) 2920{ --- 92 unchanged lines hidden (view full) --- 3013 3014 KASSERT((obj->base.write_domain & I915_GEM_GPU_DOMAINS) == 0, 3015 ("In GPU write domain")); 3016 3017 CTR5(KTR_DRM, "object_wait_rendering %p %s %x %d %d", obj, 3018 obj->ring != NULL ? obj->ring->name : "none", obj->gtt_offset, 3019 obj->active, obj->last_rendering_seqno); 3020 if (obj->active) { |
2369 ret = i915_wait_request(obj->ring, obj->last_rendering_seqno, 2370 true); | 3021 ret = i915_wait_request(obj->ring, obj->last_rendering_seqno); |
2371 if (ret != 0) 2372 return (ret); | 3022 if (ret != 0) 3023 return (ret); |
3024 i915_gem_retire_requests_ring(obj->ring); |
|
2373 } 2374 return (0); 2375} 2376 2377void 2378i915_gem_object_move_to_active(struct drm_i915_gem_object *obj, 2379 struct intel_ring_buffer *ring, uint32_t seqno) 2380{ --- 12 unchanged lines hidden (view full) --- 2393 2394 /* Move from whatever list we were on to the tail of execution. */ 2395 list_move_tail(&obj->mm_list, &dev_priv->mm.active_list); 2396 list_move_tail(&obj->ring_list, &ring->active_list); 2397 2398 obj->last_rendering_seqno = seqno; 2399 if (obj->fenced_gpu_access) { 2400 obj->last_fenced_seqno = seqno; | 3025 } 3026 return (0); 3027} 3028 3029void 3030i915_gem_object_move_to_active(struct drm_i915_gem_object *obj, 3031 struct intel_ring_buffer *ring, uint32_t seqno) 3032{ --- 12 unchanged lines hidden (view full) --- 3045 3046 /* Move from whatever list we were on to the tail of execution. */ 3047 list_move_tail(&obj->mm_list, &dev_priv->mm.active_list); 3048 list_move_tail(&obj->ring_list, &ring->active_list); 3049 3050 obj->last_rendering_seqno = seqno; 3051 if (obj->fenced_gpu_access) { 3052 obj->last_fenced_seqno = seqno; |
2401 obj->last_fenced_ring = ring; | |
2402 2403 /* Bump MRU to take account of the delayed flush */ 2404 if (obj->fence_reg != I915_FENCE_REG_NONE) { 2405 reg = &dev_priv->fence_regs[obj->fence_reg]; 2406 list_move_tail(®->lru_list, 2407 &dev_priv->mm.fence_list); 2408 } 2409 } --- 20 unchanged lines hidden (view full) --- 2430} 2431 2432static void 2433i915_gem_object_move_to_inactive(struct drm_i915_gem_object *obj) 2434{ 2435 struct drm_device *dev = obj->base.dev; 2436 struct drm_i915_private *dev_priv = dev->dev_private; 2437 | 3053 3054 /* Bump MRU to take account of the delayed flush */ 3055 if (obj->fence_reg != I915_FENCE_REG_NONE) { 3056 reg = &dev_priv->fence_regs[obj->fence_reg]; 3057 list_move_tail(®->lru_list, 3058 &dev_priv->mm.fence_list); 3059 } 3060 } --- 20 unchanged lines hidden (view full) --- 3081} 3082 3083static void 3084i915_gem_object_move_to_inactive(struct drm_i915_gem_object *obj) 3085{ 3086 struct drm_device *dev = obj->base.dev; 3087 struct drm_i915_private *dev_priv = dev->dev_private; 3088 |
2438 if (obj->pin_count != 0) 2439 list_move_tail(&obj->mm_list, &dev_priv->mm.pinned_list); 2440 else 2441 list_move_tail(&obj->mm_list, &dev_priv->mm.inactive_list); | 3089 list_move_tail(&obj->mm_list, &dev_priv->mm.inactive_list); |
2442 2443 KASSERT(list_empty(&obj->gpu_write_list), ("On gpu_write_list")); 2444 KASSERT(obj->active, ("Object not active")); 2445 obj->ring = NULL; | 3090 3091 KASSERT(list_empty(&obj->gpu_write_list), ("On gpu_write_list")); 3092 KASSERT(obj->active, ("Object not active")); 3093 obj->ring = NULL; |
2446 obj->last_fenced_ring = NULL; | |
2447 2448 i915_gem_object_move_off_active(obj); 2449 obj->fenced_gpu_access = false; 2450 2451 obj->active = 0; 2452 obj->pending_gpu_write = false; 2453 drm_gem_object_unreference(&obj->base); 2454 --- 8 unchanged lines hidden (view full) --- 2463i915_gem_object_truncate(struct drm_i915_gem_object *obj) 2464{ 2465 vm_object_t vm_obj; 2466 2467 vm_obj = obj->base.vm_obj; 2468 VM_OBJECT_WLOCK(vm_obj); 2469 vm_object_page_remove(vm_obj, 0, 0, false); 2470 VM_OBJECT_WUNLOCK(vm_obj); | 3094 3095 i915_gem_object_move_off_active(obj); 3096 obj->fenced_gpu_access = false; 3097 3098 obj->active = 0; 3099 obj->pending_gpu_write = false; 3100 drm_gem_object_unreference(&obj->base); 3101 --- 8 unchanged lines hidden (view full) --- 3110i915_gem_object_truncate(struct drm_i915_gem_object *obj) 3111{ 3112 vm_object_t vm_obj; 3113 3114 vm_obj = obj->base.vm_obj; 3115 VM_OBJECT_WLOCK(vm_obj); 3116 vm_object_page_remove(vm_obj, 0, 0, false); 3117 VM_OBJECT_WUNLOCK(vm_obj); |
3118 drm_gem_free_mmap_offset(&obj->base); |
|
2471 obj->madv = I915_MADV_PURGED_INTERNAL; 2472} 2473 2474static inline int 2475i915_gem_object_is_purgeable(struct drm_i915_gem_object *obj) 2476{ 2477 2478 return (obj->madv == I915_MADV_DONTNEED); --- 27 unchanged lines hidden (view full) --- 2506 drm_i915_private_t *dev_priv; 2507 2508 dev_priv = obj->base.dev->dev_private; 2509 return (dev_priv->mm.bit_6_swizzle_x == I915_BIT_6_SWIZZLE_9_10_17 && 2510 obj->tiling_mode != I915_TILING_NONE); 2511} 2512 2513static vm_page_t | 3119 obj->madv = I915_MADV_PURGED_INTERNAL; 3120} 3121 3122static inline int 3123i915_gem_object_is_purgeable(struct drm_i915_gem_object *obj) 3124{ 3125 3126 return (obj->madv == I915_MADV_DONTNEED); --- 27 unchanged lines hidden (view full) --- 3154 drm_i915_private_t *dev_priv; 3155 3156 dev_priv = obj->base.dev->dev_private; 3157 return (dev_priv->mm.bit_6_swizzle_x == I915_BIT_6_SWIZZLE_9_10_17 && 3158 obj->tiling_mode != I915_TILING_NONE); 3159} 3160 3161static vm_page_t |
2514i915_gem_wire_page(vm_object_t object, vm_pindex_t pindex) | 3162i915_gem_wire_page(vm_object_t object, vm_pindex_t pindex, bool *fresh) |
2515{ 2516 vm_page_t m; 2517 int rv; 2518 2519 VM_OBJECT_ASSERT_WLOCKED(object); 2520 m = vm_page_grab(object, pindex, VM_ALLOC_NORMAL); 2521 if (m->valid != VM_PAGE_BITS_ALL) { 2522 if (vm_pager_has_page(object, pindex, NULL, NULL)) { 2523 rv = vm_pager_get_pages(object, &m, 1, 0); 2524 m = vm_page_lookup(object, pindex); 2525 if (m == NULL) 2526 return (NULL); 2527 if (rv != VM_PAGER_OK) { 2528 vm_page_lock(m); 2529 vm_page_free(m); 2530 vm_page_unlock(m); 2531 return (NULL); 2532 } | 3163{ 3164 vm_page_t m; 3165 int rv; 3166 3167 VM_OBJECT_ASSERT_WLOCKED(object); 3168 m = vm_page_grab(object, pindex, VM_ALLOC_NORMAL); 3169 if (m->valid != VM_PAGE_BITS_ALL) { 3170 if (vm_pager_has_page(object, pindex, NULL, NULL)) { 3171 rv = vm_pager_get_pages(object, &m, 1, 0); 3172 m = vm_page_lookup(object, pindex); 3173 if (m == NULL) 3174 return (NULL); 3175 if (rv != VM_PAGER_OK) { 3176 vm_page_lock(m); 3177 vm_page_free(m); 3178 vm_page_unlock(m); 3179 return (NULL); 3180 } |
3181 if (fresh != NULL) 3182 *fresh = true; |
|
2533 } else { 2534 pmap_zero_page(m); 2535 m->valid = VM_PAGE_BITS_ALL; 2536 m->dirty = 0; | 3183 } else { 3184 pmap_zero_page(m); 3185 m->valid = VM_PAGE_BITS_ALL; 3186 m->dirty = 0; |
3187 if (fresh != NULL) 3188 *fresh = false; |
|
2537 } | 3189 } |
3190 } else if (fresh != NULL) { 3191 *fresh = false; |
|
2538 } 2539 vm_page_lock(m); 2540 vm_page_wire(m); 2541 vm_page_unlock(m); 2542 vm_page_xunbusy(m); 2543 atomic_add_long(&i915_gem_wired_pages_cnt, 1); 2544 return (m); 2545} --- 14 unchanged lines hidden (view full) --- 2560 return ret; 2561 2562 if (flush_domains & I915_GEM_GPU_DOMAINS) 2563 i915_gem_process_flushing_list(ring, flush_domains); 2564 return 0; 2565} 2566 2567static int | 3192 } 3193 vm_page_lock(m); 3194 vm_page_wire(m); 3195 vm_page_unlock(m); 3196 vm_page_xunbusy(m); 3197 atomic_add_long(&i915_gem_wired_pages_cnt, 1); 3198 return (m); 3199} --- 14 unchanged lines hidden (view full) --- 3214 return ret; 3215 3216 if (flush_domains & I915_GEM_GPU_DOMAINS) 3217 i915_gem_process_flushing_list(ring, flush_domains); 3218 return 0; 3219} 3220 3221static int |
2568i915_ring_idle(struct intel_ring_buffer *ring, bool do_retire) | 3222i915_ring_idle(struct intel_ring_buffer *ring) |
2569{ 2570 int ret; 2571 2572 if (list_empty(&ring->gpu_write_list) && list_empty(&ring->active_list)) 2573 return 0; 2574 2575 if (!list_empty(&ring->gpu_write_list)) { 2576 ret = i915_gem_flush_ring(ring, I915_GEM_GPU_DOMAINS, 2577 I915_GEM_GPU_DOMAINS); 2578 if (ret != 0) 2579 return ret; 2580 } 2581 | 3223{ 3224 int ret; 3225 3226 if (list_empty(&ring->gpu_write_list) && list_empty(&ring->active_list)) 3227 return 0; 3228 3229 if (!list_empty(&ring->gpu_write_list)) { 3230 ret = i915_gem_flush_ring(ring, I915_GEM_GPU_DOMAINS, 3231 I915_GEM_GPU_DOMAINS); 3232 if (ret != 0) 3233 return ret; 3234 } 3235 |
2582 return (i915_wait_request(ring, i915_gem_next_request_seqno(ring), 2583 do_retire)); | 3236 return (i915_wait_request(ring, i915_gem_next_request_seqno(ring))); |
2584} 2585 2586int | 3237} 3238 3239int |
2587i915_gpu_idle(struct drm_device *dev, bool do_retire) | 3240i915_gpu_idle(struct drm_device *dev) |
2588{ 2589 drm_i915_private_t *dev_priv = dev->dev_private; 2590 struct intel_ring_buffer *ring; 2591 int ret, i; 2592 2593 /* Flush everything onto the inactive list. */ 2594 for_each_ring(ring, dev_priv, i) { 2595 ret = i915_switch_context(ring, NULL, DEFAULT_CONTEXT_ID); 2596 if (ret) 2597 return ret; 2598 | 3241{ 3242 drm_i915_private_t *dev_priv = dev->dev_private; 3243 struct intel_ring_buffer *ring; 3244 int ret, i; 3245 3246 /* Flush everything onto the inactive list. */ 3247 for_each_ring(ring, dev_priv, i) { 3248 ret = i915_switch_context(ring, NULL, DEFAULT_CONTEXT_ID); 3249 if (ret) 3250 return ret; 3251 |
2599 ret = i915_ring_idle(ring, do_retire); | 3252 ret = i915_ring_idle(ring); |
2600 if (ret) 2601 return ret; | 3253 if (ret) 3254 return ret; |
3255 3256 /* Is the device fubar? */ 3257 if (!list_empty(&ring->gpu_write_list)) 3258 return -EBUSY; |
|
2602 } 2603 2604 return 0; 2605} 2606 | 3259 } 3260 3261 return 0; 3262} 3263 |
2607int 2608i915_wait_request(struct intel_ring_buffer *ring, uint32_t seqno, bool do_retire) | 3264static int 3265i915_gem_check_wedge(struct drm_i915_private *dev_priv) |
2609{ | 3266{ |
2610 drm_i915_private_t *dev_priv; 2611 struct drm_i915_gem_request *request; 2612 uint32_t ier; 2613 int flags, ret; 2614 bool recovery_complete; | 3267 DRM_LOCK_ASSERT(dev_priv->dev); |
2615 | 3268 |
2616 KASSERT(seqno != 0, ("Zero seqno")); 2617 2618 dev_priv = ring->dev->dev_private; 2619 ret = 0; 2620 | |
2621 if (atomic_load_acq_int(&dev_priv->mm.wedged) != 0) { | 3269 if (atomic_load_acq_int(&dev_priv->mm.wedged) != 0) { |
3270 bool recovery_complete; |
|
2622 /* Give the error handler a chance to run. */ 2623 mtx_lock(&dev_priv->error_completion_lock); 2624 recovery_complete = (&dev_priv->error_completion) > 0; 2625 mtx_unlock(&dev_priv->error_completion_lock); 2626 return (recovery_complete ? -EIO : -EAGAIN); 2627 } 2628 | 3271 /* Give the error handler a chance to run. */ 3272 mtx_lock(&dev_priv->error_completion_lock); 3273 recovery_complete = (&dev_priv->error_completion) > 0; 3274 mtx_unlock(&dev_priv->error_completion_lock); 3275 return (recovery_complete ? -EIO : -EAGAIN); 3276 } 3277 |
3278 return 0; 3279} 3280 3281/* 3282 * Compare seqno against outstanding lazy request. Emit a request if they are 3283 * equal. 3284 */ 3285static int 3286i915_gem_check_olr(struct intel_ring_buffer *ring, u32 seqno) 3287{ 3288 int ret = 0; 3289 3290 DRM_LOCK_ASSERT(ring->dev); 3291 |
|
2629 if (seqno == ring->outstanding_lazy_request) { | 3292 if (seqno == ring->outstanding_lazy_request) { |
3293 struct drm_i915_gem_request *request; 3294 |
|
2630 request = malloc(sizeof(*request), DRM_I915_GEM, 2631 M_WAITOK | M_ZERO); | 3295 request = malloc(sizeof(*request), DRM_I915_GEM, 3296 M_WAITOK | M_ZERO); |
2632 if (request == NULL) 2633 return (-ENOMEM); | |
2634 2635 ret = i915_add_request(ring, NULL, request); 2636 if (ret != 0) { 2637 free(request, DRM_I915_GEM); 2638 return (ret); 2639 } 2640 | 3297 3298 ret = i915_add_request(ring, NULL, request); 3299 if (ret != 0) { 3300 free(request, DRM_I915_GEM); 3301 return (ret); 3302 } 3303 |
2641 seqno = request->seqno; | 3304 MPASS(seqno == request->seqno); |
2642 } | 3305 } |
3306 return ret; 3307} |
|
2643 | 3308 |
2644 if (!i915_seqno_passed(ring->get_seqno(ring), seqno)) { 2645 if (HAS_PCH_SPLIT(ring->dev)) 2646 ier = I915_READ(DEIER) | I915_READ(GTIER); 2647 else 2648 ier = I915_READ(IER); 2649 if (!ier) { 2650 DRM_ERROR("something (likely vbetool) disabled " 2651 "interrupts, re-enabling\n"); 2652 ring->dev->driver->irq_preinstall(ring->dev); 2653 ring->dev->driver->irq_postinstall(ring->dev); 2654 } | 3309static int __wait_seqno(struct intel_ring_buffer *ring, u32 seqno, 3310 bool interruptible) 3311{ 3312 drm_i915_private_t *dev_priv = ring->dev->dev_private; 3313 int ret = 0, flags; |
2655 | 3314 |
2656 CTR2(KTR_DRM, "request_wait_begin %s %d", ring->name, seqno); | 3315 if (i915_seqno_passed(ring->get_seqno(ring), seqno)) 3316 return 0; |
2657 | 3317 |
2658 ring->waiting_seqno = seqno; 2659 mtx_lock(&ring->irq_lock); 2660 if (ring->irq_get(ring)) { 2661 flags = dev_priv->mm.interruptible ? PCATCH : 0; 2662 while (!i915_seqno_passed(ring->get_seqno(ring), seqno) 2663 && !atomic_load_acq_int(&dev_priv->mm.wedged) && 2664 ret == 0) { 2665 ret = -msleep(ring, &ring->irq_lock, flags, 2666 "915gwr", 0); 2667 } 2668 ring->irq_put(ring); 2669 mtx_unlock(&ring->irq_lock); 2670 } else { 2671 mtx_unlock(&ring->irq_lock); 2672 if (_intel_wait_for(ring->dev, 2673 i915_seqno_passed(ring->get_seqno(ring), seqno) || 2674 atomic_load_acq_int(&dev_priv->mm.wedged), 3000, 2675 0, "i915wrq") != 0) 2676 ret = -EBUSY; 2677 } 2678 ring->waiting_seqno = 0; | 3318 CTR2(KTR_DRM, "request_wait_begin %s %d", ring->name, seqno); |
2679 | 3319 |
2680 CTR3(KTR_DRM, "request_wait_end %s %d %d", ring->name, seqno, 2681 ret); | 3320 mtx_lock(&dev_priv->irq_lock); 3321 if (!ring->irq_get(ring)) { 3322 mtx_unlock(&dev_priv->irq_lock); 3323 return (-ENODEV); |
2682 } | 3324 } |
3325 3326 flags = interruptible ? PCATCH : 0; 3327 while (!i915_seqno_passed(ring->get_seqno(ring), seqno) 3328 && !atomic_load_acq_int(&dev_priv->mm.wedged) && 3329 ret == 0) 3330 ret = -msleep(ring, &dev_priv->irq_lock, flags, "915gwr", 0); 3331 ring->irq_put(ring); 3332 mtx_unlock(&dev_priv->irq_lock); 3333 3334 CTR3(KTR_DRM, "request_wait_end %s %d %d", ring->name, seqno, ret); 3335 3336 return ret; 3337} 3338 3339int 3340i915_wait_request(struct intel_ring_buffer *ring, uint32_t seqno) 3341{ 3342 drm_i915_private_t *dev_priv; 3343 int ret; 3344 3345 KASSERT(seqno != 0, ("Zero seqno")); 3346 3347 dev_priv = ring->dev->dev_private; 3348 ret = 0; 3349 3350 ret = i915_gem_check_wedge(dev_priv); 3351 if (ret) 3352 return ret; 3353 3354 ret = i915_gem_check_olr(ring, seqno); 3355 if (ret) 3356 return ret; 3357 3358 ret = __wait_seqno(ring, seqno, dev_priv->mm.interruptible); |
|
2683 if (atomic_load_acq_int(&dev_priv->mm.wedged)) 2684 ret = -EAGAIN; 2685 | 3359 if (atomic_load_acq_int(&dev_priv->mm.wedged)) 3360 ret = -EAGAIN; 3361 |
2686 /* Directly dispatch request retiring. While we have the work queue 2687 * to handle this, the waiter on a request often wants an associated 2688 * buffer to have made it to the inactive list, and we would need 2689 * a separate wait queue to handle that. 2690 */ 2691 if (ret == 0 && do_retire) 2692 i915_gem_retire_requests_ring(ring); 2693 | |
2694 return (ret); 2695} 2696 2697static u32 2698i915_gem_get_seqno(struct drm_device *dev) 2699{ 2700 drm_i915_private_t *dev_priv = dev->dev_private; 2701 u32 seqno = dev_priv->next_seqno; --- 144 unchanged lines hidden (view full) --- 2846static void 2847i915_gem_reset_fences(struct drm_device *dev) 2848{ 2849 struct drm_i915_private *dev_priv = dev->dev_private; 2850 int i; 2851 2852 for (i = 0; i < dev_priv->num_fence_regs; i++) { 2853 struct drm_i915_fence_reg *reg = &dev_priv->fence_regs[i]; | 3362 return (ret); 3363} 3364 3365static u32 3366i915_gem_get_seqno(struct drm_device *dev) 3367{ 3368 drm_i915_private_t *dev_priv = dev->dev_private; 3369 u32 seqno = dev_priv->next_seqno; --- 144 unchanged lines hidden (view full) --- 3514static void 3515i915_gem_reset_fences(struct drm_device *dev) 3516{ 3517 struct drm_i915_private *dev_priv = dev->dev_private; 3518 int i; 3519 3520 for (i = 0; i < dev_priv->num_fence_regs; i++) { 3521 struct drm_i915_fence_reg *reg = &dev_priv->fence_regs[i]; |
2854 struct drm_i915_gem_object *obj = reg->obj; | |
2855 | 3522 |
2856 if (!obj) 2857 continue; | 3523 i915_gem_write_fence(dev, i, NULL); |
2858 | 3524 |
2859 if (obj->tiling_mode) 2860 i915_gem_release_mmap(obj); | 3525 if (reg->obj) 3526 i915_gem_object_fence_lost(reg->obj); |
2861 | 3527 |
2862 reg->obj->fence_reg = I915_FENCE_REG_NONE; 2863 reg->obj->fenced_gpu_access = false; 2864 reg->obj->last_fenced_seqno = 0; 2865 reg->obj->last_fenced_ring = NULL; 2866 i915_gem_clear_fence_reg(dev, reg); | 3528 reg->pin_count = 0; 3529 reg->obj = NULL; 3530 INIT_LIST_HEAD(®->lru_list); |
2867 } | 3531 } |
3532 3533 INIT_LIST_HEAD(&dev_priv->mm.fence_list); |
|
2868} 2869 2870void 2871i915_gem_reset(struct drm_device *dev) 2872{ 2873 struct drm_i915_private *dev_priv = dev->dev_private; 2874 struct drm_i915_gem_object *obj; | 3534} 3535 3536void 3537i915_gem_reset(struct drm_device *dev) 3538{ 3539 struct drm_i915_private *dev_priv = dev->dev_private; 3540 struct drm_i915_gem_object *obj; |
3541 struct intel_ring_buffer *ring; |
|
2875 int i; 2876 | 3542 int i; 3543 |
2877 for (i = 0; i < I915_NUM_RINGS; i++) 2878 i915_gem_reset_ring_lists(dev_priv, &dev_priv->rings[i]); | 3544 for_each_ring(ring, dev_priv, i) 3545 i915_gem_reset_ring_lists(dev_priv, ring); |
2879 2880 /* Remove anything from the flushing lists. The GPU cache is likely 2881 * to be lost on reset along with the data, so simply move the 2882 * lost bo to the inactive list. 2883 */ 2884 while (!list_empty(&dev_priv->mm.flushing_list)) { 2885 obj = list_first_entry(&dev_priv->mm.flushing_list, 2886 struct drm_i915_gem_object, --- 69 unchanged lines hidden (view full) --- 2956 if (obj->base.write_domain != 0) 2957 i915_gem_object_move_to_flushing(obj); 2958 else 2959 i915_gem_object_move_to_inactive(obj); 2960 } 2961 2962 if (ring->trace_irq_seqno && 2963 i915_seqno_passed(seqno, ring->trace_irq_seqno)) { | 3546 3547 /* Remove anything from the flushing lists. The GPU cache is likely 3548 * to be lost on reset along with the data, so simply move the 3549 * lost bo to the inactive list. 3550 */ 3551 while (!list_empty(&dev_priv->mm.flushing_list)) { 3552 obj = list_first_entry(&dev_priv->mm.flushing_list, 3553 struct drm_i915_gem_object, --- 69 unchanged lines hidden (view full) --- 3623 if (obj->base.write_domain != 0) 3624 i915_gem_object_move_to_flushing(obj); 3625 else 3626 i915_gem_object_move_to_inactive(obj); 3627 } 3628 3629 if (ring->trace_irq_seqno && 3630 i915_seqno_passed(seqno, ring->trace_irq_seqno)) { |
2964 mtx_lock(&ring->irq_lock); | 3631 struct drm_i915_private *dev_priv = ring->dev->dev_private; 3632 mtx_lock(&dev_priv->irq_lock); |
2965 ring->irq_put(ring); | 3633 ring->irq_put(ring); |
2966 mtx_unlock(&ring->irq_lock); | 3634 mtx_unlock(&dev_priv->irq_lock); |
2967 ring->trace_irq_seqno = 0; 2968 } 2969} 2970 2971void 2972i915_gem_retire_requests(struct drm_device *dev) 2973{ 2974 drm_i915_private_t *dev_priv = dev->dev_private; | 3635 ring->trace_irq_seqno = 0; 3636 } 3637} 3638 3639void 3640i915_gem_retire_requests(struct drm_device *dev) 3641{ 3642 drm_i915_private_t *dev_priv = dev->dev_private; |
2975 struct drm_i915_gem_object *obj, *next; | 3643 struct intel_ring_buffer *ring; |
2976 int i; 2977 | 3644 int i; 3645 |
2978 if (!list_empty(&dev_priv->mm.deferred_free_list)) { 2979 list_for_each_entry_safe(obj, next, 2980 &dev_priv->mm.deferred_free_list, mm_list) 2981 i915_gem_free_object_tail(obj); 2982 } 2983 2984 for (i = 0; i < I915_NUM_RINGS; i++) 2985 i915_gem_retire_requests_ring(&dev_priv->rings[i]); | 3646 for_each_ring(ring, dev_priv, i) 3647 i915_gem_retire_requests_ring(ring); |
2986} 2987 | 3648} 3649 |
2988static int 2989sandybridge_write_fence_reg(struct drm_i915_gem_object *obj, 2990 struct intel_ring_buffer *pipelined) | 3650static void sandybridge_write_fence_reg(struct drm_device *dev, int reg, 3651 struct drm_i915_gem_object *obj) |
2991{ | 3652{ |
2992 struct drm_device *dev = obj->base.dev; | |
2993 drm_i915_private_t *dev_priv = dev->dev_private; | 3653 drm_i915_private_t *dev_priv = dev->dev_private; |
2994 u32 size = obj->gtt_space->size; 2995 int regnum = obj->fence_reg; | |
2996 uint64_t val; 2997 | 3654 uint64_t val; 3655 |
2998 val = (uint64_t)((obj->gtt_offset + size - 4096) & 2999 0xfffff000) << 32; 3000 val |= obj->gtt_offset & 0xfffff000; 3001 val |= (uint64_t)((obj->stride / 128) - 1) << 3002 SANDYBRIDGE_FENCE_PITCH_SHIFT; | 3656 if (obj) { 3657 u32 size = obj->gtt_space->size; |
3003 | 3658 |
3004 if (obj->tiling_mode == I915_TILING_Y) 3005 val |= 1 << I965_FENCE_TILING_Y_SHIFT; 3006 val |= I965_FENCE_REG_VALID; | 3659 val = (uint64_t)((obj->gtt_offset + size - 4096) & 3660 0xfffff000) << 32; 3661 val |= obj->gtt_offset & 0xfffff000; 3662 val |= (uint64_t)((obj->stride / 128) - 1) << 3663 SANDYBRIDGE_FENCE_PITCH_SHIFT; |
3007 | 3664 |
3008 if (pipelined) { 3009 int ret = intel_ring_begin(pipelined, 6); 3010 if (ret) 3011 return ret; 3012 3013 intel_ring_emit(pipelined, MI_NOOP); 3014 intel_ring_emit(pipelined, MI_LOAD_REGISTER_IMM(2)); 3015 intel_ring_emit(pipelined, FENCE_REG_SANDYBRIDGE_0 + regnum*8); 3016 intel_ring_emit(pipelined, (u32)val); 3017 intel_ring_emit(pipelined, FENCE_REG_SANDYBRIDGE_0 + regnum*8 + 4); 3018 intel_ring_emit(pipelined, (u32)(val >> 32)); 3019 intel_ring_advance(pipelined); | 3665 if (obj->tiling_mode == I915_TILING_Y) 3666 val |= 1 << I965_FENCE_TILING_Y_SHIFT; 3667 val |= I965_FENCE_REG_VALID; |
3020 } else | 3668 } else |
3021 I915_WRITE64(FENCE_REG_SANDYBRIDGE_0 + regnum * 8, val); | 3669 val = 0; |
3022 | 3670 |
3023 return 0; | 3671 I915_WRITE64(FENCE_REG_SANDYBRIDGE_0 + reg * 8, val); 3672 POSTING_READ(FENCE_REG_SANDYBRIDGE_0 + reg * 8); |
3024} 3025 | 3673} 3674 |
3026static int 3027i965_write_fence_reg(struct drm_i915_gem_object *obj, 3028 struct intel_ring_buffer *pipelined) | 3675static void i965_write_fence_reg(struct drm_device *dev, int reg, 3676 struct drm_i915_gem_object *obj) |
3029{ | 3677{ |
3030 struct drm_device *dev = obj->base.dev; | |
3031 drm_i915_private_t *dev_priv = dev->dev_private; | 3678 drm_i915_private_t *dev_priv = dev->dev_private; |
3032 u32 size = obj->gtt_space->size; 3033 int regnum = obj->fence_reg; | |
3034 uint64_t val; 3035 | 3679 uint64_t val; 3680 |
3036 val = (uint64_t)((obj->gtt_offset + size - 4096) & 3037 0xfffff000) << 32; 3038 val |= obj->gtt_offset & 0xfffff000; 3039 val |= ((obj->stride / 128) - 1) << I965_FENCE_PITCH_SHIFT; 3040 if (obj->tiling_mode == I915_TILING_Y) 3041 val |= 1 << I965_FENCE_TILING_Y_SHIFT; 3042 val |= I965_FENCE_REG_VALID; | 3681 if (obj) { 3682 u32 size = obj->gtt_space->size; |
3043 | 3683 |
3044 if (pipelined) { 3045 int ret = intel_ring_begin(pipelined, 6); 3046 if (ret) 3047 return ret; 3048 3049 intel_ring_emit(pipelined, MI_NOOP); 3050 intel_ring_emit(pipelined, MI_LOAD_REGISTER_IMM(2)); 3051 intel_ring_emit(pipelined, FENCE_REG_965_0 + regnum*8); 3052 intel_ring_emit(pipelined, (u32)val); 3053 intel_ring_emit(pipelined, FENCE_REG_965_0 + regnum*8 + 4); 3054 intel_ring_emit(pipelined, (u32)(val >> 32)); 3055 intel_ring_advance(pipelined); | 3684 val = (uint64_t)((obj->gtt_offset + size - 4096) & 3685 0xfffff000) << 32; 3686 val |= obj->gtt_offset & 0xfffff000; 3687 val |= ((obj->stride / 128) - 1) << I965_FENCE_PITCH_SHIFT; 3688 if (obj->tiling_mode == I915_TILING_Y) 3689 val |= 1 << I965_FENCE_TILING_Y_SHIFT; 3690 val |= I965_FENCE_REG_VALID; |
3056 } else | 3691 } else |
3057 I915_WRITE64(FENCE_REG_965_0 + regnum * 8, val); | 3692 val = 0; |
3058 | 3693 |
3059 return 0; | 3694 I915_WRITE64(FENCE_REG_965_0 + reg * 8, val); 3695 POSTING_READ(FENCE_REG_965_0 + reg * 8); |
3060} 3061 | 3696} 3697 |
3062static int 3063i915_write_fence_reg(struct drm_i915_gem_object *obj, 3064 struct intel_ring_buffer *pipelined) | 3698static void i915_write_fence_reg(struct drm_device *dev, int reg, 3699 struct drm_i915_gem_object *obj) |
3065{ | 3700{ |
3066 struct drm_device *dev = obj->base.dev; | |
3067 drm_i915_private_t *dev_priv = dev->dev_private; | 3701 drm_i915_private_t *dev_priv = dev->dev_private; |
3068 u32 size = obj->gtt_space->size; 3069 u32 fence_reg, val, pitch_val; 3070 int tile_width; | 3702 u32 val; |
3071 | 3703 |
3072 if ((obj->gtt_offset & ~I915_FENCE_START_MASK) || 3073 (size & -size) != size || (obj->gtt_offset & (size - 1))) { 3074 printf( 3075"object 0x%08x [fenceable? %d] not 1M or pot-size (0x%08x) aligned\n", 3076 obj->gtt_offset, obj->map_and_fenceable, size); 3077 return -EINVAL; 3078 } | 3704 if (obj) { 3705 u32 size = obj->gtt_space->size; 3706 int pitch_val; 3707 int tile_width; |
3079 | 3708 |
3080 if (obj->tiling_mode == I915_TILING_Y && HAS_128_BYTE_Y_TILING(dev)) 3081 tile_width = 128; 3082 else 3083 tile_width = 512; | 3709 if ((obj->gtt_offset & ~I915_FENCE_START_MASK) || 3710 (size & -size) != size || 3711 (obj->gtt_offset & (size - 1))) 3712 printf( 3713 "object 0x%08x [fenceable? %d] not 1M or pot-size (0x%08x) aligned\n", 3714 obj->gtt_offset, obj->map_and_fenceable, size); |
3084 | 3715 |
3085 /* Note: pitch better be a power of two tile widths */ 3086 pitch_val = obj->stride / tile_width; 3087 pitch_val = ffs(pitch_val) - 1; | 3716 if (obj->tiling_mode == I915_TILING_Y && HAS_128_BYTE_Y_TILING(dev)) 3717 tile_width = 128; 3718 else 3719 tile_width = 512; |
3088 | 3720 |
3089 val = obj->gtt_offset; 3090 if (obj->tiling_mode == I915_TILING_Y) 3091 val |= 1 << I830_FENCE_TILING_Y_SHIFT; 3092 val |= I915_FENCE_SIZE_BITS(size); 3093 val |= pitch_val << I830_FENCE_PITCH_SHIFT; 3094 val |= I830_FENCE_REG_VALID; | 3721 /* Note: pitch better be a power of two tile widths */ 3722 pitch_val = obj->stride / tile_width; 3723 pitch_val = ffs(pitch_val) - 1; |
3095 | 3724 |
3096 fence_reg = obj->fence_reg; 3097 if (fence_reg < 8) 3098 fence_reg = FENCE_REG_830_0 + fence_reg * 4; 3099 else 3100 fence_reg = FENCE_REG_945_8 + (fence_reg - 8) * 4; 3101 3102 if (pipelined) { 3103 int ret = intel_ring_begin(pipelined, 4); 3104 if (ret) 3105 return ret; 3106 3107 intel_ring_emit(pipelined, MI_NOOP); 3108 intel_ring_emit(pipelined, MI_LOAD_REGISTER_IMM(1)); 3109 intel_ring_emit(pipelined, fence_reg); 3110 intel_ring_emit(pipelined, val); 3111 intel_ring_advance(pipelined); | 3725 val = obj->gtt_offset; 3726 if (obj->tiling_mode == I915_TILING_Y) 3727 val |= 1 << I830_FENCE_TILING_Y_SHIFT; 3728 val |= I915_FENCE_SIZE_BITS(size); 3729 val |= pitch_val << I830_FENCE_PITCH_SHIFT; 3730 val |= I830_FENCE_REG_VALID; |
3112 } else | 3731 } else |
3113 I915_WRITE(fence_reg, val); | 3732 val = 0; |
3114 | 3733 |
3115 return 0; | 3734 if (reg < 8) 3735 reg = FENCE_REG_830_0 + reg * 4; 3736 else 3737 reg = FENCE_REG_945_8 + (reg - 8) * 4; 3738 3739 I915_WRITE(reg, val); 3740 POSTING_READ(reg); |
3116} 3117 | 3741} 3742 |
3118static int 3119i830_write_fence_reg(struct drm_i915_gem_object *obj, 3120 struct intel_ring_buffer *pipelined) | 3743static void i830_write_fence_reg(struct drm_device *dev, int reg, 3744 struct drm_i915_gem_object *obj) |
3121{ | 3745{ |
3122 struct drm_device *dev = obj->base.dev; | |
3123 drm_i915_private_t *dev_priv = dev->dev_private; | 3746 drm_i915_private_t *dev_priv = dev->dev_private; |
3124 u32 size = obj->gtt_space->size; 3125 int regnum = obj->fence_reg; | |
3126 uint32_t val; | 3747 uint32_t val; |
3127 uint32_t pitch_val; | |
3128 | 3748 |
3129 if ((obj->gtt_offset & ~I830_FENCE_START_MASK) || 3130 (size & -size) != size || (obj->gtt_offset & (size - 1))) { 3131 printf( 3132"object 0x%08x not 512K or pot-size 0x%08x aligned\n", 3133 obj->gtt_offset, size); 3134 return -EINVAL; 3135 } | 3749 if (obj) { 3750 u32 size = obj->gtt_space->size; 3751 uint32_t pitch_val; |
3136 | 3752 |
3137 pitch_val = obj->stride / 128; 3138 pitch_val = ffs(pitch_val) - 1; | 3753 if ((obj->gtt_offset & ~I830_FENCE_START_MASK) || 3754 (size & -size) != size || 3755 (obj->gtt_offset & (size - 1))) 3756 printf( 3757 "object 0x%08x not 512K or pot-size 0x%08x aligned\n", 3758 obj->gtt_offset, size); |
3139 | 3759 |
3140 val = obj->gtt_offset; 3141 if (obj->tiling_mode == I915_TILING_Y) 3142 val |= 1 << I830_FENCE_TILING_Y_SHIFT; 3143 val |= I830_FENCE_SIZE_BITS(size); 3144 val |= pitch_val << I830_FENCE_PITCH_SHIFT; 3145 val |= I830_FENCE_REG_VALID; | 3760 pitch_val = obj->stride / 128; 3761 pitch_val = ffs(pitch_val) - 1; |
3146 | 3762 |
3147 if (pipelined) { 3148 int ret = intel_ring_begin(pipelined, 4); 3149 if (ret) 3150 return ret; 3151 3152 intel_ring_emit(pipelined, MI_NOOP); 3153 intel_ring_emit(pipelined, MI_LOAD_REGISTER_IMM(1)); 3154 intel_ring_emit(pipelined, FENCE_REG_830_0 + regnum*4); 3155 intel_ring_emit(pipelined, val); 3156 intel_ring_advance(pipelined); | 3763 val = obj->gtt_offset; 3764 if (obj->tiling_mode == I915_TILING_Y) 3765 val |= 1 << I830_FENCE_TILING_Y_SHIFT; 3766 val |= I830_FENCE_SIZE_BITS(size); 3767 val |= pitch_val << I830_FENCE_PITCH_SHIFT; 3768 val |= I830_FENCE_REG_VALID; |
3157 } else | 3769 } else |
3158 I915_WRITE(FENCE_REG_830_0 + regnum * 4, val); | 3770 val = 0; |
3159 | 3771 |
3160 return 0; | 3772 I915_WRITE(FENCE_REG_830_0 + reg * 4, val); 3773 POSTING_READ(FENCE_REG_830_0 + reg * 4); |
3161} 3162 | 3774} 3775 |
3163static bool ring_passed_seqno(struct intel_ring_buffer *ring, u32 seqno) | 3776static void i915_gem_write_fence(struct drm_device *dev, int reg, 3777 struct drm_i915_gem_object *obj) |
3164{ | 3778{ |
3165 return i915_seqno_passed(ring->get_seqno(ring), seqno); | 3779 switch (INTEL_INFO(dev)->gen) { 3780 case 7: 3781 case 6: sandybridge_write_fence_reg(dev, reg, obj); break; 3782 case 5: 3783 case 4: i965_write_fence_reg(dev, reg, obj); break; 3784 case 3: i915_write_fence_reg(dev, reg, obj); break; 3785 case 2: i830_write_fence_reg(dev, reg, obj); break; 3786 default: break; 3787 } |
3166} 3167 | 3788} 3789 |
3790static inline int fence_number(struct drm_i915_private *dev_priv, 3791 struct drm_i915_fence_reg *fence) 3792{ 3793 return fence - dev_priv->fence_regs; 3794} 3795 3796static void i915_gem_object_update_fence(struct drm_i915_gem_object *obj, 3797 struct drm_i915_fence_reg *fence, 3798 bool enable) 3799{ 3800 struct drm_i915_private *dev_priv = obj->base.dev->dev_private; 3801 int reg = fence_number(dev_priv, fence); 3802 3803 i915_gem_write_fence(obj->base.dev, reg, enable ? obj : NULL); 3804 3805 if (enable) { 3806 obj->fence_reg = reg; 3807 fence->obj = obj; 3808 list_move_tail(&fence->lru_list, &dev_priv->mm.fence_list); 3809 } else { 3810 obj->fence_reg = I915_FENCE_REG_NONE; 3811 fence->obj = NULL; 3812 list_del_init(&fence->lru_list); 3813 } 3814} 3815 |
|
3168static int | 3816static int |
3169i915_gem_object_flush_fence(struct drm_i915_gem_object *obj, 3170 struct intel_ring_buffer *pipelined) | 3817i915_gem_object_flush_fence(struct drm_i915_gem_object *obj) |
3171{ 3172 int ret; 3173 3174 if (obj->fenced_gpu_access) { 3175 if (obj->base.write_domain & I915_GEM_GPU_DOMAINS) { | 3818{ 3819 int ret; 3820 3821 if (obj->fenced_gpu_access) { 3822 if (obj->base.write_domain & I915_GEM_GPU_DOMAINS) { |
3176 ret = i915_gem_flush_ring(obj->last_fenced_ring, 0, 3177 obj->base.write_domain); | 3823 ret = i915_gem_flush_ring(obj->ring, 3824 0, obj->base.write_domain); |
3178 if (ret) 3179 return ret; 3180 } 3181 3182 obj->fenced_gpu_access = false; 3183 } 3184 | 3825 if (ret) 3826 return ret; 3827 } 3828 3829 obj->fenced_gpu_access = false; 3830 } 3831 |
3185 if (obj->last_fenced_seqno && pipelined != obj->last_fenced_ring) { 3186 if (!ring_passed_seqno(obj->last_fenced_ring, 3187 obj->last_fenced_seqno)) { 3188 ret = i915_wait_request(obj->last_fenced_ring, 3189 obj->last_fenced_seqno, 3190 true); 3191 if (ret) 3192 return ret; 3193 } | 3832 if (obj->last_fenced_seqno) { 3833 ret = i915_wait_request(obj->ring, 3834 obj->last_fenced_seqno); 3835 if (ret) 3836 return ret; |
3194 3195 obj->last_fenced_seqno = 0; | 3837 3838 obj->last_fenced_seqno = 0; |
3196 obj->last_fenced_ring = NULL; | |
3197 } 3198 3199 /* Ensure that all CPU reads are completed before installing a fence 3200 * and all writes before removing the fence. 3201 */ 3202 if (obj->base.read_domains & I915_GEM_DOMAIN_GTT) 3203 mb(); 3204 3205 return 0; 3206} 3207 3208int 3209i915_gem_object_put_fence(struct drm_i915_gem_object *obj) 3210{ | 3839 } 3840 3841 /* Ensure that all CPU reads are completed before installing a fence 3842 * and all writes before removing the fence. 3843 */ 3844 if (obj->base.read_domains & I915_GEM_DOMAIN_GTT) 3845 mb(); 3846 3847 return 0; 3848} 3849 3850int 3851i915_gem_object_put_fence(struct drm_i915_gem_object *obj) 3852{ |
3853 struct drm_i915_private *dev_priv = obj->base.dev->dev_private; |
|
3211 int ret; 3212 | 3854 int ret; 3855 |
3213 if (obj->tiling_mode) 3214 i915_gem_release_mmap(obj); 3215 3216 ret = i915_gem_object_flush_fence(obj, NULL); | 3856 ret = i915_gem_object_flush_fence(obj); |
3217 if (ret) 3218 return ret; 3219 | 3857 if (ret) 3858 return ret; 3859 |
3220 if (obj->fence_reg != I915_FENCE_REG_NONE) { 3221 struct drm_i915_private *dev_priv = obj->base.dev->dev_private; | 3860 if (obj->fence_reg == I915_FENCE_REG_NONE) 3861 return 0; |
3222 | 3862 |
3223 if (dev_priv->fence_regs[obj->fence_reg].pin_count != 0) 3224 printf("%s: pin_count %d\n", __func__, 3225 dev_priv->fence_regs[obj->fence_reg].pin_count); 3226 i915_gem_clear_fence_reg(obj->base.dev, 3227 &dev_priv->fence_regs[obj->fence_reg]); | 3863 i915_gem_object_update_fence(obj, 3864 &dev_priv->fence_regs[obj->fence_reg], 3865 false); 3866 i915_gem_object_fence_lost(obj); |
3228 | 3867 |
3229 obj->fence_reg = I915_FENCE_REG_NONE; 3230 } 3231 | |
3232 return 0; 3233} 3234 3235static struct drm_i915_fence_reg * | 3868 return 0; 3869} 3870 3871static struct drm_i915_fence_reg * |
3236i915_find_fence_reg(struct drm_device *dev, struct intel_ring_buffer *pipelined) | 3872i915_find_fence_reg(struct drm_device *dev) |
3237{ 3238 struct drm_i915_private *dev_priv = dev->dev_private; | 3873{ 3874 struct drm_i915_private *dev_priv = dev->dev_private; |
3239 struct drm_i915_fence_reg *reg, *first, *avail; | 3875 struct drm_i915_fence_reg *reg, *avail; |
3240 int i; 3241 3242 /* First try to find a free reg */ 3243 avail = NULL; 3244 for (i = dev_priv->fence_reg_start; i < dev_priv->num_fence_regs; i++) { 3245 reg = &dev_priv->fence_regs[i]; 3246 if (!reg->obj) 3247 return reg; 3248 3249 if (!reg->pin_count) 3250 avail = reg; 3251 } 3252 3253 if (avail == NULL) 3254 return NULL; 3255 3256 /* None available, try to steal one or wait for a user to finish */ | 3876 int i; 3877 3878 /* First try to find a free reg */ 3879 avail = NULL; 3880 for (i = dev_priv->fence_reg_start; i < dev_priv->num_fence_regs; i++) { 3881 reg = &dev_priv->fence_regs[i]; 3882 if (!reg->obj) 3883 return reg; 3884 3885 if (!reg->pin_count) 3886 avail = reg; 3887 } 3888 3889 if (avail == NULL) 3890 return NULL; 3891 3892 /* None available, try to steal one or wait for a user to finish */ |
3257 avail = first = NULL; | |
3258 list_for_each_entry(reg, &dev_priv->mm.fence_list, lru_list) { 3259 if (reg->pin_count) 3260 continue; 3261 | 3893 list_for_each_entry(reg, &dev_priv->mm.fence_list, lru_list) { 3894 if (reg->pin_count) 3895 continue; 3896 |
3262 if (first == NULL) 3263 first = reg; 3264 3265 if (!pipelined || 3266 !reg->obj->last_fenced_ring || 3267 reg->obj->last_fenced_ring == pipelined) { 3268 avail = reg; 3269 break; 3270 } | 3897 return reg; |
3271 } 3272 | 3898 } 3899 |
3273 if (avail == NULL) 3274 avail = first; 3275 3276 return avail; | 3900 return NULL; |
3277} 3278 3279int | 3901} 3902 3903int |
3280i915_gem_object_get_fence(struct drm_i915_gem_object *obj, 3281 struct intel_ring_buffer *pipelined) | 3904i915_gem_object_get_fence(struct drm_i915_gem_object *obj) |
3282{ 3283 struct drm_device *dev = obj->base.dev; 3284 struct drm_i915_private *dev_priv = dev->dev_private; | 3905{ 3906 struct drm_device *dev = obj->base.dev; 3907 struct drm_i915_private *dev_priv = dev->dev_private; |
3908 bool enable = obj->tiling_mode != I915_TILING_NONE; |
|
3285 struct drm_i915_fence_reg *reg; 3286 int ret; 3287 | 3909 struct drm_i915_fence_reg *reg; 3910 int ret; 3911 |
3288 pipelined = NULL; | 3912 /* Have we updated the tiling parameters upon the object and so 3913 * will need to serialise the write to the associated fence register? 3914 */ 3915 if (obj->fence_dirty) { 3916 ret = i915_gem_object_flush_fence(obj); 3917 if (ret) 3918 return ret; 3919 } 3920 |
3289 ret = 0; 3290 3291 if (obj->fence_reg != I915_FENCE_REG_NONE) { 3292 reg = &dev_priv->fence_regs[obj->fence_reg]; | 3921 ret = 0; 3922 3923 if (obj->fence_reg != I915_FENCE_REG_NONE) { 3924 reg = &dev_priv->fence_regs[obj->fence_reg]; |
3293 list_move_tail(®->lru_list, &dev_priv->mm.fence_list); 3294 3295 if (obj->tiling_changed) { 3296 ret = i915_gem_object_flush_fence(obj, pipelined); 3297 if (ret) 3298 return ret; 3299 3300 if (!obj->fenced_gpu_access && !obj->last_fenced_seqno) 3301 pipelined = NULL; 3302 3303 if (pipelined) { 3304 reg->setup_seqno = 3305 i915_gem_next_request_seqno(pipelined); 3306 obj->last_fenced_seqno = reg->setup_seqno; 3307 obj->last_fenced_ring = pipelined; 3308 } 3309 3310 goto update; | 3925 if (!obj->fence_dirty) { 3926 list_move_tail(®->lru_list, 3927 &dev_priv->mm.fence_list); 3928 return 0; |
3311 } | 3929 } |
3930 } else if (enable) { 3931 reg = i915_find_fence_reg(dev); 3932 if (reg == NULL) 3933 return -EDEADLK; |
|
3312 | 3934 |
3313 if (!pipelined) { 3314 if (reg->setup_seqno) { 3315 if (!ring_passed_seqno(obj->last_fenced_ring, 3316 reg->setup_seqno)) { 3317 ret = i915_wait_request( 3318 obj->last_fenced_ring, 3319 reg->setup_seqno, 3320 true); 3321 if (ret) 3322 return ret; 3323 } | 3935 if (reg->obj) { 3936 struct drm_i915_gem_object *old = reg->obj; |
3324 | 3937 |
3325 reg->setup_seqno = 0; 3326 } 3327 } else if (obj->last_fenced_ring && 3328 obj->last_fenced_ring != pipelined) { 3329 ret = i915_gem_object_flush_fence(obj, pipelined); | 3938 ret = i915_gem_object_flush_fence(old); |
3330 if (ret) 3331 return ret; | 3939 if (ret) 3940 return ret; |
3332 } | |
3333 | 3941 |
3334 if (!obj->fenced_gpu_access && !obj->last_fenced_seqno) 3335 pipelined = NULL; 3336 KASSERT(pipelined || reg->setup_seqno == 0, ("!pipelined")); 3337 3338 if (obj->tiling_changed) { 3339 if (pipelined) { 3340 reg->setup_seqno = 3341 i915_gem_next_request_seqno(pipelined); 3342 obj->last_fenced_seqno = reg->setup_seqno; 3343 obj->last_fenced_ring = pipelined; 3344 } 3345 goto update; | 3942 i915_gem_object_fence_lost(old); |
3346 } | 3943 } |
3347 | 3944 } else |
3348 return 0; | 3945 return 0; |
3349 } | |
3350 | 3946 |
3351 reg = i915_find_fence_reg(dev, pipelined); 3352 if (reg == NULL) 3353 return -EDEADLK; | 3947 i915_gem_object_update_fence(obj, reg, enable); 3948 obj->fence_dirty = false; |
3354 | 3949 |
3355 ret = i915_gem_object_flush_fence(obj, pipelined); 3356 if (ret) 3357 return ret; 3358 3359 if (reg->obj) { 3360 struct drm_i915_gem_object *old = reg->obj; 3361 3362 drm_gem_object_reference(&old->base); 3363 3364 if (old->tiling_mode) 3365 i915_gem_release_mmap(old); 3366 3367 ret = i915_gem_object_flush_fence(old, pipelined); 3368 if (ret) { 3369 drm_gem_object_unreference(&old->base); 3370 return ret; 3371 } 3372 3373 if (old->last_fenced_seqno == 0 && obj->last_fenced_seqno == 0) 3374 pipelined = NULL; 3375 3376 old->fence_reg = I915_FENCE_REG_NONE; 3377 old->last_fenced_ring = pipelined; 3378 old->last_fenced_seqno = 3379 pipelined ? i915_gem_next_request_seqno(pipelined) : 0; 3380 3381 drm_gem_object_unreference(&old->base); 3382 } else if (obj->last_fenced_seqno == 0) 3383 pipelined = NULL; 3384 3385 reg->obj = obj; 3386 list_move_tail(®->lru_list, &dev_priv->mm.fence_list); 3387 obj->fence_reg = reg - dev_priv->fence_regs; 3388 obj->last_fenced_ring = pipelined; 3389 3390 reg->setup_seqno = 3391 pipelined ? i915_gem_next_request_seqno(pipelined) : 0; 3392 obj->last_fenced_seqno = reg->setup_seqno; 3393 3394update: 3395 obj->tiling_changed = false; 3396 switch (INTEL_INFO(dev)->gen) { 3397 case 7: 3398 case 6: 3399 ret = sandybridge_write_fence_reg(obj, pipelined); 3400 break; 3401 case 5: 3402 case 4: 3403 ret = i965_write_fence_reg(obj, pipelined); 3404 break; 3405 case 3: 3406 ret = i915_write_fence_reg(obj, pipelined); 3407 break; 3408 case 2: 3409 ret = i830_write_fence_reg(obj, pipelined); 3410 break; 3411 } 3412 3413 return ret; | 3950 return 0; |
3414} 3415 | 3951} 3952 |
3416static void 3417i915_gem_clear_fence_reg(struct drm_device *dev, struct drm_i915_fence_reg *reg) 3418{ 3419 drm_i915_private_t *dev_priv = dev->dev_private; 3420 uint32_t fence_reg = reg - dev_priv->fence_regs; 3421 3422 switch (INTEL_INFO(dev)->gen) { 3423 case 7: 3424 case 6: 3425 I915_WRITE64(FENCE_REG_SANDYBRIDGE_0 + fence_reg*8, 0); 3426 break; 3427 case 5: 3428 case 4: 3429 I915_WRITE64(FENCE_REG_965_0 + fence_reg*8, 0); 3430 break; 3431 case 3: 3432 if (fence_reg >= 8) 3433 fence_reg = FENCE_REG_945_8 + (fence_reg - 8) * 4; 3434 else 3435 case 2: 3436 fence_reg = FENCE_REG_830_0 + fence_reg * 4; 3437 3438 I915_WRITE(fence_reg, 0); 3439 break; 3440 } 3441 3442 list_del_init(®->lru_list); 3443 reg->obj = NULL; 3444 reg->setup_seqno = 0; 3445 reg->pin_count = 0; 3446} 3447 | |
3448int 3449i915_gem_init_object(struct drm_gem_object *obj) 3450{ 3451 3452 printf("i915_gem_init_object called\n"); 3453 return (0); 3454} 3455 3456static bool 3457i915_gem_object_is_inactive(struct drm_i915_gem_object *obj) 3458{ 3459 | 3953int 3954i915_gem_init_object(struct drm_gem_object *obj) 3955{ 3956 3957 printf("i915_gem_init_object called\n"); 3958 return (0); 3959} 3960 3961static bool 3962i915_gem_object_is_inactive(struct drm_i915_gem_object *obj) 3963{ 3964 |
3460 return (obj->gtt_space && !obj->active && obj->pin_count == 0); | 3965 return !obj->active; |
3461} 3462 3463static void 3464i915_gem_retire_task_handler(void *arg, int pending) 3465{ 3466 drm_i915_private_t *dev_priv; 3467 struct drm_device *dev; | 3966} 3967 3968static void 3969i915_gem_retire_task_handler(void *arg, int pending) 3970{ 3971 drm_i915_private_t *dev_priv; 3972 struct drm_device *dev; |
3973 struct intel_ring_buffer *ring; |
|
3468 bool idle; 3469 int i; 3470 3471 dev_priv = arg; 3472 dev = dev_priv->dev; 3473 3474 /* Come back later if the device is busy... */ 3475 if (!sx_try_xlock(&dev->dev_struct_lock)) { --- 5 unchanged lines hidden (view full) --- 3481 CTR0(KTR_DRM, "retire_task"); 3482 3483 i915_gem_retire_requests(dev); 3484 3485 /* Send a periodic flush down the ring so we don't hold onto GEM 3486 * objects indefinitely. 3487 */ 3488 idle = true; | 3974 bool idle; 3975 int i; 3976 3977 dev_priv = arg; 3978 dev = dev_priv->dev; 3979 3980 /* Come back later if the device is busy... */ 3981 if (!sx_try_xlock(&dev->dev_struct_lock)) { --- 5 unchanged lines hidden (view full) --- 3987 CTR0(KTR_DRM, "retire_task"); 3988 3989 i915_gem_retire_requests(dev); 3990 3991 /* Send a periodic flush down the ring so we don't hold onto GEM 3992 * objects indefinitely. 3993 */ 3994 idle = true; |
3489 for (i = 0; i < I915_NUM_RINGS; i++) { | 3995 for_each_ring(ring, dev_priv, i) { |
3490 struct intel_ring_buffer *ring = &dev_priv->rings[i]; 3491 3492 if (!list_empty(&ring->gpu_write_list)) { 3493 struct drm_i915_gem_request *request; 3494 int ret; 3495 3496 ret = i915_gem_flush_ring(ring, 3497 0, I915_GEM_GPU_DOMAINS); --- 99 unchanged lines hidden (view full) --- 3597 3598 if (obj->phys_obj == NULL) 3599 return; 3600 vaddr = obj->phys_obj->handle->vaddr; 3601 3602 page_count = obj->base.size / PAGE_SIZE; 3603 VM_OBJECT_WLOCK(obj->base.vm_obj); 3604 for (i = 0; i < page_count; i++) { | 3996 struct intel_ring_buffer *ring = &dev_priv->rings[i]; 3997 3998 if (!list_empty(&ring->gpu_write_list)) { 3999 struct drm_i915_gem_request *request; 4000 int ret; 4001 4002 ret = i915_gem_flush_ring(ring, 4003 0, I915_GEM_GPU_DOMAINS); --- 99 unchanged lines hidden (view full) --- 4103 4104 if (obj->phys_obj == NULL) 4105 return; 4106 vaddr = obj->phys_obj->handle->vaddr; 4107 4108 page_count = obj->base.size / PAGE_SIZE; 4109 VM_OBJECT_WLOCK(obj->base.vm_obj); 4110 for (i = 0; i < page_count; i++) { |
3605 m = i915_gem_wire_page(obj->base.vm_obj, i); | 4111 m = i915_gem_wire_page(obj->base.vm_obj, i, NULL); |
3606 if (m == NULL) 3607 continue; /* XXX */ 3608 3609 VM_OBJECT_WUNLOCK(obj->base.vm_obj); 3610 sf = sf_buf_alloc(m, 0); 3611 if (sf != NULL) { 3612 dst = (char *)sf_buf_kva(sf); 3613 memcpy(dst, vaddr + IDX_TO_OFF(i), PAGE_SIZE); --- 49 unchanged lines hidden (view full) --- 3663 obj->phys_obj = dev_priv->mm.phys_objs[id - 1]; 3664 obj->phys_obj->cur_obj = obj; 3665 3666 page_count = obj->base.size / PAGE_SIZE; 3667 3668 VM_OBJECT_WLOCK(obj->base.vm_obj); 3669 ret = 0; 3670 for (i = 0; i < page_count; i++) { | 4112 if (m == NULL) 4113 continue; /* XXX */ 4114 4115 VM_OBJECT_WUNLOCK(obj->base.vm_obj); 4116 sf = sf_buf_alloc(m, 0); 4117 if (sf != NULL) { 4118 dst = (char *)sf_buf_kva(sf); 4119 memcpy(dst, vaddr + IDX_TO_OFF(i), PAGE_SIZE); --- 49 unchanged lines hidden (view full) --- 4169 obj->phys_obj = dev_priv->mm.phys_objs[id - 1]; 4170 obj->phys_obj->cur_obj = obj; 4171 4172 page_count = obj->base.size / PAGE_SIZE; 4173 4174 VM_OBJECT_WLOCK(obj->base.vm_obj); 4175 ret = 0; 4176 for (i = 0; i < page_count; i++) { |
3671 m = i915_gem_wire_page(obj->base.vm_obj, i); | 4177 m = i915_gem_wire_page(obj->base.vm_obj, i, NULL); |
3672 if (m == NULL) { 3673 ret = -EIO; 3674 break; 3675 } 3676 VM_OBJECT_WUNLOCK(obj->base.vm_obj); 3677 sf = sf_buf_alloc(m, 0); 3678 src = (char *)sf_buf_kva(sf); 3679 dst = (char *)obj->phys_obj->handle->vaddr + IDX_TO_OFF(i); --- 9 unchanged lines hidden (view full) --- 3689 atomic_add_long(&i915_gem_wired_pages_cnt, -1); 3690 } 3691 VM_OBJECT_WUNLOCK(obj->base.vm_obj); 3692 3693 return (0); 3694} 3695 3696static int | 4178 if (m == NULL) { 4179 ret = -EIO; 4180 break; 4181 } 4182 VM_OBJECT_WUNLOCK(obj->base.vm_obj); 4183 sf = sf_buf_alloc(m, 0); 4184 src = (char *)sf_buf_kva(sf); 4185 dst = (char *)obj->phys_obj->handle->vaddr + IDX_TO_OFF(i); --- 9 unchanged lines hidden (view full) --- 4195 atomic_add_long(&i915_gem_wired_pages_cnt, -1); 4196 } 4197 VM_OBJECT_WUNLOCK(obj->base.vm_obj); 4198 4199 return (0); 4200} 4201 4202static int |
3697i915_gem_phys_pwrite(struct drm_device *dev, struct drm_i915_gem_object *obj, 3698 uint64_t data_ptr, uint64_t offset, uint64_t size, 3699 struct drm_file *file_priv) 3700{ 3701 char *user_data, *vaddr; 3702 int ret; 3703 3704 vaddr = (char *)obj->phys_obj->handle->vaddr + offset; 3705 user_data = (char *)(uintptr_t)data_ptr; 3706 3707 if (copyin_nofault(user_data, vaddr, size) != 0) { 3708 /* The physical object once assigned is fixed for the lifetime 3709 * of the obj, so we can safely drop the lock and continue 3710 * to access vaddr. 3711 */ 3712 DRM_UNLOCK(dev); 3713 ret = -copyin(user_data, vaddr, size); 3714 DRM_LOCK(dev); 3715 if (ret != 0) 3716 return (ret); 3717 } 3718 3719 intel_gtt_chipset_flush(); 3720 return (0); 3721} 3722 3723static int | |
3724i915_gpu_is_active(struct drm_device *dev) 3725{ 3726 drm_i915_private_t *dev_priv; 3727 3728 dev_priv = dev->dev_private; 3729 return (!list_empty(&dev_priv->mm.flushing_list) || 3730 !list_empty(&dev_priv->mm.active_list)); 3731} --- 40 unchanged lines hidden (view full) --- 3772 3773 if (cnt_fail > cnt_total / 100 && i915_gpu_is_active(dev)) { 3774 /* 3775 * We are desperate for pages, so as a last resort, wait 3776 * for the GPU to finish and discard whatever we can. 3777 * This has a dramatic impact to reduce the number of 3778 * OOM-killer events whilst running the GPU aggressively. 3779 */ | 4203i915_gpu_is_active(struct drm_device *dev) 4204{ 4205 drm_i915_private_t *dev_priv; 4206 4207 dev_priv = dev->dev_private; 4208 return (!list_empty(&dev_priv->mm.flushing_list) || 4209 !list_empty(&dev_priv->mm.active_list)); 4210} --- 40 unchanged lines hidden (view full) --- 4251 4252 if (cnt_fail > cnt_total / 100 && i915_gpu_is_active(dev)) { 4253 /* 4254 * We are desperate for pages, so as a last resort, wait 4255 * for the GPU to finish and discard whatever we can. 4256 * This has a dramatic impact to reduce the number of 4257 * OOM-killer events whilst running the GPU aggressively. 4258 */ |
3780 if (i915_gpu_idle(dev, true) == 0) | 4259 if (i915_gpu_idle(dev) == 0) |
3781 goto rescan; 3782 } 3783 DRM_UNLOCK(dev); 3784} 3785 3786void 3787i915_gem_unload(struct drm_device *dev) 3788{ 3789 struct drm_i915_private *dev_priv; 3790 3791 dev_priv = dev->dev_private; 3792 EVENTHANDLER_DEREGISTER(vm_lowmem, dev_priv->mm.i915_lowmem); 3793} | 4260 goto rescan; 4261 } 4262 DRM_UNLOCK(dev); 4263} 4264 4265void 4266i915_gem_unload(struct drm_device *dev) 4267{ 4268 struct drm_i915_private *dev_priv; 4269 4270 dev_priv = dev->dev_private; 4271 EVENTHANDLER_DEREGISTER(vm_lowmem, dev_priv->mm.i915_lowmem); 4272} |