1010#include <linux/slab.h>
1111#include <linux/types.h>
1212
13+ #include "xe_assert.h"
1314#include "xe_bo.h"
1415#include "xe_bo_types.h"
1516#include "xe_device_types.h"
@@ -151,10 +152,13 @@ void xe_drm_client_add_bo(struct xe_drm_client *client,
151152 */
152153void xe_drm_client_remove_bo (struct xe_bo * bo )
153154{
155+ struct xe_device * xe = ttm_to_xe_device (bo -> ttm .bdev );
154156 struct xe_drm_client * client = bo -> client ;
155157
158+ xe_assert (xe , !kref_read (& bo -> ttm .base .refcount ));
159+
156160 spin_lock (& client -> bos_lock );
157- list_del (& bo -> client_link );
161+ list_del_init (& bo -> client_link );
158162 spin_unlock (& client -> bos_lock );
159163
160164 xe_drm_client_put (client );
@@ -164,12 +168,9 @@ static void bo_meminfo(struct xe_bo *bo,
164168 struct drm_memory_stats stats [TTM_NUM_MEM_TYPES ])
165169{
166170 u64 sz = bo -> size ;
167- u32 mem_type ;
171+ u32 mem_type = bo -> ttm . resource -> mem_type ;
168172
169- if (bo -> placement .placement )
170- mem_type = bo -> placement .placement -> mem_type ;
171- else
172- mem_type = XE_PL_TT ;
173+ xe_bo_assert_held (bo );
173174
174175 if (drm_gem_object_is_shared_for_memory_stats (& bo -> ttm .base ))
175176 stats [mem_type ].shared += sz ;
@@ -196,6 +197,7 @@ static void show_meminfo(struct drm_printer *p, struct drm_file *file)
196197 struct xe_drm_client * client ;
197198 struct drm_gem_object * obj ;
198199 struct xe_bo * bo ;
200+ LLIST_HEAD (deferred );
199201 unsigned int id ;
200202 u32 mem_type ;
201203
@@ -206,7 +208,20 @@ static void show_meminfo(struct drm_printer *p, struct drm_file *file)
206208 idr_for_each_entry (& file -> object_idr , obj , id ) {
207209 struct xe_bo * bo = gem_to_xe_bo (obj );
208210
209- bo_meminfo (bo , stats );
211+ if (dma_resv_trylock (bo -> ttm .base .resv )) {
212+ bo_meminfo (bo , stats );
213+ xe_bo_unlock (bo );
214+ } else {
215+ xe_bo_get (bo );
216+ spin_unlock (& file -> table_lock );
217+
218+ xe_bo_lock (bo , false);
219+ bo_meminfo (bo , stats );
220+ xe_bo_unlock (bo );
221+
222+ xe_bo_put (bo );
223+ spin_lock (& file -> table_lock );
224+ }
210225 }
211226 spin_unlock (& file -> table_lock );
212227
@@ -215,11 +230,28 @@ static void show_meminfo(struct drm_printer *p, struct drm_file *file)
215230 list_for_each_entry (bo , & client -> bos_list , client_link ) {
216231 if (!kref_get_unless_zero (& bo -> ttm .base .refcount ))
217232 continue ;
218- bo_meminfo (bo , stats );
219- xe_bo_put (bo );
233+
234+ if (dma_resv_trylock (bo -> ttm .base .resv )) {
235+ bo_meminfo (bo , stats );
236+ xe_bo_unlock (bo );
237+ } else {
238+ spin_unlock (& client -> bos_lock );
239+
240+ xe_bo_lock (bo , false);
241+ bo_meminfo (bo , stats );
242+ xe_bo_unlock (bo );
243+
244+ spin_lock (& client -> bos_lock );
245+ /* The bo ref will prevent this bo from being removed from the list */
246+ xe_assert (xef -> xe , !list_empty (& bo -> client_link ));
247+ }
248+
249+ xe_bo_put_deferred (bo , & deferred );
220250 }
221251 spin_unlock (& client -> bos_lock );
222252
253+ xe_bo_put_commit (& deferred );
254+
223255 for (mem_type = XE_PL_SYSTEM ; mem_type < TTM_NUM_MEM_TYPES ; ++ mem_type ) {
224256 if (!xe_mem_type_to_name [mem_type ])
225257 continue ;
0 commit comments