1 // SPDX-License-Identifier: MIT 2 /* 3 * Copyright © 2023 Intel Corporation 4 */ 5 #include "xe_drm_client.h" 6 7 #include <drm/drm_print.h> 8 #include <uapi/drm/xe_drm.h> 9 #include <linux/kernel.h> 10 #include <linux/slab.h> 11 #include <linux/types.h> 12 13 #include "xe_assert.h" 14 #include "xe_bo.h" 15 #include "xe_bo_types.h" 16 #include "xe_device_types.h" 17 #include "xe_exec_queue.h" 18 #include "xe_force_wake.h" 19 #include "xe_gt.h" 20 #include "xe_hw_engine.h" 21 #include "xe_pm.h" 22 #include "xe_trace.h" 23 24 /** 25 * DOC: DRM Client usage stats 26 * 27 * The drm/xe driver implements the DRM client usage stats specification as 28 * documented in :ref:`drm-client-usage-stats`. 29 * 30 * Example of the output showing the implemented key value pairs and entirety of 31 * the currently possible format options: 32 * 33 * :: 34 * 35 * pos: 0 36 * flags: 0100002 37 * mnt_id: 26 38 * ino: 685 39 * drm-driver: xe 40 * drm-client-id: 3 41 * drm-pdev: 0000:03:00.0 42 * drm-total-system: 0 43 * drm-shared-system: 0 44 * drm-active-system: 0 45 * drm-resident-system: 0 46 * drm-purgeable-system: 0 47 * drm-total-gtt: 192 KiB 48 * drm-shared-gtt: 0 49 * drm-active-gtt: 0 50 * drm-resident-gtt: 192 KiB 51 * drm-total-vram0: 23992 KiB 52 * drm-shared-vram0: 16 MiB 53 * drm-active-vram0: 0 54 * drm-resident-vram0: 23992 KiB 55 * drm-total-stolen: 0 56 * drm-shared-stolen: 0 57 * drm-active-stolen: 0 58 * drm-resident-stolen: 0 59 * drm-cycles-rcs: 28257900 60 * drm-total-cycles-rcs: 7655183225 61 * drm-cycles-bcs: 0 62 * drm-total-cycles-bcs: 7655183225 63 * drm-cycles-vcs: 0 64 * drm-total-cycles-vcs: 7655183225 65 * drm-engine-capacity-vcs: 2 66 * drm-cycles-vecs: 0 67 * drm-total-cycles-vecs: 7655183225 68 * drm-engine-capacity-vecs: 2 69 * drm-cycles-ccs: 0 70 * drm-total-cycles-ccs: 7655183225 71 * drm-engine-capacity-ccs: 4 72 * 73 * Possible `drm-cycles-` key names are: `rcs`, `ccs`, `bcs`, `vcs`, `vecs` and 74 * "other". 75 */ 76 77 /** 78 * xe_drm_client_alloc() - Allocate drm client 79 * @void: No arg 80 * 81 * Allocate drm client struct to track client memory against 82 * same till client life. Call this API whenever new client 83 * has opened xe device. 84 * 85 * Return: pointer to client struct or NULL if can't allocate 86 */ 87 struct xe_drm_client *xe_drm_client_alloc(void) 88 { 89 struct xe_drm_client *client; 90 91 client = kzalloc_obj(*client); 92 if (!client) 93 return NULL; 94 95 kref_init(&client->kref); 96 97 #ifdef CONFIG_PROC_FS 98 spin_lock_init(&client->bos_lock); 99 INIT_LIST_HEAD(&client->bos_list); 100 #endif 101 return client; 102 } 103 104 /** 105 * __xe_drm_client_free() - Free client struct 106 * @kref: The reference 107 * 108 * This frees client struct. Call this API when xe device is closed 109 * by drm client. 110 * 111 * Return: void 112 */ 113 void __xe_drm_client_free(struct kref *kref) 114 { 115 struct xe_drm_client *client = 116 container_of(kref, typeof(*client), kref); 117 118 kfree(client); 119 } 120 121 #ifdef CONFIG_PROC_FS 122 /** 123 * xe_drm_client_add_bo() - Add BO for tracking client mem usage 124 * @client: The drm client ptr 125 * @bo: The xe BO ptr 126 * 127 * Add all BO created by individual drm client by calling this function. 128 * This helps in tracking client memory usage. 129 * 130 * Return: void 131 */ 132 void xe_drm_client_add_bo(struct xe_drm_client *client, 133 struct xe_bo *bo) 134 { 135 XE_WARN_ON(bo->client); 136 XE_WARN_ON(!list_empty(&bo->client_link)); 137 138 bo->client = xe_drm_client_get(client); 139 spin_lock(&client->bos_lock); 140 list_add_tail(&bo->client_link, &client->bos_list); 141 spin_unlock(&client->bos_lock); 142 } 143 144 /** 145 * xe_drm_client_remove_bo() - Remove BO for tracking client mem usage 146 * @bo: The xe BO ptr 147 * 148 * Remove all BO removed by individual drm client by calling this function. 149 * This helps in tracking client memory usage. 150 * 151 * Return: void 152 */ 153 void xe_drm_client_remove_bo(struct xe_bo *bo) 154 { 155 struct xe_device *xe = ttm_to_xe_device(bo->ttm.bdev); 156 struct xe_drm_client *client = bo->client; 157 158 xe_assert(xe, !kref_read(&bo->ttm.base.refcount)); 159 160 spin_lock(&client->bos_lock); 161 list_del_init(&bo->client_link); 162 spin_unlock(&client->bos_lock); 163 164 xe_drm_client_put(client); 165 } 166 167 static void bo_meminfo(struct xe_bo *bo, 168 struct drm_memory_stats stats[TTM_NUM_MEM_TYPES]) 169 { 170 u64 sz = xe_bo_size(bo); 171 u32 mem_type; 172 173 xe_bo_assert_held(bo); 174 175 /* 176 * The resource can be NULL if the BO has been purged, plus maybe some 177 * other cases. Either way there shouldn't be any memory to account for, 178 * or a current resource to account this against, so skip for now. 179 */ 180 if (!bo->ttm.resource) 181 return; 182 183 mem_type = bo->ttm.resource->mem_type; 184 185 if (drm_gem_object_is_shared_for_memory_stats(&bo->ttm.base)) 186 stats[mem_type].shared += sz; 187 else 188 stats[mem_type].private += sz; 189 190 if (xe_bo_has_pages(bo)) { 191 stats[mem_type].resident += sz; 192 193 if (!dma_resv_test_signaled(bo->ttm.base.resv, 194 DMA_RESV_USAGE_BOOKKEEP)) 195 stats[mem_type].active += sz; 196 else if (mem_type == XE_PL_SYSTEM) 197 stats[mem_type].purgeable += sz; 198 } 199 } 200 201 static void show_meminfo(struct drm_printer *p, struct drm_file *file) 202 { 203 struct drm_memory_stats stats[TTM_NUM_MEM_TYPES] = {}; 204 struct xe_file *xef = file->driver_priv; 205 struct ttm_device *bdev = &xef->xe->ttm; 206 struct ttm_resource_manager *man; 207 struct xe_drm_client *client; 208 struct drm_gem_object *obj; 209 struct xe_bo *bo; 210 LLIST_HEAD(deferred); 211 unsigned int id; 212 u32 mem_type; 213 214 client = xef->client; 215 216 /* Public objects. */ 217 spin_lock(&file->table_lock); 218 idr_for_each_entry(&file->object_idr, obj, id) { 219 struct xe_bo *bo = gem_to_xe_bo(obj); 220 221 if (dma_resv_trylock(bo->ttm.base.resv)) { 222 bo_meminfo(bo, stats); 223 xe_bo_unlock(bo); 224 } else { 225 xe_bo_get(bo); 226 spin_unlock(&file->table_lock); 227 228 xe_bo_lock(bo, false); 229 bo_meminfo(bo, stats); 230 xe_bo_unlock(bo); 231 232 xe_bo_put(bo); 233 spin_lock(&file->table_lock); 234 } 235 } 236 spin_unlock(&file->table_lock); 237 238 /* Internal objects. */ 239 spin_lock(&client->bos_lock); 240 list_for_each_entry(bo, &client->bos_list, client_link) { 241 if (!kref_get_unless_zero(&bo->ttm.base.refcount)) 242 continue; 243 244 if (dma_resv_trylock(bo->ttm.base.resv)) { 245 bo_meminfo(bo, stats); 246 xe_bo_unlock(bo); 247 } else { 248 spin_unlock(&client->bos_lock); 249 250 xe_bo_lock(bo, false); 251 bo_meminfo(bo, stats); 252 xe_bo_unlock(bo); 253 254 spin_lock(&client->bos_lock); 255 /* The bo ref will prevent this bo from being removed from the list */ 256 xe_assert(xef->xe, !list_empty(&bo->client_link)); 257 } 258 259 xe_bo_put_deferred(bo, &deferred); 260 } 261 spin_unlock(&client->bos_lock); 262 263 xe_bo_put_commit(&deferred); 264 265 for (mem_type = XE_PL_SYSTEM; mem_type < TTM_NUM_MEM_TYPES; ++mem_type) { 266 if (!xe_mem_type_to_name[mem_type]) 267 continue; 268 269 man = ttm_manager_type(bdev, mem_type); 270 271 if (man) { 272 drm_print_memory_stats(p, 273 &stats[mem_type], 274 DRM_GEM_OBJECT_ACTIVE | 275 DRM_GEM_OBJECT_RESIDENT | 276 (mem_type != XE_PL_SYSTEM ? 0 : 277 DRM_GEM_OBJECT_PURGEABLE), 278 xe_mem_type_to_name[mem_type]); 279 } 280 } 281 } 282 283 static struct xe_hw_engine *any_engine(struct xe_device *xe) 284 { 285 struct xe_gt *gt; 286 unsigned long gt_id; 287 288 for_each_gt(gt, xe, gt_id) { 289 struct xe_hw_engine *hwe = xe_gt_any_hw_engine(gt); 290 291 if (hwe) 292 return hwe; 293 } 294 295 return NULL; 296 } 297 298 /* 299 * Pick any engine and grab its forcewake. On error phwe will be NULL and 300 * the returned forcewake reference will be invalid. Callers should check 301 * phwe against NULL. 302 */ 303 static struct xe_force_wake_ref force_wake_get_any_engine(struct xe_device *xe, 304 struct xe_hw_engine **phwe) 305 { 306 enum xe_force_wake_domains domain; 307 struct xe_force_wake_ref fw_ref = {}; 308 struct xe_hw_engine *hwe; 309 310 *phwe = NULL; 311 312 hwe = any_engine(xe); 313 if (!hwe) 314 return fw_ref; /* will be invalid */ 315 316 domain = xe_hw_engine_to_fw_domain(hwe); 317 318 fw_ref = xe_force_wake_constructor(gt_to_fw(hwe->gt), domain); 319 if (xe_force_wake_ref_has_domain(fw_ref.domains, domain)) 320 *phwe = hwe; /* valid forcewake */ 321 322 return fw_ref; 323 } 324 325 static void show_run_ticks(struct drm_printer *p, struct drm_file *file) 326 { 327 unsigned long class, i, gt_id, capacity[XE_ENGINE_CLASS_MAX] = { }; 328 struct xe_file *xef = file->driver_priv; 329 struct xe_device *xe = xef->xe; 330 struct xe_gt *gt; 331 struct xe_hw_engine *hwe; 332 struct xe_exec_queue *q; 333 u64 gpu_timestamp; 334 335 /* 336 * RING_TIMESTAMP registers are inaccessible in VF mode. 337 * Without drm-total-cycles-*, other keys provide little value. 338 * Show all or none of the optional "run_ticks" keys in this case. 339 */ 340 if (IS_SRIOV_VF(xe)) 341 return; 342 343 /* 344 * Wait for any exec queue going away: their cycles will get updated on 345 * context switch out, so wait for that to happen 346 */ 347 wait_var_event(&xef->exec_queue.pending_removal, 348 !atomic_read(&xef->exec_queue.pending_removal)); 349 350 scoped_guard(xe_pm_runtime, xe) { 351 CLASS(xe_force_wake_release_only, fw_ref)(force_wake_get_any_engine(xe, &hwe)); 352 if (!hwe) 353 return; 354 355 /* Accumulate all the exec queues from this client */ 356 mutex_lock(&xef->exec_queue.lock); 357 xa_for_each(&xef->exec_queue.xa, i, q) { 358 xe_exec_queue_get(q); 359 mutex_unlock(&xef->exec_queue.lock); 360 361 xe_exec_queue_update_run_ticks(q); 362 363 mutex_lock(&xef->exec_queue.lock); 364 xe_exec_queue_put(q); 365 } 366 mutex_unlock(&xef->exec_queue.lock); 367 368 gpu_timestamp = xe_hw_engine_read_timestamp(hwe); 369 } 370 371 for (class = 0; class < XE_ENGINE_CLASS_MAX; class++) { 372 const char *class_name; 373 374 for_each_gt(gt, xe, gt_id) 375 capacity[class] += gt->user_engines.instances_per_class[class]; 376 377 /* 378 * Engines may be fused off or not exposed to userspace. Don't 379 * return anything if this entire class is not available 380 */ 381 if (!capacity[class]) 382 continue; 383 384 class_name = xe_hw_engine_class_to_str(class); 385 drm_printf(p, "drm-cycles-%s:\t%llu\n", 386 class_name, xef->run_ticks[class]); 387 drm_printf(p, "drm-total-cycles-%s:\t%llu\n", 388 class_name, gpu_timestamp); 389 390 if (capacity[class] > 1) 391 drm_printf(p, "drm-engine-capacity-%s:\t%lu\n", 392 class_name, capacity[class]); 393 } 394 } 395 396 /** 397 * xe_drm_client_fdinfo() - Callback for fdinfo interface 398 * @p: The drm_printer ptr 399 * @file: The drm_file ptr 400 * 401 * This is callback for drm fdinfo interface. Register this callback 402 * in drm driver ops for show_fdinfo. 403 * 404 * Return: void 405 */ 406 void xe_drm_client_fdinfo(struct drm_printer *p, struct drm_file *file) 407 { 408 show_meminfo(p, file); 409 show_run_ticks(p, file); 410 } 411 #endif 412