xref: /linux/drivers/gpu/drm/xe/xe_gt_tlb_invalidation.c (revision a3a02a52bcfcbcc4a637d4b68bf1bc391c9fad02)
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(&gt->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(&gt->tlb_invalidation.pending_lock);
66 	list_for_each_entry_safe(fence, next,
67 				 &gt->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(&gt->tlb_invalidation.pending_fences))
82 		queue_delayed_work(system_wq,
83 				   &gt->tlb_invalidation.fence_tdr,
84 				   tlb_timeout_jiffies(gt));
85 	spin_unlock_irq(&gt->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(&gt->tlb_invalidation.pending_fences);
101 	spin_lock_init(&gt->tlb_invalidation.pending_lock);
102 	spin_lock_init(&gt->tlb_invalidation.lock);
103 	INIT_DELAYED_WORK(&gt->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(&gt->uc.guc.ct.lock);
126 	spin_lock_irq(&gt->tlb_invalidation.pending_lock);
127 	cancel_delayed_work(&gt->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 				 &gt->tlb_invalidation.pending_fences, link)
143 		invalidation_fence_signal(gt_to_xe(gt), fence);
144 	spin_unlock_irq(&gt->tlb_invalidation.pending_lock);
145 	mutex_unlock(&gt->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(&gt->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 				      &gt->tlb_invalidation.pending_fences);
199 
200 			if (list_is_singular(&gt->tlb_invalidation.pending_fences))
201 				queue_delayed_work(system_wq,
202 						   &gt->tlb_invalidation.fence_tdr,
203 						   tlb_timeout_jiffies(gt));
204 		}
205 		spin_unlock_irq(&gt->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(&gt->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(&gt->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(&gt->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(&gt->tlb_invalidation.pending_lock, flags);
444 	if (tlb_invalidation_seqno_past(gt, msg[0])) {
445 		spin_unlock_irqrestore(&gt->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 				 &gt->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(&gt->tlb_invalidation.pending_fences))
462 		mod_delayed_work(system_wq,
463 				 &gt->tlb_invalidation.fence_tdr,
464 				 tlb_timeout_jiffies(gt));
465 	else
466 		cancel_delayed_work(&gt->tlb_invalidation.fence_tdr);
467 
468 	spin_unlock_irqrestore(&gt->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(&gt->tlb_invalidation.lock);
506 	dma_fence_init(&fence->base, &invalidation_fence_ops,
507 		       &gt->tlb_invalidation.lock,
508 		       dma_fence_context_alloc(1), 1);
509 	spin_unlock_irq(&gt->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