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 );
@@ -166,6 +170,8 @@ static void bo_meminfo(struct xe_bo *bo,
166170 u64 sz = bo -> size ;
167171 u32 mem_type ;
168172
173+ xe_bo_assert_held (bo );
174+
169175 if (bo -> placement .placement )
170176 mem_type = bo -> placement .placement -> mem_type ;
171177 else
@@ -196,6 +202,7 @@ static void show_meminfo(struct drm_printer *p, struct drm_file *file)
196202 struct xe_drm_client * client ;
197203 struct drm_gem_object * obj ;
198204 struct xe_bo * bo ;
205+ LLIST_HEAD (deferred );
199206 unsigned int id ;
200207 u32 mem_type ;
201208
@@ -206,7 +213,20 @@ static void show_meminfo(struct drm_printer *p, struct drm_file *file)
206213 idr_for_each_entry (& file -> object_idr , obj , id ) {
207214 struct xe_bo * bo = gem_to_xe_bo (obj );
208215
209- bo_meminfo (bo , stats );
216+ if (dma_resv_trylock (bo -> ttm .base .resv )) {
217+ bo_meminfo (bo , stats );
218+ xe_bo_unlock (bo );
219+ } else {
220+ xe_bo_get (bo );
221+ spin_unlock (& file -> table_lock );
222+
223+ xe_bo_lock (bo , false);
224+ bo_meminfo (bo , stats );
225+ xe_bo_unlock (bo );
226+
227+ xe_bo_put (bo );
228+ spin_lock (& file -> table_lock );
229+ }
210230 }
211231 spin_unlock (& file -> table_lock );
212232
@@ -215,11 +235,28 @@ static void show_meminfo(struct drm_printer *p, struct drm_file *file)
215235 list_for_each_entry (bo , & client -> bos_list , client_link ) {
216236 if (!kref_get_unless_zero (& bo -> ttm .base .refcount ))
217237 continue ;
218- bo_meminfo (bo , stats );
219- xe_bo_put (bo );
238+
239+ if (dma_resv_trylock (bo -> ttm .base .resv )) {
240+ bo_meminfo (bo , stats );
241+ xe_bo_unlock (bo );
242+ } else {
243+ spin_unlock (& client -> bos_lock );
244+
245+ xe_bo_lock (bo , false);
246+ bo_meminfo (bo , stats );
247+ xe_bo_unlock (bo );
248+
249+ spin_lock (& client -> bos_lock );
250+ /* The bo ref will prevent this bo from being removed from the list */
251+ xe_assert (xef -> xe , !list_empty (& bo -> client_link ));
252+ }
253+
254+ xe_bo_put_deferred (bo , & deferred );
220255 }
221256 spin_unlock (& client -> bos_lock );
222257
258+ xe_bo_put_commit (& deferred );
259+
223260 for (mem_type = XE_PL_SYSTEM ; mem_type < TTM_NUM_MEM_TYPES ; ++ mem_type ) {
224261 if (!xe_mem_type_to_name [mem_type ])
225262 continue ;
0 commit comments