1 1.5 riastrad /* $NetBSD: intel_timeline.c,v 1.5 2021/12/19 12:32:15 riastradh Exp $ */ 2 1.1 riastrad 3 1.1 riastrad /* 4 1.1 riastrad * SPDX-License-Identifier: MIT 5 1.1 riastrad * 6 1.1 riastrad * Copyright 2016-2018 Intel Corporation 7 1.1 riastrad */ 8 1.1 riastrad 9 1.1 riastrad #include <sys/cdefs.h> 10 1.5 riastrad __KERNEL_RCSID(0, "$NetBSD: intel_timeline.c,v 1.5 2021/12/19 12:32:15 riastradh Exp $"); 11 1.1 riastrad 12 1.1 riastrad #include "i915_drv.h" 13 1.1 riastrad 14 1.1 riastrad #include "i915_active.h" 15 1.1 riastrad #include "i915_syncmap.h" 16 1.1 riastrad #include "intel_gt.h" 17 1.1 riastrad #include "intel_ring.h" 18 1.1 riastrad #include "intel_timeline.h" 19 1.1 riastrad 20 1.3 riastrad #include <linux/nbsd-namespace.h> 21 1.3 riastrad 22 1.1 riastrad #define ptr_set_bit(ptr, bit) ((typeof(ptr))((unsigned long)(ptr) | BIT(bit))) 23 1.1 riastrad #define ptr_test_bit(ptr, bit) ((unsigned long)(ptr) & BIT(bit)) 24 1.1 riastrad 25 1.1 riastrad #define CACHELINE_BITS 6 26 1.1 riastrad #define CACHELINE_FREE CACHELINE_BITS 27 1.1 riastrad 28 1.1 riastrad struct intel_timeline_hwsp { 29 1.1 riastrad struct intel_gt *gt; 30 1.1 riastrad struct intel_gt_timelines *gt_timelines; 31 1.1 riastrad struct list_head free_link; 32 1.1 riastrad struct i915_vma *vma; 33 1.1 riastrad u64 free_bitmap; 34 1.1 riastrad }; 35 1.1 riastrad 36 1.1 riastrad static struct i915_vma *__hwsp_alloc(struct intel_gt *gt) 37 1.1 riastrad { 38 1.1 riastrad struct drm_i915_private *i915 = gt->i915; 39 1.1 riastrad struct drm_i915_gem_object *obj; 40 1.1 riastrad struct i915_vma *vma; 41 1.1 riastrad 42 1.1 riastrad obj = i915_gem_object_create_internal(i915, PAGE_SIZE); 43 1.1 riastrad if (IS_ERR(obj)) 44 1.1 riastrad return ERR_CAST(obj); 45 1.1 riastrad 46 1.1 riastrad i915_gem_object_set_cache_coherency(obj, I915_CACHE_LLC); 47 1.1 riastrad 48 1.1 riastrad vma = i915_vma_instance(obj, >->ggtt->vm, NULL); 49 1.1 riastrad if (IS_ERR(vma)) 50 1.1 riastrad i915_gem_object_put(obj); 51 1.1 riastrad 52 1.1 riastrad return vma; 53 1.1 riastrad } 54 1.1 riastrad 55 1.1 riastrad static struct i915_vma * 56 1.1 riastrad hwsp_alloc(struct intel_timeline *timeline, unsigned int *cacheline) 57 1.1 riastrad { 58 1.1 riastrad struct intel_gt_timelines *gt = &timeline->gt->timelines; 59 1.1 riastrad struct intel_timeline_hwsp *hwsp; 60 1.1 riastrad 61 1.1 riastrad BUILD_BUG_ON(BITS_PER_TYPE(u64) * CACHELINE_BYTES > PAGE_SIZE); 62 1.1 riastrad 63 1.1 riastrad spin_lock_irq(>->hwsp_lock); 64 1.1 riastrad 65 1.1 riastrad /* hwsp_free_list only contains HWSP that have available cachelines */ 66 1.1 riastrad hwsp = list_first_entry_or_null(>->hwsp_free_list, 67 1.1 riastrad typeof(*hwsp), free_link); 68 1.1 riastrad if (!hwsp) { 69 1.1 riastrad struct i915_vma *vma; 70 1.1 riastrad 71 1.1 riastrad spin_unlock_irq(>->hwsp_lock); 72 1.1 riastrad 73 1.1 riastrad hwsp = kmalloc(sizeof(*hwsp), GFP_KERNEL); 74 1.1 riastrad if (!hwsp) 75 1.1 riastrad return ERR_PTR(-ENOMEM); 76 1.1 riastrad 77 1.1 riastrad vma = __hwsp_alloc(timeline->gt); 78 1.1 riastrad if (IS_ERR(vma)) { 79 1.1 riastrad kfree(hwsp); 80 1.1 riastrad return vma; 81 1.1 riastrad } 82 1.1 riastrad 83 1.1 riastrad vma->private = hwsp; 84 1.1 riastrad hwsp->gt = timeline->gt; 85 1.1 riastrad hwsp->vma = vma; 86 1.1 riastrad hwsp->free_bitmap = ~0ull; 87 1.1 riastrad hwsp->gt_timelines = gt; 88 1.1 riastrad 89 1.1 riastrad spin_lock_irq(>->hwsp_lock); 90 1.1 riastrad list_add(&hwsp->free_link, >->hwsp_free_list); 91 1.1 riastrad } 92 1.1 riastrad 93 1.1 riastrad GEM_BUG_ON(!hwsp->free_bitmap); 94 1.1 riastrad *cacheline = __ffs64(hwsp->free_bitmap); 95 1.1 riastrad hwsp->free_bitmap &= ~BIT_ULL(*cacheline); 96 1.1 riastrad if (!hwsp->free_bitmap) 97 1.1 riastrad list_del(&hwsp->free_link); 98 1.1 riastrad 99 1.1 riastrad spin_unlock_irq(>->hwsp_lock); 100 1.1 riastrad 101 1.1 riastrad GEM_BUG_ON(hwsp->vma->private != hwsp); 102 1.1 riastrad return hwsp->vma; 103 1.1 riastrad } 104 1.1 riastrad 105 1.1 riastrad static void __idle_hwsp_free(struct intel_timeline_hwsp *hwsp, int cacheline) 106 1.1 riastrad { 107 1.1 riastrad struct intel_gt_timelines *gt = hwsp->gt_timelines; 108 1.1 riastrad unsigned long flags; 109 1.1 riastrad 110 1.1 riastrad spin_lock_irqsave(>->hwsp_lock, flags); 111 1.1 riastrad 112 1.1 riastrad /* As a cacheline becomes available, publish the HWSP on the freelist */ 113 1.1 riastrad if (!hwsp->free_bitmap) 114 1.1 riastrad list_add_tail(&hwsp->free_link, >->hwsp_free_list); 115 1.1 riastrad 116 1.1 riastrad GEM_BUG_ON(cacheline >= BITS_PER_TYPE(hwsp->free_bitmap)); 117 1.1 riastrad hwsp->free_bitmap |= BIT_ULL(cacheline); 118 1.1 riastrad 119 1.1 riastrad /* And if no one is left using it, give the page back to the system */ 120 1.1 riastrad if (hwsp->free_bitmap == ~0ull) { 121 1.1 riastrad i915_vma_put(hwsp->vma); 122 1.1 riastrad list_del(&hwsp->free_link); 123 1.1 riastrad kfree(hwsp); 124 1.1 riastrad } 125 1.1 riastrad 126 1.1 riastrad spin_unlock_irqrestore(>->hwsp_lock, flags); 127 1.1 riastrad } 128 1.1 riastrad 129 1.1 riastrad static void __idle_cacheline_free(struct intel_timeline_cacheline *cl) 130 1.1 riastrad { 131 1.1 riastrad GEM_BUG_ON(!i915_active_is_idle(&cl->active)); 132 1.1 riastrad 133 1.1 riastrad i915_gem_object_unpin_map(cl->hwsp->vma->obj); 134 1.1 riastrad i915_vma_put(cl->hwsp->vma); 135 1.1 riastrad __idle_hwsp_free(cl->hwsp, ptr_unmask_bits(cl->vaddr, CACHELINE_BITS)); 136 1.1 riastrad 137 1.1 riastrad i915_active_fini(&cl->active); 138 1.1 riastrad kfree_rcu(cl, rcu); 139 1.1 riastrad } 140 1.1 riastrad 141 1.1 riastrad __i915_active_call 142 1.1 riastrad static void __cacheline_retire(struct i915_active *active) 143 1.1 riastrad { 144 1.1 riastrad struct intel_timeline_cacheline *cl = 145 1.1 riastrad container_of(active, typeof(*cl), active); 146 1.1 riastrad 147 1.1 riastrad i915_vma_unpin(cl->hwsp->vma); 148 1.1 riastrad if (ptr_test_bit(cl->vaddr, CACHELINE_FREE)) 149 1.1 riastrad __idle_cacheline_free(cl); 150 1.1 riastrad } 151 1.1 riastrad 152 1.1 riastrad static int __cacheline_active(struct i915_active *active) 153 1.1 riastrad { 154 1.1 riastrad struct intel_timeline_cacheline *cl = 155 1.1 riastrad container_of(active, typeof(*cl), active); 156 1.1 riastrad 157 1.1 riastrad __i915_vma_pin(cl->hwsp->vma); 158 1.1 riastrad return 0; 159 1.1 riastrad } 160 1.1 riastrad 161 1.1 riastrad static struct intel_timeline_cacheline * 162 1.1 riastrad cacheline_alloc(struct intel_timeline_hwsp *hwsp, unsigned int cacheline) 163 1.1 riastrad { 164 1.1 riastrad struct intel_timeline_cacheline *cl; 165 1.1 riastrad void *vaddr; 166 1.1 riastrad 167 1.1 riastrad GEM_BUG_ON(cacheline >= BIT(CACHELINE_BITS)); 168 1.1 riastrad 169 1.1 riastrad cl = kmalloc(sizeof(*cl), GFP_KERNEL); 170 1.1 riastrad if (!cl) 171 1.1 riastrad return ERR_PTR(-ENOMEM); 172 1.1 riastrad 173 1.1 riastrad vaddr = i915_gem_object_pin_map(hwsp->vma->obj, I915_MAP_WB); 174 1.1 riastrad if (IS_ERR(vaddr)) { 175 1.1 riastrad kfree(cl); 176 1.1 riastrad return ERR_CAST(vaddr); 177 1.1 riastrad } 178 1.1 riastrad 179 1.1 riastrad i915_vma_get(hwsp->vma); 180 1.1 riastrad cl->hwsp = hwsp; 181 1.1 riastrad cl->vaddr = page_pack_bits(vaddr, cacheline); 182 1.1 riastrad 183 1.1 riastrad i915_active_init(&cl->active, __cacheline_active, __cacheline_retire); 184 1.1 riastrad 185 1.1 riastrad return cl; 186 1.1 riastrad } 187 1.1 riastrad 188 1.1 riastrad static void cacheline_acquire(struct intel_timeline_cacheline *cl) 189 1.1 riastrad { 190 1.1 riastrad if (cl) 191 1.1 riastrad i915_active_acquire(&cl->active); 192 1.1 riastrad } 193 1.1 riastrad 194 1.1 riastrad static void cacheline_release(struct intel_timeline_cacheline *cl) 195 1.1 riastrad { 196 1.1 riastrad if (cl) 197 1.1 riastrad i915_active_release(&cl->active); 198 1.1 riastrad } 199 1.1 riastrad 200 1.1 riastrad static void cacheline_free(struct intel_timeline_cacheline *cl) 201 1.1 riastrad { 202 1.1 riastrad GEM_BUG_ON(ptr_test_bit(cl->vaddr, CACHELINE_FREE)); 203 1.1 riastrad cl->vaddr = ptr_set_bit(cl->vaddr, CACHELINE_FREE); 204 1.1 riastrad 205 1.1 riastrad if (i915_active_is_idle(&cl->active)) 206 1.1 riastrad __idle_cacheline_free(cl); 207 1.1 riastrad } 208 1.1 riastrad 209 1.1 riastrad int intel_timeline_init(struct intel_timeline *timeline, 210 1.1 riastrad struct intel_gt *gt, 211 1.1 riastrad struct i915_vma *hwsp) 212 1.1 riastrad { 213 1.1 riastrad void *vaddr; 214 1.1 riastrad 215 1.1 riastrad kref_init(&timeline->kref); 216 1.1 riastrad atomic_set(&timeline->pin_count, 0); 217 1.1 riastrad 218 1.1 riastrad timeline->gt = gt; 219 1.1 riastrad 220 1.1 riastrad timeline->has_initial_breadcrumb = !hwsp; 221 1.1 riastrad timeline->hwsp_cacheline = NULL; 222 1.1 riastrad 223 1.1 riastrad if (!hwsp) { 224 1.1 riastrad struct intel_timeline_cacheline *cl; 225 1.1 riastrad unsigned int cacheline; 226 1.1 riastrad 227 1.1 riastrad hwsp = hwsp_alloc(timeline, &cacheline); 228 1.1 riastrad if (IS_ERR(hwsp)) 229 1.1 riastrad return PTR_ERR(hwsp); 230 1.1 riastrad 231 1.1 riastrad cl = cacheline_alloc(hwsp->private, cacheline); 232 1.1 riastrad if (IS_ERR(cl)) { 233 1.1 riastrad __idle_hwsp_free(hwsp->private, cacheline); 234 1.1 riastrad return PTR_ERR(cl); 235 1.1 riastrad } 236 1.1 riastrad 237 1.1 riastrad timeline->hwsp_cacheline = cl; 238 1.1 riastrad timeline->hwsp_offset = cacheline * CACHELINE_BYTES; 239 1.1 riastrad 240 1.1 riastrad vaddr = page_mask_bits(cl->vaddr); 241 1.1 riastrad } else { 242 1.1 riastrad timeline->hwsp_offset = I915_GEM_HWS_SEQNO_ADDR; 243 1.1 riastrad 244 1.1 riastrad vaddr = i915_gem_object_pin_map(hwsp->obj, I915_MAP_WB); 245 1.1 riastrad if (IS_ERR(vaddr)) 246 1.1 riastrad return PTR_ERR(vaddr); 247 1.1 riastrad } 248 1.1 riastrad 249 1.1 riastrad timeline->hwsp_seqno = 250 1.1 riastrad memset(vaddr + timeline->hwsp_offset, 0, CACHELINE_BYTES); 251 1.1 riastrad 252 1.1 riastrad timeline->hwsp_ggtt = i915_vma_get(hwsp); 253 1.1 riastrad GEM_BUG_ON(timeline->hwsp_offset >= hwsp->size); 254 1.1 riastrad 255 1.1 riastrad timeline->fence_context = dma_fence_context_alloc(1); 256 1.1 riastrad 257 1.1 riastrad mutex_init(&timeline->mutex); 258 1.1 riastrad 259 1.1 riastrad INIT_ACTIVE_FENCE(&timeline->last_request); 260 1.1 riastrad INIT_LIST_HEAD(&timeline->requests); 261 1.1 riastrad 262 1.1 riastrad i915_syncmap_init(&timeline->sync); 263 1.1 riastrad 264 1.1 riastrad return 0; 265 1.1 riastrad } 266 1.1 riastrad 267 1.1 riastrad void intel_gt_init_timelines(struct intel_gt *gt) 268 1.1 riastrad { 269 1.1 riastrad struct intel_gt_timelines *timelines = >->timelines; 270 1.1 riastrad 271 1.1 riastrad spin_lock_init(&timelines->lock); 272 1.1 riastrad INIT_LIST_HEAD(&timelines->active_list); 273 1.1 riastrad 274 1.1 riastrad spin_lock_init(&timelines->hwsp_lock); 275 1.1 riastrad INIT_LIST_HEAD(&timelines->hwsp_free_list); 276 1.1 riastrad } 277 1.1 riastrad 278 1.1 riastrad void intel_timeline_fini(struct intel_timeline *timeline) 279 1.1 riastrad { 280 1.1 riastrad GEM_BUG_ON(atomic_read(&timeline->pin_count)); 281 1.1 riastrad GEM_BUG_ON(!list_empty(&timeline->requests)); 282 1.1 riastrad GEM_BUG_ON(timeline->retire); 283 1.1 riastrad 284 1.1 riastrad if (timeline->hwsp_cacheline) 285 1.1 riastrad cacheline_free(timeline->hwsp_cacheline); 286 1.1 riastrad else 287 1.1 riastrad i915_gem_object_unpin_map(timeline->hwsp_ggtt->obj); 288 1.1 riastrad 289 1.1 riastrad i915_vma_put(timeline->hwsp_ggtt); 290 1.4 riastrad 291 1.4 riastrad mutex_destroy(&timeline->mutex); 292 1.1 riastrad } 293 1.1 riastrad 294 1.1 riastrad struct intel_timeline * 295 1.1 riastrad intel_timeline_create(struct intel_gt *gt, struct i915_vma *global_hwsp) 296 1.1 riastrad { 297 1.1 riastrad struct intel_timeline *timeline; 298 1.1 riastrad int err; 299 1.1 riastrad 300 1.1 riastrad timeline = kzalloc(sizeof(*timeline), GFP_KERNEL); 301 1.1 riastrad if (!timeline) 302 1.1 riastrad return ERR_PTR(-ENOMEM); 303 1.1 riastrad 304 1.1 riastrad err = intel_timeline_init(timeline, gt, global_hwsp); 305 1.1 riastrad if (err) { 306 1.1 riastrad kfree(timeline); 307 1.1 riastrad return ERR_PTR(err); 308 1.1 riastrad } 309 1.1 riastrad 310 1.1 riastrad return timeline; 311 1.1 riastrad } 312 1.1 riastrad 313 1.1 riastrad int intel_timeline_pin(struct intel_timeline *tl) 314 1.1 riastrad { 315 1.1 riastrad int err; 316 1.1 riastrad 317 1.1 riastrad if (atomic_add_unless(&tl->pin_count, 1, 0)) 318 1.1 riastrad return 0; 319 1.1 riastrad 320 1.1 riastrad err = i915_vma_pin(tl->hwsp_ggtt, 0, 0, PIN_GLOBAL | PIN_HIGH); 321 1.1 riastrad if (err) 322 1.1 riastrad return err; 323 1.1 riastrad 324 1.1 riastrad tl->hwsp_offset = 325 1.1 riastrad i915_ggtt_offset(tl->hwsp_ggtt) + 326 1.1 riastrad offset_in_page(tl->hwsp_offset); 327 1.1 riastrad 328 1.1 riastrad cacheline_acquire(tl->hwsp_cacheline); 329 1.1 riastrad if (atomic_fetch_inc(&tl->pin_count)) { 330 1.1 riastrad cacheline_release(tl->hwsp_cacheline); 331 1.1 riastrad __i915_vma_unpin(tl->hwsp_ggtt); 332 1.1 riastrad } 333 1.1 riastrad 334 1.1 riastrad return 0; 335 1.1 riastrad } 336 1.1 riastrad 337 1.1 riastrad void intel_timeline_enter(struct intel_timeline *tl) 338 1.1 riastrad { 339 1.1 riastrad struct intel_gt_timelines *timelines = &tl->gt->timelines; 340 1.1 riastrad 341 1.1 riastrad /* 342 1.1 riastrad * Pretend we are serialised by the timeline->mutex. 343 1.1 riastrad * 344 1.1 riastrad * While generally true, there are a few exceptions to the rule 345 1.1 riastrad * for the engine->kernel_context being used to manage power 346 1.1 riastrad * transitions. As the engine_park may be called from under any 347 1.1 riastrad * timeline, it uses the power mutex as a global serialisation 348 1.1 riastrad * lock to prevent any other request entering its timeline. 349 1.1 riastrad * 350 1.1 riastrad * The rule is generally tl->mutex, otherwise engine->wakeref.mutex. 351 1.1 riastrad * 352 1.1 riastrad * However, intel_gt_retire_request() does not know which engine 353 1.1 riastrad * it is retiring along and so cannot partake in the engine-pm 354 1.1 riastrad * barrier, and there we use the tl->active_count as a means to 355 1.1 riastrad * pin the timeline in the active_list while the locks are dropped. 356 1.1 riastrad * Ergo, as that is outside of the engine-pm barrier, we need to 357 1.1 riastrad * use atomic to manipulate tl->active_count. 358 1.1 riastrad */ 359 1.1 riastrad lockdep_assert_held(&tl->mutex); 360 1.1 riastrad 361 1.1 riastrad if (atomic_add_unless(&tl->active_count, 1, 0)) 362 1.1 riastrad return; 363 1.1 riastrad 364 1.1 riastrad spin_lock(&timelines->lock); 365 1.1 riastrad if (!atomic_fetch_inc(&tl->active_count)) 366 1.1 riastrad list_add_tail(&tl->link, &timelines->active_list); 367 1.1 riastrad spin_unlock(&timelines->lock); 368 1.1 riastrad } 369 1.1 riastrad 370 1.1 riastrad void intel_timeline_exit(struct intel_timeline *tl) 371 1.1 riastrad { 372 1.1 riastrad struct intel_gt_timelines *timelines = &tl->gt->timelines; 373 1.1 riastrad 374 1.1 riastrad /* See intel_timeline_enter() */ 375 1.1 riastrad lockdep_assert_held(&tl->mutex); 376 1.1 riastrad 377 1.1 riastrad GEM_BUG_ON(!atomic_read(&tl->active_count)); 378 1.1 riastrad if (atomic_add_unless(&tl->active_count, -1, 1)) 379 1.1 riastrad return; 380 1.1 riastrad 381 1.1 riastrad spin_lock(&timelines->lock); 382 1.1 riastrad if (atomic_dec_and_test(&tl->active_count)) 383 1.1 riastrad list_del(&tl->link); 384 1.1 riastrad spin_unlock(&timelines->lock); 385 1.1 riastrad 386 1.1 riastrad /* 387 1.1 riastrad * Since this timeline is idle, all bariers upon which we were waiting 388 1.1 riastrad * must also be complete and so we can discard the last used barriers 389 1.1 riastrad * without loss of information. 390 1.1 riastrad */ 391 1.1 riastrad i915_syncmap_free(&tl->sync); 392 1.1 riastrad } 393 1.1 riastrad 394 1.1 riastrad static u32 timeline_advance(struct intel_timeline *tl) 395 1.1 riastrad { 396 1.1 riastrad GEM_BUG_ON(!atomic_read(&tl->pin_count)); 397 1.1 riastrad GEM_BUG_ON(tl->seqno & tl->has_initial_breadcrumb); 398 1.1 riastrad 399 1.1 riastrad return tl->seqno += 1 + tl->has_initial_breadcrumb; 400 1.1 riastrad } 401 1.1 riastrad 402 1.1 riastrad static void timeline_rollback(struct intel_timeline *tl) 403 1.1 riastrad { 404 1.1 riastrad tl->seqno -= 1 + tl->has_initial_breadcrumb; 405 1.1 riastrad } 406 1.1 riastrad 407 1.1 riastrad static noinline int 408 1.1 riastrad __intel_timeline_get_seqno(struct intel_timeline *tl, 409 1.1 riastrad struct i915_request *rq, 410 1.1 riastrad u32 *seqno) 411 1.1 riastrad { 412 1.1 riastrad struct intel_timeline_cacheline *cl; 413 1.1 riastrad unsigned int cacheline; 414 1.1 riastrad struct i915_vma *vma; 415 1.1 riastrad void *vaddr; 416 1.1 riastrad int err; 417 1.1 riastrad 418 1.1 riastrad /* 419 1.1 riastrad * If there is an outstanding GPU reference to this cacheline, 420 1.1 riastrad * such as it being sampled by a HW semaphore on another timeline, 421 1.1 riastrad * we cannot wraparound our seqno value (the HW semaphore does 422 1.1 riastrad * a strict greater-than-or-equals compare, not i915_seqno_passed). 423 1.1 riastrad * So if the cacheline is still busy, we must detach ourselves 424 1.1 riastrad * from it and leave it inflight alongside its users. 425 1.1 riastrad * 426 1.1 riastrad * However, if nobody is watching and we can guarantee that nobody 427 1.1 riastrad * will, we could simply reuse the same cacheline. 428 1.1 riastrad * 429 1.1 riastrad * if (i915_active_request_is_signaled(&tl->last_request) && 430 1.1 riastrad * i915_active_is_signaled(&tl->hwsp_cacheline->active)) 431 1.1 riastrad * return 0; 432 1.1 riastrad * 433 1.1 riastrad * That seems unlikely for a busy timeline that needed to wrap in 434 1.1 riastrad * the first place, so just replace the cacheline. 435 1.1 riastrad */ 436 1.1 riastrad 437 1.1 riastrad vma = hwsp_alloc(tl, &cacheline); 438 1.1 riastrad if (IS_ERR(vma)) { 439 1.1 riastrad err = PTR_ERR(vma); 440 1.1 riastrad goto err_rollback; 441 1.1 riastrad } 442 1.1 riastrad 443 1.1 riastrad err = i915_vma_pin(vma, 0, 0, PIN_GLOBAL | PIN_HIGH); 444 1.1 riastrad if (err) { 445 1.1 riastrad __idle_hwsp_free(vma->private, cacheline); 446 1.1 riastrad goto err_rollback; 447 1.1 riastrad } 448 1.1 riastrad 449 1.1 riastrad cl = cacheline_alloc(vma->private, cacheline); 450 1.1 riastrad if (IS_ERR(cl)) { 451 1.1 riastrad err = PTR_ERR(cl); 452 1.1 riastrad __idle_hwsp_free(vma->private, cacheline); 453 1.1 riastrad goto err_unpin; 454 1.1 riastrad } 455 1.1 riastrad GEM_BUG_ON(cl->hwsp->vma != vma); 456 1.1 riastrad 457 1.1 riastrad /* 458 1.1 riastrad * Attach the old cacheline to the current request, so that we only 459 1.1 riastrad * free it after the current request is retired, which ensures that 460 1.1 riastrad * all writes into the cacheline from previous requests are complete. 461 1.1 riastrad */ 462 1.1 riastrad err = i915_active_ref(&tl->hwsp_cacheline->active, tl, &rq->fence); 463 1.1 riastrad if (err) 464 1.1 riastrad goto err_cacheline; 465 1.1 riastrad 466 1.1 riastrad cacheline_release(tl->hwsp_cacheline); /* ownership now xfered to rq */ 467 1.1 riastrad cacheline_free(tl->hwsp_cacheline); 468 1.1 riastrad 469 1.1 riastrad i915_vma_unpin(tl->hwsp_ggtt); /* binding kept alive by old cacheline */ 470 1.1 riastrad i915_vma_put(tl->hwsp_ggtt); 471 1.1 riastrad 472 1.1 riastrad tl->hwsp_ggtt = i915_vma_get(vma); 473 1.1 riastrad 474 1.1 riastrad vaddr = page_mask_bits(cl->vaddr); 475 1.1 riastrad tl->hwsp_offset = cacheline * CACHELINE_BYTES; 476 1.1 riastrad tl->hwsp_seqno = 477 1.1 riastrad memset(vaddr + tl->hwsp_offset, 0, CACHELINE_BYTES); 478 1.1 riastrad 479 1.1 riastrad tl->hwsp_offset += i915_ggtt_offset(vma); 480 1.1 riastrad 481 1.1 riastrad cacheline_acquire(cl); 482 1.1 riastrad tl->hwsp_cacheline = cl; 483 1.1 riastrad 484 1.1 riastrad *seqno = timeline_advance(tl); 485 1.1 riastrad GEM_BUG_ON(i915_seqno_passed(*tl->hwsp_seqno, *seqno)); 486 1.1 riastrad return 0; 487 1.1 riastrad 488 1.1 riastrad err_cacheline: 489 1.1 riastrad cacheline_free(cl); 490 1.1 riastrad err_unpin: 491 1.1 riastrad i915_vma_unpin(vma); 492 1.1 riastrad err_rollback: 493 1.1 riastrad timeline_rollback(tl); 494 1.1 riastrad return err; 495 1.1 riastrad } 496 1.1 riastrad 497 1.1 riastrad int intel_timeline_get_seqno(struct intel_timeline *tl, 498 1.1 riastrad struct i915_request *rq, 499 1.1 riastrad u32 *seqno) 500 1.1 riastrad { 501 1.1 riastrad *seqno = timeline_advance(tl); 502 1.1 riastrad 503 1.1 riastrad /* Replace the HWSP on wraparound for HW semaphores */ 504 1.1 riastrad if (unlikely(!*seqno && tl->hwsp_cacheline)) 505 1.1 riastrad return __intel_timeline_get_seqno(tl, rq, seqno); 506 1.1 riastrad 507 1.1 riastrad return 0; 508 1.1 riastrad } 509 1.1 riastrad 510 1.1 riastrad static int cacheline_ref(struct intel_timeline_cacheline *cl, 511 1.1 riastrad struct i915_request *rq) 512 1.1 riastrad { 513 1.1 riastrad return i915_active_add_request(&cl->active, rq); 514 1.1 riastrad } 515 1.1 riastrad 516 1.1 riastrad int intel_timeline_read_hwsp(struct i915_request *from, 517 1.1 riastrad struct i915_request *to, 518 1.1 riastrad u32 *hwsp) 519 1.1 riastrad { 520 1.1 riastrad struct intel_timeline_cacheline *cl; 521 1.1 riastrad int err; 522 1.1 riastrad 523 1.1 riastrad GEM_BUG_ON(!rcu_access_pointer(from->hwsp_cacheline)); 524 1.1 riastrad 525 1.1 riastrad rcu_read_lock(); 526 1.1 riastrad cl = rcu_dereference(from->hwsp_cacheline); 527 1.1 riastrad if (unlikely(!i915_active_acquire_if_busy(&cl->active))) 528 1.1 riastrad goto unlock; /* seqno wrapped and completed! */ 529 1.1 riastrad if (unlikely(i915_request_completed(from))) 530 1.1 riastrad goto release; 531 1.1 riastrad rcu_read_unlock(); 532 1.1 riastrad 533 1.1 riastrad err = cacheline_ref(cl, to); 534 1.1 riastrad if (err) 535 1.1 riastrad goto out; 536 1.1 riastrad 537 1.1 riastrad *hwsp = i915_ggtt_offset(cl->hwsp->vma) + 538 1.1 riastrad ptr_unmask_bits(cl->vaddr, CACHELINE_BITS) * CACHELINE_BYTES; 539 1.1 riastrad 540 1.1 riastrad out: 541 1.1 riastrad i915_active_release(&cl->active); 542 1.1 riastrad return err; 543 1.1 riastrad 544 1.1 riastrad release: 545 1.1 riastrad i915_active_release(&cl->active); 546 1.1 riastrad unlock: 547 1.1 riastrad rcu_read_unlock(); 548 1.1 riastrad return 1; 549 1.1 riastrad } 550 1.1 riastrad 551 1.1 riastrad void intel_timeline_unpin(struct intel_timeline *tl) 552 1.1 riastrad { 553 1.1 riastrad GEM_BUG_ON(!atomic_read(&tl->pin_count)); 554 1.1 riastrad if (!atomic_dec_and_test(&tl->pin_count)) 555 1.1 riastrad return; 556 1.1 riastrad 557 1.1 riastrad cacheline_release(tl->hwsp_cacheline); 558 1.1 riastrad 559 1.1 riastrad __i915_vma_unpin(tl->hwsp_ggtt); 560 1.1 riastrad } 561 1.1 riastrad 562 1.1 riastrad void __intel_timeline_free(struct kref *kref) 563 1.1 riastrad { 564 1.1 riastrad struct intel_timeline *timeline = 565 1.1 riastrad container_of(kref, typeof(*timeline), kref); 566 1.1 riastrad 567 1.1 riastrad intel_timeline_fini(timeline); 568 1.1 riastrad kfree_rcu(timeline, rcu); 569 1.1 riastrad } 570 1.1 riastrad 571 1.1 riastrad void intel_gt_fini_timelines(struct intel_gt *gt) 572 1.1 riastrad { 573 1.1 riastrad struct intel_gt_timelines *timelines = >->timelines; 574 1.1 riastrad 575 1.1 riastrad GEM_BUG_ON(!list_empty(&timelines->active_list)); 576 1.1 riastrad GEM_BUG_ON(!list_empty(&timelines->hwsp_free_list)); 577 1.5 riastrad 578 1.5 riastrad spin_lock_destroy(&timelines->hwsp_lock); 579 1.5 riastrad spin_lock_destroy(&timelines->lock); 580 1.1 riastrad } 581 1.1 riastrad 582 1.1 riastrad #if IS_ENABLED(CONFIG_DRM_I915_SELFTEST) 583 1.1 riastrad #include "gt/selftests/mock_timeline.c" 584 1.1 riastrad #include "gt/selftest_timeline.c" 585 1.1 riastrad #endif 586