Skip to content

Commit bf75822

Browse files
committed
drm/xe: Invalidate media_gt TLBs in PT code
Testing on LNL has shown media GT's TLBs need to be invalidated via the GuC, update PT code appropriately. v2: - Do dma_fence_get before first call of invalidation_fence_init (Himal) - No need to check for valid chain fence (Himal) v3: - Use dma-fence-array Fixes: 3330361 ("drm/xe/lnl: Add LNL platform definition") Signed-off-by: Matthew Brost <[email protected]> Acked-by: Christian König <[email protected]> Reviewed-by: Matthew Auld <[email protected]> Link: https://patchwork.freedesktop.org/patch/msgid/[email protected]
1 parent ddc94d0 commit bf75822

File tree

1 file changed

+96
-21
lines changed

1 file changed

+96
-21
lines changed

drivers/gpu/drm/xe/xe_pt.c

Lines changed: 96 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
* Copyright © 2022 Intel Corporation
44
*/
55

6+
#include <linux/dma-fence-array.h>
7+
68
#include "xe_pt.h"
79

810
#include "regs/xe_gtt_defs.h"
@@ -1627,9 +1629,11 @@ xe_pt_update_ops_rfence_interval(struct xe_vm_pgtable_update_ops *pt_update_ops,
16271629

16281630
static int vma_reserve_fences(struct xe_device *xe, struct xe_vma *vma)
16291631
{
1632+
int shift = xe_device_get_root_tile(xe)->media_gt ? 1 : 0;
1633+
16301634
if (!xe_vma_has_no_bo(vma) && !xe_vma_bo(vma)->vm)
16311635
return dma_resv_reserve_fences(xe_vma_bo(vma)->ttm.base.resv,
1632-
xe->info.tile_count);
1636+
xe->info.tile_count << shift);
16331637

16341638
return 0;
16351639
}
@@ -1816,6 +1820,7 @@ int xe_pt_update_ops_prepare(struct xe_tile *tile, struct xe_vma_ops *vops)
18161820
struct xe_vm_pgtable_update_ops *pt_update_ops =
18171821
&vops->pt_update_ops[tile->id];
18181822
struct xe_vma_op *op;
1823+
int shift = tile->media_gt ? 1 : 0;
18191824
int err;
18201825

18211826
lockdep_assert_held(&vops->vm->lock);
@@ -1824,7 +1829,7 @@ int xe_pt_update_ops_prepare(struct xe_tile *tile, struct xe_vma_ops *vops)
18241829
xe_pt_update_ops_init(pt_update_ops);
18251830

18261831
err = dma_resv_reserve_fences(xe_vm_resv(vops->vm),
1827-
tile_to_xe(tile)->info.tile_count);
1832+
tile_to_xe(tile)->info.tile_count << shift);
18281833
if (err)
18291834
return err;
18301835

@@ -1849,13 +1854,20 @@ int xe_pt_update_ops_prepare(struct xe_tile *tile, struct xe_vma_ops *vops)
18491854

18501855
static void bind_op_commit(struct xe_vm *vm, struct xe_tile *tile,
18511856
struct xe_vm_pgtable_update_ops *pt_update_ops,
1852-
struct xe_vma *vma, struct dma_fence *fence)
1857+
struct xe_vma *vma, struct dma_fence *fence,
1858+
struct dma_fence *fence2)
18531859
{
1854-
if (!xe_vma_has_no_bo(vma) && !xe_vma_bo(vma)->vm)
1860+
if (!xe_vma_has_no_bo(vma) && !xe_vma_bo(vma)->vm) {
18551861
dma_resv_add_fence(xe_vma_bo(vma)->ttm.base.resv, fence,
18561862
pt_update_ops->wait_vm_bookkeep ?
18571863
DMA_RESV_USAGE_KERNEL :
18581864
DMA_RESV_USAGE_BOOKKEEP);
1865+
if (fence2)
1866+
dma_resv_add_fence(xe_vma_bo(vma)->ttm.base.resv, fence2,
1867+
pt_update_ops->wait_vm_bookkeep ?
1868+
DMA_RESV_USAGE_KERNEL :
1869+
DMA_RESV_USAGE_BOOKKEEP);
1870+
}
18591871
vma->tile_present |= BIT(tile->id);
18601872
vma->tile_staged &= ~BIT(tile->id);
18611873
if (xe_vma_is_userptr(vma)) {
@@ -1875,13 +1887,20 @@ static void bind_op_commit(struct xe_vm *vm, struct xe_tile *tile,
18751887

18761888
static void unbind_op_commit(struct xe_vm *vm, struct xe_tile *tile,
18771889
struct xe_vm_pgtable_update_ops *pt_update_ops,
1878-
struct xe_vma *vma, struct dma_fence *fence)
1890+
struct xe_vma *vma, struct dma_fence *fence,
1891+
struct dma_fence *fence2)
18791892
{
1880-
if (!xe_vma_has_no_bo(vma) && !xe_vma_bo(vma)->vm)
1893+
if (!xe_vma_has_no_bo(vma) && !xe_vma_bo(vma)->vm) {
18811894
dma_resv_add_fence(xe_vma_bo(vma)->ttm.base.resv, fence,
18821895
pt_update_ops->wait_vm_bookkeep ?
18831896
DMA_RESV_USAGE_KERNEL :
18841897
DMA_RESV_USAGE_BOOKKEEP);
1898+
if (fence2)
1899+
dma_resv_add_fence(xe_vma_bo(vma)->ttm.base.resv, fence2,
1900+
pt_update_ops->wait_vm_bookkeep ?
1901+
DMA_RESV_USAGE_KERNEL :
1902+
DMA_RESV_USAGE_BOOKKEEP);
1903+
}
18851904
vma->tile_present &= ~BIT(tile->id);
18861905
if (!vma->tile_present) {
18871906
list_del_init(&vma->combined_links.rebind);
@@ -1898,7 +1917,8 @@ static void unbind_op_commit(struct xe_vm *vm, struct xe_tile *tile,
18981917
static void op_commit(struct xe_vm *vm,
18991918
struct xe_tile *tile,
19001919
struct xe_vm_pgtable_update_ops *pt_update_ops,
1901-
struct xe_vma_op *op, struct dma_fence *fence)
1920+
struct xe_vma_op *op, struct dma_fence *fence,
1921+
struct dma_fence *fence2)
19021922
{
19031923
xe_vm_assert_held(vm);
19041924

@@ -1907,26 +1927,28 @@ static void op_commit(struct xe_vm *vm,
19071927
if (!op->map.immediate && xe_vm_in_fault_mode(vm))
19081928
break;
19091929

1910-
bind_op_commit(vm, tile, pt_update_ops, op->map.vma, fence);
1930+
bind_op_commit(vm, tile, pt_update_ops, op->map.vma, fence,
1931+
fence2);
19111932
break;
19121933
case DRM_GPUVA_OP_REMAP:
19131934
unbind_op_commit(vm, tile, pt_update_ops,
1914-
gpuva_to_vma(op->base.remap.unmap->va), fence);
1935+
gpuva_to_vma(op->base.remap.unmap->va), fence,
1936+
fence2);
19151937

19161938
if (op->remap.prev)
19171939
bind_op_commit(vm, tile, pt_update_ops, op->remap.prev,
1918-
fence);
1940+
fence, fence2);
19191941
if (op->remap.next)
19201942
bind_op_commit(vm, tile, pt_update_ops, op->remap.next,
1921-
fence);
1943+
fence, fence2);
19221944
break;
19231945
case DRM_GPUVA_OP_UNMAP:
19241946
unbind_op_commit(vm, tile, pt_update_ops,
1925-
gpuva_to_vma(op->base.unmap.va), fence);
1947+
gpuva_to_vma(op->base.unmap.va), fence, fence2);
19261948
break;
19271949
case DRM_GPUVA_OP_PREFETCH:
19281950
bind_op_commit(vm, tile, pt_update_ops,
1929-
gpuva_to_vma(op->base.prefetch.va), fence);
1951+
gpuva_to_vma(op->base.prefetch.va), fence, fence2);
19301952
break;
19311953
default:
19321954
drm_warn(&vm->xe->drm, "NOT POSSIBLE");
@@ -1963,7 +1985,9 @@ xe_pt_update_ops_run(struct xe_tile *tile, struct xe_vma_ops *vops)
19631985
struct xe_vm_pgtable_update_ops *pt_update_ops =
19641986
&vops->pt_update_ops[tile->id];
19651987
struct dma_fence *fence;
1966-
struct invalidation_fence *ifence = NULL;
1988+
struct invalidation_fence *ifence = NULL, *mfence = NULL;
1989+
struct dma_fence **fences = NULL;
1990+
struct dma_fence_array *cf = NULL;
19671991
struct xe_range_fence *rfence;
19681992
struct xe_vma_op *op;
19691993
int err = 0, i;
@@ -1996,6 +2020,23 @@ xe_pt_update_ops_run(struct xe_tile *tile, struct xe_vma_ops *vops)
19962020
err = -ENOMEM;
19972021
goto kill_vm_tile1;
19982022
}
2023+
if (tile->media_gt) {
2024+
mfence = kzalloc(sizeof(*ifence), GFP_KERNEL);
2025+
if (!mfence) {
2026+
err = -ENOMEM;
2027+
goto free_ifence;
2028+
}
2029+
fences = kmalloc_array(2, sizeof(*fences), GFP_KERNEL);
2030+
if (!fences) {
2031+
err = -ENOMEM;
2032+
goto free_ifence;
2033+
}
2034+
cf = dma_fence_array_alloc(2);
2035+
if (!cf) {
2036+
err = -ENOMEM;
2037+
goto free_ifence;
2038+
}
2039+
}
19992040
}
20002041

20012042
rfence = kzalloc(sizeof(*rfence), GFP_KERNEL);
@@ -2027,19 +2068,50 @@ xe_pt_update_ops_run(struct xe_tile *tile, struct xe_vma_ops *vops)
20272068

20282069
/* tlb invalidation must be done before signaling rebind */
20292070
if (ifence) {
2071+
if (mfence)
2072+
dma_fence_get(fence);
20302073
invalidation_fence_init(tile->primary_gt, ifence, fence,
20312074
pt_update_ops->start,
20322075
pt_update_ops->last, vm->usm.asid);
2033-
fence = &ifence->base.base;
2076+
if (mfence) {
2077+
invalidation_fence_init(tile->media_gt, mfence, fence,
2078+
pt_update_ops->start,
2079+
pt_update_ops->last, vm->usm.asid);
2080+
fences[0] = &ifence->base.base;
2081+
fences[1] = &mfence->base.base;
2082+
dma_fence_array_init(cf, 2, fences,
2083+
vm->composite_fence_ctx,
2084+
vm->composite_fence_seqno++,
2085+
false);
2086+
fence = &cf->base;
2087+
} else {
2088+
fence = &ifence->base.base;
2089+
}
20342090
}
20352091

2036-
dma_resv_add_fence(xe_vm_resv(vm), fence,
2037-
pt_update_ops->wait_vm_bookkeep ?
2038-
DMA_RESV_USAGE_KERNEL :
2039-
DMA_RESV_USAGE_BOOKKEEP);
2092+
if (!mfence) {
2093+
dma_resv_add_fence(xe_vm_resv(vm), fence,
2094+
pt_update_ops->wait_vm_bookkeep ?
2095+
DMA_RESV_USAGE_KERNEL :
2096+
DMA_RESV_USAGE_BOOKKEEP);
20402097

2041-
list_for_each_entry(op, &vops->list, link)
2042-
op_commit(vops->vm, tile, pt_update_ops, op, fence);
2098+
list_for_each_entry(op, &vops->list, link)
2099+
op_commit(vops->vm, tile, pt_update_ops, op, fence, NULL);
2100+
} else {
2101+
dma_resv_add_fence(xe_vm_resv(vm), &ifence->base.base,
2102+
pt_update_ops->wait_vm_bookkeep ?
2103+
DMA_RESV_USAGE_KERNEL :
2104+
DMA_RESV_USAGE_BOOKKEEP);
2105+
2106+
dma_resv_add_fence(xe_vm_resv(vm), &mfence->base.base,
2107+
pt_update_ops->wait_vm_bookkeep ?
2108+
DMA_RESV_USAGE_KERNEL :
2109+
DMA_RESV_USAGE_BOOKKEEP);
2110+
2111+
list_for_each_entry(op, &vops->list, link)
2112+
op_commit(vops->vm, tile, pt_update_ops, op,
2113+
&ifence->base.base, &mfence->base.base);
2114+
}
20432115

20442116
if (pt_update_ops->needs_userptr_lock)
20452117
up_read(&vm->userptr.notifier_lock);
@@ -2049,6 +2121,9 @@ xe_pt_update_ops_run(struct xe_tile *tile, struct xe_vma_ops *vops)
20492121
free_rfence:
20502122
kfree(rfence);
20512123
free_ifence:
2124+
kfree(cf);
2125+
kfree(fences);
2126+
kfree(mfence);
20522127
kfree(ifence);
20532128
kill_vm_tile1:
20542129
if (err != -EAGAIN && tile->id)

0 commit comments

Comments
 (0)