1 // SPDX-License-Identifier: MIT
3 * Copyright © 2023 Intel Corporation
6 #include "xe_gt_tlb_invalidation.h"
8 #include "abi/guc_actions_abi.h"
12 #include "xe_guc_ct.h"
15 #define TLB_TIMEOUT (HZ / 4)
17 static void xe_gt_tlb_fence_timeout(struct work_struct *work)
19 struct xe_gt *gt = container_of(work, struct xe_gt,
20 tlb_invalidation.fence_tdr.work);
21 struct xe_gt_tlb_invalidation_fence *fence, *next;
23 spin_lock_irq(>->tlb_invalidation.pending_lock);
24 list_for_each_entry_safe(fence, next,
25 >->tlb_invalidation.pending_fences, link) {
26 s64 since_inval_ms = ktime_ms_delta(ktime_get(),
27 fence->invalidation_time);
29 if (msecs_to_jiffies(since_inval_ms) < TLB_TIMEOUT)
32 trace_xe_gt_tlb_invalidation_fence_timeout(fence);
33 drm_err(>_to_xe(gt)->drm, "gt%d: TLB invalidation fence timeout, seqno=%d recv=%d",
34 gt->info.id, fence->seqno, gt->tlb_invalidation.seqno_recv);
36 list_del(&fence->link);
37 fence->base.error = -ETIME;
38 dma_fence_signal(&fence->base);
39 dma_fence_put(&fence->base);
41 if (!list_empty(>->tlb_invalidation.pending_fences))
42 queue_delayed_work(system_wq,
43 >->tlb_invalidation.fence_tdr,
45 spin_unlock_irq(>->tlb_invalidation.pending_lock);
49 * xe_gt_tlb_invalidation_init - Initialize GT TLB invalidation state
52 * Initialize GT TLB invalidation state, purely software initialization, should
53 * be called once during driver load.
55 * Return: 0 on success, negative error code on error.
57 int xe_gt_tlb_invalidation_init(struct xe_gt *gt)
59 gt->tlb_invalidation.seqno = 1;
60 INIT_LIST_HEAD(>->tlb_invalidation.pending_fences);
61 spin_lock_init(>->tlb_invalidation.pending_lock);
62 spin_lock_init(>->tlb_invalidation.lock);
63 gt->tlb_invalidation.fence_context = dma_fence_context_alloc(1);
64 INIT_DELAYED_WORK(>->tlb_invalidation.fence_tdr,
65 xe_gt_tlb_fence_timeout);
71 __invalidation_fence_signal(struct xe_gt_tlb_invalidation_fence *fence)
73 trace_xe_gt_tlb_invalidation_fence_signal(fence);
74 dma_fence_signal(&fence->base);
75 dma_fence_put(&fence->base);
79 invalidation_fence_signal(struct xe_gt_tlb_invalidation_fence *fence)
81 list_del(&fence->link);
82 __invalidation_fence_signal(fence);
86 * xe_gt_tlb_invalidation_reset - Initialize GT TLB invalidation reset
89 * Signal any pending invalidation fences, should be called during a GT reset
91 void xe_gt_tlb_invalidation_reset(struct xe_gt *gt)
93 struct xe_gt_tlb_invalidation_fence *fence, *next;
94 struct xe_guc *guc = >->uc.guc;
98 * CT channel is already disabled at this point. No new TLB requests can
102 mutex_lock(>->uc.guc.ct.lock);
103 spin_lock_irq(>->tlb_invalidation.pending_lock);
104 cancel_delayed_work(>->tlb_invalidation.fence_tdr);
106 * We might have various kworkers waiting for TLB flushes to complete
107 * which are not tracked with an explicit TLB fence, however at this
108 * stage that will never happen since the CT is already disabled, so
109 * make sure we signal them here under the assumption that we have
110 * completed a full GT reset.
112 if (gt->tlb_invalidation.seqno == 1)
113 pending_seqno = TLB_INVALIDATION_SEQNO_MAX - 1;
115 pending_seqno = gt->tlb_invalidation.seqno - 1;
116 WRITE_ONCE(gt->tlb_invalidation.seqno_recv, pending_seqno);
117 wake_up_all(&guc->ct.wq);
119 list_for_each_entry_safe(fence, next,
120 >->tlb_invalidation.pending_fences, link)
121 invalidation_fence_signal(fence);
122 spin_unlock_irq(>->tlb_invalidation.pending_lock);
123 mutex_unlock(>->uc.guc.ct.lock);
126 static bool tlb_invalidation_seqno_past(struct xe_gt *gt, int seqno)
128 int seqno_recv = READ_ONCE(gt->tlb_invalidation.seqno_recv);
130 if (seqno - seqno_recv < -(TLB_INVALIDATION_SEQNO_MAX / 2))
133 if (seqno - seqno_recv > (TLB_INVALIDATION_SEQNO_MAX / 2))
136 return seqno_recv >= seqno;
139 static int send_tlb_invalidation(struct xe_guc *guc,
140 struct xe_gt_tlb_invalidation_fence *fence,
141 u32 *action, int len)
143 struct xe_gt *gt = guc_to_gt(guc);
148 * XXX: The seqno algorithm relies on TLB invalidation being processed
149 * in order which they currently are, if that changes the algorithm will
150 * need to be updated.
153 mutex_lock(&guc->ct.lock);
154 seqno = gt->tlb_invalidation.seqno;
156 fence->seqno = seqno;
157 trace_xe_gt_tlb_invalidation_fence_send(fence);
160 ret = xe_guc_ct_send_locked(&guc->ct, action, len,
161 G2H_LEN_DW_TLB_INVALIDATE, 1);
163 spin_lock_irq(>->tlb_invalidation.pending_lock);
165 * We haven't actually published the TLB fence as per
166 * pending_fences, but in theory our seqno could have already
167 * been written as we acquired the pending_lock. In such a case
168 * we can just go ahead and signal the fence here.
170 if (tlb_invalidation_seqno_past(gt, seqno)) {
171 __invalidation_fence_signal(fence);
173 fence->invalidation_time = ktime_get();
174 list_add_tail(&fence->link,
175 >->tlb_invalidation.pending_fences);
177 if (list_is_singular(>->tlb_invalidation.pending_fences))
178 queue_delayed_work(system_wq,
179 >->tlb_invalidation.fence_tdr,
182 spin_unlock_irq(>->tlb_invalidation.pending_lock);
183 } else if (ret < 0 && fence) {
184 __invalidation_fence_signal(fence);
187 gt->tlb_invalidation.seqno = (gt->tlb_invalidation.seqno + 1) %
188 TLB_INVALIDATION_SEQNO_MAX;
189 if (!gt->tlb_invalidation.seqno)
190 gt->tlb_invalidation.seqno = 1;
193 mutex_unlock(&guc->ct.lock);
198 #define MAKE_INVAL_OP(type) ((type << XE_GUC_TLB_INVAL_TYPE_SHIFT) | \
199 XE_GUC_TLB_INVAL_MODE_HEAVY << XE_GUC_TLB_INVAL_MODE_SHIFT | \
200 XE_GUC_TLB_INVAL_FLUSH_CACHE)
203 * xe_gt_tlb_invalidation_guc - Issue a TLB invalidation on this GT for the GuC
206 * Issue a TLB invalidation for the GuC. Completion of TLB is asynchronous and
207 * caller can use seqno + xe_gt_tlb_invalidation_wait to wait for completion.
209 * Return: Seqno which can be passed to xe_gt_tlb_invalidation_wait on success,
210 * negative error code on error.
212 int xe_gt_tlb_invalidation_guc(struct xe_gt *gt)
215 XE_GUC_ACTION_TLB_INVALIDATION,
216 0, /* seqno, replaced in send_tlb_invalidation */
217 MAKE_INVAL_OP(XE_GUC_TLB_INVAL_GUC),
220 return send_tlb_invalidation(>->uc.guc, NULL, action,
225 * xe_gt_tlb_invalidation_vma - Issue a TLB invalidation on this GT for a VMA
227 * @fence: invalidation fence which will be signal on TLB invalidation
228 * completion, can be NULL
229 * @vma: VMA to invalidate
231 * Issue a range based TLB invalidation if supported, if not fallback to a full
232 * TLB invalidation. Completion of TLB is asynchronous and caller can either use
233 * the invalidation fence or seqno + xe_gt_tlb_invalidation_wait to wait for
236 * Return: Seqno which can be passed to xe_gt_tlb_invalidation_wait on success,
237 * negative error code on error.
239 int xe_gt_tlb_invalidation_vma(struct xe_gt *gt,
240 struct xe_gt_tlb_invalidation_fence *fence,
243 struct xe_device *xe = gt_to_xe(gt);
244 #define MAX_TLB_INVALIDATION_LEN 7
245 u32 action[MAX_TLB_INVALIDATION_LEN];
248 xe_gt_assert(gt, vma);
250 action[len++] = XE_GUC_ACTION_TLB_INVALIDATION;
251 action[len++] = 0; /* seqno, replaced in send_tlb_invalidation */
252 if (!xe->info.has_range_tlb_invalidation) {
253 action[len++] = MAKE_INVAL_OP(XE_GUC_TLB_INVAL_FULL);
255 u64 start = xe_vma_start(vma);
256 u64 length = xe_vma_size(vma);
263 * We need to invalidate a higher granularity if start address
264 * is not aligned to length. When start is not aligned with
265 * length we need to find the length large enough to create an
266 * address mask covering the required range.
268 align = roundup_pow_of_two(length);
269 start = ALIGN_DOWN(xe_vma_start(vma), align);
270 end = ALIGN(xe_vma_end(vma), align);
272 while (start + length < end) {
274 start = ALIGN_DOWN(xe_vma_start(vma), length);
278 * Minimum invalidation size for a 2MB page that the hardware
281 if (length >= SZ_2M) {
282 length = max_t(u64, SZ_16M, length);
283 start = ALIGN_DOWN(xe_vma_start(vma), length);
286 xe_gt_assert(gt, length >= SZ_4K);
287 xe_gt_assert(gt, is_power_of_2(length));
288 xe_gt_assert(gt, !(length & GENMASK(ilog2(SZ_16M) - 1, ilog2(SZ_2M) + 1)));
289 xe_gt_assert(gt, IS_ALIGNED(start, length));
291 action[len++] = MAKE_INVAL_OP(XE_GUC_TLB_INVAL_PAGE_SELECTIVE);
292 action[len++] = xe_vma_vm(vma)->usm.asid;
293 action[len++] = lower_32_bits(start);
294 action[len++] = upper_32_bits(start);
295 action[len++] = ilog2(length) - ilog2(SZ_4K);
298 xe_gt_assert(gt, len <= MAX_TLB_INVALIDATION_LEN);
300 return send_tlb_invalidation(>->uc.guc, fence, action, len);
304 * xe_gt_tlb_invalidation_wait - Wait for TLB to complete
306 * @seqno: seqno to wait which was returned from xe_gt_tlb_invalidation
308 * Wait for 200ms for a TLB invalidation to complete, in practice we always
309 * should receive the TLB invalidation within 200ms.
311 * Return: 0 on success, -ETIME on TLB invalidation timeout
313 int xe_gt_tlb_invalidation_wait(struct xe_gt *gt, int seqno)
315 struct xe_device *xe = gt_to_xe(gt);
316 struct xe_guc *guc = >->uc.guc;
317 struct drm_printer p = drm_err_printer(__func__);
321 * XXX: See above, this algorithm only works if seqno are always in
324 ret = wait_event_timeout(guc->ct.wq,
325 tlb_invalidation_seqno_past(gt, seqno),
328 drm_err(&xe->drm, "gt%d: TLB invalidation time'd out, seqno=%d, recv=%d\n",
329 gt->info.id, seqno, gt->tlb_invalidation.seqno_recv);
330 xe_guc_ct_print(&guc->ct, &p, true);
338 * xe_guc_tlb_invalidation_done_handler - TLB invalidation done handler
340 * @msg: message indicating TLB invalidation done
341 * @len: length of message
343 * Parse seqno of TLB invalidation, wake any waiters for seqno, and signal any
344 * invalidation fences for seqno. Algorithm for this depends on seqno being
345 * received in-order and asserts this assumption.
347 * Return: 0 on success, -EPROTO for malformed messages.
349 int xe_guc_tlb_invalidation_done_handler(struct xe_guc *guc, u32 *msg, u32 len)
351 struct xe_gt *gt = guc_to_gt(guc);
352 struct xe_gt_tlb_invalidation_fence *fence, *next;
355 if (unlikely(len != 1))
359 * This can also be run both directly from the IRQ handler and also in
360 * process_g2h_msg(). Only one may process any individual CT message,
361 * however the order they are processed here could result in skipping a
362 * seqno. To handle that we just process all the seqnos from the last
363 * seqno_recv up to and including the one in msg[0]. The delta should be
364 * very small so there shouldn't be much of pending_fences we actually
365 * need to iterate over here.
367 * From GuC POV we expect the seqnos to always appear in-order, so if we
368 * see something later in the timeline we can be sure that anything
369 * appearing earlier has already signalled, just that we have yet to
370 * officially process the CT message like if racing against
373 spin_lock_irqsave(>->tlb_invalidation.pending_lock, flags);
374 if (tlb_invalidation_seqno_past(gt, msg[0])) {
375 spin_unlock_irqrestore(>->tlb_invalidation.pending_lock, flags);
380 * wake_up_all() and wait_event_timeout() already have the correct
383 WRITE_ONCE(gt->tlb_invalidation.seqno_recv, msg[0]);
384 wake_up_all(&guc->ct.wq);
386 list_for_each_entry_safe(fence, next,
387 >->tlb_invalidation.pending_fences, link) {
388 trace_xe_gt_tlb_invalidation_fence_recv(fence);
390 if (!tlb_invalidation_seqno_past(gt, fence->seqno))
393 invalidation_fence_signal(fence);
396 if (!list_empty(>->tlb_invalidation.pending_fences))
397 mod_delayed_work(system_wq,
398 >->tlb_invalidation.fence_tdr,
401 cancel_delayed_work(>->tlb_invalidation.fence_tdr);
403 spin_unlock_irqrestore(>->tlb_invalidation.pending_lock, flags);