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
16281630static 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
18501855static 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
18761888static 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,
18981917static 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)
20492121free_rfence :
20502122 kfree (rfence );
20512123free_ifence :
2124+ kfree (cf );
2125+ kfree (fences );
2126+ kfree (mfence );
20522127 kfree (ifence );
20532128kill_vm_tile1 :
20542129 if (err != - EAGAIN && tile -> id )
0 commit comments