1 // SPDX-License-Identifier: MIT 2 /* 3 * Copyright © 2023-2024 Intel Corporation 4 */ 5 6 #include "abi/guc_actions_sriov_abi.h" 7 8 #include "xe_bo.h" 9 #include "xe_gt.h" 10 #include "xe_gt_sriov_pf_helpers.h" 11 #include "xe_gt_sriov_pf_policy.h" 12 #include "xe_gt_sriov_printk.h" 13 #include "xe_guc_buf.h" 14 #include "xe_guc_ct.h" 15 #include "xe_guc_klv_helpers.h" 16 #include "xe_pm.h" 17 18 /* 19 * Return: number of KLVs that were successfully parsed and saved, 20 * negative error code on failure. 21 */ 22 static int guc_action_update_vgt_policy(struct xe_guc *guc, u64 addr, u32 size) 23 { 24 u32 request[] = { 25 GUC_ACTION_PF2GUC_UPDATE_VGT_POLICY, 26 lower_32_bits(addr), 27 upper_32_bits(addr), 28 size, 29 }; 30 31 return xe_guc_ct_send_block(&guc->ct, request, ARRAY_SIZE(request)); 32 } 33 34 /* 35 * Return: number of KLVs that were successfully parsed and saved, 36 * negative error code on failure. 37 */ 38 static int pf_send_policy_klvs(struct xe_gt *gt, struct xe_guc_buf buf, u32 num_dwords) 39 { 40 struct xe_guc *guc = >->uc.guc; 41 42 return guc_action_update_vgt_policy(guc, xe_guc_buf_flush(buf), num_dwords); 43 } 44 45 /* 46 * Return: 0 on success, -ENOKEY if some KLVs were not updated, -EPROTO if reply was malformed, 47 * negative error code on failure. 48 */ 49 static int pf_push_policy_buf_klvs(struct xe_gt *gt, u32 num_klvs, 50 struct xe_guc_buf buf, u32 num_dwords) 51 { 52 int ret; 53 54 ret = pf_send_policy_klvs(gt, buf, num_dwords); 55 56 if (ret != num_klvs) { 57 int err = ret < 0 ? ret : ret < num_klvs ? -ENOKEY : -EPROTO; 58 struct drm_printer p = xe_gt_info_printer(gt); 59 void *klvs = xe_guc_buf_cpu_ptr(buf); 60 61 xe_gt_sriov_notice(gt, "Failed to push %u policy KLV%s (%pe)\n", 62 num_klvs, str_plural(num_klvs), ERR_PTR(err)); 63 xe_guc_klv_print(klvs, num_dwords, &p); 64 return err; 65 } 66 67 return 0; 68 } 69 70 /* 71 * Return: 0 on success, -ENOBUFS if there is no free buffer for the indirect data, 72 * negative error code on failure. 73 */ 74 static int pf_push_policy_klvs(struct xe_gt *gt, u32 num_klvs, 75 const u32 *klvs, u32 num_dwords) 76 { 77 CLASS(xe_guc_buf_from_data, buf)(>->uc.guc.buf, klvs, num_dwords * sizeof(u32)); 78 79 xe_gt_assert(gt, num_klvs == xe_guc_klv_count(klvs, num_dwords)); 80 81 if (!xe_guc_buf_is_valid(buf)) 82 return -ENOBUFS; 83 84 return pf_push_policy_buf_klvs(gt, num_klvs, buf, num_dwords); 85 } 86 87 static int pf_push_policy_u32(struct xe_gt *gt, u16 key, u32 value) 88 { 89 u32 klv[] = { 90 PREP_GUC_KLV(key, 1), 91 value, 92 }; 93 94 return pf_push_policy_klvs(gt, 1, klv, ARRAY_SIZE(klv)); 95 } 96 97 static int pf_update_policy_bool(struct xe_gt *gt, u16 key, bool *policy, bool value) 98 { 99 int err; 100 101 err = pf_push_policy_u32(gt, key, value); 102 if (unlikely(err)) { 103 xe_gt_sriov_notice(gt, "Failed to update policy %#x '%s' to '%s' (%pe)\n", 104 key, xe_guc_klv_key_to_string(key), 105 str_enabled_disabled(value), ERR_PTR(err)); 106 return err; 107 } 108 109 xe_gt_sriov_dbg(gt, "policy key %#x '%s' updated to '%s'\n", 110 key, xe_guc_klv_key_to_string(key), 111 str_enabled_disabled(value)); 112 113 *policy = value; 114 return 0; 115 } 116 117 static int pf_update_policy_u32(struct xe_gt *gt, u16 key, u32 *policy, u32 value) 118 { 119 int err; 120 121 err = pf_push_policy_u32(gt, key, value); 122 if (unlikely(err)) { 123 xe_gt_sriov_notice(gt, "Failed to update policy %#x '%s' to '%s' (%pe)\n", 124 key, xe_guc_klv_key_to_string(key), 125 str_enabled_disabled(value), ERR_PTR(err)); 126 return err; 127 } 128 129 xe_gt_sriov_dbg(gt, "policy key %#x '%s' updated to %u\n", 130 key, xe_guc_klv_key_to_string(key), value); 131 132 *policy = value; 133 return 0; 134 } 135 136 static void pf_bulk_reset_sched_priority(struct xe_gt *gt, u32 priority) 137 { 138 unsigned int total_vfs = 1 + xe_gt_sriov_pf_get_totalvfs(gt); 139 unsigned int n; 140 141 xe_gt_assert(gt, IS_SRIOV_PF(gt_to_xe(gt))); 142 lockdep_assert_held(xe_gt_sriov_pf_master_mutex(gt)); 143 144 for (n = 0; n < total_vfs; n++) 145 gt->sriov.pf.vfs[n].config.sched_priority = priority; 146 } 147 148 static int pf_provision_sched_if_idle(struct xe_gt *gt, bool enable) 149 { 150 int err; 151 152 xe_gt_assert(gt, IS_SRIOV_PF(gt_to_xe(gt))); 153 lockdep_assert_held(xe_gt_sriov_pf_master_mutex(gt)); 154 155 err = pf_update_policy_bool(gt, GUC_KLV_VGT_POLICY_SCHED_IF_IDLE_KEY, 156 >->sriov.pf.policy.guc.sched_if_idle, 157 enable); 158 159 if (!err) 160 pf_bulk_reset_sched_priority(gt, enable ? GUC_SCHED_PRIORITY_NORMAL : 161 GUC_SCHED_PRIORITY_LOW); 162 return err; 163 } 164 165 static int pf_reprovision_sched_if_idle(struct xe_gt *gt) 166 { 167 xe_gt_assert(gt, IS_SRIOV_PF(gt_to_xe(gt))); 168 lockdep_assert_held(xe_gt_sriov_pf_master_mutex(gt)); 169 170 return pf_provision_sched_if_idle(gt, gt->sriov.pf.policy.guc.sched_if_idle); 171 } 172 173 static void pf_sanitize_sched_if_idle(struct xe_gt *gt) 174 { 175 xe_gt_assert(gt, IS_SRIOV_PF(gt_to_xe(gt))); 176 lockdep_assert_held(xe_gt_sriov_pf_master_mutex(gt)); 177 178 gt->sriov.pf.policy.guc.sched_if_idle = false; 179 } 180 181 /** 182 * xe_gt_sriov_pf_policy_set_sched_if_idle - Control the 'sched_if_idle' policy. 183 * @gt: the &xe_gt where to apply the policy 184 * @enable: the value of the 'sched_if_idle' policy 185 * 186 * This function can only be called on PF. 187 * 188 * Return: 0 on success or a negative error code on failure. 189 */ 190 int xe_gt_sriov_pf_policy_set_sched_if_idle(struct xe_gt *gt, bool enable) 191 { 192 int err; 193 194 mutex_lock(xe_gt_sriov_pf_master_mutex(gt)); 195 err = pf_provision_sched_if_idle(gt, enable); 196 mutex_unlock(xe_gt_sriov_pf_master_mutex(gt)); 197 198 return err; 199 } 200 201 /** 202 * xe_gt_sriov_pf_policy_get_sched_if_idle - Retrieve value of 'sched_if_idle' policy. 203 * @gt: the &xe_gt where to read the policy from 204 * 205 * This function can only be called on PF. 206 * 207 * Return: value of 'sched_if_idle' policy. 208 */ 209 bool xe_gt_sriov_pf_policy_get_sched_if_idle(struct xe_gt *gt) 210 { 211 bool enable; 212 213 xe_gt_assert(gt, IS_SRIOV_PF(gt_to_xe(gt))); 214 215 mutex_lock(xe_gt_sriov_pf_master_mutex(gt)); 216 enable = gt->sriov.pf.policy.guc.sched_if_idle; 217 mutex_unlock(xe_gt_sriov_pf_master_mutex(gt)); 218 219 return enable; 220 } 221 222 static int pf_provision_reset_engine(struct xe_gt *gt, bool enable) 223 { 224 xe_gt_assert(gt, IS_SRIOV_PF(gt_to_xe(gt))); 225 lockdep_assert_held(xe_gt_sriov_pf_master_mutex(gt)); 226 227 return pf_update_policy_bool(gt, GUC_KLV_VGT_POLICY_RESET_AFTER_VF_SWITCH_KEY, 228 >->sriov.pf.policy.guc.reset_engine, enable); 229 } 230 231 static int pf_reprovision_reset_engine(struct xe_gt *gt) 232 { 233 xe_gt_assert(gt, IS_SRIOV_PF(gt_to_xe(gt))); 234 lockdep_assert_held(xe_gt_sriov_pf_master_mutex(gt)); 235 236 return pf_provision_reset_engine(gt, gt->sriov.pf.policy.guc.reset_engine); 237 } 238 239 static void pf_sanitize_reset_engine(struct xe_gt *gt) 240 { 241 xe_gt_assert(gt, IS_SRIOV_PF(gt_to_xe(gt))); 242 lockdep_assert_held(xe_gt_sriov_pf_master_mutex(gt)); 243 244 gt->sriov.pf.policy.guc.reset_engine = false; 245 } 246 247 /** 248 * xe_gt_sriov_pf_policy_set_reset_engine - Control the 'reset_engine' policy. 249 * @gt: the &xe_gt where to apply the policy 250 * @enable: the value of the 'reset_engine' policy 251 * 252 * This function can only be called on PF. 253 * 254 * Return: 0 on success or a negative error code on failure. 255 */ 256 int xe_gt_sriov_pf_policy_set_reset_engine(struct xe_gt *gt, bool enable) 257 { 258 int err; 259 260 mutex_lock(xe_gt_sriov_pf_master_mutex(gt)); 261 err = pf_provision_reset_engine(gt, enable); 262 mutex_unlock(xe_gt_sriov_pf_master_mutex(gt)); 263 264 return err; 265 } 266 267 /** 268 * xe_gt_sriov_pf_policy_get_reset_engine - Retrieve value of 'reset_engine' policy. 269 * @gt: the &xe_gt where to read the policy from 270 * 271 * This function can only be called on PF. 272 * 273 * Return: value of 'reset_engine' policy. 274 */ 275 bool xe_gt_sriov_pf_policy_get_reset_engine(struct xe_gt *gt) 276 { 277 bool enable; 278 279 xe_gt_assert(gt, IS_SRIOV_PF(gt_to_xe(gt))); 280 281 mutex_lock(xe_gt_sriov_pf_master_mutex(gt)); 282 enable = gt->sriov.pf.policy.guc.reset_engine; 283 mutex_unlock(xe_gt_sriov_pf_master_mutex(gt)); 284 285 return enable; 286 } 287 288 static int pf_provision_sample_period(struct xe_gt *gt, u32 value) 289 { 290 xe_gt_assert(gt, IS_SRIOV_PF(gt_to_xe(gt))); 291 lockdep_assert_held(xe_gt_sriov_pf_master_mutex(gt)); 292 293 return pf_update_policy_u32(gt, GUC_KLV_VGT_POLICY_ADVERSE_SAMPLE_PERIOD_KEY, 294 >->sriov.pf.policy.guc.sample_period, value); 295 } 296 297 static int pf_reprovision_sample_period(struct xe_gt *gt) 298 { 299 xe_gt_assert(gt, IS_SRIOV_PF(gt_to_xe(gt))); 300 lockdep_assert_held(xe_gt_sriov_pf_master_mutex(gt)); 301 302 return pf_provision_sample_period(gt, gt->sriov.pf.policy.guc.sample_period); 303 } 304 305 static void pf_sanitize_sample_period(struct xe_gt *gt) 306 { 307 xe_gt_assert(gt, IS_SRIOV_PF(gt_to_xe(gt))); 308 lockdep_assert_held(xe_gt_sriov_pf_master_mutex(gt)); 309 310 gt->sriov.pf.policy.guc.sample_period = 0; 311 } 312 313 /** 314 * xe_gt_sriov_pf_policy_set_sample_period - Control the 'sample_period' policy. 315 * @gt: the &xe_gt where to apply the policy 316 * @value: the value of the 'sample_period' policy 317 * 318 * This function can only be called on PF. 319 * 320 * Return: 0 on success or a negative error code on failure. 321 */ 322 int xe_gt_sriov_pf_policy_set_sample_period(struct xe_gt *gt, u32 value) 323 { 324 int err; 325 326 mutex_lock(xe_gt_sriov_pf_master_mutex(gt)); 327 err = pf_provision_sample_period(gt, value); 328 mutex_unlock(xe_gt_sriov_pf_master_mutex(gt)); 329 330 return err; 331 } 332 333 /** 334 * xe_gt_sriov_pf_policy_get_sample_period - Retrieve value of 'sample_period' policy. 335 * @gt: the &xe_gt where to read the policy from 336 * 337 * This function can only be called on PF. 338 * 339 * Return: value of 'sample_period' policy. 340 */ 341 u32 xe_gt_sriov_pf_policy_get_sample_period(struct xe_gt *gt) 342 { 343 u32 value; 344 345 xe_gt_assert(gt, IS_SRIOV_PF(gt_to_xe(gt))); 346 347 mutex_lock(xe_gt_sriov_pf_master_mutex(gt)); 348 value = gt->sriov.pf.policy.guc.sample_period; 349 mutex_unlock(xe_gt_sriov_pf_master_mutex(gt)); 350 351 return value; 352 } 353 354 static void pf_sanitize_guc_policies(struct xe_gt *gt) 355 { 356 pf_sanitize_sched_if_idle(gt); 357 pf_sanitize_reset_engine(gt); 358 pf_sanitize_sample_period(gt); 359 } 360 361 /** 362 * xe_gt_sriov_pf_policy_sanitize - Reset policy settings. 363 * @gt: the &xe_gt 364 * 365 * This function can only be called on PF. 366 * 367 * Return: 0 on success or a negative error code on failure. 368 */ 369 void xe_gt_sriov_pf_policy_sanitize(struct xe_gt *gt) 370 { 371 mutex_lock(xe_gt_sriov_pf_master_mutex(gt)); 372 pf_sanitize_guc_policies(gt); 373 mutex_unlock(xe_gt_sriov_pf_master_mutex(gt)); 374 } 375 376 /** 377 * xe_gt_sriov_pf_policy_reprovision - Reprovision (and optionally reset) policy settings. 378 * @gt: the &xe_gt 379 * @reset: if true will reprovision using default values instead of latest 380 * 381 * This function can only be called on PF. 382 * 383 * Return: 0 on success or a negative error code on failure. 384 */ 385 int xe_gt_sriov_pf_policy_reprovision(struct xe_gt *gt, bool reset) 386 { 387 int err = 0; 388 389 xe_pm_runtime_get_noresume(gt_to_xe(gt)); 390 391 mutex_lock(xe_gt_sriov_pf_master_mutex(gt)); 392 if (reset) 393 pf_sanitize_guc_policies(gt); 394 err |= pf_reprovision_sched_if_idle(gt); 395 err |= pf_reprovision_reset_engine(gt); 396 err |= pf_reprovision_sample_period(gt); 397 mutex_unlock(xe_gt_sriov_pf_master_mutex(gt)); 398 399 xe_pm_runtime_put(gt_to_xe(gt)); 400 401 return err ? -ENXIO : 0; 402 } 403 404 static void print_guc_policies(struct drm_printer *p, struct xe_gt_sriov_guc_policies *policy) 405 { 406 drm_printf(p, "%s:\t%s\n", 407 xe_guc_klv_key_to_string(GUC_KLV_VGT_POLICY_SCHED_IF_IDLE_KEY), 408 str_enabled_disabled(policy->sched_if_idle)); 409 drm_printf(p, "%s:\t%s\n", 410 xe_guc_klv_key_to_string(GUC_KLV_VGT_POLICY_RESET_AFTER_VF_SWITCH_KEY), 411 str_enabled_disabled(policy->reset_engine)); 412 drm_printf(p, "%s:\t%u %s\n", 413 xe_guc_klv_key_to_string(GUC_KLV_VGT_POLICY_ADVERSE_SAMPLE_PERIOD_KEY), 414 policy->sample_period, policy->sample_period ? "ms" : "(disabled)"); 415 } 416 417 /** 418 * xe_gt_sriov_pf_policy_print - Dump actual policy values. 419 * @gt: the &xe_gt where to read the policy from 420 * @p: the &drm_printer 421 * 422 * This function can only be called on PF. 423 * 424 * Return: 0 on success or a negative error code on failure. 425 */ 426 int xe_gt_sriov_pf_policy_print(struct xe_gt *gt, struct drm_printer *p) 427 { 428 xe_gt_assert(gt, IS_SRIOV_PF(gt_to_xe(gt))); 429 430 mutex_lock(xe_gt_sriov_pf_master_mutex(gt)); 431 print_guc_policies(p, >->sriov.pf.policy.guc); 432 mutex_unlock(xe_gt_sriov_pf_master_mutex(gt)); 433 434 return 0; 435 } 436