@@ -28,6 +28,8 @@ struct xe_pt_dir {
2828 struct xe_pt pt ;
2929 /** @children: Array of page-table child nodes */
3030 struct xe_ptw * children [XE_PDES ];
31+ /** @staging: Array of page-table staging nodes */
32+ struct xe_ptw * staging [XE_PDES ];
3133};
3234
3335#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)
4850 return container_of (pt , struct xe_pt_dir , pt );
4951}
5052
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 )
5255{
53- return container_of (pt_dir -> children [index ], struct xe_pt , base );
56+ return container_of (pt_dir -> staging [index ], struct xe_pt , base );
5457}
5558
5659static 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,
125128 }
126129 pt -> bo = bo ;
127130 pt -> base .children = level ? as_xe_pt_dir (pt )-> children : NULL ;
131+ pt -> base .staging = level ? as_xe_pt_dir (pt )-> staging : NULL ;
128132
129133 if (vm -> xef )
130134 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)
206210 struct xe_pt_dir * pt_dir = as_xe_pt_dir (pt );
207211
208212 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 ,
211215 deferred );
212216 }
213217 }
@@ -376,8 +380,10 @@ xe_pt_insert_entry(struct xe_pt_stage_bind_walk *xe_walk, struct xe_pt *parent,
376380 /* Continue building a non-connected subtree. */
377381 struct iosys_map * map = & parent -> bo -> vmap ;
378382
379- if (unlikely (xe_child ))
383+ if (unlikely (xe_child )) {
380384 parent -> base .children [offset ] = & xe_child -> base ;
385+ parent -> base .staging [offset ] = & xe_child -> base ;
386+ }
381387
382388 xe_pt_write (xe_walk -> vm -> xe , map , offset , pte );
383389 parent -> num_live ++ ;
@@ -614,6 +620,7 @@ xe_pt_stage_bind(struct xe_tile *tile, struct xe_vma *vma,
614620 .ops = & xe_pt_stage_bind_ops ,
615621 .shifts = xe_normal_pt_shifts ,
616622 .max_level = XE_PT_HIGHEST_LEVEL ,
623+ .staging = true,
617624 },
618625 .vm = xe_vma_vm (vma ),
619626 .tile = tile ,
@@ -873,7 +880,7 @@ static void xe_pt_cancel_bind(struct xe_vma *vma,
873880 }
874881}
875882
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 )
877884{
878885 struct xe_vm * vm = xe_vma_vm (vma );
879886
@@ -885,6 +892,16 @@ static void xe_pt_commit_locks_assert(struct xe_vma *vma)
885892 xe_vm_assert_held (vm );
886893}
887894
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+
888905static void xe_pt_commit (struct xe_vma * vma ,
889906 struct xe_vm_pgtable_update * entries ,
890907 u32 num_entries , struct llist_head * deferred )
@@ -895,13 +912,17 @@ static void xe_pt_commit(struct xe_vma *vma,
895912
896913 for (i = 0 ; i < num_entries ; i ++ ) {
897914 struct xe_pt * pt = entries [i ].pt ;
915+ struct xe_pt_dir * pt_dir ;
898916
899917 if (!pt -> level )
900918 continue ;
901919
920+ pt_dir = as_xe_pt_dir (pt );
902921 for (j = 0 ; j < entries [i ].qwords ; j ++ ) {
903922 struct xe_pt * oldpte = entries [i ].pt_entries [j ].pt ;
923+ int j_ = j + entries [i ].ofs ;
904924
925+ pt_dir -> children [j_ ] = pt_dir -> staging [j_ ];
905926 xe_pt_destroy (oldpte , xe_vma_vm (vma )-> flags , deferred );
906927 }
907928 }
@@ -913,7 +934,7 @@ static void xe_pt_abort_bind(struct xe_vma *vma,
913934{
914935 int i , j ;
915936
916- xe_pt_commit_locks_assert (vma );
937+ xe_pt_commit_prepare_locks_assert (vma );
917938
918939 for (i = num_entries - 1 ; i >= 0 ; -- i ) {
919940 struct xe_pt * pt = entries [i ].pt ;
@@ -928,10 +949,10 @@ static void xe_pt_abort_bind(struct xe_vma *vma,
928949 pt_dir = as_xe_pt_dir (pt );
929950 for (j = 0 ; j < entries [i ].qwords ; j ++ ) {
930951 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_ );
932953 struct xe_pt * oldpte = entries [i ].pt_entries [j ].pt ;
933954
934- pt_dir -> children [j_ ] = oldpte ? & oldpte -> base : 0 ;
955+ pt_dir -> staging [j_ ] = oldpte ? & oldpte -> base : 0 ;
935956 xe_pt_destroy (newpte , xe_vma_vm (vma )-> flags , NULL );
936957 }
937958 }
@@ -943,7 +964,7 @@ static void xe_pt_commit_prepare_bind(struct xe_vma *vma,
943964{
944965 u32 i , j ;
945966
946- xe_pt_commit_locks_assert (vma );
967+ xe_pt_commit_prepare_locks_assert (vma );
947968
948969 for (i = 0 ; i < num_entries ; i ++ ) {
949970 struct xe_pt * pt = entries [i ].pt ;
@@ -961,10 +982,10 @@ static void xe_pt_commit_prepare_bind(struct xe_vma *vma,
961982 struct xe_pt * newpte = entries [i ].pt_entries [j ].pt ;
962983 struct xe_pt * oldpte = NULL ;
963984
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_ );
966987
967- pt_dir -> children [j_ ] = & newpte -> base ;
988+ pt_dir -> staging [j_ ] = & newpte -> base ;
968989 entries [i ].pt_entries [j ].pt = oldpte ;
969990 }
970991 }
@@ -1494,6 +1515,7 @@ static unsigned int xe_pt_stage_unbind(struct xe_tile *tile, struct xe_vma *vma,
14941515 .ops = & xe_pt_stage_unbind_ops ,
14951516 .shifts = xe_normal_pt_shifts ,
14961517 .max_level = XE_PT_HIGHEST_LEVEL ,
1518+ .staging = true,
14971519 },
14981520 .tile = tile ,
14991521 .modified_start = xe_vma_start (vma ),
@@ -1535,7 +1557,7 @@ static void xe_pt_abort_unbind(struct xe_vma *vma,
15351557{
15361558 int i , j ;
15371559
1538- xe_pt_commit_locks_assert (vma );
1560+ xe_pt_commit_prepare_locks_assert (vma );
15391561
15401562 for (i = num_entries - 1 ; i >= 0 ; -- i ) {
15411563 struct xe_vm_pgtable_update * entry = & entries [i ];
@@ -1548,7 +1570,7 @@ static void xe_pt_abort_unbind(struct xe_vma *vma,
15481570 continue ;
15491571
15501572 for (j = entry -> ofs ; j < entry -> ofs + entry -> qwords ; j ++ )
1551- pt_dir -> children [j ] =
1573+ pt_dir -> staging [j ] =
15521574 entries [i ].pt_entries [j - entry -> ofs ].pt ?
15531575 & entries [i ].pt_entries [j - entry -> ofs ].pt -> base : NULL ;
15541576 }
@@ -1561,7 +1583,7 @@ xe_pt_commit_prepare_unbind(struct xe_vma *vma,
15611583{
15621584 int i , j ;
15631585
1564- xe_pt_commit_locks_assert (vma );
1586+ xe_pt_commit_prepare_locks_assert (vma );
15651587
15661588 for (i = 0 ; i < num_entries ; ++ i ) {
15671589 struct xe_vm_pgtable_update * entry = & entries [i ];
@@ -1575,8 +1597,8 @@ xe_pt_commit_prepare_unbind(struct xe_vma *vma,
15751597 pt_dir = as_xe_pt_dir (pt );
15761598 for (j = entry -> ofs ; j < entry -> ofs + entry -> qwords ; j ++ ) {
15771599 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 ;
15801602 }
15811603 }
15821604}
0 commit comments