FILE
xe_gt_sriov_pf_config.c
File preview with syntax highlighting.
linux-6.19.14/drivers/gpu/drm/xe/xe_gt_sriov_pf_config.c
1// SPDX-License-Identifier: MIT 2/* 3 * Copyright © 2023-2024 Intel Corporation 4 */ 5 6#include <linux/string_choices.h> 7#include <linux/wordpart.h> 8 9#include "abi/guc_actions_sriov_abi.h" 10#include "abi/guc_klvs_abi.h" 11 12#include "regs/xe_gtt_defs.h" 13#include "regs/xe_guc_regs.h" 14 15#include "xe_bo.h" 16#include "xe_device.h" 17#include "xe_ggtt.h" 18#include "xe_gt.h" 19#include "xe_gt_sriov_pf_config.h" 20#include "xe_gt_sriov_pf_helpers.h" 21#include "xe_gt_sriov_pf_policy.h" 22#include "xe_gt_sriov_printk.h" 23#include "xe_guc.h" 24#include "xe_guc_buf.h" 25#include "xe_guc_ct.h" 26#include "xe_guc_db_mgr.h" 27#include "xe_guc_fwif.h" 28#include "xe_guc_id_mgr.h" 29#include "xe_guc_klv_helpers.h" 30#include "xe_guc_klv_thresholds_set.h" 31#include "xe_guc_submit.h" 32#include "xe_lmtt.h" 33#include "xe_map.h" 34#include "xe_migrate.h" 35#include "xe_sriov.h" 36#include "xe_ttm_vram_mgr.h" 37#include "xe_vram_types.h" 38#include "xe_wopcm.h" 39 40#define make_u64_from_u32(hi, lo) ((u64)((u64)(u32)(hi) << 32 | (u32)(lo))) 41 42/* 43 * Return: number of KLVs that were successfully parsed and saved, 44 * negative error code on failure. 45 */ 46static int guc_action_update_vf_cfg(struct xe_guc *guc, u32 vfid, 47 u64 addr, u32 size) 48{ 49 u32 request[] = { 50 GUC_ACTION_PF2GUC_UPDATE_VF_CFG, 51 vfid, 52 lower_32_bits(addr), 53 upper_32_bits(addr), 54 size, 55 }; 56 57 return xe_guc_ct_send_block(&guc->ct, request, ARRAY_SIZE(request)); 58} 59 60/* 61 * Return: 0 on success, negative error code on failure. 62 */ 63static int pf_send_vf_cfg_reset(struct xe_gt *gt, u32 vfid) 64{ 65 struct xe_guc *guc = >->uc.guc; 66 int ret; 67 68 ret = guc_action_update_vf_cfg(guc, vfid, 0, 0); 69 70 return ret <= 0 ? ret : -EPROTO; 71} 72 73/* 74 * Return: number of KLVs that were successfully parsed and saved, 75 * negative error code on failure. 76 */ 77static int pf_send_vf_buf_klvs(struct xe_gt *gt, u32 vfid, struct xe_guc_buf buf, u32 num_dwords) 78{ 79 struct xe_guc *guc = >->uc.guc; 80 81 return guc_action_update_vf_cfg(guc, vfid, xe_guc_buf_flush(buf), num_dwords); 82} 83 84/* 85 * Return: 0 on success, -ENOKEY if some KLVs were not updated, -EPROTO if reply was malformed, 86 * negative error code on failure. 87 */ 88static int pf_push_vf_buf_klvs(struct xe_gt *gt, unsigned int vfid, u32 num_klvs, 89 struct xe_guc_buf buf, u32 num_dwords) 90{ 91 int ret; 92 93 ret = pf_send_vf_buf_klvs(gt, vfid, buf, num_dwords); 94 95 if (ret != num_klvs) { 96 int err = ret < 0 ? ret : ret < num_klvs ? -ENOKEY : -EPROTO; 97 void *klvs = xe_guc_buf_cpu_ptr(buf); 98 struct drm_printer p = xe_gt_info_printer(gt); 99 char name[8]; 100 101 xe_gt_sriov_notice(gt, "Failed to push %s %u config KLV%s (%pe)\n", 102 xe_sriov_function_name(vfid, name, sizeof(name)), 103 num_klvs, str_plural(num_klvs), ERR_PTR(err)); 104 xe_guc_klv_print(klvs, num_dwords, &p); 105 return err; 106 } 107 108 if (IS_ENABLED(CONFIG_DRM_XE_DEBUG_SRIOV)) { 109 struct drm_printer p = xe_gt_dbg_printer(gt); 110 void *klvs = xe_guc_buf_cpu_ptr(buf); 111 char name[8]; 112 113 xe_gt_sriov_dbg(gt, "pushed %s config with %u KLV%s:\n", 114 xe_sriov_function_name(vfid, name, sizeof(name)), 115 num_klvs, str_plural(num_klvs)); 116 xe_guc_klv_print(klvs, num_dwords, &p); 117 } 118 119 return 0; 120} 121 122/* 123 * Return: 0 on success, -ENOBUFS if no free buffer for the indirect data, 124 * negative error code on failure. 125 */ 126static int pf_push_vf_cfg_klvs(struct xe_gt *gt, unsigned int vfid, u32 num_klvs, 127 const u32 *klvs, u32 num_dwords) 128{ 129 CLASS(xe_guc_buf_from_data, buf)(>->uc.guc.buf, klvs, num_dwords * sizeof(u32)); 130 131 xe_gt_assert(gt, num_klvs == xe_guc_klv_count(klvs, num_dwords)); 132 133 if (!xe_guc_buf_is_valid(buf)) 134 return -ENOBUFS; 135 136 return pf_push_vf_buf_klvs(gt, vfid, num_klvs, buf, num_dwords); 137} 138 139static int pf_push_vf_cfg_u32(struct xe_gt *gt, unsigned int vfid, u16 key, u32 value) 140{ 141 u32 klv[] = { 142 FIELD_PREP(GUC_KLV_0_KEY, key) | FIELD_PREP(GUC_KLV_0_LEN, 1), 143 value, 144 }; 145 146 return pf_push_vf_cfg_klvs(gt, vfid, 1, klv, ARRAY_SIZE(klv)); 147} 148 149static int pf_push_vf_cfg_u64(struct xe_gt *gt, unsigned int vfid, u16 key, u64 value) 150{ 151 u32 klv[] = { 152 FIELD_PREP(GUC_KLV_0_KEY, key) | FIELD_PREP(GUC_KLV_0_LEN, 2), 153 lower_32_bits(value), 154 upper_32_bits(value), 155 }; 156 157 return pf_push_vf_cfg_klvs(gt, vfid, 1, klv, ARRAY_SIZE(klv)); 158} 159 160static int pf_push_vf_cfg_ggtt(struct xe_gt *gt, unsigned int vfid, u64 start, u64 size) 161{ 162 u32 klvs[] = { 163 PREP_GUC_KLV_TAG(VF_CFG_GGTT_START), 164 lower_32_bits(start), 165 upper_32_bits(start), 166 PREP_GUC_KLV_TAG(VF_CFG_GGTT_SIZE), 167 lower_32_bits(size), 168 upper_32_bits(size), 169 }; 170 171 return pf_push_vf_cfg_klvs(gt, vfid, 2, klvs, ARRAY_SIZE(klvs)); 172} 173 174static int pf_push_vf_cfg_ctxs(struct xe_gt *gt, unsigned int vfid, u32 begin, u32 num) 175{ 176 u32 klvs[] = { 177 PREP_GUC_KLV_TAG(VF_CFG_BEGIN_CONTEXT_ID), 178 begin, 179 PREP_GUC_KLV_TAG(VF_CFG_NUM_CONTEXTS), 180 num, 181 }; 182 183 return pf_push_vf_cfg_klvs(gt, vfid, 2, klvs, ARRAY_SIZE(klvs)); 184} 185 186static int pf_push_vf_cfg_dbs(struct xe_gt *gt, unsigned int vfid, u32 begin, u32 num) 187{ 188 u32 klvs[] = { 189 PREP_GUC_KLV_TAG(VF_CFG_BEGIN_DOORBELL_ID), 190 begin, 191 PREP_GUC_KLV_TAG(VF_CFG_NUM_DOORBELLS), 192 num, 193 }; 194 195 return pf_push_vf_cfg_klvs(gt, vfid, 2, klvs, ARRAY_SIZE(klvs)); 196} 197 198static int pf_push_vf_cfg_exec_quantum(struct xe_gt *gt, unsigned int vfid, u32 *exec_quantum) 199{ 200 /* GuC will silently clamp values exceeding max */ 201 *exec_quantum = min_t(u32, *exec_quantum, GUC_KLV_VF_CFG_EXEC_QUANTUM_MAX_VALUE); 202 203 return pf_push_vf_cfg_u32(gt, vfid, GUC_KLV_VF_CFG_EXEC_QUANTUM_KEY, *exec_quantum); 204} 205 206static int pf_push_vf_cfg_preempt_timeout(struct xe_gt *gt, unsigned int vfid, u32 *preempt_timeout) 207{ 208 /* GuC will silently clamp values exceeding max */ 209 *preempt_timeout = min_t(u32, *preempt_timeout, GUC_KLV_VF_CFG_PREEMPT_TIMEOUT_MAX_VALUE); 210 211 return pf_push_vf_cfg_u32(gt, vfid, GUC_KLV_VF_CFG_PREEMPT_TIMEOUT_KEY, *preempt_timeout); 212} 213 214static int pf_push_vf_cfg_sched_priority(struct xe_gt *gt, unsigned int vfid, u32 priority) 215{ 216 return pf_push_vf_cfg_u32(gt, vfid, GUC_KLV_VF_CFG_SCHED_PRIORITY_KEY, priority); 217} 218 219static int pf_push_vf_cfg_lmem(struct xe_gt *gt, unsigned int vfid, u64 size) 220{ 221 return pf_push_vf_cfg_u64(gt, vfid, GUC_KLV_VF_CFG_LMEM_SIZE_KEY, size); 222} 223 224static int pf_push_vf_cfg_threshold(struct xe_gt *gt, unsigned int vfid, 225 enum xe_guc_klv_threshold_index index, u32 value) 226{ 227 u32 key = xe_guc_klv_threshold_index_to_key(index); 228 229 xe_gt_assert(gt, key); 230 return pf_push_vf_cfg_u32(gt, vfid, key, value); 231} 232 233static struct xe_gt_sriov_config *pf_pick_vf_config(struct xe_gt *gt, unsigned int vfid) 234{ 235 xe_gt_assert(gt, IS_SRIOV_PF(gt_to_xe(gt))); 236 xe_gt_assert(gt, vfid <= xe_sriov_pf_get_totalvfs(gt_to_xe(gt))); 237 lockdep_assert_held(xe_gt_sriov_pf_master_mutex(gt)); 238 239 return >->sriov.pf.vfs[vfid].config; 240} 241 242/* Return: number of configuration dwords written */ 243static u32 encode_ggtt(u32 *cfg, u64 start, u64 size, bool details) 244{ 245 u32 n = 0; 246 247 if (details) { 248 cfg[n++] = PREP_GUC_KLV_TAG(VF_CFG_GGTT_START); 249 cfg[n++] = lower_32_bits(start); 250 cfg[n++] = upper_32_bits(start); 251 } 252 253 cfg[n++] = PREP_GUC_KLV_TAG(VF_CFG_GGTT_SIZE); 254 cfg[n++] = lower_32_bits(size); 255 cfg[n++] = upper_32_bits(size); 256 257 return n; 258} 259 260/* Return: number of configuration dwords written */ 261static u32 encode_config_ggtt(u32 *cfg, const struct xe_gt_sriov_config *config, bool details) 262{ 263 struct xe_ggtt_node *node = config->ggtt_region; 264 265 if (!xe_ggtt_node_allocated(node)) 266 return 0; 267 268 return encode_ggtt(cfg, node->base.start, node->base.size, details); 269} 270 271/* Return: number of configuration dwords written */ 272static u32 encode_config(u32 *cfg, const struct xe_gt_sriov_config *config, bool details) 273{ 274 u32 n = 0; 275 276 n += encode_config_ggtt(cfg, config, details); 277 278 if (details && config->num_ctxs) { 279 cfg[n++] = PREP_GUC_KLV_TAG(VF_CFG_BEGIN_CONTEXT_ID); 280 cfg[n++] = config->begin_ctx; 281 } 282 283 cfg[n++] = PREP_GUC_KLV_TAG(VF_CFG_NUM_CONTEXTS); 284 cfg[n++] = config->num_ctxs; 285 286 if (details && config->num_dbs) { 287 cfg[n++] = PREP_GUC_KLV_TAG(VF_CFG_BEGIN_DOORBELL_ID); 288 cfg[n++] = config->begin_db; 289 } 290 291 cfg[n++] = PREP_GUC_KLV_TAG(VF_CFG_NUM_DOORBELLS); 292 cfg[n++] = config->num_dbs; 293 294 if (config->lmem_obj) { 295 cfg[n++] = PREP_GUC_KLV_TAG(VF_CFG_LMEM_SIZE); 296 cfg[n++] = lower_32_bits(xe_bo_size(config->lmem_obj)); 297 cfg[n++] = upper_32_bits(xe_bo_size(config->lmem_obj)); 298 } 299 300 cfg[n++] = PREP_GUC_KLV_TAG(VF_CFG_EXEC_QUANTUM); 301 cfg[n++] = config->exec_quantum; 302 303 cfg[n++] = PREP_GUC_KLV_TAG(VF_CFG_PREEMPT_TIMEOUT); 304 cfg[n++] = config->preempt_timeout; 305 306#define encode_threshold_config(TAG, ...) ({ \ 307 cfg[n++] = PREP_GUC_KLV_TAG(VF_CFG_THRESHOLD_##TAG); \ 308 cfg[n++] = config->thresholds[MAKE_XE_GUC_KLV_THRESHOLD_INDEX(TAG)]; \ 309}); 310 311 MAKE_XE_GUC_KLV_THRESHOLDS_SET(encode_threshold_config); 312#undef encode_threshold_config 313 314 return n; 315} 316 317static int pf_push_full_vf_config(struct xe_gt *gt, unsigned int vfid) 318{ 319 struct xe_gt_sriov_config *config = pf_pick_vf_config(gt, vfid); 320 u32 max_cfg_dwords = xe_guc_buf_cache_dwords(>->uc.guc.buf); 321 CLASS(xe_guc_buf, buf)(>->uc.guc.buf, max_cfg_dwords); 322 u32 num_dwords; 323 int num_klvs; 324 u32 *cfg; 325 int err; 326 327 if (!xe_guc_buf_is_valid(buf)) 328 return -ENOBUFS; 329 330 cfg = xe_guc_buf_cpu_ptr(buf); 331 num_dwords = encode_config(cfg, config, true); 332 xe_gt_assert(gt, num_dwords <= max_cfg_dwords); 333 334 if (xe_gt_is_media_type(gt)) { 335 struct xe_gt *primary = gt->tile->primary_gt; 336 struct xe_gt_sriov_config *other = pf_pick_vf_config(primary, vfid); 337 338 /* media-GT will never include a GGTT config */ 339 xe_gt_assert(gt, !encode_config_ggtt(cfg + num_dwords, config, true)); 340 341 /* the GGTT config must be taken from the primary-GT instead */ 342 num_dwords += encode_config_ggtt(cfg + num_dwords, other, true); 343 } 344 xe_gt_assert(gt, num_dwords <= max_cfg_dwords); 345 346 if (vfid == PFID) { 347 u64 ggtt_start = xe_wopcm_size(gt_to_xe(gt)); 348 u64 ggtt_size = gt_to_tile(gt)->mem.ggtt->size - ggtt_start; 349 350 /* plain PF config data will never include a real GGTT region */ 351 xe_gt_assert(gt, !encode_config_ggtt(cfg + num_dwords, config, true)); 352 353 /* fake PF GGTT config covers full GGTT range except reserved WOPCM */ 354 num_dwords += encode_ggtt(cfg + num_dwords, ggtt_start, ggtt_size, true); 355 } 356 357 num_klvs = xe_guc_klv_count(cfg, num_dwords); 358 err = pf_push_vf_buf_klvs(gt, vfid, num_klvs, buf, num_dwords); 359 360 return err; 361} 362 363static int pf_push_vf_cfg(struct xe_gt *gt, unsigned int vfid, bool reset) 364{ 365 int err = 0; 366 367 xe_gt_assert(gt, vfid); 368 lockdep_assert_held(xe_gt_sriov_pf_master_mutex(gt)); 369 370 if (reset) 371 err = pf_send_vf_cfg_reset(gt, vfid); 372 if (!err) 373 err = pf_push_full_vf_config(gt, vfid); 374 375 return err; 376} 377 378static int pf_refresh_vf_cfg(struct xe_gt *gt, unsigned int vfid) 379{ 380 return pf_push_vf_cfg(gt, vfid, true); 381} 382 383static u64 pf_get_ggtt_alignment(struct xe_gt *gt) 384{ 385 struct xe_device *xe = gt_to_xe(gt); 386 387 return IS_DGFX(xe) && xe->info.vram_flags & XE_VRAM_FLAGS_NEED64K ? SZ_64K : SZ_4K; 388} 389 390static u64 pf_get_min_spare_ggtt(struct xe_gt *gt) 391{ 392 /* XXX: preliminary */ 393 return IS_ENABLED(CONFIG_DRM_XE_DEBUG_SRIOV) ? 394 pf_get_ggtt_alignment(gt) : SZ_64M; 395} 396 397static u64 pf_get_spare_ggtt(struct xe_gt *gt) 398{ 399 u64 spare; 400 401 xe_gt_assert(gt, xe_gt_is_main_type(gt)); 402 xe_gt_assert(gt, IS_SRIOV_PF(gt_to_xe(gt))); 403 lockdep_assert_held(xe_gt_sriov_pf_master_mutex(gt)); 404 405 spare = gt->sriov.pf.spare.ggtt_size; 406 spare = max_t(u64, spare, pf_get_min_spare_ggtt(gt)); 407 408 return spare; 409} 410 411static int pf_set_spare_ggtt(struct xe_gt *gt, u64 size) 412{ 413 xe_gt_assert(gt, xe_gt_is_main_type(gt)); 414 xe_gt_assert(gt, IS_SRIOV_PF(gt_to_xe(gt))); 415 lockdep_assert_held(xe_gt_sriov_pf_master_mutex(gt)); 416 417 if (size && size < pf_get_min_spare_ggtt(gt)) 418 return -EINVAL; 419 420 size = round_up(size, pf_get_ggtt_alignment(gt)); 421 gt->sriov.pf.spare.ggtt_size = size; 422 423 return 0; 424} 425 426static int pf_distribute_config_ggtt(struct xe_tile *tile, unsigned int vfid, u64 start, u64 size) 427{ 428 int err, err2 = 0; 429 430 err = pf_push_vf_cfg_ggtt(tile->primary_gt, vfid, start, size); 431 432 if (tile->media_gt && !err) 433 err2 = pf_push_vf_cfg_ggtt(tile->media_gt, vfid, start, size); 434 435 return err ?: err2; 436} 437 438static void pf_release_ggtt(struct xe_tile *tile, struct xe_ggtt_node *node) 439{ 440 if (xe_ggtt_node_allocated(node)) { 441 /* 442 * explicit GGTT PTE assignment to the PF using xe_ggtt_assign() 443 * is redundant, as PTE will be implicitly re-assigned to PF by 444 * the xe_ggtt_clear() called by below xe_ggtt_remove_node(). 445 */ 446 xe_ggtt_node_remove(node, false); 447 } else { 448 xe_ggtt_node_fini(node); 449 } 450} 451 452static void pf_release_vf_config_ggtt(struct xe_gt *gt, struct xe_gt_sriov_config *config) 453{ 454 pf_release_ggtt(gt_to_tile(gt), config->ggtt_region); 455 config->ggtt_region = NULL; 456} 457 458static int pf_provision_vf_ggtt(struct xe_gt *gt, unsigned int vfid, u64 size) 459{ 460 struct xe_gt_sriov_config *config = pf_pick_vf_config(gt, vfid); 461 struct xe_ggtt_node *node; 462 struct xe_tile *tile = gt_to_tile(gt); 463 struct xe_ggtt *ggtt = tile->mem.ggtt; 464 u64 alignment = pf_get_ggtt_alignment(gt); 465 int err; 466 467 xe_gt_assert(gt, vfid); 468 xe_gt_assert(gt, xe_gt_is_main_type(gt)); 469 xe_gt_assert(gt, IS_SRIOV_PF(gt_to_xe(gt))); 470 471 size = round_up(size, alignment); 472 473 if (xe_ggtt_node_allocated(config->ggtt_region)) { 474 err = pf_distribute_config_ggtt(tile, vfid, 0, 0); 475 if (unlikely(err)) 476 return err; 477 478 pf_release_vf_config_ggtt(gt, config); 479 480 err = pf_refresh_vf_cfg(gt, vfid); 481 if (unlikely(err)) 482 return err; 483 } 484 xe_gt_assert(gt, !xe_ggtt_node_allocated(config->ggtt_region)); 485 486 if (!size) 487 return 0; 488 489 node = xe_ggtt_node_init(ggtt); 490 if (IS_ERR(node)) 491 return PTR_ERR(node); 492 493 err = xe_ggtt_node_insert(node, size, alignment); 494 if (unlikely(err)) 495 goto err; 496 497 xe_ggtt_assign(node, vfid); 498 xe_gt_sriov_dbg_verbose(gt, "VF%u assigned GGTT %llx-%llx\n", 499 vfid, node->base.start, node->base.start + node->base.size - 1); 500 501 err = pf_distribute_config_ggtt(gt->tile, vfid, node->base.start, node->base.size); 502 if (unlikely(err)) 503 goto err; 504 505 config->ggtt_region = node; 506 return 0; 507err: 508 pf_release_ggtt(tile, node); 509 return err; 510} 511 512static u64 pf_get_vf_config_ggtt(struct xe_gt *gt, unsigned int vfid) 513{ 514 struct xe_gt_sriov_config *config = pf_pick_vf_config(gt, vfid); 515 struct xe_ggtt_node *node = config->ggtt_region; 516 517 xe_gt_assert(gt, xe_gt_is_main_type(gt)); 518 return xe_ggtt_node_allocated(node) ? node->base.size : 0; 519} 520 521/** 522 * xe_gt_sriov_pf_config_get_ggtt - Query size of GGTT address space of the VF. 523 * @gt: the &xe_gt 524 * @vfid: the VF identifier 525 * 526 * This function can only be called on PF. 527 * 528 * Return: size of the VF's assigned (or PF's spare) GGTT address space. 529 */ 530u64 xe_gt_sriov_pf_config_get_ggtt(struct xe_gt *gt, unsigned int vfid) 531{ 532 u64 size; 533 534 mutex_lock(xe_gt_sriov_pf_master_mutex(gt)); 535 if (vfid) 536 size = pf_get_vf_config_ggtt(gt_to_tile(gt)->primary_gt, vfid); 537 else 538 size = pf_get_spare_ggtt(gt_to_tile(gt)->primary_gt); 539 mutex_unlock(xe_gt_sriov_pf_master_mutex(gt)); 540 541 return size; 542} 543 544static int pf_config_set_u64_done(struct xe_gt *gt, unsigned int vfid, u64 value, 545 u64 actual, const char *what, int err) 546{ 547 char size[10]; 548 char name[8]; 549 550 xe_sriov_function_name(vfid, name, sizeof(name)); 551 552 if (unlikely(err)) { 553 string_get_size(value, 1, STRING_UNITS_2, size, sizeof(size)); 554 xe_gt_sriov_notice(gt, "Failed to provision %s with %llu (%s) %s (%pe)\n", 555 name, value, size, what, ERR_PTR(err)); 556 string_get_size(actual, 1, STRING_UNITS_2, size, sizeof(size)); 557 xe_gt_sriov_info(gt, "%s provisioning remains at %llu (%s) %s\n", 558 name, actual, size, what); 559 return err; 560 } 561 562 /* the actual value may have changed during provisioning */ 563 string_get_size(actual, 1, STRING_UNITS_2, size, sizeof(size)); 564 xe_gt_sriov_info(gt, "%s provisioned with %llu (%s) %s\n", 565 name, actual, size, what); 566 return 0; 567} 568 569/** 570 * xe_gt_sriov_pf_config_set_ggtt - Provision VF with GGTT space. 571 * @gt: the &xe_gt (can't be media) 572 * @vfid: the VF identifier 573 * @size: requested GGTT size 574 * 575 * If &vfid represents PF, then function will change PF's spare GGTT config. 576 * 577 * This function can only be called on PF. 578 * 579 * Return: 0 on success or a negative error code on failure. 580 */ 581int xe_gt_sriov_pf_config_set_ggtt(struct xe_gt *gt, unsigned int vfid, u64 size) 582{ 583 int err; 584 585 xe_gt_assert(gt, xe_gt_is_main_type(gt)); 586 587 mutex_lock(xe_gt_sriov_pf_master_mutex(gt)); 588 if (vfid) 589 err = pf_provision_vf_ggtt(gt, vfid, size); 590 else 591 err = pf_set_spare_ggtt(gt, size); 592 mutex_unlock(xe_gt_sriov_pf_master_mutex(gt)); 593 594 return pf_config_set_u64_done(gt, vfid, size, 595 xe_gt_sriov_pf_config_get_ggtt(gt, vfid), 596 vfid ? "GGTT" : "spare GGTT", err); 597} 598 599static int pf_config_bulk_set_u64_done(struct xe_gt *gt, unsigned int first, unsigned int num_vfs, 600 u64 value, u64 (*get)(struct xe_gt*, unsigned int), 601 const char *what, unsigned int last, int err) 602{ 603 char size[10]; 604 605 xe_gt_assert(gt, first); 606 xe_gt_assert(gt, num_vfs); 607 xe_gt_assert(gt, first <= last); 608 609 if (num_vfs == 1) 610 return pf_config_set_u64_done(gt, first, value, get(gt, first), what, err); 611 612 if (unlikely(err)) { 613 xe_gt_sriov_notice(gt, "Failed to bulk provision VF%u..VF%u with %s\n", 614 first, first + num_vfs - 1, what); 615 if (last > first) 616 pf_config_bulk_set_u64_done(gt, first, last - first, value, 617 get, what, last, 0); 618 return pf_config_set_u64_done(gt, last, value, get(gt, last), what, err); 619 } 620 621 /* pick actual value from first VF - bulk provisioning shall be equal across all VFs */ 622 value = get(gt, first); 623 string_get_size(value, 1, STRING_UNITS_2, size, sizeof(size)); 624 xe_gt_sriov_info(gt, "VF%u..VF%u provisioned with %llu (%s) %s\n", 625 first, first + num_vfs - 1, value, size, what); 626 return 0; 627} 628 629/** 630 * xe_gt_sriov_pf_config_bulk_set_ggtt - Provision many VFs with GGTT. 631 * @gt: the &xe_gt (can't be media) 632 * @vfid: starting VF identifier (can't be 0) 633 * @num_vfs: number of VFs to provision 634 * @size: requested GGTT size 635 * 636 * This function can only be called on PF. 637 * 638 * Return: 0 on success or a negative error code on failure. 639 */ 640int xe_gt_sriov_pf_config_bulk_set_ggtt(struct xe_gt *gt, unsigned int vfid, 641 unsigned int num_vfs, u64 size) 642{ 643 unsigned int n; 644 int err = 0; 645 646 xe_gt_assert(gt, vfid); 647 xe_gt_assert(gt, xe_gt_is_main_type(gt)); 648 649 if (!num_vfs) 650 return 0; 651 652 mutex_lock(xe_gt_sriov_pf_master_mutex(gt)); 653 for (n = vfid; n < vfid + num_vfs; n++) { 654 err = pf_provision_vf_ggtt(gt, n, size); 655 if (err) 656 break; 657 } 658 mutex_unlock(xe_gt_sriov_pf_master_mutex(gt)); 659 660 return pf_config_bulk_set_u64_done(gt, vfid, num_vfs, size, 661 xe_gt_sriov_pf_config_get_ggtt, 662 "GGTT", n, err); 663} 664 665/* Return: size of the largest continuous GGTT region */ 666static u64 pf_get_max_ggtt(struct xe_gt *gt) 667{ 668 struct xe_ggtt *ggtt = gt_to_tile(gt)->mem.ggtt; 669 u64 alignment = pf_get_ggtt_alignment(gt); 670 u64 spare = pf_get_spare_ggtt(gt); 671 u64 max_hole; 672 673 max_hole = xe_ggtt_largest_hole(ggtt, alignment, &spare); 674 675 xe_gt_sriov_dbg_verbose(gt, "HOLE max %lluK reserved %lluK\n", 676 max_hole / SZ_1K, spare / SZ_1K); 677 return max_hole > spare ? max_hole - spare : 0; 678} 679 680static u64 pf_estimate_fair_ggtt(struct xe_gt *gt, unsigned int num_vfs) 681{ 682 u64 available = pf_get_max_ggtt(gt); 683 u64 alignment = pf_get_ggtt_alignment(gt); 684 u64 fair; 685 686 /* 687 * To simplify the logic we only look at single largest GGTT region 688 * as that will be always the best fit for 1 VF case, and most likely 689 * will also nicely cover other cases where VFs are provisioned on the 690 * fresh and idle PF driver, without any stale GGTT allocations spread 691 * in the middle of the full GGTT range. 692 */ 693 694 fair = div_u64(available, num_vfs); 695 fair = ALIGN_DOWN(fair, alignment); 696 xe_gt_sriov_dbg_verbose(gt, "GGTT available(%lluK) fair(%u x %lluK)\n", 697 available / SZ_1K, num_vfs, fair / SZ_1K); 698 return fair; 699} 700 701static u64 pf_profile_fair_ggtt(struct xe_gt *gt, unsigned int num_vfs) 702{ 703 bool admin_only_pf = xe_sriov_pf_admin_only(gt_to_xe(gt)); 704 u64 shareable = ALIGN_DOWN(GUC_GGTT_TOP, SZ_512M); 705 u64 alignment = pf_get_ggtt_alignment(gt); 706 707 if (admin_only_pf && num_vfs == 1) 708 return ALIGN_DOWN(shareable, alignment); 709 710 /* need to hardcode due to ~512M of GGTT being reserved */ 711 if (num_vfs > 56) 712 return SZ_64M - SZ_8M; 713 714 return rounddown_pow_of_two(div_u64(shareable, num_vfs)); 715} 716 717/** 718 * xe_gt_sriov_pf_config_set_fair_ggtt - Provision many VFs with fair GGTT. 719 * @gt: the &xe_gt (can't be media) 720 * @vfid: starting VF identifier (can't be 0) 721 * @num_vfs: number of VFs to provision 722 * 723 * This function can only be called on PF. 724 * 725 * Return: 0 on success or a negative error code on failure. 726 */ 727int xe_gt_sriov_pf_config_set_fair_ggtt(struct xe_gt *gt, unsigned int vfid, 728 unsigned int num_vfs) 729{ 730 u64 profile = pf_profile_fair_ggtt(gt, num_vfs); 731 u64 fair; 732 733 xe_gt_assert(gt, vfid); 734 xe_gt_assert(gt, num_vfs); 735 xe_gt_assert(gt, xe_gt_is_main_type(gt)); 736 737 mutex_lock(xe_gt_sriov_pf_master_mutex(gt)); 738 fair = pf_estimate_fair_ggtt(gt, num_vfs); 739 mutex_unlock(xe_gt_sriov_pf_master_mutex(gt)); 740 741 if (!fair) 742 return -ENOSPC; 743 744 fair = min(fair, profile); 745 if (fair < profile) 746 xe_gt_sriov_info(gt, "Using non-profile provisioning (%s %llu vs %llu)\n", 747 "GGTT", fair, profile); 748 749 return xe_gt_sriov_pf_config_bulk_set_ggtt(gt, vfid, num_vfs, fair); 750} 751 752/** 753 * xe_gt_sriov_pf_config_ggtt_save() - Save a VF provisioned GGTT data into a buffer. 754 * @gt: the &xe_gt 755 * @vfid: VF identifier (can't be 0) 756 * @buf: the GGTT data destination buffer (or NULL to query the buf size) 757 * @size: the size of the buffer (or 0 to query the buf size) 758 * 759 * This function can only be called on PF. 760 * 761 * Return: size of the buffer needed to save GGTT data if querying, 762 * 0 on successful save or a negative error code on failure. 763 */ 764ssize_t xe_gt_sriov_pf_config_ggtt_save(struct xe_gt *gt, unsigned int vfid, 765 void *buf, size_t size) 766{ 767 struct xe_ggtt_node *node; 768 769 xe_gt_assert(gt, IS_SRIOV_PF(gt_to_xe(gt))); 770 xe_gt_assert(gt, vfid); 771 xe_gt_assert(gt, !(!buf ^ !size)); 772 773 guard(mutex)(xe_gt_sriov_pf_master_mutex(gt)); 774 775 node = pf_pick_vf_config(gt, vfid)->ggtt_region; 776 777 if (!buf) 778 return xe_ggtt_node_pt_size(node); 779 780 return xe_ggtt_node_save(node, buf, size, vfid); 781} 782 783/** 784 * xe_gt_sriov_pf_config_ggtt_restore() - Restore a VF provisioned GGTT data from a buffer. 785 * @gt: the &xe_gt 786 * @vfid: VF identifier (can't be 0) 787 * @buf: the GGTT data source buffer 788 * @size: the size of the buffer 789 * 790 * This function can only be called on PF. 791 * 792 * Return: 0 on success or a negative error code on failure. 793 */ 794int xe_gt_sriov_pf_config_ggtt_restore(struct xe_gt *gt, unsigned int vfid, 795 const void *buf, size_t size) 796{ 797 struct xe_ggtt_node *node; 798 799 xe_gt_assert(gt, IS_SRIOV_PF(gt_to_xe(gt))); 800 xe_gt_assert(gt, vfid); 801 802 guard(mutex)(xe_gt_sriov_pf_master_mutex(gt)); 803 804 node = pf_pick_vf_config(gt, vfid)->ggtt_region; 805 806 return xe_ggtt_node_load(node, buf, size, vfid); 807} 808 809static u32 pf_get_min_spare_ctxs(struct xe_gt *gt) 810{ 811 /* XXX: preliminary */ 812 return IS_ENABLED(CONFIG_DRM_XE_DEBUG_SRIOV) ? 813 hweight64(gt->info.engine_mask) : SZ_256; 814} 815 816static u32 pf_get_spare_ctxs(struct xe_gt *gt) 817{ 818 u32 spare; 819 820 xe_gt_assert(gt, IS_SRIOV_PF(gt_to_xe(gt))); 821 lockdep_assert_held(xe_gt_sriov_pf_master_mutex(gt)); 822 823 spare = gt->sriov.pf.spare.num_ctxs; 824 spare = max_t(u32, spare, pf_get_min_spare_ctxs(gt)); 825 826 return spare; 827} 828 829static int pf_set_spare_ctxs(struct xe_gt *gt, u32 spare) 830{ 831 xe_gt_assert(gt, IS_SRIOV_PF(gt_to_xe(gt))); 832 lockdep_assert_held(xe_gt_sriov_pf_master_mutex(gt)); 833 834 if (spare > GUC_ID_MAX) 835 return -EINVAL; 836 837 if (spare && spare < pf_get_min_spare_ctxs(gt)) 838 return -EINVAL; 839 840 gt->sriov.pf.spare.num_ctxs = spare; 841 842 return 0; 843} 844 845/* Return: start ID or negative error code on failure */ 846static int pf_reserve_ctxs(struct xe_gt *gt, u32 num) 847{ 848 struct xe_guc_id_mgr *idm = >->uc.guc.submission_state.idm; 849 unsigned int spare = pf_get_spare_ctxs(gt); 850 851 return xe_guc_id_mgr_reserve(idm, num, spare); 852} 853 854static void pf_release_ctxs(struct xe_gt *gt, u32 start, u32 num) 855{ 856 struct xe_guc_id_mgr *idm = >->uc.guc.submission_state.idm; 857 858 if (num) 859 xe_guc_id_mgr_release(idm, start, num); 860} 861 862static void pf_release_config_ctxs(struct xe_gt *gt, struct xe_gt_sriov_config *config) 863{ 864 lockdep_assert_held(xe_gt_sriov_pf_master_mutex(gt)); 865 866 pf_release_ctxs(gt, config->begin_ctx, config->num_ctxs); 867 config->begin_ctx = 0; 868 config->num_ctxs = 0; 869} 870 871static int pf_provision_vf_ctxs(struct xe_gt *gt, unsigned int vfid, u32 num_ctxs) 872{ 873 struct xe_gt_sriov_config *config = pf_pick_vf_config(gt, vfid); 874 int ret; 875 876 xe_gt_assert(gt, vfid); 877 878 if (num_ctxs > GUC_ID_MAX) 879 return -EINVAL; 880 881 if (config->num_ctxs) { 882 ret = pf_push_vf_cfg_ctxs(gt, vfid, 0, 0); 883 if (unlikely(ret)) 884 return ret; 885 886 pf_release_config_ctxs(gt, config); 887 888 ret = pf_refresh_vf_cfg(gt, vfid); 889 if (unlikely(ret)) 890 return ret; 891 } 892 893 if (!num_ctxs) 894 return 0; 895 896 ret = pf_reserve_ctxs(gt, num_ctxs); 897 if (unlikely(ret < 0)) 898 return ret; 899 900 config->begin_ctx = ret; 901 config->num_ctxs = num_ctxs; 902 903 ret = pf_push_vf_cfg_ctxs(gt, vfid, config->begin_ctx, config->num_ctxs); 904 if (unlikely(ret)) { 905 pf_release_config_ctxs(gt, config); 906 return ret; 907 } 908 909 xe_gt_sriov_dbg_verbose(gt, "VF%u contexts %u-%u\n", 910 vfid, config->begin_ctx, config->begin_ctx + config->num_ctxs - 1); 911 return 0; 912} 913 914static u32 pf_get_vf_config_ctxs(struct xe_gt *gt, unsigned int vfid) 915{ 916 struct xe_gt_sriov_config *config = pf_pick_vf_config(gt, vfid); 917 918 return config->num_ctxs; 919} 920 921/** 922 * xe_gt_sriov_pf_config_get_ctxs - Get VF's GuC contexts IDs quota. 923 * @gt: the &xe_gt 924 * @vfid: the VF identifier 925 * 926 * This function can only be called on PF. 927 * If &vfid represents a PF then number of PF's spare GuC context IDs is returned. 928 * 929 * Return: VF's quota (or PF's spare). 930 */ 931u32 xe_gt_sriov_pf_config_get_ctxs(struct xe_gt *gt, unsigned int vfid) 932{ 933 u32 num_ctxs; 934 935 mutex_lock(xe_gt_sriov_pf_master_mutex(gt)); 936 if (vfid) 937 num_ctxs = pf_get_vf_config_ctxs(gt, vfid); 938 else 939 num_ctxs = pf_get_spare_ctxs(gt); 940 mutex_unlock(xe_gt_sriov_pf_master_mutex(gt)); 941 942 return num_ctxs; 943} 944 945static const char *no_unit(u32 unused) 946{ 947 return ""; 948} 949 950static const char *spare_unit(u32 unused) 951{ 952 return " spare"; 953} 954 955static int pf_config_set_u32_done(struct xe_gt *gt, unsigned int vfid, u32 value, u32 actual, 956 const char *what, const char *(*unit)(u32), int err) 957{ 958 char name[8]; 959 960 xe_sriov_function_name(vfid, name, sizeof(name)); 961 962 if (unlikely(err)) { 963 xe_gt_sriov_notice(gt, "Failed to provision %s with %u%s %s (%pe)\n", 964 name, value, unit(value), what, ERR_PTR(err)); 965 xe_gt_sriov_info(gt, "%s provisioning remains at %u%s %s\n", 966 name, actual, unit(actual), what); 967 return err; 968 } 969 970 /* the actual value may have changed during provisioning */ 971 xe_gt_sriov_info(gt, "%s provisioned with %u%s %s\n", 972 name, actual, unit(actual), what); 973 return 0; 974} 975 976/** 977 * xe_gt_sriov_pf_config_set_ctxs - Configure GuC contexts IDs quota for the VF. 978 * @gt: the &xe_gt 979 * @vfid: the VF identifier 980 * @num_ctxs: requested number of GuC contexts IDs (0 to release) 981 * 982 * This function can only be called on PF. 983 * 984 * Return: 0 on success or a negative error code on failure. 985 */ 986int xe_gt_sriov_pf_config_set_ctxs(struct xe_gt *gt, unsigned int vfid, u32 num_ctxs) 987{ 988 int err; 989 990 mutex_lock(xe_gt_sriov_pf_master_mutex(gt)); 991 if (vfid) 992 err = pf_provision_vf_ctxs(gt, vfid, num_ctxs); 993 else 994 err = pf_set_spare_ctxs(gt, num_ctxs); 995 mutex_unlock(xe_gt_sriov_pf_master_mutex(gt)); 996 997 return pf_config_set_u32_done(gt, vfid, num_ctxs, 998 xe_gt_sriov_pf_config_get_ctxs(gt, vfid), 999 "GuC context IDs", vfid ? no_unit : spare_unit, err); 1000} 1001 1002static int pf_config_bulk_set_u32_done(struct xe_gt *gt, unsigned int first, unsigned int num_vfs, 1003 u32 value, u32 (*get)(struct xe_gt*, unsigned int), 1004 const char *what, const char *(*unit)(u32), 1005 unsigned int last, int err) 1006{ 1007 char name[8]; 1008 1009 xe_gt_assert(gt, num_vfs); 1010 xe_gt_assert(gt, first <= last); 1011 1012 if (num_vfs == 1) 1013 return pf_config_set_u32_done(gt, first, value, get(gt, first), what, unit, err); 1014 1015 if (unlikely(err)) { 1016 xe_gt_sriov_notice(gt, "Failed to bulk provision %s..VF%u with %s\n", 1017 xe_sriov_function_name(first, name, sizeof(name)), 1018 first + num_vfs - 1, what); 1019 if (last > first) 1020 pf_config_bulk_set_u32_done(gt, first, last - first, value, 1021 get, what, unit, last, 0); 1022 return pf_config_set_u32_done(gt, last, value, get(gt, last), what, unit, err); 1023 } 1024 1025 /* pick actual value from first VF - bulk provisioning shall be equal across all VFs */ 1026 value = get(gt, first); 1027 xe_gt_sriov_info(gt, "%s..VF%u provisioned with %u%s %s\n", 1028 xe_sriov_function_name(first, name, sizeof(name)), 1029 first + num_vfs - 1, value, unit(value), what); 1030 return 0; 1031} 1032 1033/** 1034 * xe_gt_sriov_pf_config_bulk_set_ctxs - Provision many VFs with GuC context IDs. 1035 * @gt: the &xe_gt 1036 * @vfid: starting VF identifier 1037 * @num_vfs: number of VFs to provision 1038 * @num_ctxs: requested number of GuC contexts IDs (0 to release) 1039 * 1040 * This function can only be called on PF. 1041 * 1042 * Return: 0 on success or a negative error code on failure. 1043 */ 1044int xe_gt_sriov_pf_config_bulk_set_ctxs(struct xe_gt *gt, unsigned int vfid, 1045 unsigned int num_vfs, u32 num_ctxs) 1046{ 1047 unsigned int n; 1048 int err = 0; 1049 1050 xe_gt_assert(gt, vfid); 1051 1052 if (!num_vfs) 1053 return 0; 1054 1055 mutex_lock(xe_gt_sriov_pf_master_mutex(gt)); 1056 for (n = vfid; n < vfid + num_vfs; n++) { 1057 err = pf_provision_vf_ctxs(gt, n, num_ctxs); 1058 if (err) 1059 break; 1060 } 1061 mutex_unlock(xe_gt_sriov_pf_master_mutex(gt)); 1062 1063 return pf_config_bulk_set_u32_done(gt, vfid, num_vfs, num_ctxs, 1064 xe_gt_sriov_pf_config_get_ctxs, 1065 "GuC context IDs", no_unit, n, err); 1066} 1067 1068static u32 pf_profile_fair_ctxs(struct xe_gt *gt, unsigned int num_vfs) 1069{ 1070 bool admin_only_pf = xe_sriov_pf_admin_only(gt_to_xe(gt)); 1071 1072 if (admin_only_pf && num_vfs == 1) 1073 return ALIGN_DOWN(GUC_ID_MAX, SZ_1K); 1074 1075 return rounddown_pow_of_two(GUC_ID_MAX / num_vfs); 1076} 1077 1078static u32 pf_estimate_fair_ctxs(struct xe_gt *gt, unsigned int num_vfs) 1079{ 1080 struct xe_guc_id_mgr *idm = >->uc.guc.submission_state.idm; 1081 u32 spare = pf_get_spare_ctxs(gt); 1082 u32 fair = (idm->total - spare) / num_vfs; 1083 int ret; 1084 1085 for (; fair; --fair) { 1086 ret = xe_guc_id_mgr_reserve(idm, fair * num_vfs, spare); 1087 if (ret < 0) 1088 continue; 1089 xe_guc_id_mgr_release(idm, ret, fair * num_vfs); 1090 break; 1091 } 1092 1093 xe_gt_sriov_dbg_verbose(gt, "contexts fair(%u x %u)\n", num_vfs, fair); 1094 return fair; 1095} 1096 1097/** 1098 * xe_gt_sriov_pf_config_set_fair_ctxs - Provision many VFs with fair GuC context IDs. 1099 * @gt: the &xe_gt 1100 * @vfid: starting VF identifier (can't be 0) 1101 * @num_vfs: number of VFs to provision (can't be 0) 1102 * 1103 * This function can only be called on PF. 1104 * 1105 * Return: 0 on success or a negative error code on failure. 1106 */ 1107int xe_gt_sriov_pf_config_set_fair_ctxs(struct xe_gt *gt, unsigned int vfid, 1108 unsigned int num_vfs) 1109{ 1110 u32 profile = pf_profile_fair_ctxs(gt, num_vfs); 1111 u32 fair; 1112 1113 xe_gt_assert(gt, vfid); 1114 xe_gt_assert(gt, num_vfs); 1115 1116 mutex_lock(xe_gt_sriov_pf_master_mutex(gt)); 1117 fair = pf_estimate_fair_ctxs(gt, num_vfs); 1118 mutex_unlock(xe_gt_sriov_pf_master_mutex(gt)); 1119 1120 if (!fair) 1121 return -ENOSPC; 1122 1123 fair = min(fair, profile); 1124 if (fair < profile) 1125 xe_gt_sriov_info(gt, "Using non-profile provisioning (%s %u vs %u)\n", 1126 "GuC context IDs", fair, profile); 1127 1128 return xe_gt_sriov_pf_config_bulk_set_ctxs(gt, vfid, num_vfs, fair); 1129} 1130 1131static u32 pf_get_min_spare_dbs(struct xe_gt *gt) 1132{ 1133 /* XXX: preliminary, we don't use doorbells yet! */ 1134 return IS_ENABLED(CONFIG_DRM_XE_DEBUG_SRIOV) ? 1 : 0; 1135} 1136 1137static u32 pf_get_spare_dbs(struct xe_gt *gt) 1138{ 1139 u32 spare; 1140 1141 xe_gt_assert(gt, IS_SRIOV_PF(gt_to_xe(gt))); 1142 lockdep_assert_held(xe_gt_sriov_pf_master_mutex(gt)); 1143 1144 spare = gt->sriov.pf.spare.num_dbs; 1145 spare = max_t(u32, spare, pf_get_min_spare_dbs(gt)); 1146 1147 return spare; 1148} 1149 1150static int pf_set_spare_dbs(struct xe_gt *gt, u32 spare) 1151{ 1152 xe_gt_assert(gt, IS_SRIOV_PF(gt_to_xe(gt))); 1153 lockdep_assert_held(xe_gt_sriov_pf_master_mutex(gt)); 1154 1155 if (spare > GUC_NUM_DOORBELLS) 1156 return -EINVAL; 1157 1158 if (spare && spare < pf_get_min_spare_dbs(gt)) 1159 return -EINVAL; 1160 1161 gt->sriov.pf.spare.num_dbs = spare; 1162 return 0; 1163} 1164 1165/* Return: start ID or negative error code on failure */ 1166static int pf_reserve_dbs(struct xe_gt *gt, u32 num) 1167{ 1168 struct xe_guc_db_mgr *dbm = >->uc.guc.dbm; 1169 unsigned int spare = pf_get_spare_dbs(gt); 1170 1171 return xe_guc_db_mgr_reserve_range(dbm, num, spare); 1172} 1173 1174static void pf_release_dbs(struct xe_gt *gt, u32 start, u32 num) 1175{ 1176 struct xe_guc_db_mgr *dbm = >->uc.guc.dbm; 1177 1178 if (num) 1179 xe_guc_db_mgr_release_range(dbm, start, num); 1180} 1181 1182static void pf_release_config_dbs(struct xe_gt *gt, struct xe_gt_sriov_config *config) 1183{ 1184 lockdep_assert_held(xe_gt_sriov_pf_master_mutex(gt)); 1185 1186 pf_release_dbs(gt, config->begin_db, config->num_dbs); 1187 config->begin_db = 0; 1188 config->num_dbs = 0; 1189} 1190 1191static int pf_provision_vf_dbs(struct xe_gt *gt, unsigned int vfid, u32 num_dbs) 1192{ 1193 struct xe_gt_sriov_config *config = pf_pick_vf_config(gt, vfid); 1194 int ret; 1195 1196 xe_gt_assert(gt, vfid); 1197 1198 if (num_dbs > GUC_NUM_DOORBELLS) 1199 return -EINVAL; 1200 1201 if (config->num_dbs) { 1202 ret = pf_push_vf_cfg_dbs(gt, vfid, 0, 0); 1203 if (unlikely(ret)) 1204 return ret; 1205 1206 pf_release_config_dbs(gt, config); 1207 1208 ret = pf_refresh_vf_cfg(gt, vfid); 1209 if (unlikely(ret)) 1210 return ret; 1211 } 1212 1213 if (!num_dbs) 1214 return 0; 1215 1216 ret = pf_reserve_dbs(gt, num_dbs); 1217 if (unlikely(ret < 0)) 1218 return ret; 1219 1220 config->begin_db = ret; 1221 config->num_dbs = num_dbs; 1222 1223 ret = pf_push_vf_cfg_dbs(gt, vfid, config->begin_db, config->num_dbs); 1224 if (unlikely(ret)) { 1225 pf_release_config_dbs(gt, config); 1226 return ret; 1227 } 1228 1229 xe_gt_sriov_dbg_verbose(gt, "VF%u doorbells %u-%u\n", 1230 vfid, config->begin_db, config->begin_db + config->num_dbs - 1); 1231 return 0; 1232} 1233 1234static u32 pf_get_vf_config_dbs(struct xe_gt *gt, unsigned int vfid) 1235{ 1236 struct xe_gt_sriov_config *config = pf_pick_vf_config(gt, vfid); 1237 1238 return config->num_dbs; 1239} 1240 1241/** 1242 * xe_gt_sriov_pf_config_get_dbs - Get VF's GuC doorbells IDs quota. 1243 * @gt: the &xe_gt 1244 * @vfid: the VF identifier 1245 * 1246 * This function can only be called on PF. 1247 * If &vfid represents a PF then number of PF's spare GuC doorbells IDs is returned. 1248 * 1249 * Return: VF's quota (or PF's spare). 1250 */ 1251u32 xe_gt_sriov_pf_config_get_dbs(struct xe_gt *gt, unsigned int vfid) 1252{ 1253 u32 num_dbs; 1254 1255 xe_gt_assert(gt, IS_SRIOV_PF(gt_to_xe(gt))); 1256 xe_gt_assert(gt, vfid <= xe_sriov_pf_get_totalvfs(gt_to_xe(gt))); 1257 1258 mutex_lock(xe_gt_sriov_pf_master_mutex(gt)); 1259 if (vfid) 1260 num_dbs = pf_get_vf_config_dbs(gt, vfid); 1261 else 1262 num_dbs = pf_get_spare_dbs(gt); 1263 mutex_unlock(xe_gt_sriov_pf_master_mutex(gt)); 1264 1265 return num_dbs; 1266} 1267 1268/** 1269 * xe_gt_sriov_pf_config_set_dbs - Configure GuC doorbells IDs quota for the VF. 1270 * @gt: the &xe_gt 1271 * @vfid: the VF identifier 1272 * @num_dbs: requested number of GuC doorbells IDs (0 to release) 1273 * 1274 * This function can only be called on PF. 1275 * 1276 * Return: 0 on success or a negative error code on failure. 1277 */ 1278int xe_gt_sriov_pf_config_set_dbs(struct xe_gt *gt, unsigned int vfid, u32 num_dbs) 1279{ 1280 int err; 1281 1282 xe_gt_assert(gt, IS_SRIOV_PF(gt_to_xe(gt))); 1283 xe_gt_assert(gt, vfid <= xe_sriov_pf_get_totalvfs(gt_to_xe(gt))); 1284 1285 mutex_lock(xe_gt_sriov_pf_master_mutex(gt)); 1286 if (vfid) 1287 err = pf_provision_vf_dbs(gt, vfid, num_dbs); 1288 else 1289 err = pf_set_spare_dbs(gt, num_dbs); 1290 mutex_unlock(xe_gt_sriov_pf_master_mutex(gt)); 1291 1292 return pf_config_set_u32_done(gt, vfid, num_dbs, 1293 xe_gt_sriov_pf_config_get_dbs(gt, vfid), 1294 "GuC doorbell IDs", vfid ? no_unit : spare_unit, err); 1295} 1296 1297/** 1298 * xe_gt_sriov_pf_config_bulk_set_dbs - Provision many VFs with GuC context IDs. 1299 * @gt: the &xe_gt 1300 * @vfid: starting VF identifier (can't be 0) 1301 * @num_vfs: number of VFs to provision 1302 * @num_dbs: requested number of GuC doorbell IDs (0 to release) 1303 * 1304 * This function can only be called on PF. 1305 * 1306 * Return: 0 on success or a negative error code on failure. 1307 */ 1308int xe_gt_sriov_pf_config_bulk_set_dbs(struct xe_gt *gt, unsigned int vfid, 1309 unsigned int num_vfs, u32 num_dbs) 1310{ 1311 unsigned int n; 1312 int err = 0; 1313 1314 xe_gt_assert(gt, vfid); 1315 1316 if (!num_vfs) 1317 return 0; 1318 1319 mutex_lock(xe_gt_sriov_pf_master_mutex(gt)); 1320 for (n = vfid; n < vfid + num_vfs; n++) { 1321 err = pf_provision_vf_dbs(gt, n, num_dbs); 1322 if (err) 1323 break; 1324 } 1325 mutex_unlock(xe_gt_sriov_pf_master_mutex(gt)); 1326 1327 return pf_config_bulk_set_u32_done(gt, vfid, num_vfs, num_dbs, 1328 xe_gt_sriov_pf_config_get_dbs, 1329 "GuC doorbell IDs", no_unit, n, err); 1330} 1331 1332static u32 pf_profile_fair_dbs(struct xe_gt *gt, unsigned int num_vfs) 1333{ 1334 bool admin_only_pf = xe_sriov_pf_admin_only(gt_to_xe(gt)); 1335 1336 /* XXX: preliminary */ 1337 if (admin_only_pf && num_vfs == 1) 1338 return GUC_NUM_DOORBELLS - SZ_16; 1339 1340 return rounddown_pow_of_two(GUC_NUM_DOORBELLS / (num_vfs + 1)); 1341} 1342 1343static u32 pf_estimate_fair_dbs(struct xe_gt *gt, unsigned int num_vfs) 1344{ 1345 struct xe_guc_db_mgr *dbm = >->uc.guc.dbm; 1346 u32 spare = pf_get_spare_dbs(gt); 1347 u32 fair = (GUC_NUM_DOORBELLS - spare) / num_vfs; 1348 int ret; 1349 1350 for (; fair; --fair) { 1351 ret = xe_guc_db_mgr_reserve_range(dbm, fair * num_vfs, spare); 1352 if (ret < 0) 1353 continue; 1354 xe_guc_db_mgr_release_range(dbm, ret, fair * num_vfs); 1355 break; 1356 } 1357 1358 xe_gt_sriov_dbg_verbose(gt, "doorbells fair(%u x %u)\n", num_vfs, fair); 1359 return fair; 1360} 1361 1362/** 1363 * xe_gt_sriov_pf_config_set_fair_dbs - Provision many VFs with fair GuC doorbell IDs. 1364 * @gt: the &xe_gt 1365 * @vfid: starting VF identifier (can't be 0) 1366 * @num_vfs: number of VFs to provision (can't be 0) 1367 * 1368 * This function can only be called on PF. 1369 * 1370 * Return: 0 on success or a negative error code on failure. 1371 */ 1372int xe_gt_sriov_pf_config_set_fair_dbs(struct xe_gt *gt, unsigned int vfid, 1373 unsigned int num_vfs) 1374{ 1375 u32 profile = pf_profile_fair_dbs(gt, num_vfs); 1376 u32 fair; 1377 1378 xe_gt_assert(gt, vfid); 1379 xe_gt_assert(gt, num_vfs); 1380 1381 mutex_lock(xe_gt_sriov_pf_master_mutex(gt)); 1382 fair = pf_estimate_fair_dbs(gt, num_vfs); 1383 mutex_unlock(xe_gt_sriov_pf_master_mutex(gt)); 1384 1385 if (!fair) 1386 return -ENOSPC; 1387 1388 fair = min(fair, profile); 1389 if (fair < profile) 1390 xe_gt_sriov_info(gt, "Using non-profile provisioning (%s %u vs %u)\n", 1391 "GuC doorbell IDs", fair, profile); 1392 1393 return xe_gt_sriov_pf_config_bulk_set_dbs(gt, vfid, num_vfs, fair); 1394} 1395 1396static u64 pf_get_lmem_alignment(struct xe_gt *gt) 1397{ 1398 /* this might be platform dependent */ 1399 return SZ_2M; 1400} 1401 1402static u64 pf_get_min_spare_lmem(struct xe_gt *gt) 1403{ 1404 /* this might be platform dependent */ 1405 return SZ_128M; /* XXX: preliminary */ 1406} 1407 1408static u64 pf_get_spare_lmem(struct xe_gt *gt) 1409{ 1410 u64 spare; 1411 1412 xe_gt_assert(gt, IS_SRIOV_PF(gt_to_xe(gt))); 1413 lockdep_assert_held(xe_gt_sriov_pf_master_mutex(gt)); 1414 1415 spare = gt->sriov.pf.spare.lmem_size; 1416 spare = max_t(u64, spare, pf_get_min_spare_lmem(gt)); 1417 1418 return spare; 1419} 1420 1421static int pf_set_spare_lmem(struct xe_gt *gt, u64 size) 1422{ 1423 xe_gt_assert(gt, IS_SRIOV_PF(gt_to_xe(gt))); 1424 lockdep_assert_held(xe_gt_sriov_pf_master_mutex(gt)); 1425 1426 if (size && size < pf_get_min_spare_lmem(gt)) 1427 return -EINVAL; 1428 1429 gt->sriov.pf.spare.lmem_size = size; 1430 return 0; 1431} 1432 1433static u64 pf_get_vf_config_lmem(struct xe_gt *gt, unsigned int vfid) 1434{ 1435 struct xe_gt_sriov_config *config = pf_pick_vf_config(gt, vfid); 1436 struct xe_bo *bo; 1437 1438 bo = config->lmem_obj; 1439 return bo ? xe_bo_size(bo) : 0; 1440} 1441 1442static int pf_distribute_config_lmem(struct xe_gt *gt, unsigned int vfid, u64 size) 1443{ 1444 struct xe_device *xe = gt_to_xe(gt); 1445 struct xe_tile *tile; 1446 unsigned int tid; 1447 int err; 1448 1449 for_each_tile(tile, xe, tid) { 1450 if (tile->primary_gt == gt) { 1451 err = pf_push_vf_cfg_lmem(gt, vfid, size); 1452 } else { 1453 u64 lmem = pf_get_vf_config_lmem(tile->primary_gt, vfid); 1454 1455 if (!lmem) 1456 continue; 1457 err = pf_push_vf_cfg_lmem(gt, vfid, lmem); 1458 } 1459 if (unlikely(err)) 1460 return err; 1461 } 1462 return 0; 1463} 1464 1465static void pf_force_lmtt_invalidate(struct xe_device *xe) 1466{ 1467 struct xe_lmtt *lmtt; 1468 struct xe_tile *tile; 1469 unsigned int tid; 1470 1471 xe_assert(xe, xe_device_has_lmtt(xe)); 1472 xe_assert(xe, IS_SRIOV_PF(xe)); 1473 1474 for_each_tile(tile, xe, tid) { 1475 lmtt = &tile->sriov.pf.lmtt; 1476 xe_lmtt_invalidate_hw(lmtt); 1477 } 1478} 1479 1480static void pf_reset_vf_lmtt(struct xe_device *xe, unsigned int vfid) 1481{ 1482 struct xe_lmtt *lmtt; 1483 struct xe_tile *tile; 1484 unsigned int tid; 1485 1486 xe_assert(xe, xe_device_has_lmtt(xe)); 1487 xe_assert(xe, IS_SRIOV_PF(xe)); 1488 1489 for_each_tile(tile, xe, tid) { 1490 lmtt = &tile->sriov.pf.lmtt; 1491 xe_lmtt_drop_pages(lmtt, vfid); 1492 } 1493} 1494 1495static int pf_update_vf_lmtt(struct xe_device *xe, unsigned int vfid) 1496{ 1497 struct xe_gt_sriov_config *config; 1498 struct xe_tile *tile; 1499 struct xe_lmtt *lmtt; 1500 struct xe_bo *bo; 1501 struct xe_gt *gt; 1502 u64 total, offset; 1503 unsigned int gtid; 1504 unsigned int tid; 1505 int err; 1506 1507 xe_assert(xe, xe_device_has_lmtt(xe)); 1508 xe_assert(xe, IS_SRIOV_PF(xe)); 1509 1510 total = 0; 1511 for_each_tile(tile, xe, tid) 1512 total += pf_get_vf_config_lmem(tile->primary_gt, vfid); 1513 1514 for_each_tile(tile, xe, tid) { 1515 lmtt = &tile->sriov.pf.lmtt; 1516 1517 xe_lmtt_drop_pages(lmtt, vfid); 1518 if (!total) 1519 continue; 1520 1521 err = xe_lmtt_prepare_pages(lmtt, vfid, total); 1522 if (err) 1523 goto fail; 1524 1525 offset = 0; 1526 for_each_gt(gt, xe, gtid) { 1527 if (xe_gt_is_media_type(gt)) 1528 continue; 1529 1530 config = pf_pick_vf_config(gt, vfid); 1531 bo = config->lmem_obj; 1532 if (!bo) 1533 continue; 1534 1535 err = xe_lmtt_populate_pages(lmtt, vfid, bo, offset); 1536 if (err) 1537 goto fail; 1538 offset += xe_bo_size(bo); 1539 } 1540 } 1541 1542 pf_force_lmtt_invalidate(xe); 1543 return 0; 1544 1545fail: 1546 for_each_tile(tile, xe, tid) { 1547 lmtt = &tile->sriov.pf.lmtt; 1548 xe_lmtt_drop_pages(lmtt, vfid); 1549 } 1550 return err; 1551} 1552 1553/* Return: %true if there was an LMEM provisioned, %false otherwise */ 1554static bool pf_release_vf_config_lmem(struct xe_gt *gt, struct xe_gt_sriov_config *config) 1555{ 1556 xe_gt_assert(gt, IS_DGFX(gt_to_xe(gt))); 1557 xe_gt_assert(gt, xe_gt_is_main_type(gt)); 1558 lockdep_assert_held(xe_gt_sriov_pf_master_mutex(gt)); 1559 1560 if (config->lmem_obj) { 1561 xe_bo_unpin_map_no_vm(config->lmem_obj); 1562 config->lmem_obj = NULL; 1563 return true; 1564 } 1565 return false; 1566} 1567 1568static int pf_provision_vf_lmem(struct xe_gt *gt, unsigned int vfid, u64 size) 1569{ 1570 struct xe_gt_sriov_config *config = pf_pick_vf_config(gt, vfid); 1571 struct xe_device *xe = gt_to_xe(gt); 1572 struct xe_tile *tile = gt_to_tile(gt); 1573 struct xe_bo *bo; 1574 int err; 1575 1576 xe_gt_assert(gt, vfid); 1577 xe_gt_assert(gt, IS_DGFX(xe)); 1578 xe_gt_assert(gt, xe_gt_is_main_type(gt)); 1579 1580 size = round_up(size, pf_get_lmem_alignment(gt)); 1581 1582 if (config->lmem_obj) { 1583 err = pf_distribute_config_lmem(gt, vfid, 0); 1584 if (unlikely(err)) 1585 return err; 1586 1587 if (xe_device_has_lmtt(xe)) 1588 pf_reset_vf_lmtt(xe, vfid); 1589 pf_release_vf_config_lmem(gt, config); 1590 } 1591 xe_gt_assert(gt, !config->lmem_obj); 1592 1593 if (!size) 1594 return 0; 1595 1596 xe_gt_assert(gt, pf_get_lmem_alignment(gt) == SZ_2M); 1597 bo = xe_bo_create_pin_range_novm(xe, tile, 1598 ALIGN(size, PAGE_SIZE), 0, ~0ull, 1599 ttm_bo_type_kernel, 1600 XE_BO_FLAG_VRAM_IF_DGFX(tile) | 1601 XE_BO_FLAG_NEEDS_2M | 1602 XE_BO_FLAG_PINNED | 1603 XE_BO_FLAG_PINNED_LATE_RESTORE | 1604 XE_BO_FLAG_FORCE_USER_VRAM); 1605 if (IS_ERR(bo)) 1606 return PTR_ERR(bo); 1607 1608 config->lmem_obj = bo; 1609 1610 if (xe_device_has_lmtt(xe)) { 1611 err = pf_update_vf_lmtt(xe, vfid); 1612 if (unlikely(err)) 1613 goto release; 1614 } 1615 1616 err = pf_push_vf_cfg_lmem(gt, vfid, xe_bo_size(bo)); 1617 if (unlikely(err)) 1618 goto reset_lmtt; 1619 1620 xe_gt_sriov_dbg_verbose(gt, "VF%u LMEM %zu (%zuM)\n", 1621 vfid, xe_bo_size(bo), xe_bo_size(bo) / SZ_1M); 1622 return 0; 1623 1624reset_lmtt: 1625 if (xe_device_has_lmtt(xe)) 1626 pf_reset_vf_lmtt(xe, vfid); 1627release: 1628 pf_release_vf_config_lmem(gt, config); 1629 return err; 1630} 1631 1632/** 1633 * xe_gt_sriov_pf_config_get_lmem - Get VF's LMEM quota. 1634 * @gt: the &xe_gt 1635 * @vfid: the VF identifier 1636 * 1637 * This function can only be called on PF. 1638 * 1639 * Return: VF's (or PF's spare) LMEM quota. 1640 */ 1641u64 xe_gt_sriov_pf_config_get_lmem(struct xe_gt *gt, unsigned int vfid) 1642{ 1643 u64 size; 1644 1645 mutex_lock(xe_gt_sriov_pf_master_mutex(gt)); 1646 if (vfid) 1647 size = pf_get_vf_config_lmem(gt, vfid); 1648 else 1649 size = pf_get_spare_lmem(gt); 1650 mutex_unlock(xe_gt_sriov_pf_master_mutex(gt)); 1651 1652 return size; 1653} 1654 1655/** 1656 * xe_gt_sriov_pf_config_set_lmem - Provision VF with LMEM. 1657 * @gt: the &xe_gt (can't be media) 1658 * @vfid: the VF identifier 1659 * @size: requested LMEM size 1660 * 1661 * This function can only be called on PF. 1662 */ 1663int xe_gt_sriov_pf_config_set_lmem(struct xe_gt *gt, unsigned int vfid, u64 size) 1664{ 1665 int err; 1666 1667 if (!xe_device_has_lmtt(gt_to_xe(gt))) 1668 return -EPERM; 1669 1670 mutex_lock(xe_gt_sriov_pf_master_mutex(gt)); 1671 if (vfid) 1672 err = pf_provision_vf_lmem(gt, vfid, size); 1673 else 1674 err = pf_set_spare_lmem(gt, size); 1675 mutex_unlock(xe_gt_sriov_pf_master_mutex(gt)); 1676 1677 return pf_config_set_u64_done(gt, vfid, size, 1678 xe_gt_sriov_pf_config_get_lmem(gt, vfid), 1679 vfid ? "LMEM" : "spare LMEM", err); 1680} 1681 1682/** 1683 * xe_gt_sriov_pf_config_bulk_set_lmem - Provision many VFs with LMEM. 1684 * @gt: the &xe_gt (can't be media) 1685 * @vfid: starting VF identifier (can't be 0) 1686 * @num_vfs: number of VFs to provision 1687 * @size: requested LMEM size 1688 * 1689 * This function can only be called on PF. 1690 * 1691 * Return: 0 on success or a negative error code on failure. 1692 */ 1693int xe_gt_sriov_pf_config_bulk_set_lmem(struct xe_gt *gt, unsigned int vfid, 1694 unsigned int num_vfs, u64 size) 1695{ 1696 unsigned int n; 1697 int err = 0; 1698 1699 xe_gt_assert(gt, vfid); 1700 xe_gt_assert(gt, xe_gt_is_main_type(gt)); 1701 1702 if (!num_vfs) 1703 return 0; 1704 1705 mutex_lock(xe_gt_sriov_pf_master_mutex(gt)); 1706 for (n = vfid; n < vfid + num_vfs; n++) { 1707 err = pf_provision_vf_lmem(gt, n, size); 1708 if (err) 1709 break; 1710 } 1711 mutex_unlock(xe_gt_sriov_pf_master_mutex(gt)); 1712 1713 return pf_config_bulk_set_u64_done(gt, vfid, num_vfs, size, 1714 xe_gt_sriov_pf_config_get_lmem, 1715 "LMEM", n, err); 1716} 1717 1718static struct xe_bo *pf_get_vf_config_lmem_obj(struct xe_gt *gt, unsigned int vfid) 1719{ 1720 struct xe_gt_sriov_config *config = pf_pick_vf_config(gt, vfid); 1721 1722 return config->lmem_obj; 1723} 1724 1725/** 1726 * xe_gt_sriov_pf_config_get_lmem_obj() - Take a reference to the struct &xe_bo backing VF LMEM. 1727 * @gt: the &xe_gt 1728 * @vfid: the VF identifier (can't be 0) 1729 * 1730 * This function can only be called on PF. 1731 * The caller is responsible for calling xe_bo_put() on the returned object. 1732 * 1733 * Return: pointer to struct &xe_bo backing VF LMEM (if any). 1734 */ 1735struct xe_bo *xe_gt_sriov_pf_config_get_lmem_obj(struct xe_gt *gt, unsigned int vfid) 1736{ 1737 xe_gt_assert(gt, vfid); 1738 1739 guard(mutex)(xe_gt_sriov_pf_master_mutex(gt)); 1740 1741 return xe_bo_get(pf_get_vf_config_lmem_obj(gt, vfid)); 1742} 1743 1744static u64 pf_query_free_lmem(struct xe_gt *gt) 1745{ 1746 struct xe_tile *tile = gt->tile; 1747 1748 return xe_ttm_vram_get_avail(&tile->mem.vram->ttm.manager); 1749} 1750 1751static u64 pf_query_max_lmem(struct xe_gt *gt) 1752{ 1753 u64 alignment = pf_get_lmem_alignment(gt); 1754 u64 spare = pf_get_spare_lmem(gt); 1755 u64 free = pf_query_free_lmem(gt); 1756 u64 avail; 1757 1758 /* XXX: need to account for 2MB blocks only */ 1759 avail = free > spare ? free - spare : 0; 1760 avail = round_down(avail, alignment); 1761 1762 return avail; 1763} 1764 1765#ifdef CONFIG_DRM_XE_DEBUG_SRIOV 1766#define MAX_FAIR_LMEM SZ_128M /* XXX: make it small for the driver bringup */ 1767#endif 1768 1769static u64 pf_estimate_fair_lmem(struct xe_gt *gt, unsigned int num_vfs) 1770{ 1771 u64 available = pf_query_max_lmem(gt); 1772 u64 alignment = pf_get_lmem_alignment(gt); 1773 u64 fair; 1774 1775 fair = div_u64(available, num_vfs); 1776 fair = ALIGN_DOWN(fair, alignment); 1777#ifdef MAX_FAIR_LMEM 1778 fair = min_t(u64, MAX_FAIR_LMEM, fair); 1779#endif 1780 xe_gt_sriov_dbg_verbose(gt, "LMEM available(%lluM) fair(%u x %lluM)\n", 1781 available / SZ_1M, num_vfs, fair / SZ_1M); 1782 return fair; 1783} 1784 1785/** 1786 * xe_gt_sriov_pf_config_set_fair_lmem - Provision many VFs with fair LMEM. 1787 * @gt: the &xe_gt (can't be media) 1788 * @vfid: starting VF identifier (can't be 0) 1789 * @num_vfs: number of VFs to provision (can't be 0) 1790 * 1791 * This function can only be called on PF. 1792 * 1793 * Return: 0 on success or a negative error code on failure. 1794 */ 1795int xe_gt_sriov_pf_config_set_fair_lmem(struct xe_gt *gt, unsigned int vfid, 1796 unsigned int num_vfs) 1797{ 1798 u64 fair; 1799 1800 xe_gt_assert(gt, vfid); 1801 xe_gt_assert(gt, num_vfs); 1802 xe_gt_assert(gt, xe_gt_is_main_type(gt)); 1803 1804 if (!xe_device_has_lmtt(gt_to_xe(gt))) 1805 return 0; 1806 1807 mutex_lock(xe_gt_sriov_pf_master_mutex(gt)); 1808 fair = pf_estimate_fair_lmem(gt, num_vfs); 1809 mutex_unlock(xe_gt_sriov_pf_master_mutex(gt)); 1810 1811 if (!fair) 1812 return -ENOSPC; 1813 1814 return xe_gt_sriov_pf_config_bulk_set_lmem(gt, vfid, num_vfs, fair); 1815} 1816 1817/** 1818 * xe_gt_sriov_pf_config_set_fair - Provision many VFs with fair resources. 1819 * @gt: the &xe_gt 1820 * @vfid: starting VF identifier (can't be 0) 1821 * @num_vfs: number of VFs to provision (can't be 0) 1822 * 1823 * This function can only be called on PF. 1824 * 1825 * Return: 0 on success or a negative error code on failure. 1826 */ 1827int xe_gt_sriov_pf_config_set_fair(struct xe_gt *gt, unsigned int vfid, 1828 unsigned int num_vfs) 1829{ 1830 int result = 0; 1831 int err; 1832 1833 xe_gt_assert(gt, vfid); 1834 xe_gt_assert(gt, num_vfs); 1835 1836 if (xe_gt_is_main_type(gt)) { 1837 err = xe_gt_sriov_pf_config_set_fair_ggtt(gt, vfid, num_vfs); 1838 result = result ?: err; 1839 err = xe_gt_sriov_pf_config_set_fair_lmem(gt, vfid, num_vfs); 1840 result = result ?: err; 1841 } 1842 err = xe_gt_sriov_pf_config_set_fair_ctxs(gt, vfid, num_vfs); 1843 result = result ?: err; 1844 err = xe_gt_sriov_pf_config_set_fair_dbs(gt, vfid, num_vfs); 1845 result = result ?: err; 1846 1847 return result; 1848} 1849 1850static const char *exec_quantum_unit(u32 exec_quantum) 1851{ 1852 return exec_quantum ? "ms" : "(infinity)"; 1853} 1854 1855static int pf_provision_exec_quantum(struct xe_gt *gt, unsigned int vfid, 1856 u32 exec_quantum) 1857{ 1858 struct xe_gt_sriov_config *config = pf_pick_vf_config(gt, vfid); 1859 int err; 1860 1861 err = pf_push_vf_cfg_exec_quantum(gt, vfid, &exec_quantum); 1862 if (unlikely(err)) 1863 return err; 1864 1865 config->exec_quantum = exec_quantum; 1866 return 0; 1867} 1868 1869static u32 pf_get_exec_quantum(struct xe_gt *gt, unsigned int vfid) 1870{ 1871 struct xe_gt_sriov_config *config = pf_pick_vf_config(gt, vfid); 1872 1873 return config->exec_quantum; 1874} 1875 1876/** 1877 * xe_gt_sriov_pf_config_set_exec_quantum_locked() - Configure PF/VF execution quantum. 1878 * @gt: the &xe_gt 1879 * @vfid: the PF or VF identifier 1880 * @exec_quantum: requested execution quantum in milliseconds (0 is infinity) 1881 * 1882 * This function can only be called on PF with the master mutex hold. 1883 * It will log the provisioned value or an error in case of the failure. 1884 * 1885 * Return: 0 on success or a negative error code on failure. 1886 */ 1887int xe_gt_sriov_pf_config_set_exec_quantum_locked(struct xe_gt *gt, unsigned int vfid, 1888 u32 exec_quantum) 1889{ 1890 int err; 1891 1892 lockdep_assert_held(xe_gt_sriov_pf_master_mutex(gt)); 1893 1894 err = pf_provision_exec_quantum(gt, vfid, exec_quantum); 1895 1896 return pf_config_set_u32_done(gt, vfid, exec_quantum, 1897 pf_get_exec_quantum(gt, vfid), 1898 "execution quantum", exec_quantum_unit, err); 1899} 1900 1901/** 1902 * xe_gt_sriov_pf_config_set_exec_quantum() - Configure PF/VF execution quantum. 1903 * @gt: the &xe_gt 1904 * @vfid: the PF or VF identifier 1905 * @exec_quantum: requested execution quantum in milliseconds (0 is infinity) 1906 * 1907 * This function can only be called on PF. 1908 * It will log the provisioned value or an error in case of the failure. 1909 * 1910 * Return: 0 on success or a negative error code on failure. 1911 */ 1912int xe_gt_sriov_pf_config_set_exec_quantum(struct xe_gt *gt, unsigned int vfid, 1913 u32 exec_quantum) 1914{ 1915 guard(mutex)(xe_gt_sriov_pf_master_mutex(gt)); 1916 1917 return xe_gt_sriov_pf_config_set_exec_quantum_locked(gt, vfid, exec_quantum); 1918} 1919 1920/** 1921 * xe_gt_sriov_pf_config_get_exec_quantum_locked() - Get PF/VF execution quantum. 1922 * @gt: the &xe_gt 1923 * @vfid: the PF or VF identifier 1924 * 1925 * This function can only be called on PF with the master mutex hold. 1926 * 1927 * Return: execution quantum in milliseconds (or 0 if infinity). 1928 */ 1929u32 xe_gt_sriov_pf_config_get_exec_quantum_locked(struct xe_gt *gt, unsigned int vfid) 1930{ 1931 lockdep_assert_held(xe_gt_sriov_pf_master_mutex(gt)); 1932 1933 return pf_get_exec_quantum(gt, vfid); 1934} 1935 1936/** 1937 * xe_gt_sriov_pf_config_get_exec_quantum() - Get PF/VF execution quantum. 1938 * @gt: the &xe_gt 1939 * @vfid: the PF or VF identifier 1940 * 1941 * This function can only be called on PF. 1942 * 1943 * Return: execution quantum in milliseconds (or 0 if infinity). 1944 */ 1945u32 xe_gt_sriov_pf_config_get_exec_quantum(struct xe_gt *gt, unsigned int vfid) 1946{ 1947 guard(mutex)(xe_gt_sriov_pf_master_mutex(gt)); 1948 1949 return pf_get_exec_quantum(gt, vfid); 1950} 1951 1952/** 1953 * xe_gt_sriov_pf_config_bulk_set_exec_quantum_locked() - Configure EQ for PF and VFs. 1954 * @gt: the &xe_gt to configure 1955 * @exec_quantum: requested execution quantum in milliseconds (0 is infinity) 1956 * 1957 * This function can only be called on PF with the master mutex hold. 1958 * 1959 * Return: 0 on success or a negative error code on failure. 1960 */ 1961int xe_gt_sriov_pf_config_bulk_set_exec_quantum_locked(struct xe_gt *gt, u32 exec_quantum) 1962{ 1963 unsigned int totalvfs = xe_gt_sriov_pf_get_totalvfs(gt); 1964 unsigned int n; 1965 int err = 0; 1966 1967 lockdep_assert_held(xe_gt_sriov_pf_master_mutex(gt)); 1968 1969 for (n = 0; n <= totalvfs; n++) { 1970 err = pf_provision_exec_quantum(gt, VFID(n), exec_quantum); 1971 if (err) 1972 break; 1973 } 1974 1975 return pf_config_bulk_set_u32_done(gt, 0, 1 + totalvfs, exec_quantum, 1976 pf_get_exec_quantum, "execution quantum", 1977 exec_quantum_unit, n, err); 1978} 1979 1980static const char *preempt_timeout_unit(u32 preempt_timeout) 1981{ 1982 return preempt_timeout ? "us" : "(infinity)"; 1983} 1984 1985static int pf_provision_preempt_timeout(struct xe_gt *gt, unsigned int vfid, 1986 u32 preempt_timeout) 1987{ 1988 struct xe_gt_sriov_config *config = pf_pick_vf_config(gt, vfid); 1989 int err; 1990 1991 err = pf_push_vf_cfg_preempt_timeout(gt, vfid, &preempt_timeout); 1992 if (unlikely(err)) 1993 return err; 1994 1995 config->preempt_timeout = preempt_timeout; 1996 1997 return 0; 1998} 1999 2000static u32 pf_get_preempt_timeout(struct xe_gt *gt, unsigned int vfid) 2001{ 2002 struct xe_gt_sriov_config *config = pf_pick_vf_config(gt, vfid); 2003 2004 return config->preempt_timeout; 2005} 2006 2007/** 2008 * xe_gt_sriov_pf_config_set_preempt_timeout_locked() - Configure PF/VF preemption timeout. 2009 * @gt: the &xe_gt 2010 * @vfid: the PF or VF identifier 2011 * @preempt_timeout: requested preemption timeout in microseconds (0 is infinity) 2012 * 2013 * This function can only be called on PF with the master mutex hold. 2014 * It will log the provisioned value or an error in case of the failure. 2015 * 2016 * Return: 0 on success or a negative error code on failure. 2017 */ 2018int xe_gt_sriov_pf_config_set_preempt_timeout_locked(struct xe_gt *gt, unsigned int vfid, 2019 u32 preempt_timeout) 2020{ 2021 int err; 2022 2023 lockdep_assert_held(xe_gt_sriov_pf_master_mutex(gt)); 2024 2025 err = pf_provision_preempt_timeout(gt, vfid, preempt_timeout); 2026 2027 return pf_config_set_u32_done(gt, vfid, preempt_timeout, 2028 pf_get_preempt_timeout(gt, vfid), 2029 "preemption timeout", preempt_timeout_unit, err); 2030} 2031 2032/** 2033 * xe_gt_sriov_pf_config_set_preempt_timeout() - Configure PF/VF preemption timeout. 2034 * @gt: the &xe_gt 2035 * @vfid: the PF or VF identifier 2036 * @preempt_timeout: requested preemption timeout in microseconds (0 is infinity) 2037 * 2038 * This function can only be called on PF. 2039 * 2040 * Return: 0 on success or a negative error code on failure. 2041 */ 2042int xe_gt_sriov_pf_config_set_preempt_timeout(struct xe_gt *gt, unsigned int vfid, 2043 u32 preempt_timeout) 2044{ 2045 guard(mutex)(xe_gt_sriov_pf_master_mutex(gt)); 2046 2047 return xe_gt_sriov_pf_config_set_preempt_timeout_locked(gt, vfid, preempt_timeout); 2048} 2049 2050/** 2051 * xe_gt_sriov_pf_config_get_preempt_timeout_locked() - Get PF/VF preemption timeout. 2052 * @gt: the &xe_gt 2053 * @vfid: the PF or VF identifier 2054 * 2055 * This function can only be called on PF with the master mutex hold. 2056 * 2057 * Return: preemption timeout in microseconds (or 0 if infinity). 2058 */ 2059u32 xe_gt_sriov_pf_config_get_preempt_timeout_locked(struct xe_gt *gt, unsigned int vfid) 2060{ 2061 lockdep_assert_held(xe_gt_sriov_pf_master_mutex(gt)); 2062 2063 return pf_get_preempt_timeout(gt, vfid); 2064} 2065 2066/** 2067 * xe_gt_sriov_pf_config_get_preempt_timeout() - Get PF/VF preemption timeout. 2068 * @gt: the &xe_gt 2069 * @vfid: the PF or VF identifier 2070 * 2071 * This function can only be called on PF. 2072 * 2073 * Return: preemption timeout in microseconds (or 0 if infinity). 2074 */ 2075u32 xe_gt_sriov_pf_config_get_preempt_timeout(struct xe_gt *gt, unsigned int vfid) 2076{ 2077 guard(mutex)(xe_gt_sriov_pf_master_mutex(gt)); 2078 2079 return pf_get_preempt_timeout(gt, vfid); 2080} 2081 2082/** 2083 * xe_gt_sriov_pf_config_bulk_set_preempt_timeout_locked() - Configure PT for PF and VFs. 2084 * @gt: the &xe_gt to configure 2085 * @preempt_timeout: requested preemption timeout in microseconds (0 is infinity) 2086 * 2087 * This function can only be called on PF with the master mutex hold. 2088 * 2089 * Return: 0 on success or a negative error code on failure. 2090 */ 2091int xe_gt_sriov_pf_config_bulk_set_preempt_timeout_locked(struct xe_gt *gt, u32 preempt_timeout) 2092{ 2093 unsigned int totalvfs = xe_gt_sriov_pf_get_totalvfs(gt); 2094 unsigned int n; 2095 int err = 0; 2096 2097 lockdep_assert_held(xe_gt_sriov_pf_master_mutex(gt)); 2098 2099 for (n = 0; n <= totalvfs; n++) { 2100 err = pf_provision_preempt_timeout(gt, VFID(n), preempt_timeout); 2101 if (err) 2102 break; 2103 } 2104 2105 return pf_config_bulk_set_u32_done(gt, 0, 1 + totalvfs, preempt_timeout, 2106 pf_get_preempt_timeout, "preemption timeout", 2107 preempt_timeout_unit, n, err); 2108} 2109 2110static const char *sched_priority_unit(u32 priority) 2111{ 2112 return priority == GUC_SCHED_PRIORITY_LOW ? "(low)" : 2113 priority == GUC_SCHED_PRIORITY_NORMAL ? "(normal)" : 2114 priority == GUC_SCHED_PRIORITY_HIGH ? "(high)" : 2115 "(?)"; 2116} 2117 2118static int pf_provision_sched_priority(struct xe_gt *gt, unsigned int vfid, u32 priority) 2119{ 2120 struct xe_gt_sriov_config *config = pf_pick_vf_config(gt, vfid); 2121 int err; 2122 2123 err = pf_push_vf_cfg_sched_priority(gt, vfid, priority); 2124 if (unlikely(err)) 2125 return err; 2126 2127 config->sched_priority = priority; 2128 return 0; 2129} 2130 2131static int pf_get_sched_priority(struct xe_gt *gt, unsigned int vfid) 2132{ 2133 struct xe_gt_sriov_config *config = pf_pick_vf_config(gt, vfid); 2134 2135 return config->sched_priority; 2136} 2137 2138/** 2139 * xe_gt_sriov_pf_config_set_sched_priority() - Configure scheduling priority. 2140 * @gt: the &xe_gt 2141 * @vfid: the VF identifier 2142 * @priority: requested scheduling priority 2143 * 2144 * This function can only be called on PF. 2145 * 2146 * Return: 0 on success or a negative error code on failure. 2147 */ 2148int xe_gt_sriov_pf_config_set_sched_priority(struct xe_gt *gt, unsigned int vfid, u32 priority) 2149{ 2150 int err; 2151 2152 mutex_lock(xe_gt_sriov_pf_master_mutex(gt)); 2153 err = pf_provision_sched_priority(gt, vfid, priority); 2154 mutex_unlock(xe_gt_sriov_pf_master_mutex(gt)); 2155 2156 return pf_config_set_u32_done(gt, vfid, priority, 2157 xe_gt_sriov_pf_config_get_sched_priority(gt, vfid), 2158 "scheduling priority", sched_priority_unit, err); 2159} 2160 2161/** 2162 * xe_gt_sriov_pf_config_get_sched_priority - Get VF's scheduling priority. 2163 * @gt: the &xe_gt 2164 * @vfid: the VF identifier 2165 * 2166 * This function can only be called on PF. 2167 * 2168 * Return: VF's (or PF's) scheduling priority. 2169 */ 2170u32 xe_gt_sriov_pf_config_get_sched_priority(struct xe_gt *gt, unsigned int vfid) 2171{ 2172 u32 priority; 2173 2174 mutex_lock(xe_gt_sriov_pf_master_mutex(gt)); 2175 priority = pf_get_sched_priority(gt, vfid); 2176 mutex_unlock(xe_gt_sriov_pf_master_mutex(gt)); 2177 2178 return priority; 2179} 2180 2181static void pf_reset_config_sched(struct xe_gt *gt, struct xe_gt_sriov_config *config) 2182{ 2183 lockdep_assert_held(xe_gt_sriov_pf_master_mutex(gt)); 2184 2185 config->exec_quantum = 0; 2186 config->preempt_timeout = 0; 2187} 2188 2189static int pf_provision_threshold(struct xe_gt *gt, unsigned int vfid, 2190 enum xe_guc_klv_threshold_index index, u32 value) 2191{ 2192 struct xe_gt_sriov_config *config = pf_pick_vf_config(gt, vfid); 2193 int err; 2194 2195 err = pf_push_vf_cfg_threshold(gt, vfid, index, value); 2196 if (unlikely(err)) 2197 return err; 2198 2199 config->thresholds[index] = value; 2200 2201 return 0; 2202} 2203 2204static int pf_get_threshold(struct xe_gt *gt, unsigned int vfid, 2205 enum xe_guc_klv_threshold_index index) 2206{ 2207 struct xe_gt_sriov_config *config = pf_pick_vf_config(gt, vfid); 2208 2209 return config->thresholds[index]; 2210} 2211 2212static const char *threshold_unit(u32 threshold) 2213{ 2214 return threshold ? "" : "(disabled)"; 2215} 2216 2217/** 2218 * xe_gt_sriov_pf_config_set_threshold - Configure threshold for the VF. 2219 * @gt: the &xe_gt 2220 * @vfid: the VF identifier 2221 * @index: the threshold index 2222 * @value: requested value (0 means disabled) 2223 * 2224 * This function can only be called on PF. 2225 * 2226 * Return: 0 on success or a negative error code on failure. 2227 */ 2228int xe_gt_sriov_pf_config_set_threshold(struct xe_gt *gt, unsigned int vfid, 2229 enum xe_guc_klv_threshold_index index, u32 value) 2230{ 2231 u32 key = xe_guc_klv_threshold_index_to_key(index); 2232 const char *name = xe_guc_klv_key_to_string(key); 2233 int err; 2234 2235 mutex_lock(xe_gt_sriov_pf_master_mutex(gt)); 2236 err = pf_provision_threshold(gt, vfid, index, value); 2237 mutex_unlock(xe_gt_sriov_pf_master_mutex(gt)); 2238 2239 return pf_config_set_u32_done(gt, vfid, value, 2240 xe_gt_sriov_pf_config_get_threshold(gt, vfid, index), 2241 name, threshold_unit, err); 2242} 2243 2244/** 2245 * xe_gt_sriov_pf_config_get_threshold - Get VF's threshold. 2246 * @gt: the &xe_gt 2247 * @vfid: the VF identifier 2248 * @index: the threshold index 2249 * 2250 * This function can only be called on PF. 2251 * 2252 * Return: value of VF's (or PF's) threshold. 2253 */ 2254u32 xe_gt_sriov_pf_config_get_threshold(struct xe_gt *gt, unsigned int vfid, 2255 enum xe_guc_klv_threshold_index index) 2256{ 2257 u32 value; 2258 2259 mutex_lock(xe_gt_sriov_pf_master_mutex(gt)); 2260 value = pf_get_threshold(gt, vfid, index); 2261 mutex_unlock(xe_gt_sriov_pf_master_mutex(gt)); 2262 2263 return value; 2264} 2265 2266static void pf_reset_config_thresholds(struct xe_gt *gt, struct xe_gt_sriov_config *config) 2267{ 2268 lockdep_assert_held(xe_gt_sriov_pf_master_mutex(gt)); 2269 2270#define reset_threshold_config(TAG, ...) ({ \ 2271 config->thresholds[MAKE_XE_GUC_KLV_THRESHOLD_INDEX(TAG)] = 0; \ 2272}); 2273 2274 MAKE_XE_GUC_KLV_THRESHOLDS_SET(reset_threshold_config); 2275#undef reset_threshold_config 2276} 2277 2278static void pf_release_vf_config(struct xe_gt *gt, unsigned int vfid) 2279{ 2280 struct xe_gt_sriov_config *config = pf_pick_vf_config(gt, vfid); 2281 struct xe_device *xe = gt_to_xe(gt); 2282 bool released; 2283 2284 if (xe_gt_is_main_type(gt)) { 2285 pf_release_vf_config_ggtt(gt, config); 2286 if (IS_DGFX(xe)) { 2287 released = pf_release_vf_config_lmem(gt, config); 2288 if (released && xe_device_has_lmtt(xe)) 2289 pf_update_vf_lmtt(xe, vfid); 2290 } 2291 } 2292 pf_release_config_ctxs(gt, config); 2293 pf_release_config_dbs(gt, config); 2294 pf_reset_config_sched(gt, config); 2295 pf_reset_config_thresholds(gt, config); 2296} 2297 2298/** 2299 * xe_gt_sriov_pf_config_release - Release and reset VF configuration. 2300 * @gt: the &xe_gt 2301 * @vfid: the VF identifier (can't be PF) 2302 * @force: force configuration release 2303 * 2304 * This function can only be called on PF. 2305 * 2306 * Return: 0 on success or a negative error code on failure. 2307 */ 2308int xe_gt_sriov_pf_config_release(struct xe_gt *gt, unsigned int vfid, bool force) 2309{ 2310 int err; 2311 2312 xe_gt_assert(gt, vfid); 2313 2314 mutex_lock(xe_gt_sriov_pf_master_mutex(gt)); 2315 err = pf_send_vf_cfg_reset(gt, vfid); 2316 if (!err || force) 2317 pf_release_vf_config(gt, vfid); 2318 mutex_unlock(xe_gt_sriov_pf_master_mutex(gt)); 2319 2320 if (unlikely(err)) { 2321 xe_gt_sriov_notice(gt, "VF%u unprovisioning failed with error (%pe)%s\n", 2322 vfid, ERR_PTR(err), 2323 force ? " but all resources were released anyway!" : ""); 2324 } 2325 2326 return force ? 0 : err; 2327} 2328 2329static void pf_sanitize_ggtt(struct xe_ggtt_node *ggtt_region, unsigned int vfid) 2330{ 2331 if (xe_ggtt_node_allocated(ggtt_region)) 2332 xe_ggtt_assign(ggtt_region, vfid); 2333} 2334 2335static int pf_sanitize_lmem(struct xe_tile *tile, struct xe_bo *bo, long timeout) 2336{ 2337 struct xe_migrate *m = tile->migrate; 2338 struct dma_fence *fence; 2339 int err; 2340 2341 if (!bo) 2342 return 0; 2343 2344 xe_bo_lock(bo, false); 2345 fence = xe_migrate_clear(m, bo, bo->ttm.resource, XE_MIGRATE_CLEAR_FLAG_FULL); 2346 if (IS_ERR(fence)) { 2347 err = PTR_ERR(fence); 2348 } else if (!fence) { 2349 err = -ENOMEM; 2350 } else { 2351 long ret = dma_fence_wait_timeout(fence, false, timeout); 2352 2353 err = ret > 0 ? 0 : ret < 0 ? ret : -ETIMEDOUT; 2354 dma_fence_put(fence); 2355 if (!err) 2356 xe_gt_sriov_dbg_verbose(tile->primary_gt, "LMEM cleared in %dms\n", 2357 jiffies_to_msecs(timeout - ret)); 2358 } 2359 xe_bo_unlock(bo); 2360 2361 return err; 2362} 2363 2364static int pf_sanitize_vf_resources(struct xe_gt *gt, u32 vfid, long timeout) 2365{ 2366 struct xe_gt_sriov_config *config = pf_pick_vf_config(gt, vfid); 2367 struct xe_tile *tile = gt_to_tile(gt); 2368 struct xe_device *xe = gt_to_xe(gt); 2369 int err = 0; 2370 2371 /* 2372 * Only GGTT and LMEM requires to be cleared by the PF. 2373 * GuC doorbell IDs and context IDs do not need any clearing. 2374 */ 2375 if (xe_gt_is_main_type(gt)) { 2376 pf_sanitize_ggtt(config->ggtt_region, vfid); 2377 if (IS_DGFX(xe)) 2378 err = pf_sanitize_lmem(tile, config->lmem_obj, timeout); 2379 } 2380 2381 return err; 2382} 2383 2384/** 2385 * xe_gt_sriov_pf_config_sanitize() - Sanitize VF's resources. 2386 * @gt: the &xe_gt 2387 * @vfid: the VF identifier (can't be PF) 2388 * @timeout: maximum timeout to wait for completion in jiffies 2389 * 2390 * This function can only be called on PF. 2391 * 2392 * Return: 0 on success or a negative error code on failure. 2393 */ 2394int xe_gt_sriov_pf_config_sanitize(struct xe_gt *gt, unsigned int vfid, long timeout) 2395{ 2396 int err; 2397 2398 xe_gt_assert(gt, vfid != PFID); 2399 2400 mutex_lock(xe_gt_sriov_pf_master_mutex(gt)); 2401 err = pf_sanitize_vf_resources(gt, vfid, timeout); 2402 mutex_unlock(xe_gt_sriov_pf_master_mutex(gt)); 2403 2404 if (unlikely(err)) 2405 xe_gt_sriov_notice(gt, "VF%u resource sanitizing failed (%pe)\n", 2406 vfid, ERR_PTR(err)); 2407 return err; 2408} 2409 2410/** 2411 * xe_gt_sriov_pf_config_push - Reprovision VF's configuration. 2412 * @gt: the &xe_gt 2413 * @vfid: the VF identifier (can't be PF) 2414 * @refresh: explicit refresh 2415 * 2416 * This function can only be called on PF. 2417 * 2418 * Return: 0 on success or a negative error code on failure. 2419 */ 2420int xe_gt_sriov_pf_config_push(struct xe_gt *gt, unsigned int vfid, bool refresh) 2421{ 2422 int err = 0; 2423 2424 xe_gt_assert(gt, vfid); 2425 2426 mutex_lock(xe_gt_sriov_pf_master_mutex(gt)); 2427 err = pf_push_vf_cfg(gt, vfid, refresh); 2428 mutex_unlock(xe_gt_sriov_pf_master_mutex(gt)); 2429 2430 if (unlikely(err)) { 2431 xe_gt_sriov_notice(gt, "Failed to %s VF%u configuration (%pe)\n", 2432 refresh ? "refresh" : "push", vfid, ERR_PTR(err)); 2433 } 2434 2435 return err; 2436} 2437 2438static int pf_validate_vf_config(struct xe_gt *gt, unsigned int vfid) 2439{ 2440 struct xe_gt *primary_gt = gt_to_tile(gt)->primary_gt; 2441 struct xe_device *xe = gt_to_xe(gt); 2442 bool is_primary = xe_gt_is_main_type(gt); 2443 bool valid_ggtt, valid_ctxs, valid_dbs; 2444 bool valid_any, valid_all; 2445 2446 valid_ggtt = pf_get_vf_config_ggtt(primary_gt, vfid); 2447 valid_ctxs = pf_get_vf_config_ctxs(gt, vfid); 2448 valid_dbs = pf_get_vf_config_dbs(gt, vfid); 2449 2450 /* note that GuC doorbells are optional */ 2451 valid_any = valid_ctxs || valid_dbs; 2452 valid_all = valid_ctxs; 2453 2454 /* and GGTT/LMEM is configured on primary GT only */ 2455 valid_all = valid_all && valid_ggtt; 2456 valid_any = valid_any || (valid_ggtt && is_primary); 2457 2458 if (xe_device_has_lmtt(xe)) { 2459 bool valid_lmem = pf_get_vf_config_lmem(primary_gt, vfid); 2460 2461 valid_any = valid_any || (valid_lmem && is_primary); 2462 valid_all = valid_all && valid_lmem; 2463 } 2464 2465 return valid_all ? 0 : valid_any ? -ENOKEY : -ENODATA; 2466} 2467 2468/** 2469 * xe_gt_sriov_pf_config_is_empty - Check VF's configuration. 2470 * @gt: the &xe_gt 2471 * @vfid: the VF identifier (can't be PF) 2472 * 2473 * This function can only be called on PF. 2474 * 2475 * Return: true if VF mandatory configuration (GGTT, LMEM, ...) is empty. 2476 */ 2477bool xe_gt_sriov_pf_config_is_empty(struct xe_gt *gt, unsigned int vfid) 2478{ 2479 bool empty; 2480 2481 xe_gt_assert(gt, IS_SRIOV_PF(gt_to_xe(gt))); 2482 xe_gt_assert(gt, vfid); 2483 2484 mutex_lock(xe_gt_sriov_pf_master_mutex(gt)); 2485 empty = pf_validate_vf_config(gt, vfid) == -ENODATA; 2486 mutex_unlock(xe_gt_sriov_pf_master_mutex(gt)); 2487 2488 return empty; 2489} 2490 2491/** 2492 * xe_gt_sriov_pf_config_save - Save a VF provisioning config as binary blob. 2493 * @gt: the &xe_gt 2494 * @vfid: the VF identifier (can't be PF) 2495 * @buf: the buffer to save a config to (or NULL if query the buf size) 2496 * @size: the size of the buffer (or 0 if query the buf size) 2497 * 2498 * This function can only be called on PF. 2499 * 2500 * Return: minimum size of the buffer or the number of bytes saved, 2501 * or a negative error code on failure. 2502 */ 2503ssize_t xe_gt_sriov_pf_config_save(struct xe_gt *gt, unsigned int vfid, void *buf, size_t size) 2504{ 2505 struct xe_gt_sriov_config *config; 2506 ssize_t ret; 2507 2508 xe_gt_assert(gt, IS_SRIOV_PF(gt_to_xe(gt))); 2509 xe_gt_assert(gt, vfid); 2510 xe_gt_assert(gt, !(!buf ^ !size)); 2511 2512 mutex_lock(xe_gt_sriov_pf_master_mutex(gt)); 2513 ret = pf_validate_vf_config(gt, vfid); 2514 if (!size) { 2515 ret = ret ? 0 : SZ_4K; 2516 } else if (!ret) { 2517 if (size < SZ_4K) { 2518 ret = -ENOBUFS; 2519 } else { 2520 config = pf_pick_vf_config(gt, vfid); 2521 ret = encode_config(buf, config, false) * sizeof(u32); 2522 } 2523 } 2524 mutex_unlock(xe_gt_sriov_pf_master_mutex(gt)); 2525 2526 return ret; 2527} 2528 2529static int pf_restore_vf_config_klv(struct xe_gt *gt, unsigned int vfid, 2530 u32 key, u32 len, const u32 *value) 2531{ 2532 switch (key) { 2533 case GUC_KLV_VF_CFG_NUM_CONTEXTS_KEY: 2534 if (len != GUC_KLV_VF_CFG_NUM_CONTEXTS_LEN) 2535 return -EBADMSG; 2536 return pf_provision_vf_ctxs(gt, vfid, value[0]); 2537 2538 case GUC_KLV_VF_CFG_NUM_DOORBELLS_KEY: 2539 if (len != GUC_KLV_VF_CFG_NUM_DOORBELLS_LEN) 2540 return -EBADMSG; 2541 return pf_provision_vf_dbs(gt, vfid, value[0]); 2542 2543 case GUC_KLV_VF_CFG_EXEC_QUANTUM_KEY: 2544 if (len != GUC_KLV_VF_CFG_EXEC_QUANTUM_LEN) 2545 return -EBADMSG; 2546 return pf_provision_exec_quantum(gt, vfid, value[0]); 2547 2548 case GUC_KLV_VF_CFG_PREEMPT_TIMEOUT_KEY: 2549 if (len != GUC_KLV_VF_CFG_PREEMPT_TIMEOUT_LEN) 2550 return -EBADMSG; 2551 return pf_provision_preempt_timeout(gt, vfid, value[0]); 2552 2553 /* auto-generate case statements */ 2554#define define_threshold_key_to_provision_case(TAG, ...) \ 2555 case MAKE_GUC_KLV_VF_CFG_THRESHOLD_KEY(TAG): \ 2556 BUILD_BUG_ON(MAKE_GUC_KLV_VF_CFG_THRESHOLD_LEN(TAG) != 1u); \ 2557 if (len != MAKE_GUC_KLV_VF_CFG_THRESHOLD_LEN(TAG)) \ 2558 return -EBADMSG; \ 2559 return pf_provision_threshold(gt, vfid, \ 2560 MAKE_XE_GUC_KLV_THRESHOLD_INDEX(TAG), \ 2561 value[0]); 2562 2563 MAKE_XE_GUC_KLV_THRESHOLDS_SET(define_threshold_key_to_provision_case) 2564#undef define_threshold_key_to_provision_case 2565 } 2566 2567 if (xe_gt_is_media_type(gt)) 2568 return -EKEYREJECTED; 2569 2570 switch (key) { 2571 case GUC_KLV_VF_CFG_GGTT_SIZE_KEY: 2572 if (len != GUC_KLV_VF_CFG_GGTT_SIZE_LEN) 2573 return -EBADMSG; 2574 return pf_provision_vf_ggtt(gt, vfid, make_u64_from_u32(value[1], value[0])); 2575 2576 case GUC_KLV_VF_CFG_LMEM_SIZE_KEY: 2577 if (!IS_DGFX(gt_to_xe(gt))) 2578 return -EKEYREJECTED; 2579 if (len != GUC_KLV_VF_CFG_LMEM_SIZE_LEN) 2580 return -EBADMSG; 2581 return pf_provision_vf_lmem(gt, vfid, make_u64_from_u32(value[1], value[0])); 2582 } 2583 2584 return -EKEYREJECTED; 2585} 2586 2587static int pf_restore_vf_config(struct xe_gt *gt, unsigned int vfid, 2588 const u32 *klvs, size_t num_dwords) 2589{ 2590 int err; 2591 2592 while (num_dwords >= GUC_KLV_LEN_MIN) { 2593 u32 key = FIELD_GET(GUC_KLV_0_KEY, klvs[0]); 2594 u32 len = FIELD_GET(GUC_KLV_0_LEN, klvs[0]); 2595 2596 klvs += GUC_KLV_LEN_MIN; 2597 num_dwords -= GUC_KLV_LEN_MIN; 2598 2599 if (num_dwords < len) 2600 err = -EBADMSG; 2601 else 2602 err = pf_restore_vf_config_klv(gt, vfid, key, len, klvs); 2603 2604 if (err) { 2605 xe_gt_sriov_dbg(gt, "restore failed on key %#x (%pe)\n", key, ERR_PTR(err)); 2606 return err; 2607 } 2608 2609 klvs += len; 2610 num_dwords -= len; 2611 } 2612 2613 return pf_validate_vf_config(gt, vfid); 2614} 2615 2616/** 2617 * xe_gt_sriov_pf_config_restore - Restore a VF provisioning config from binary blob. 2618 * @gt: the &xe_gt 2619 * @vfid: the VF identifier (can't be PF) 2620 * @buf: the buffer with config data 2621 * @size: the size of the config data 2622 * 2623 * This function can only be called on PF. 2624 * 2625 * Return: 0 on success or a negative error code on failure. 2626 */ 2627int xe_gt_sriov_pf_config_restore(struct xe_gt *gt, unsigned int vfid, 2628 const void *buf, size_t size) 2629{ 2630 int err; 2631 2632 xe_gt_assert(gt, IS_SRIOV_PF(gt_to_xe(gt))); 2633 xe_gt_assert(gt, vfid); 2634 2635 if (!size) 2636 return -ENODATA; 2637 2638 if (size % sizeof(u32)) 2639 return -EINVAL; 2640 2641 if (IS_ENABLED(CONFIG_DRM_XE_DEBUG_SRIOV)) { 2642 struct drm_printer p = xe_gt_dbg_printer(gt); 2643 2644 drm_printf(&p, "restoring VF%u config:\n", vfid); 2645 xe_guc_klv_print(buf, size / sizeof(u32), &p); 2646 } 2647 2648 mutex_lock(xe_gt_sriov_pf_master_mutex(gt)); 2649 err = pf_send_vf_cfg_reset(gt, vfid); 2650 if (!err) { 2651 pf_release_vf_config(gt, vfid); 2652 err = pf_restore_vf_config(gt, vfid, buf, size / sizeof(u32)); 2653 } 2654 mutex_unlock(xe_gt_sriov_pf_master_mutex(gt)); 2655 2656 return err; 2657} 2658 2659static void pf_prepare_self_config(struct xe_gt *gt) 2660{ 2661 struct xe_gt_sriov_config *config = pf_pick_vf_config(gt, PFID); 2662 2663 /* 2664 * We want PF to be allowed to use all of context ID, doorbells IDs 2665 * and whole usable GGTT area. While we can store ctxs/dbs numbers 2666 * directly in the config structure, can't do the same with the GGTT 2667 * configuration, so let it be prepared on demand while pushing KLVs. 2668 */ 2669 config->num_ctxs = GUC_ID_MAX; 2670 config->num_dbs = GUC_NUM_DOORBELLS; 2671} 2672 2673static int pf_push_self_config(struct xe_gt *gt) 2674{ 2675 int err; 2676 2677 err = pf_push_full_vf_config(gt, PFID); 2678 if (err) { 2679 xe_gt_sriov_err(gt, "Failed to push self configuration (%pe)\n", 2680 ERR_PTR(err)); 2681 return err; 2682 } 2683 2684 xe_gt_sriov_dbg_verbose(gt, "self configuration completed\n"); 2685 return 0; 2686} 2687 2688static void fini_config(void *arg) 2689{ 2690 struct xe_gt *gt = arg; 2691 struct xe_device *xe = gt_to_xe(gt); 2692 unsigned int n, total_vfs = xe_sriov_pf_get_totalvfs(xe); 2693 2694 mutex_lock(xe_gt_sriov_pf_master_mutex(gt)); 2695 for (n = 1; n <= total_vfs; n++) 2696 pf_release_vf_config(gt, n); 2697 mutex_unlock(xe_gt_sriov_pf_master_mutex(gt)); 2698} 2699 2700/** 2701 * xe_gt_sriov_pf_config_init - Initialize SR-IOV configuration data. 2702 * @gt: the &xe_gt 2703 * 2704 * This function can only be called on PF. 2705 * 2706 * Return: 0 on success or a negative error code on failure. 2707 */ 2708int xe_gt_sriov_pf_config_init(struct xe_gt *gt) 2709{ 2710 struct xe_device *xe = gt_to_xe(gt); 2711 int err; 2712 2713 xe_gt_assert(gt, IS_SRIOV_PF(xe)); 2714 2715 mutex_lock(xe_gt_sriov_pf_master_mutex(gt)); 2716 pf_prepare_self_config(gt); 2717 err = pf_push_self_config(gt); 2718 mutex_unlock(xe_gt_sriov_pf_master_mutex(gt)); 2719 2720 if (err) 2721 return err; 2722 2723 return devm_add_action_or_reset(xe->drm.dev, fini_config, gt); 2724} 2725 2726/** 2727 * xe_gt_sriov_pf_config_restart - Restart SR-IOV configurations after a GT reset. 2728 * @gt: the &xe_gt 2729 * 2730 * Any prior configurations pushed to GuC are lost when the GT is reset. 2731 * Push again all non-empty VF configurations to the GuC. 2732 * 2733 * This function can only be called on PF. 2734 */ 2735void xe_gt_sriov_pf_config_restart(struct xe_gt *gt) 2736{ 2737 unsigned int n, total_vfs = xe_sriov_pf_get_totalvfs(gt_to_xe(gt)); 2738 unsigned int fail = 0, skip = 0; 2739 2740 mutex_lock(xe_gt_sriov_pf_master_mutex(gt)); 2741 pf_push_self_config(gt); 2742 mutex_unlock(xe_gt_sriov_pf_master_mutex(gt)); 2743 2744 for (n = 1; n <= total_vfs; n++) { 2745 if (xe_gt_sriov_pf_config_is_empty(gt, n)) 2746 skip++; 2747 else if (xe_gt_sriov_pf_config_push(gt, n, false)) 2748 fail++; 2749 } 2750 2751 if (fail) 2752 xe_gt_sriov_notice(gt, "Failed to push %u of %u VF%s configurations\n", 2753 fail, total_vfs - skip, str_plural(total_vfs)); 2754 2755 if (fail != total_vfs) 2756 xe_gt_sriov_dbg(gt, "pushed %u skip %u of %u VF%s configurations\n", 2757 total_vfs - skip - fail, skip, total_vfs, str_plural(total_vfs)); 2758} 2759 2760/** 2761 * xe_gt_sriov_pf_config_print_ggtt - Print GGTT configurations. 2762 * @gt: the &xe_gt 2763 * @p: the &drm_printer 2764 * 2765 * Print GGTT configuration data for all VFs. 2766 * VFs without provisioned GGTT are ignored. 2767 * 2768 * This function can only be called on PF. 2769 */ 2770int xe_gt_sriov_pf_config_print_ggtt(struct xe_gt *gt, struct drm_printer *p) 2771{ 2772 unsigned int n, total_vfs = xe_sriov_pf_get_totalvfs(gt_to_xe(gt)); 2773 const struct xe_gt_sriov_config *config; 2774 char buf[10]; 2775 2776 for (n = 1; n <= total_vfs; n++) { 2777 config = >->sriov.pf.vfs[n].config; 2778 if (!xe_ggtt_node_allocated(config->ggtt_region)) 2779 continue; 2780 2781 string_get_size(config->ggtt_region->base.size, 1, STRING_UNITS_2, 2782 buf, sizeof(buf)); 2783 drm_printf(p, "VF%u:\t%#0llx-%#llx\t(%s)\n", 2784 n, config->ggtt_region->base.start, 2785 config->ggtt_region->base.start + config->ggtt_region->base.size - 1, 2786 buf); 2787 } 2788 2789 return 0; 2790} 2791 2792/** 2793 * xe_gt_sriov_pf_config_print_ctxs - Print GuC context IDs configurations. 2794 * @gt: the &xe_gt 2795 * @p: the &drm_printer 2796 * 2797 * Print GuC context ID allocations across all VFs. 2798 * VFs without GuC context IDs are skipped. 2799 * 2800 * This function can only be called on PF. 2801 * Return: 0 on success or a negative error code on failure. 2802 */ 2803int xe_gt_sriov_pf_config_print_ctxs(struct xe_gt *gt, struct drm_printer *p) 2804{ 2805 unsigned int n, total_vfs = xe_sriov_pf_get_totalvfs(gt_to_xe(gt)); 2806 const struct xe_gt_sriov_config *config; 2807 2808 xe_gt_assert(gt, IS_SRIOV_PF(gt_to_xe(gt))); 2809 mutex_lock(xe_gt_sriov_pf_master_mutex(gt)); 2810 2811 for (n = 1; n <= total_vfs; n++) { 2812 config = >->sriov.pf.vfs[n].config; 2813 if (!config->num_ctxs) 2814 continue; 2815 2816 drm_printf(p, "VF%u:\t%u-%u\t(%u)\n", 2817 n, 2818 config->begin_ctx, 2819 config->begin_ctx + config->num_ctxs - 1, 2820 config->num_ctxs); 2821 } 2822 2823 mutex_unlock(xe_gt_sriov_pf_master_mutex(gt)); 2824 return 0; 2825} 2826 2827/** 2828 * xe_gt_sriov_pf_config_print_dbs - Print GuC doorbell ID configurations. 2829 * @gt: the &xe_gt 2830 * @p: the &drm_printer 2831 * 2832 * Print GuC doorbell IDs allocations across all VFs. 2833 * VFs without GuC doorbell IDs are skipped. 2834 * 2835 * This function can only be called on PF. 2836 * Return: 0 on success or a negative error code on failure. 2837 */ 2838int xe_gt_sriov_pf_config_print_dbs(struct xe_gt *gt, struct drm_printer *p) 2839{ 2840 unsigned int n, total_vfs = xe_sriov_pf_get_totalvfs(gt_to_xe(gt)); 2841 const struct xe_gt_sriov_config *config; 2842 2843 xe_gt_assert(gt, IS_SRIOV_PF(gt_to_xe(gt))); 2844 mutex_lock(xe_gt_sriov_pf_master_mutex(gt)); 2845 2846 for (n = 1; n <= total_vfs; n++) { 2847 config = >->sriov.pf.vfs[n].config; 2848 if (!config->num_dbs) 2849 continue; 2850 2851 drm_printf(p, "VF%u:\t%u-%u\t(%u)\n", 2852 n, 2853 config->begin_db, 2854 config->begin_db + config->num_dbs - 1, 2855 config->num_dbs); 2856 } 2857 2858 mutex_unlock(xe_gt_sriov_pf_master_mutex(gt)); 2859 return 0; 2860} 2861 2862/** 2863 * xe_gt_sriov_pf_config_print_lmem - Print LMEM configurations. 2864 * @gt: the &xe_gt 2865 * @p: the &drm_printer 2866 * 2867 * Print LMEM allocations across all VFs. 2868 * VFs without LMEM allocation are skipped. 2869 * 2870 * This function can only be called on PF. 2871 * Return: 0 on success or a negative error code on failure. 2872 */ 2873int xe_gt_sriov_pf_config_print_lmem(struct xe_gt *gt, struct drm_printer *p) 2874{ 2875 unsigned int n, total_vfs = xe_sriov_pf_get_totalvfs(gt_to_xe(gt)); 2876 const struct xe_gt_sriov_config *config; 2877 char buf[10]; 2878 2879 xe_gt_assert(gt, IS_SRIOV_PF(gt_to_xe(gt))); 2880 mutex_lock(xe_gt_sriov_pf_master_mutex(gt)); 2881 2882 for (n = 1; n <= total_vfs; n++) { 2883 config = >->sriov.pf.vfs[n].config; 2884 if (!config->lmem_obj) 2885 continue; 2886 2887 string_get_size(xe_bo_size(config->lmem_obj), 1, STRING_UNITS_2, 2888 buf, sizeof(buf)); 2889 drm_printf(p, "VF%u:\t%zu\t(%s)\n", 2890 n, xe_bo_size(config->lmem_obj), buf); 2891 } 2892 2893 mutex_unlock(xe_gt_sriov_pf_master_mutex(gt)); 2894 return 0; 2895} 2896 2897/** 2898 * xe_gt_sriov_pf_config_print_available_ggtt - Print available GGTT ranges. 2899 * @gt: the &xe_gt 2900 * @p: the &drm_printer 2901 * 2902 * Print GGTT ranges that are available for the provisioning. 2903 * 2904 * This function can only be called on PF. 2905 */ 2906int xe_gt_sriov_pf_config_print_available_ggtt(struct xe_gt *gt, struct drm_printer *p) 2907{ 2908 struct xe_ggtt *ggtt = gt_to_tile(gt)->mem.ggtt; 2909 u64 alignment = pf_get_ggtt_alignment(gt); 2910 u64 spare, avail, total; 2911 char buf[10]; 2912 2913 xe_gt_assert(gt, IS_SRIOV_PF(gt_to_xe(gt))); 2914 2915 mutex_lock(xe_gt_sriov_pf_master_mutex(gt)); 2916 2917 spare = pf_get_spare_ggtt(gt); 2918 total = xe_ggtt_print_holes(ggtt, alignment, p); 2919 2920 mutex_unlock(xe_gt_sriov_pf_master_mutex(gt)); 2921 2922 string_get_size(total, 1, STRING_UNITS_2, buf, sizeof(buf)); 2923 drm_printf(p, "total:\t%llu\t(%s)\n", total, buf); 2924 2925 string_get_size(spare, 1, STRING_UNITS_2, buf, sizeof(buf)); 2926 drm_printf(p, "spare:\t%llu\t(%s)\n", spare, buf); 2927 2928 avail = total > spare ? total - spare : 0; 2929 2930 string_get_size(avail, 1, STRING_UNITS_2, buf, sizeof(buf)); 2931 drm_printf(p, "avail:\t%llu\t(%s)\n", avail, buf); 2932 2933 return 0; 2934} 2935 2936#if IS_BUILTIN(CONFIG_DRM_XE_KUNIT_TEST) 2937#include "tests/xe_gt_sriov_pf_config_kunit.c" 2938#endif
~/
Read-only file preview.