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