@@ -28,6 +28,8 @@ struct xe_pt_dir {
28
28
struct xe_pt pt ;
29
29
/** @children: Array of page-table child nodes */
30
30
struct xe_ptw * children [XE_PDES ];
31
+ /** @staging: Array of page-table staging nodes */
32
+ struct xe_ptw * staging [XE_PDES ];
31
33
};
32
34
33
35
#if IS_ENABLED (CONFIG_DRM_XE_DEBUG_VM )
@@ -48,9 +50,10 @@ static struct xe_pt_dir *as_xe_pt_dir(struct xe_pt *pt)
48
50
return container_of (pt , struct xe_pt_dir , pt );
49
51
}
50
52
51
- static struct xe_pt * xe_pt_entry (struct xe_pt_dir * pt_dir , unsigned int index )
53
+ static struct xe_pt *
54
+ xe_pt_entry_staging (struct xe_pt_dir * pt_dir , unsigned int index )
52
55
{
53
- return container_of (pt_dir -> children [index ], struct xe_pt , base );
56
+ return container_of (pt_dir -> staging [index ], struct xe_pt , base );
54
57
}
55
58
56
59
static u64 __xe_pt_empty_pte (struct xe_tile * tile , struct xe_vm * vm ,
@@ -125,6 +128,7 @@ struct xe_pt *xe_pt_create(struct xe_vm *vm, struct xe_tile *tile,
125
128
}
126
129
pt -> bo = bo ;
127
130
pt -> base .children = level ? as_xe_pt_dir (pt )-> children : NULL ;
131
+ pt -> base .staging = level ? as_xe_pt_dir (pt )-> staging : NULL ;
128
132
129
133
if (vm -> xef )
130
134
xe_drm_client_add_bo (vm -> xef -> client , pt -> bo );
@@ -206,8 +210,8 @@ void xe_pt_destroy(struct xe_pt *pt, u32 flags, struct llist_head *deferred)
206
210
struct xe_pt_dir * pt_dir = as_xe_pt_dir (pt );
207
211
208
212
for (i = 0 ; i < XE_PDES ; i ++ ) {
209
- if (xe_pt_entry (pt_dir , i ))
210
- xe_pt_destroy (xe_pt_entry (pt_dir , i ), flags ,
213
+ if (xe_pt_entry_staging (pt_dir , i ))
214
+ xe_pt_destroy (xe_pt_entry_staging (pt_dir , i ), flags ,
211
215
deferred );
212
216
}
213
217
}
@@ -376,8 +380,10 @@ xe_pt_insert_entry(struct xe_pt_stage_bind_walk *xe_walk, struct xe_pt *parent,
376
380
/* Continue building a non-connected subtree. */
377
381
struct iosys_map * map = & parent -> bo -> vmap ;
378
382
379
- if (unlikely (xe_child ))
383
+ if (unlikely (xe_child )) {
380
384
parent -> base .children [offset ] = & xe_child -> base ;
385
+ parent -> base .staging [offset ] = & xe_child -> base ;
386
+ }
381
387
382
388
xe_pt_write (xe_walk -> vm -> xe , map , offset , pte );
383
389
parent -> num_live ++ ;
@@ -614,6 +620,7 @@ xe_pt_stage_bind(struct xe_tile *tile, struct xe_vma *vma,
614
620
.ops = & xe_pt_stage_bind_ops ,
615
621
.shifts = xe_normal_pt_shifts ,
616
622
.max_level = XE_PT_HIGHEST_LEVEL ,
623
+ .staging = true,
617
624
},
618
625
.vm = xe_vma_vm (vma ),
619
626
.tile = tile ,
@@ -873,7 +880,7 @@ static void xe_pt_cancel_bind(struct xe_vma *vma,
873
880
}
874
881
}
875
882
876
- static void xe_pt_commit_locks_assert (struct xe_vma * vma )
883
+ static void xe_pt_commit_prepare_locks_assert (struct xe_vma * vma )
877
884
{
878
885
struct xe_vm * vm = xe_vma_vm (vma );
879
886
@@ -885,6 +892,16 @@ static void xe_pt_commit_locks_assert(struct xe_vma *vma)
885
892
xe_vm_assert_held (vm );
886
893
}
887
894
895
+ static void xe_pt_commit_locks_assert (struct xe_vma * vma )
896
+ {
897
+ struct xe_vm * vm = xe_vma_vm (vma );
898
+
899
+ xe_pt_commit_prepare_locks_assert (vma );
900
+
901
+ if (xe_vma_is_userptr (vma ))
902
+ lockdep_assert_held_read (& vm -> userptr .notifier_lock );
903
+ }
904
+
888
905
static void xe_pt_commit (struct xe_vma * vma ,
889
906
struct xe_vm_pgtable_update * entries ,
890
907
u32 num_entries , struct llist_head * deferred )
@@ -895,13 +912,17 @@ static void xe_pt_commit(struct xe_vma *vma,
895
912
896
913
for (i = 0 ; i < num_entries ; i ++ ) {
897
914
struct xe_pt * pt = entries [i ].pt ;
915
+ struct xe_pt_dir * pt_dir ;
898
916
899
917
if (!pt -> level )
900
918
continue ;
901
919
920
+ pt_dir = as_xe_pt_dir (pt );
902
921
for (j = 0 ; j < entries [i ].qwords ; j ++ ) {
903
922
struct xe_pt * oldpte = entries [i ].pt_entries [j ].pt ;
923
+ int j_ = j + entries [i ].ofs ;
904
924
925
+ pt_dir -> children [j_ ] = pt_dir -> staging [j_ ];
905
926
xe_pt_destroy (oldpte , xe_vma_vm (vma )-> flags , deferred );
906
927
}
907
928
}
@@ -913,7 +934,7 @@ static void xe_pt_abort_bind(struct xe_vma *vma,
913
934
{
914
935
int i , j ;
915
936
916
- xe_pt_commit_locks_assert (vma );
937
+ xe_pt_commit_prepare_locks_assert (vma );
917
938
918
939
for (i = num_entries - 1 ; i >= 0 ; -- i ) {
919
940
struct xe_pt * pt = entries [i ].pt ;
@@ -928,10 +949,10 @@ static void xe_pt_abort_bind(struct xe_vma *vma,
928
949
pt_dir = as_xe_pt_dir (pt );
929
950
for (j = 0 ; j < entries [i ].qwords ; j ++ ) {
930
951
u32 j_ = j + entries [i ].ofs ;
931
- struct xe_pt * newpte = xe_pt_entry (pt_dir , j_ );
952
+ struct xe_pt * newpte = xe_pt_entry_staging (pt_dir , j_ );
932
953
struct xe_pt * oldpte = entries [i ].pt_entries [j ].pt ;
933
954
934
- pt_dir -> children [j_ ] = oldpte ? & oldpte -> base : 0 ;
955
+ pt_dir -> staging [j_ ] = oldpte ? & oldpte -> base : 0 ;
935
956
xe_pt_destroy (newpte , xe_vma_vm (vma )-> flags , NULL );
936
957
}
937
958
}
@@ -943,7 +964,7 @@ static void xe_pt_commit_prepare_bind(struct xe_vma *vma,
943
964
{
944
965
u32 i , j ;
945
966
946
- xe_pt_commit_locks_assert (vma );
967
+ xe_pt_commit_prepare_locks_assert (vma );
947
968
948
969
for (i = 0 ; i < num_entries ; i ++ ) {
949
970
struct xe_pt * pt = entries [i ].pt ;
@@ -961,10 +982,10 @@ static void xe_pt_commit_prepare_bind(struct xe_vma *vma,
961
982
struct xe_pt * newpte = entries [i ].pt_entries [j ].pt ;
962
983
struct xe_pt * oldpte = NULL ;
963
984
964
- if (xe_pt_entry (pt_dir , j_ ))
965
- oldpte = xe_pt_entry (pt_dir , j_ );
985
+ if (xe_pt_entry_staging (pt_dir , j_ ))
986
+ oldpte = xe_pt_entry_staging (pt_dir , j_ );
966
987
967
- pt_dir -> children [j_ ] = & newpte -> base ;
988
+ pt_dir -> staging [j_ ] = & newpte -> base ;
968
989
entries [i ].pt_entries [j ].pt = oldpte ;
969
990
}
970
991
}
@@ -1494,6 +1515,7 @@ static unsigned int xe_pt_stage_unbind(struct xe_tile *tile, struct xe_vma *vma,
1494
1515
.ops = & xe_pt_stage_unbind_ops ,
1495
1516
.shifts = xe_normal_pt_shifts ,
1496
1517
.max_level = XE_PT_HIGHEST_LEVEL ,
1518
+ .staging = true,
1497
1519
},
1498
1520
.tile = tile ,
1499
1521
.modified_start = xe_vma_start (vma ),
@@ -1535,7 +1557,7 @@ static void xe_pt_abort_unbind(struct xe_vma *vma,
1535
1557
{
1536
1558
int i , j ;
1537
1559
1538
- xe_pt_commit_locks_assert (vma );
1560
+ xe_pt_commit_prepare_locks_assert (vma );
1539
1561
1540
1562
for (i = num_entries - 1 ; i >= 0 ; -- i ) {
1541
1563
struct xe_vm_pgtable_update * entry = & entries [i ];
@@ -1548,7 +1570,7 @@ static void xe_pt_abort_unbind(struct xe_vma *vma,
1548
1570
continue ;
1549
1571
1550
1572
for (j = entry -> ofs ; j < entry -> ofs + entry -> qwords ; j ++ )
1551
- pt_dir -> children [j ] =
1573
+ pt_dir -> staging [j ] =
1552
1574
entries [i ].pt_entries [j - entry -> ofs ].pt ?
1553
1575
& entries [i ].pt_entries [j - entry -> ofs ].pt -> base : NULL ;
1554
1576
}
@@ -1561,7 +1583,7 @@ xe_pt_commit_prepare_unbind(struct xe_vma *vma,
1561
1583
{
1562
1584
int i , j ;
1563
1585
1564
- xe_pt_commit_locks_assert (vma );
1586
+ xe_pt_commit_prepare_locks_assert (vma );
1565
1587
1566
1588
for (i = 0 ; i < num_entries ; ++ i ) {
1567
1589
struct xe_vm_pgtable_update * entry = & entries [i ];
@@ -1575,8 +1597,8 @@ xe_pt_commit_prepare_unbind(struct xe_vma *vma,
1575
1597
pt_dir = as_xe_pt_dir (pt );
1576
1598
for (j = entry -> ofs ; j < entry -> ofs + entry -> qwords ; j ++ ) {
1577
1599
entry -> pt_entries [j - entry -> ofs ].pt =
1578
- xe_pt_entry (pt_dir , j );
1579
- pt_dir -> children [j ] = NULL ;
1600
+ xe_pt_entry_staging (pt_dir , j );
1601
+ pt_dir -> staging [j ] = NULL ;
1580
1602
}
1581
1603
}
1582
1604
}
0 commit comments