1 // SPDX-License-Identifier: MIT 2 /* 3 * Copyright © 2023 Intel Corporation 4 */ 5 6 #include "xe_gt_tlb_invalidation.h" 7 8 #include "abi/guc_actions_abi.h" 9 #include "xe_device.h" 10 #include "xe_force_wake.h" 11 #include "xe_gt.h" 12 #include "xe_gt_printk.h" 13 #include "xe_guc.h" 14 #include "xe_guc_ct.h" 15 #include "xe_mmio.h" 16 #include "xe_pm.h" 17 #include "xe_sriov.h" 18 #include "xe_trace.h" 19 #include "regs/xe_guc_regs.h" 20 21 #define FENCE_STACK_BIT DMA_FENCE_FLAG_USER_BITS 22 23 /* 24 * TLB inval depends on pending commands in the CT queue and then the real 25 * invalidation time. Double up the time to process full CT queue 26 * just to be on the safe side. 27 */ 28 static long tlb_timeout_jiffies(struct xe_gt *gt) 29 { 30 /* this reflects what HW/GuC needs to process TLB inv request */ 31 const long hw_tlb_timeout = HZ / 4; 32 33 /* this estimates actual delay caused by the CTB transport */ 34 long delay = xe_guc_ct_queue_proc_time_jiffies(>->uc.guc.ct); 35 36 return hw_tlb_timeout + 2 * delay; 37 } 38 39 static void 40 __invalidation_fence_signal(struct xe_device *xe, struct xe_gt_tlb_invalidation_fence *fence) 41 { 42 bool stack = test_bit(FENCE_STACK_BIT, &fence->base.flags); 43 44 trace_xe_gt_tlb_invalidation_fence_signal(xe, fence); 45 xe_gt_tlb_invalidation_fence_fini(fence); 46 dma_fence_signal(&fence->base); 47 if (!stack) 48 dma_fence_put(&fence->base); 49 } 50 51 static void 52 invalidation_fence_signal(struct xe_device *xe, struct xe_gt_tlb_invalidation_fence *fence) 53 { 54 list_del(&fence->link); 55 __invalidation_fence_signal(xe, fence); 56 } 57 58 static void xe_gt_tlb_fence_timeout(struct work_struct *work) 59 { 60 struct xe_gt *gt = container_of(work, struct xe_gt, 61 tlb_invalidation.fence_tdr.work); 62 struct xe_device *xe = gt_to_xe(gt); 63 struct xe_gt_tlb_invalidation_fence *fence, *next; 64 65 spin_lock_irq(>->tlb_invalidation.pending_lock); 66 list_for_each_entry_safe(fence, next, 67 >->tlb_invalidation.pending_fences, link) { 68 s64 since_inval_ms = ktime_ms_delta(ktime_get(), 69 fence->invalidation_time); 70 71 if (msecs_to_jiffies(since_inval_ms) < tlb_timeout_jiffies(gt)) 72 break; 73 74 trace_xe_gt_tlb_invalidation_fence_timeout(xe, fence); 75 xe_gt_err(gt, "TLB invalidation fence timeout, seqno=%d recv=%d", 76 fence->seqno, gt->tlb_invalidation.seqno_recv); 77 78 fence->base.error = -ETIME; 79 invalidation_fence_signal(xe, fence); 80 } 81 if (!list_empty(>->tlb_invalidation.pending_fences)) 82 queue_delayed_work(system_wq, 83 >->tlb_invalidation.fence_tdr, 84 tlb_timeout_jiffies(gt)); 85 spin_unlock_irq(>->tlb_invalidation.pending_lock); 86 } 87 88 /** 89 * xe_gt_tlb_invalidation_init - Initialize GT TLB invalidation state 90 * @gt: graphics tile 91 * 92 * Initialize GT TLB invalidation state, purely software initialization, should 93 * be called once during driver load. 94 * 95 * Return: 0 on success, negative error code on error. 96 */ 97 int xe_gt_tlb_invalidation_init(struct xe_gt *gt) 98 { 99 gt->tlb_invalidation.seqno = 1; 100 INIT_LIST_HEAD(>->tlb_invalidation.pending_fences); 101 spin_lock_init(>->tlb_invalidation.pending_lock); 102 spin_lock_init(>->tlb_invalidation.lock); 103 INIT_DELAYED_WORK(>->tlb_invalidation.fence_tdr, 104 xe_gt_tlb_fence_timeout); 105 106 return 0; 107 } 108 109 /** 110 * xe_gt_tlb_invalidation_reset - Initialize GT TLB invalidation reset 111 * @gt: graphics tile 112 * 113 * Signal any pending invalidation fences, should be called during a GT reset 114 */ 115 void xe_gt_tlb_invalidation_reset(struct xe_gt *gt) 116 { 117 struct xe_gt_tlb_invalidation_fence *fence, *next; 118 int pending_seqno; 119 120 /* 121 * CT channel is already disabled at this point. No new TLB requests can 122 * appear. 123 */ 124 125 mutex_lock(>->uc.guc.ct.lock); 126 spin_lock_irq(>->tlb_invalidation.pending_lock); 127 cancel_delayed_work(>->tlb_invalidation.fence_tdr); 128 /* 129 * We might have various kworkers waiting for TLB flushes to complete 130 * which are not tracked with an explicit TLB fence, however at this 131 * stage that will never happen since the CT is already disabled, so 132 * make sure we signal them here under the assumption that we have 133 * completed a full GT reset. 134 */ 135 if (gt->tlb_invalidation.seqno == 1) 136 pending_seqno = TLB_INVALIDATION_SEQNO_MAX - 1; 137 else 138 pending_seqno = gt->tlb_invalidation.seqno - 1; 139 WRITE_ONCE(gt->tlb_invalidation.seqno_recv, pending_seqno); 140 141 list_for_each_entry_safe(fence, next, 142 >->tlb_invalidation.pending_fences, link) 143 invalidation_fence_signal(gt_to_xe(gt), fence); 144 spin_unlock_irq(>->tlb_invalidation.pending_lock); 145 mutex_unlock(>->uc.guc.ct.lock); 146 } 147 148 static bool tlb_invalidation_seqno_past(struct xe_gt *gt, int seqno) 149 { 150 int seqno_recv = READ_ONCE(gt->tlb_invalidation.seqno_recv); 151 152 if (seqno - seqno_recv < -(TLB_INVALIDATION_SEQNO_MAX / 2)) 153 return false; 154 155 if (seqno - seqno_recv > (TLB_INVALIDATION_SEQNO_MAX / 2)) 156 return true; 157 158 return seqno_recv >= seqno; 159 } 160 161 static int send_tlb_invalidation(struct xe_guc *guc, 162 struct xe_gt_tlb_invalidation_fence *fence, 163 u32 *action, int len) 164 { 165 struct xe_gt *gt = guc_to_gt(guc); 166 struct xe_device *xe = gt_to_xe(gt); 167 int seqno; 168 int ret; 169 170 xe_gt_assert(gt, fence); 171 172 /* 173 * XXX: The seqno algorithm relies on TLB invalidation being processed 174 * in order which they currently are, if that changes the algorithm will 175 * need to be updated. 176 */ 177 178 mutex_lock(&guc->ct.lock); 179 seqno = gt->tlb_invalidation.seqno; 180 fence->seqno = seqno; 181 trace_xe_gt_tlb_invalidation_fence_send(xe, fence); 182 action[1] = seqno; 183 ret = xe_guc_ct_send_locked(&guc->ct, action, len, 184 G2H_LEN_DW_TLB_INVALIDATE, 1); 185 if (!ret && fence) { 186 spin_lock_irq(>->tlb_invalidation.pending_lock); 187 /* 188 * We haven't actually published the TLB fence as per 189 * pending_fences, but in theory our seqno could have already 190 * been written as we acquired the pending_lock. In such a case 191 * we can just go ahead and signal the fence here. 192 */ 193 if (tlb_invalidation_seqno_past(gt, seqno)) { 194 __invalidation_fence_signal(xe, fence); 195 } else { 196 fence->invalidation_time = ktime_get(); 197 list_add_tail(&fence->link, 198 >->tlb_invalidation.pending_fences); 199 200 if (list_is_singular(>->tlb_invalidation.pending_fences)) 201 queue_delayed_work(system_wq, 202 >->tlb_invalidation.fence_tdr, 203 tlb_timeout_jiffies(gt)); 204 } 205 spin_unlock_irq(>->tlb_invalidation.pending_lock); 206 } else if (ret < 0 && fence) { 207 __invalidation_fence_signal(xe, fence); 208 } 209 if (!ret) { 210 gt->tlb_invalidation.seqno = (gt->tlb_invalidation.seqno + 1) % 211 TLB_INVALIDATION_SEQNO_MAX; 212 if (!gt->tlb_invalidation.seqno) 213 gt->tlb_invalidation.seqno = 1; 214 } 215 mutex_unlock(&guc->ct.lock); 216 217 return ret; 218 } 219 220 #define MAKE_INVAL_OP(type) ((type << XE_GUC_TLB_INVAL_TYPE_SHIFT) | \ 221 XE_GUC_TLB_INVAL_MODE_HEAVY << XE_GUC_TLB_INVAL_MODE_SHIFT | \ 222 XE_GUC_TLB_INVAL_FLUSH_CACHE) 223 224 /** 225 * xe_gt_tlb_invalidation_guc - Issue a TLB invalidation on this GT for the GuC 226 * @gt: graphics tile 227 * @fence: invalidation fence which will be signal on TLB invalidation 228 * completion 229 * 230 * Issue a TLB invalidation for the GuC. Completion of TLB is asynchronous and 231 * caller can use the invalidation fence to wait for completion. 232 * 233 * Return: 0 on success, negative error code on error 234 */ 235 static int xe_gt_tlb_invalidation_guc(struct xe_gt *gt, 236 struct xe_gt_tlb_invalidation_fence *fence) 237 { 238 u32 action[] = { 239 XE_GUC_ACTION_TLB_INVALIDATION, 240 0, /* seqno, replaced in send_tlb_invalidation */ 241 MAKE_INVAL_OP(XE_GUC_TLB_INVAL_GUC), 242 }; 243 244 return send_tlb_invalidation(>->uc.guc, fence, action, 245 ARRAY_SIZE(action)); 246 } 247 248 /** 249 * xe_gt_tlb_invalidation_ggtt - Issue a TLB invalidation on this GT for the GGTT 250 * @gt: graphics tile 251 * 252 * Issue a TLB invalidation for the GGTT. Completion of TLB invalidation is 253 * synchronous. 254 * 255 * Return: 0 on success, negative error code on error 256 */ 257 int xe_gt_tlb_invalidation_ggtt(struct xe_gt *gt) 258 { 259 struct xe_device *xe = gt_to_xe(gt); 260 261 if (xe_guc_ct_enabled(>->uc.guc.ct) && 262 gt->uc.guc.submission_state.enabled) { 263 struct xe_gt_tlb_invalidation_fence fence; 264 int ret; 265 266 xe_gt_tlb_invalidation_fence_init(gt, &fence, true); 267 ret = xe_gt_tlb_invalidation_guc(gt, &fence); 268 if (ret < 0) { 269 xe_gt_tlb_invalidation_fence_fini(&fence); 270 return ret; 271 } 272 273 xe_gt_tlb_invalidation_fence_wait(&fence); 274 } else if (xe_device_uc_enabled(xe) && !xe_device_wedged(xe)) { 275 if (IS_SRIOV_VF(xe)) 276 return 0; 277 278 xe_gt_WARN_ON(gt, xe_force_wake_get(gt_to_fw(gt), XE_FW_GT)); 279 if (xe->info.platform == XE_PVC || GRAPHICS_VER(xe) >= 20) { 280 xe_mmio_write32(gt, PVC_GUC_TLB_INV_DESC1, 281 PVC_GUC_TLB_INV_DESC1_INVALIDATE); 282 xe_mmio_write32(gt, PVC_GUC_TLB_INV_DESC0, 283 PVC_GUC_TLB_INV_DESC0_VALID); 284 } else { 285 xe_mmio_write32(gt, GUC_TLB_INV_CR, 286 GUC_TLB_INV_CR_INVALIDATE); 287 } 288 xe_force_wake_put(gt_to_fw(gt), XE_FW_GT); 289 } 290 291 return 0; 292 } 293 294 /** 295 * xe_gt_tlb_invalidation_range - Issue a TLB invalidation on this GT for an 296 * address range 297 * 298 * @gt: graphics tile 299 * @fence: invalidation fence which will be signal on TLB invalidation 300 * completion 301 * @start: start address 302 * @end: end address 303 * @asid: address space id 304 * 305 * Issue a range based TLB invalidation if supported, if not fallback to a full 306 * TLB invalidation. Completion of TLB is asynchronous and caller can use 307 * the invalidation fence to wait for completion. 308 * 309 * Return: Negative error code on error, 0 on success 310 */ 311 int xe_gt_tlb_invalidation_range(struct xe_gt *gt, 312 struct xe_gt_tlb_invalidation_fence *fence, 313 u64 start, u64 end, u32 asid) 314 { 315 struct xe_device *xe = gt_to_xe(gt); 316 #define MAX_TLB_INVALIDATION_LEN 7 317 u32 action[MAX_TLB_INVALIDATION_LEN]; 318 int len = 0; 319 320 xe_gt_assert(gt, fence); 321 322 /* Execlists not supported */ 323 if (gt_to_xe(gt)->info.force_execlist) { 324 __invalidation_fence_signal(xe, fence); 325 return 0; 326 } 327 328 action[len++] = XE_GUC_ACTION_TLB_INVALIDATION; 329 action[len++] = 0; /* seqno, replaced in send_tlb_invalidation */ 330 if (!xe->info.has_range_tlb_invalidation) { 331 action[len++] = MAKE_INVAL_OP(XE_GUC_TLB_INVAL_FULL); 332 } else { 333 u64 orig_start = start; 334 u64 length = end - start; 335 u64 align; 336 337 if (length < SZ_4K) 338 length = SZ_4K; 339 340 /* 341 * We need to invalidate a higher granularity if start address 342 * is not aligned to length. When start is not aligned with 343 * length we need to find the length large enough to create an 344 * address mask covering the required range. 345 */ 346 align = roundup_pow_of_two(length); 347 start = ALIGN_DOWN(start, align); 348 end = ALIGN(end, align); 349 length = align; 350 while (start + length < end) { 351 length <<= 1; 352 start = ALIGN_DOWN(orig_start, length); 353 } 354 355 /* 356 * Minimum invalidation size for a 2MB page that the hardware 357 * expects is 16MB 358 */ 359 if (length >= SZ_2M) { 360 length = max_t(u64, SZ_16M, length); 361 start = ALIGN_DOWN(orig_start, length); 362 } 363 364 xe_gt_assert(gt, length >= SZ_4K); 365 xe_gt_assert(gt, is_power_of_2(length)); 366 xe_gt_assert(gt, !(length & GENMASK(ilog2(SZ_16M) - 1, 367 ilog2(SZ_2M) + 1))); 368 xe_gt_assert(gt, IS_ALIGNED(start, length)); 369 370 action[len++] = MAKE_INVAL_OP(XE_GUC_TLB_INVAL_PAGE_SELECTIVE); 371 action[len++] = asid; 372 action[len++] = lower_32_bits(start); 373 action[len++] = upper_32_bits(start); 374 action[len++] = ilog2(length) - ilog2(SZ_4K); 375 } 376 377 xe_gt_assert(gt, len <= MAX_TLB_INVALIDATION_LEN); 378 379 return send_tlb_invalidation(>->uc.guc, fence, action, len); 380 } 381 382 /** 383 * xe_gt_tlb_invalidation_vma - Issue a TLB invalidation on this GT for a VMA 384 * @gt: graphics tile 385 * @fence: invalidation fence which will be signal on TLB invalidation 386 * completion, can be NULL 387 * @vma: VMA to invalidate 388 * 389 * Issue a range based TLB invalidation if supported, if not fallback to a full 390 * TLB invalidation. Completion of TLB is asynchronous and caller can use 391 * the invalidation fence to wait for completion. 392 * 393 * Return: Negative error code on error, 0 on success 394 */ 395 int xe_gt_tlb_invalidation_vma(struct xe_gt *gt, 396 struct xe_gt_tlb_invalidation_fence *fence, 397 struct xe_vma *vma) 398 { 399 xe_gt_assert(gt, vma); 400 401 return xe_gt_tlb_invalidation_range(gt, fence, xe_vma_start(vma), 402 xe_vma_end(vma), 403 xe_vma_vm(vma)->usm.asid); 404 } 405 406 /** 407 * xe_guc_tlb_invalidation_done_handler - TLB invalidation done handler 408 * @guc: guc 409 * @msg: message indicating TLB invalidation done 410 * @len: length of message 411 * 412 * Parse seqno of TLB invalidation, wake any waiters for seqno, and signal any 413 * invalidation fences for seqno. Algorithm for this depends on seqno being 414 * received in-order and asserts this assumption. 415 * 416 * Return: 0 on success, -EPROTO for malformed messages. 417 */ 418 int xe_guc_tlb_invalidation_done_handler(struct xe_guc *guc, u32 *msg, u32 len) 419 { 420 struct xe_gt *gt = guc_to_gt(guc); 421 struct xe_device *xe = gt_to_xe(gt); 422 struct xe_gt_tlb_invalidation_fence *fence, *next; 423 unsigned long flags; 424 425 if (unlikely(len != 1)) 426 return -EPROTO; 427 428 /* 429 * This can also be run both directly from the IRQ handler and also in 430 * process_g2h_msg(). Only one may process any individual CT message, 431 * however the order they are processed here could result in skipping a 432 * seqno. To handle that we just process all the seqnos from the last 433 * seqno_recv up to and including the one in msg[0]. The delta should be 434 * very small so there shouldn't be much of pending_fences we actually 435 * need to iterate over here. 436 * 437 * From GuC POV we expect the seqnos to always appear in-order, so if we 438 * see something later in the timeline we can be sure that anything 439 * appearing earlier has already signalled, just that we have yet to 440 * officially process the CT message like if racing against 441 * process_g2h_msg(). 442 */ 443 spin_lock_irqsave(>->tlb_invalidation.pending_lock, flags); 444 if (tlb_invalidation_seqno_past(gt, msg[0])) { 445 spin_unlock_irqrestore(>->tlb_invalidation.pending_lock, flags); 446 return 0; 447 } 448 449 WRITE_ONCE(gt->tlb_invalidation.seqno_recv, msg[0]); 450 451 list_for_each_entry_safe(fence, next, 452 >->tlb_invalidation.pending_fences, link) { 453 trace_xe_gt_tlb_invalidation_fence_recv(xe, fence); 454 455 if (!tlb_invalidation_seqno_past(gt, fence->seqno)) 456 break; 457 458 invalidation_fence_signal(xe, fence); 459 } 460 461 if (!list_empty(>->tlb_invalidation.pending_fences)) 462 mod_delayed_work(system_wq, 463 >->tlb_invalidation.fence_tdr, 464 tlb_timeout_jiffies(gt)); 465 else 466 cancel_delayed_work(>->tlb_invalidation.fence_tdr); 467 468 spin_unlock_irqrestore(>->tlb_invalidation.pending_lock, flags); 469 470 return 0; 471 } 472 473 static const char * 474 invalidation_fence_get_driver_name(struct dma_fence *dma_fence) 475 { 476 return "xe"; 477 } 478 479 static const char * 480 invalidation_fence_get_timeline_name(struct dma_fence *dma_fence) 481 { 482 return "invalidation_fence"; 483 } 484 485 static const struct dma_fence_ops invalidation_fence_ops = { 486 .get_driver_name = invalidation_fence_get_driver_name, 487 .get_timeline_name = invalidation_fence_get_timeline_name, 488 }; 489 490 /** 491 * xe_gt_tlb_invalidation_fence_init - Initialize TLB invalidation fence 492 * @gt: GT 493 * @fence: TLB invalidation fence to initialize 494 * @stack: fence is stack variable 495 * 496 * Initialize TLB invalidation fence for use. xe_gt_tlb_invalidation_fence_fini 497 * must be called if fence is not signaled. 498 */ 499 void xe_gt_tlb_invalidation_fence_init(struct xe_gt *gt, 500 struct xe_gt_tlb_invalidation_fence *fence, 501 bool stack) 502 { 503 xe_pm_runtime_get_noresume(gt_to_xe(gt)); 504 505 spin_lock_irq(>->tlb_invalidation.lock); 506 dma_fence_init(&fence->base, &invalidation_fence_ops, 507 >->tlb_invalidation.lock, 508 dma_fence_context_alloc(1), 1); 509 spin_unlock_irq(>->tlb_invalidation.lock); 510 INIT_LIST_HEAD(&fence->link); 511 if (stack) 512 set_bit(FENCE_STACK_BIT, &fence->base.flags); 513 else 514 dma_fence_get(&fence->base); 515 fence->gt = gt; 516 } 517 518 /** 519 * xe_gt_tlb_invalidation_fence_fini - Finalize TLB invalidation fence 520 * @fence: TLB invalidation fence to finalize 521 * 522 * Drop PM ref which fence took durinig init. 523 */ 524 void xe_gt_tlb_invalidation_fence_fini(struct xe_gt_tlb_invalidation_fence *fence) 525 { 526 xe_pm_runtime_put(gt_to_xe(fence->gt)); 527 } 528