|
11 | 11 |
|
12 | 12 | #include "xe_assert.h"
|
13 | 13 | #include "xe_bo.h"
|
| 14 | +#include "xe_gt_tlb_invalidation.h" |
14 | 15 | #include "xe_lmtt.h"
|
15 | 16 | #include "xe_map.h"
|
16 | 17 | #include "xe_mmio.h"
|
@@ -222,6 +223,58 @@ void xe_lmtt_init_hw(struct xe_lmtt *lmtt)
|
222 | 223 | lmtt_setup_dir_ptr(lmtt);
|
223 | 224 | }
|
224 | 225 |
|
| 226 | +static int lmtt_invalidate_hw(struct xe_lmtt *lmtt) |
| 227 | +{ |
| 228 | + struct xe_gt_tlb_invalidation_fence fences[XE_MAX_GT_PER_TILE]; |
| 229 | + struct xe_gt_tlb_invalidation_fence *fence = fences; |
| 230 | + struct xe_tile *tile = lmtt_to_tile(lmtt); |
| 231 | + struct xe_gt *gt; |
| 232 | + int result = 0; |
| 233 | + int err; |
| 234 | + u8 id; |
| 235 | + |
| 236 | + for_each_gt_on_tile(gt, tile, id) { |
| 237 | + xe_gt_tlb_invalidation_fence_init(gt, fence, true); |
| 238 | + err = xe_gt_tlb_invalidation_all(gt, fence); |
| 239 | + result = result ?: err; |
| 240 | + fence++; |
| 241 | + } |
| 242 | + |
| 243 | + lmtt_debug(lmtt, "num_fences=%d err=%d\n", (int)(fence - fences), result); |
| 244 | + |
| 245 | + /* |
| 246 | + * It is fine to wait for all fences, even for those which covers the |
| 247 | + * invalidation request that failed, as such fence should be already |
| 248 | + * marked as signaled. |
| 249 | + */ |
| 250 | + fence = fences; |
| 251 | + for_each_gt_on_tile(gt, tile, id) |
| 252 | + xe_gt_tlb_invalidation_fence_wait(fence++); |
| 253 | + |
| 254 | + return result; |
| 255 | +} |
| 256 | + |
| 257 | +/** |
| 258 | + * xe_lmtt_invalidate_hw - Invalidate LMTT hardware. |
| 259 | + * @lmtt: the &xe_lmtt to invalidate |
| 260 | + * |
| 261 | + * Send requests to all GuCs on this tile to invalidate all TLBs. |
| 262 | + * |
| 263 | + * This function should be called only when running as a PF driver. |
| 264 | + */ |
| 265 | +void xe_lmtt_invalidate_hw(struct xe_lmtt *lmtt) |
| 266 | +{ |
| 267 | + struct xe_device *xe = lmtt_to_xe(lmtt); |
| 268 | + int err; |
| 269 | + |
| 270 | + lmtt_assert(lmtt, IS_SRIOV_PF(xe)); |
| 271 | + |
| 272 | + err = lmtt_invalidate_hw(lmtt); |
| 273 | + if (err) |
| 274 | + xe_sriov_warn(xe, "LMTT%u invalidation failed (%pe)", |
| 275 | + lmtt_to_tile(lmtt)->id, ERR_PTR(err)); |
| 276 | +} |
| 277 | + |
225 | 278 | static void lmtt_write_pte(struct xe_lmtt *lmtt, struct xe_lmtt_pt *pt,
|
226 | 279 | u64 pte, unsigned int idx)
|
227 | 280 | {
|
@@ -276,6 +329,7 @@ static void lmtt_drop_pages(struct xe_lmtt *lmtt, unsigned int vfid)
|
276 | 329 | return;
|
277 | 330 |
|
278 | 331 | lmtt_write_pte(lmtt, pd, LMTT_PTE_INVALID, vfid);
|
| 332 | + lmtt_invalidate_hw(lmtt); |
279 | 333 |
|
280 | 334 | lmtt_assert(lmtt, pd->level > 0);
|
281 | 335 | lmtt_assert(lmtt, pt->level == pd->level - 1);
|
|
0 commit comments